Skip to content

Commit 7e831cc

Browse files
changeDirectoryToWorkspaceRoot will return to previous dir
In windows use pushd and popd to change directory. In bash we can use a subshell which has the benefit of guaranteeing that we return to the original directory without needing to run a second command.
1 parent 7e6cfa2 commit 7e831cc

5 files changed

Lines changed: 50 additions & 13 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
All notable changes to the "spec-runner" extension will be documented in this file.
44

5+
## [4.0.0]
6+
7+
- Changing directory to workspace root will now return to the previous directory after the command has finished
8+
- (I don't have access to a windows machine so have done my best but can't guarantee that it isn't broken)
9+
510
## [3.11.0]
611

712
- Remove underline for passed tests to reduce visual noise

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
},
1010
"icon": "images/icon.png",
1111
"license": "MIT",
12-
"version": "3.11.0",
12+
"version": "4.0.0",
1313
"engines": {
1414
"vscode": "^1.94.0"
1515
},

src/minitest/MinitestRunner.ts

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as vscode from 'vscode';
22
import SpecRunnerConfig, { TerminalClear } from '../SpecRunnerConfig';
3-
import { cmdJoin, quote, remapPath, stringifyEnvs, teeCommand } from '../util';
3+
import { cdCommands, cmdJoin, quote, remapPath, stringifyEnvs, teeCommand } from '../util';
44
import SpecResultPresenter from '../SpecResultPresenter';
55
import { RubyDebugger, RunRspecOrMinitestArg } from '../types';
66

@@ -122,21 +122,33 @@ export class MinitestRunner {
122122
}
123123
const minitestArgs = [quote(testFile), testNameFilter].filter(Boolean).join(' -- ');
124124

125-
const cdCommand = this.buildChangeDirectoryToWorkspaceRootCommand();
125+
const [cdCommand, returnCommand] = this.buildChangeDirectoryToWorkspaceRootCommand();
126126
const minitestCommand = [stringifyEnvs(this.config.minitestEnv), this.config.minitestCommand, minitestArgs].filter(Boolean).join(' ');
127127

128128
const lineNumber = lines.length ? JSON.stringify(lines) : 'ALL';
129129
const saveRunOptions = cmdJoin(`echo ${fileName} > ${this.outputFilePath}`, `echo ${quote(lineNumber)} >> ${this.outputFilePath}`);
130130
const outputRedirect = `| ${teeCommand(this.outputFilePath, true, this.config.usingBashInWindows)}`;
131+
132+
let fullCommand;
131133
if (this.config.minitestDecorateEditorWithResults) {
132-
return cmdJoin(cdCommand, saveRunOptions, [minitestCommand, outputRedirect].filter(Boolean).join(' '));
134+
fullCommand = cmdJoin(cdCommand, saveRunOptions, [minitestCommand, outputRedirect].filter(Boolean).join(' '));
135+
} else {
136+
fullCommand = cmdJoin(cdCommand, minitestCommand);
133137
}
134138

135-
return cmdJoin(cdCommand, minitestCommand);
139+
if (returnCommand === false) {
140+
return `(${fullCommand})`;
141+
} else {
142+
return cmdJoin(fullCommand, returnCommand);
143+
}
136144
}
137145

138146
private buildChangeDirectoryToWorkspaceRootCommand() {
139-
return this.config.changeDirectoryToWorkspaceRoot ? `cd ${quote(this.config.projectPath)}` : '';
147+
if (!this.config.changeDirectoryToWorkspaceRoot) {
148+
return ['', ''];
149+
}
150+
151+
return cdCommands(this.config.projectPath, this.config.usingBashInWindows);
140152
}
141153

142154
private remappedPath(filePath: string) {

src/rspec/SpecRunner.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as vscode from 'vscode';
22
import SpecRunnerConfig, { TerminalClear } from '../SpecRunnerConfig';
3-
import { cmdJoin, quote, remapPath, stringifyEnvs } from '../util';
3+
import { cdCommands, cmdJoin, quote, remapPath, stringifyEnvs } from '../util';
44
import SpecResultPresenter from '../SpecResultPresenter';
55
import { RubyDebugger, RunRspecOrMinitestArg } from '../types';
66

@@ -117,17 +117,23 @@ export class SpecRunner {
117117
const format = `-f ${this.config.rspecFormat}`;
118118
const jsonOutput = this.config.rspecDecorateEditorWithResults ? `-f j --out ${quote(this.outputFilePath)}` : '';
119119

120-
const cdCommand = this.buildChangeDirectoryToWorkspaceRootCommand();
120+
const [cdCommand, returnCommand] = this.buildChangeDirectoryToWorkspaceRootCommand();
121121
const rspecCommand = [stringifyEnvs(this.config.rspecEnv), this.config.rspecCommand, failedOnlyModifier, format, jsonOutput, quote(file)].filter(Boolean).join(' ');
122-
return cmdJoin(cdCommand, rspecCommand);
122+
123+
const fullCommand = cmdJoin(cdCommand, rspecCommand, returnCommand || '');
124+
return returnCommand === false ? `(${fullCommand})` : fullCommand;
123125
}
124126

125127
private remappedPath(filePath: string) {
126128
return remapPath(filePath, this.config.rewriteTestPaths);
127129
}
128130

129131
private buildChangeDirectoryToWorkspaceRootCommand() {
130-
return this.config.changeDirectoryToWorkspaceRoot ? `cd ${quote(this.config.projectPath)}` : '';
132+
if (!this.config.changeDirectoryToWorkspaceRoot) {
133+
return ['', ''];
134+
}
135+
136+
return cdCommands(this.config.projectPath, this.config.usingBashInWindows);
131137
}
132138

133139
private async runTerminalCommand(command: string) {

src/util.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,23 @@ export function teeCommand(outputFile: string, append = false, bashInWindowsOver
1616
return command.join(' ');
1717
}
1818

19-
// Windows will still execute second command even if first command fails.
20-
export function cmdJoin(...args: string[]): string {
21-
return args.filter(Boolean).join(isWindows() ? '; ' : ' && ');
19+
/**
20+
* Returns two commands, the cdCommand and the returnCommand.
21+
*
22+
* If the returnCommand is false, then that means we should use a subshell to handle
23+
* returning to the current directory.
24+
*/
25+
export function cdCommands(path: string, bashInWindowsOverride = false): [string, string | false] {
26+
if (isWindows() && !bashInWindowsOverride) {
27+
return [`pushd ${quote(path)} >nul`, 'popd >nul'];
28+
}
29+
return [`cd ${quote(path)}`, false];
30+
}
31+
32+
export function cmdJoin(...args: Array<string>): string {
33+
return args
34+
.filter(Boolean)
35+
.join(isWindows() ? '; ' : ' && ');
2236
}
2337

2438
export function isRspecOutput(output: any): output is RspecOutput {

0 commit comments

Comments
 (0)