From f0a8658737b54bf840a1a29fa152d5b8f103bbee Mon Sep 17 00:00:00 2001 From: Aziz Fikri Date: Thu, 28 Oct 2021 23:15:45 +0700 Subject: [PATCH 1/5] change drive first before directory when run on windows and has ':' in path --- .../codeExecution/terminalCodeExecution.ts | 4 ++++ .../codeExecution/terminalCodeExec.unit.test.ts | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/client/terminals/codeExecution/terminalCodeExecution.ts b/src/client/terminals/codeExecution/terminalCodeExecution.ts index e3277ce18566..0c123539c7c1 100644 --- a/src/client/terminals/codeExecution/terminalCodeExecution.ts +++ b/src/client/terminals/codeExecution/terminalCodeExecution.ts @@ -92,6 +92,10 @@ 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 drive = fileDirPath.replace(/\:.*/g, ''); + await this.getTerminalService(file).sendText(`${drive}:`); + } 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..2c8f97b5ea3e 100644 --- a/src/test/terminals/codeExecution/terminalCodeExec.unit.test.ts +++ b/src/test/terminals/codeExecution/terminalCodeExec.unit.test.ts @@ -163,6 +163,22 @@ 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.getWorkspaceFolder(TypeMoq.It.isAny())).returns(() => workspaceFolder.object); + workspaceFolder.setup((w) => w.uri).returns(() => Uri.file(path.join('d:', '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 ensureWeSetCurrentDirectoryBeforeExecutingAFile(_isWindows: boolean): Promise { const file = Uri.file(path.join('c', 'path', 'to', 'file', 'one.py')); terminalSettings.setup((t) => t.executeInFileDir).returns(() => true); From 9b4c0dac26c1242a1eab9726c295b22872182af9 Mon Sep 17 00:00:00 2001 From: Aziz Fikri Date: Thu, 28 Oct 2021 23:50:14 +0700 Subject: [PATCH 2/5] add news file --- news/2 Fixes/14730.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 news/2 Fixes/14730.md 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)) From b725bf63fa9a4dec77db91e518f4b00b2bb6915e Mon Sep 17 00:00:00 2001 From: Aziz Fikri Date: Fri, 29 Oct 2021 16:57:08 +0700 Subject: [PATCH 3/5] check currentDrive first, if it's different then change current drive --- .../terminals/codeExecution/terminalCodeExecution.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/client/terminals/codeExecution/terminalCodeExecution.ts b/src/client/terminals/codeExecution/terminalCodeExecution.ts index 0c123539c7c1..63c44be38ae9 100644 --- a/src/client/terminals/codeExecution/terminalCodeExecution.ts +++ b/src/client/terminals/codeExecution/terminalCodeExecution.ts @@ -93,8 +93,14 @@ 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 drive = fileDirPath.replace(/\:.*/g, ''); - await this.getTerminalService(file).sendText(`${drive}:`); + 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()}`); } From 8d03beb459c1d532b55ab612213a38be0cc5576a Mon Sep 17 00:00:00 2001 From: Aziz Fikri Date: Fri, 29 Oct 2021 16:57:42 +0700 Subject: [PATCH 4/5] modify workspace in testing case --- src/test/terminals/codeExecution/terminalCodeExec.unit.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/terminals/codeExecution/terminalCodeExec.unit.test.ts b/src/test/terminals/codeExecution/terminalCodeExec.unit.test.ts index 2c8f97b5ea3e..dd087c77edcd 100644 --- a/src/test/terminals/codeExecution/terminalCodeExec.unit.test.ts +++ b/src/test/terminals/codeExecution/terminalCodeExec.unit.test.ts @@ -167,7 +167,7 @@ suite('Terminal - Code Execution', () => { const file = Uri.file(path.join('d:', 'path', 'to', 'file', 'one.py')); terminalSettings.setup((t) => t.executeInFileDir).returns(() => true); workspace.setup((w) => w.getWorkspaceFolder(TypeMoq.It.isAny())).returns(() => workspaceFolder.object); - workspaceFolder.setup((w) => w.uri).returns(() => Uri.file(path.join('d:', '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(() => []); From 54a103881dc7e50fb7d7daf94445144bc640ec20 Mon Sep 17 00:00:00 2001 From: Aziz Fikri Date: Sat, 30 Oct 2021 02:19:06 +0700 Subject: [PATCH 5/5] modify test to mock workspace rootPath instead of workspace folder and add another test --- .../terminalCodeExec.unit.test.ts | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/test/terminals/codeExecution/terminalCodeExec.unit.test.ts b/src/test/terminals/codeExecution/terminalCodeExec.unit.test.ts index dd087c77edcd..7644b592a249 100644 --- a/src/test/terminals/codeExecution/terminalCodeExec.unit.test.ts +++ b/src/test/terminals/codeExecution/terminalCodeExec.unit.test.ts @@ -166,7 +166,7 @@ suite('Terminal - Code Execution', () => { 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.getWorkspaceFolder(TypeMoq.It.isAny())).returns(() => workspaceFolder.object); + 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); @@ -179,6 +179,24 @@ suite('Terminal - Code Execution', () => { 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);