diff --git a/news/2 Fixes/14730.md b/news/2 Fixes/14730.md new file mode 100644 index 000000000000..1cc2782becc2 --- /dev/null +++ b/news/2 Fixes/14730.md @@ -0,0 +1 @@ +Change drive first before changing directory in windows, to anticipate running file outside working directory with different storage drive. (thanks [afikrim](https://github.com/afikrim)) diff --git a/src/client/terminals/codeExecution/terminalCodeExecution.ts b/src/client/terminals/codeExecution/terminalCodeExecution.ts index e3277ce18566..63c44be38ae9 100644 --- a/src/client/terminals/codeExecution/terminalCodeExecution.ts +++ b/src/client/terminals/codeExecution/terminalCodeExecution.ts @@ -92,6 +92,16 @@ export class TerminalCodeExecutionProvider implements ICodeExecutionService { } const fileDirPath = path.dirname(file.fsPath); if (fileDirPath.length > 0) { + if (this.platformService.isWindows && /[a-z]\:/i.test(fileDirPath)) { + const currentDrive = + typeof this.workspace.rootPath === 'string' + ? this.workspace.rootPath.replace(/\:.*/g, '') + : undefined; + const fileDrive = fileDirPath.replace(/\:.*/g, ''); + if (fileDrive !== currentDrive) { + await this.getTerminalService(file).sendText(`${fileDrive}:`); + } + } await this.getTerminalService(file).sendText(`cd ${fileDirPath.fileToCommandArgument()}`); } } diff --git a/src/test/terminals/codeExecution/terminalCodeExec.unit.test.ts b/src/test/terminals/codeExecution/terminalCodeExec.unit.test.ts index 1bdfd90253fe..7644b592a249 100644 --- a/src/test/terminals/codeExecution/terminalCodeExec.unit.test.ts +++ b/src/test/terminals/codeExecution/terminalCodeExec.unit.test.ts @@ -163,6 +163,40 @@ suite('Terminal - Code Execution', () => { .returns(() => terminalService.object); }); + async function ensureWeSetCurrentDriveBeforeChangingDirectory(_isWindows: boolean): Promise { + const file = Uri.file(path.join('d:', 'path', 'to', 'file', 'one.py')); + terminalSettings.setup((t) => t.executeInFileDir).returns(() => true); + workspace.setup((w) => w.rootPath).returns(() => path.join('c:', 'path', 'to')); + workspaceFolder.setup((w) => w.uri).returns(() => Uri.file(path.join('c:', 'path', 'to'))); + platform.setup((p) => p.isWindows).returns(() => true); + settings.setup((s) => s.pythonPath).returns(() => PYTHON_PATH); + terminalSettings.setup((t) => t.launchArgs).returns(() => []); + + await executor.executeFile(file); + terminalService.verify(async (t) => t.sendText(TypeMoq.It.isValue('d:')), TypeMoq.Times.once()); + } + test('Ensure we set current drive before changing directory on windows', async () => { + await ensureWeSetCurrentDriveBeforeChangingDirectory(true); + }); + + async function ensureWeDoNotChangeDriveIfDriveLetterSameAsFileDriveLetter( + _isWindows: boolean, + ): Promise { + const file = Uri.file(path.join('c:', 'path', 'to', 'file', 'one.py')); + terminalSettings.setup((t) => t.executeInFileDir).returns(() => true); + workspace.setup((w) => w.rootPath).returns(() => path.join('c:', 'path', 'to')); + workspaceFolder.setup((w) => w.uri).returns(() => Uri.file(path.join('c:', 'path', 'to'))); + platform.setup((p) => p.isWindows).returns(() => true); + settings.setup((s) => s.pythonPath).returns(() => PYTHON_PATH); + terminalSettings.setup((t) => t.launchArgs).returns(() => []); + + await executor.executeFile(file); + terminalService.verify(async (t) => t.sendText(TypeMoq.It.isValue('c:')), TypeMoq.Times.never()); + } + test('Ensure we do not change drive if current drive letter is same as the file drive letter on windows', async () => { + await ensureWeDoNotChangeDriveIfDriveLetterSameAsFileDriveLetter(true); + }); + async function ensureWeSetCurrentDirectoryBeforeExecutingAFile(_isWindows: boolean): Promise { const file = Uri.file(path.join('c', 'path', 'to', 'file', 'one.py')); terminalSettings.setup((t) => t.executeInFileDir).returns(() => true);