diff --git a/.vscode/launch.json b/.vscode/launch.json index 3cc9f6c671c6..3fbf982ae0b3 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -8,12 +8,12 @@ "request": "launch", "runtimeExecutable": "${execPath}", "args": [ - "--extensionDevelopmentPath=${workspaceRoot}" + "--extensionDevelopmentPath=${workspaceFolder}" ], "stopOnEntry": false, "sourceMaps": true, "outFiles": [ - "${workspaceRoot}/out/**/*.js" + "${workspaceFolder}/out/**/*.js" ], "preLaunchTask": "compile" }, @@ -21,16 +21,16 @@ "name": "Launch Extension as debugServer", // https://code.visualstudio.com/docs/extensions/example-debuggers "type": "node", "request": "launch", - "program": "${workspaceRoot}/out/client/debugger/Main.js", + "program": "${workspaceFolder}/out/client/debugger/Main.js", "stopOnEntry": false, "args": [ "--server=4711" ], "sourceMaps": true, "outFiles": [ - "${workspaceRoot}/out/client/**/*.js" + "${workspaceFolder}/out/client/**/*.js" ], - "cwd": "${workspaceRoot}" + "cwd": "${workspaceFolder}" }, { "name": "Launch Tests", @@ -38,14 +38,14 @@ "request": "launch", "runtimeExecutable": "${execPath}", "args": [ - "${workspaceRoot}/src/test", - "--extensionDevelopmentPath=${workspaceRoot}", - "--extensionTestsPath=${workspaceRoot}/out/test" + "${workspaceFolder}/src/test", + "--extensionDevelopmentPath=${workspaceFolder}", + "--extensionTestsPath=${workspaceFolder}/out/test" ], "stopOnEntry": false, "sourceMaps": true, "outFiles": [ - "${workspaceRoot}/out/**/*.js" + "${workspaceFolder}/out/**/*.js" ], "preLaunchTask": "compile" }, @@ -55,14 +55,14 @@ "request": "launch", "runtimeExecutable": "${execPath}", "args": [ - "${workspaceRoot}/src/testMultiRootWkspc/multi.code-workspace", - "--extensionDevelopmentPath=${workspaceRoot}", - "--extensionTestsPath=${workspaceRoot}/out/test" + "${workspaceFolder}/src/testMultiRootWkspc/multi.code-workspace", + "--extensionDevelopmentPath=${workspaceFolder}", + "--extensionTestsPath=${workspaceFolder}/out/test" ], "stopOnEntry": false, "sourceMaps": true, "outFiles": [ - "${workspaceRoot}/out/**/*.js" + "${workspaceFolder}/out/**/*.js" ], "preLaunchTask": "compile" } diff --git a/package.json b/package.json index c5d20e802b67..b483de2294ca 100644 --- a/package.json +++ b/package.json @@ -289,9 +289,9 @@ "stopOnEntry": true, "pythonPath": "^\"\\${config:python.pythonPath}\"", "program": "^\"\\${file}\"", - "cwd": "^\"\\${workspaceRoot}\"", + "cwd": "^\"\\${workspaceFolder}\"", "env": {}, - "envFile": "^\"\\${workspaceRoot}/.env\"", + "envFile": "^\"\\${workspaceFolder}/.env\"", "debugOptions": [ "RedirectOutput" ] @@ -315,9 +315,9 @@ "pythonPath": "^\"\\${env:SPARK_HOME}/bin/spark-submit\"" }, "program": "^\"\\${file}\"", - "cwd": "^\"\\${workspaceRoot}\"", + "cwd": "^\"\\${workspaceFolder}\"", "env": {}, - "envFile": "^\"\\${workspaceRoot}/.env\"", + "envFile": "^\"\\${workspaceFolder}/.env\"", "debugOptions": [ "RedirectOutput" ] @@ -333,9 +333,9 @@ "stopOnEntry": true, "pythonPath": "^\"\\${config:python.pythonPath}\"", "module": "module.name", - "cwd": "^\"\\${workspaceRoot}\"", + "cwd": "^\"\\${workspaceFolder}\"", "env": {}, - "envFile": "^\"\\${workspaceRoot}/.env\"", + "envFile": "^\"\\${workspaceFolder}/.env\"", "debugOptions": [ "RedirectOutput" ] @@ -354,7 +354,7 @@ "cwd": "", "console": "integratedTerminal", "env": {}, - "envFile": "^\"\\${workspaceRoot}/.env\"", + "envFile": "^\"\\${workspaceFolder}/.env\"", "debugOptions": [] } }, @@ -371,7 +371,7 @@ "cwd": "", "console": "externalTerminal", "env": {}, - "envFile": "^\"\\${workspaceRoot}/.env\"", + "envFile": "^\"\\${workspaceFolder}/.env\"", "debugOptions": [] } }, @@ -384,15 +384,15 @@ "request": "launch", "stopOnEntry": true, "pythonPath": "^\"\\${config:python.pythonPath}\"", - "program": "^\"\\${workspaceRoot}/manage.py\"", - "cwd": "^\"\\${workspaceRoot}\"", + "program": "^\"\\${workspaceFolder}/manage.py\"", + "cwd": "^\"\\${workspaceFolder}\"", "args": [ "runserver", "--noreload", "--nothreading" ], "env": {}, - "envFile": "^\"\\${workspaceRoot}/.env\"", + "envFile": "^\"\\${workspaceFolder}/.env\"", "debugOptions": [ "RedirectOutput", "DjangoDebugging" @@ -409,16 +409,16 @@ "stopOnEntry": false, "pythonPath": "^\"\\${config:python.pythonPath}\"", "program": "fully qualified path fo 'flask' executable. Generally located along with python interpreter", - "cwd": "^\"\\${workspaceRoot}\"", + "cwd": "^\"\\${workspaceFolder}\"", "env": { - "FLASK_APP": "^\"\\${workspaceRoot}/quickstart/app.py\"" + "FLASK_APP": "^\"\\${workspaceFolder}/quickstart/app.py\"" }, "args": [ "run", "--no-debugger", "--no-reload" ], - "envFile": "^\"\\${workspaceRoot}/.env\"", + "envFile": "^\"\\${workspaceFolder}/.env\"", "debugOptions": [ "RedirectOutput" ] @@ -433,11 +433,11 @@ "request": "launch", "stopOnEntry": false, "pythonPath": "^\"\\${config:python.pythonPath}\"", - "program": "^\"\\${workspaceRoot}/run.py\"", - "cwd": "^\"\\${workspaceRoot}\"", + "program": "^\"\\${workspaceFolder}/run.py\"", + "cwd": "^\"\\${workspaceFolder}\"", "args": [], "env": {}, - "envFile": "^\"\\${workspaceRoot}/.env\"", + "envFile": "^\"\\${workspaceFolder}/.env\"", "debugOptions": [ "RedirectOutput" ] @@ -452,11 +452,11 @@ "request": "launch", "stopOnEntry": true, "pythonPath": "^\"\\${config:python.pythonPath}\"", - "cwd": "^\"\\${workspaceRoot}\"", + "cwd": "^\"\\${workspaceFolder}\"", "env": {}, - "envFile": "^\"\\${workspaceRoot}/.env\"", + "envFile": "^\"\\${workspaceFolder}/.env\"", "args": [ - "^\"\\${workspaceRoot}/development.ini\"" + "^\"\\${workspaceFolder}/development.ini\"" ], "debugOptions": [ "RedirectOutput", @@ -473,15 +473,15 @@ "request": "launch", "stopOnEntry": true, "pythonPath": "^\"\\${config:python.pythonPath}\"", - "program": "^\"\\${workspaceRoot}/console.py\"", - "cwd": "^\"\\${workspaceRoot}\"", + "program": "^\"\\${workspaceFolder}/console.py\"", + "cwd": "^\"\\${workspaceFolder}\"", "args": [ "dev", "runserver", "--noreload=True" ], "env": {}, - "envFile": "^\"\\${workspaceRoot}/.env\"", + "envFile": "^\"\\${workspaceFolder}/.env\"", "debugOptions": [ "RedirectOutput" ] @@ -497,7 +497,7 @@ "stopOnEntry": true, "pythonPath": "^\"\\${config:python.pythonPath}\"", "program": "~/.virtualenvs/scrapy/bin/scrapy", - "cwd": "^\"\\${workspaceRoot}\"", + "cwd": "^\"\\${workspaceFolder}\"", "args": [ "crawl", "specs", @@ -506,7 +506,7 @@ ], "console": "integratedTerminal", "env": {}, - "envFile": "^\"\\${workspaceRoot}/.env\"", + "envFile": "^\"\\${workspaceFolder}/.env\"", "debugOptions": [] } }, @@ -517,8 +517,8 @@ "name": "Attach (Remote Debug)", "type": "python", "request": "attach", - "localRoot": "^\"\\${workspaceRoot}\"", - "remoteRoot": "^\"\\${workspaceRoot}\"", + "localRoot": "^\"\\${workspaceFolder}\"", + "remoteRoot": "^\"\\${workspaceFolder}\"", "port": 3000, "secret": "my_secret", "host": "localhost" @@ -639,7 +639,7 @@ "localRoot": { "type": "string", "description": "Local source root that corrresponds to the 'remoteRoot'.", - "default": "${workspaceRoot}" + "default": "${workspaceFolder}" }, "remoteRoot": { "type": "string", @@ -672,9 +672,9 @@ "stopOnEntry": true, "pythonPath": "${config:python.pythonPath}", "program": "${file}", - "cwd": "${workspaceRoot}", + "cwd": "${workspaceFolder}", "env": {}, - "envFile": "${workspaceRoot}/.env", + "envFile": "${workspaceFolder}/.env", "debugOptions": [ "RedirectOutput" ] @@ -683,8 +683,8 @@ "name": "Python: Attach", "type": "python", "request": "attach", - "localRoot": "${workspaceRoot}", - "remoteRoot": "${workspaceRoot}", + "localRoot": "${workspaceFolder}", + "remoteRoot": "${workspaceFolder}", "port": 3000, "secret": "my_secret", "host": "localhost" @@ -699,7 +699,7 @@ "cwd": "", "console": "integratedTerminal", "env": {}, - "envFile": "${workspaceRoot}/.env", + "envFile": "${workspaceFolder}/.env", "debugOptions": [] }, { @@ -712,7 +712,7 @@ "cwd": "", "console": "externalTerminal", "env": {}, - "envFile": "${workspaceRoot}/.env", + "envFile": "${workspaceFolder}/.env", "debugOptions": [] }, { @@ -721,15 +721,15 @@ "request": "launch", "stopOnEntry": true, "pythonPath": "${config:python.pythonPath}", - "program": "${workspaceRoot}/manage.py", - "cwd": "${workspaceRoot}", + "program": "${workspaceFolder}/manage.py", + "cwd": "${workspaceFolder}", "args": [ "runserver", "--noreload", "--nothreading" ], "env": {}, - "envFile": "${workspaceRoot}/.env", + "envFile": "${workspaceFolder}/.env", "debugOptions": [ "RedirectOutput", "DjangoDebugging" @@ -742,16 +742,16 @@ "stopOnEntry": false, "pythonPath": "${config:python.pythonPath}", "program": "fully qualified path fo 'flask' executable. Generally located along with python interpreter", - "cwd": "${workspaceRoot}", + "cwd": "${workspaceFolder}", "env": { - "FLASK_APP": "${workspaceRoot}/quickstart/app.py" + "FLASK_APP": "${workspaceFolder}/quickstart/app.py" }, "args": [ "run", "--no-debugger", "--no-reload" ], - "envFile": "${workspaceRoot}/.env", + "envFile": "${workspaceFolder}/.env", "debugOptions": [ "RedirectOutput" ] @@ -762,11 +762,11 @@ "request": "launch", "stopOnEntry": false, "pythonPath": "${config:python.pythonPath}", - "program": "${workspaceRoot}/run.py", - "cwd": "${workspaceRoot}", + "program": "${workspaceFolder}/run.py", + "cwd": "${workspaceFolder}", "args": [], "env": {}, - "envFile": "${workspaceRoot}/.env", + "envFile": "${workspaceFolder}/.env", "debugOptions": [ "RedirectOutput" ] @@ -786,9 +786,9 @@ "pythonPath": "${env:SPARK_HOME}/bin/spark-submit" }, "program": "${file}", - "cwd": "${workspaceRoot}", + "cwd": "${workspaceFolder}", "env": {}, - "envFile": "${workspaceRoot}/.env", + "envFile": "${workspaceFolder}/.env", "debugOptions": [ "RedirectOutput" ] @@ -800,9 +800,9 @@ "stopOnEntry": true, "pythonPath": "${config:python.pythonPath}", "module": "module.name", - "cwd": "${workspaceRoot}", + "cwd": "${workspaceFolder}", "env": {}, - "envFile": "${workspaceRoot}/.env", + "envFile": "${workspaceFolder}/.env", "debugOptions": [ "RedirectOutput" ] @@ -813,11 +813,11 @@ "request": "launch", "stopOnEntry": true, "pythonPath": "${config:python.pythonPath}", - "cwd": "${workspaceRoot}", + "cwd": "${workspaceFolder}", "env": {}, - "envFile": "${workspaceRoot}/.env", + "envFile": "${workspaceFolder}/.env", "args": [ - "${workspaceRoot}/development.ini" + "${workspaceFolder}/development.ini" ], "debugOptions": [ "RedirectOutput", @@ -830,15 +830,15 @@ "request": "launch", "stopOnEntry": true, "pythonPath": "${config:python.pythonPath}", - "program": "${workspaceRoot}/console.py", - "cwd": "${workspaceRoot}", + "program": "${workspaceFolder}/console.py", + "cwd": "${workspaceFolder}", "args": [ "dev", "runserver", "--noreload=True" ], "env": {}, - "envFile": "${workspaceRoot}/.env", + "envFile": "${workspaceFolder}/.env", "debugOptions": [ "RedirectOutput" ] @@ -871,7 +871,7 @@ "python.envFile": { "type": "string", "description": "Absolute path to a file containing environment variable definitions.", - "default": "${workspaceRoot}/.env", + "default": "${workspaceFolder}/.env", "scope": "resource" }, "python.jediPath": { @@ -1300,7 +1300,7 @@ }, "python.workspaceSymbols.tagFilePath": { "type": "string", - "default": "${workspaceRoot}/.vscode/tags", + "default": "${workspaceFolder}/.vscode/tags", "description": "Fully qualified path to tag file (exuberant ctag file), used to provide workspace symbols.", "scope": "resource" }, diff --git a/src/client/common/systemVariables.ts b/src/client/common/systemVariables.ts index 444d782d6eea..50962cc77b64 100644 --- a/src/client/common/systemVariables.ts +++ b/src/client/common/systemVariables.ts @@ -131,27 +131,35 @@ export abstract class AbstractSystemVariables implements ISystemVariables { export class SystemVariables extends AbstractSystemVariables { - private _workspaceRoot: string; - private _workspaceRootFolderName: string; + private _workspaceFolder: string; + private _workspaceFolderName: string; - constructor(workspaceRoot?: string) { + constructor(workspaceFolder?: string) { super(); - this._workspaceRoot = typeof workspaceRoot === 'string' ? workspaceRoot : __dirname; - this._workspaceRootFolderName = Path.basename(this._workspaceRoot); + this._workspaceFolder = typeof workspaceFolder === 'string' ? workspaceFolder : __dirname; + this._workspaceFolderName = Path.basename(this._workspaceFolder); Object.keys(process.env).forEach(key => { this[`env:${key}`] = this[`env.${key}`] = process.env[key]; }); } public get cwd(): string { - return this.workspaceRoot; + return this.workspaceFolder; } public get workspaceRoot(): string { - return this._workspaceRoot; + return this._workspaceFolder; + } + + public get workspaceFolder(): string { + return this._workspaceFolder; } public get workspaceRootFolderName(): string { - return this._workspaceRootFolderName; + return this._workspaceFolderName; + } + + public get workspaceFolderBasename(): string { + return this._workspaceFolderName; } } diff --git a/src/client/interpreter/configuration/services/workspaceFolderUpdaterService.ts b/src/client/interpreter/configuration/services/workspaceFolderUpdaterService.ts index 37f45d5cde14..38224d7c4e50 100644 --- a/src/client/interpreter/configuration/services/workspaceFolderUpdaterService.ts +++ b/src/client/interpreter/configuration/services/workspaceFolderUpdaterService.ts @@ -14,7 +14,7 @@ export class WorkspaceFolderPythonPathUpdaterService implements IPythonPathUpdat } if (pythonPath.startsWith(this.workspaceFolder.fsPath)) { // tslint:disable-next-line:no-invalid-template-strings - pythonPath = path.join('${workspaceRoot}', path.relative(this.workspaceFolder.fsPath, pythonPath)); + pythonPath = path.join('${workspaceFolder}', path.relative(this.workspaceFolder.fsPath, pythonPath)); } await pythonConfig.update('pythonPath', pythonPath, ConfigurationTarget.WorkspaceFolder); } diff --git a/src/client/interpreter/configuration/services/workspaceUpdaterService.ts b/src/client/interpreter/configuration/services/workspaceUpdaterService.ts index a5a35c3483e5..51c0644c503e 100644 --- a/src/client/interpreter/configuration/services/workspaceUpdaterService.ts +++ b/src/client/interpreter/configuration/services/workspaceUpdaterService.ts @@ -14,7 +14,7 @@ export class WorkspacePythonPathUpdaterService implements IPythonPathUpdaterServ } if (pythonPath.startsWith(this.wkspace.fsPath)) { // tslint:disable-next-line:no-invalid-template-strings - pythonPath = path.join('${workspaceRoot}', path.relative(this.wkspace.fsPath, pythonPath)); + pythonPath = path.join('${workspaceFolder}', path.relative(this.wkspace.fsPath, pythonPath)); } await pythonConfig.update('pythonPath', pythonPath, false); } diff --git a/src/test/common/configSettings.multiroot.test.ts b/src/test/common/configSettings.multiroot.test.ts index dc7ef9590885..1f3190995858 100644 --- a/src/test/common/configSettings.multiroot.test.ts +++ b/src/test/common/configSettings.multiroot.test.ts @@ -162,7 +162,7 @@ suite('Multiroot Config Settings', () => { }); // tslint:disable-next-line:no-invalid-template-strings - test('${workspaceRoot} variable in settings should be replaced with the right value', async () => { + test('${workspaceFolder} variable in settings should be replaced with the right value', async () => { const workspace2Uri = Uri.file(path.join(multirootPath, 'workspace2')); let fileToOpen = path.join(workspace2Uri.fsPath, 'file.py'); diff --git a/src/test/interpreters/pythonPathUpdater.multiroot.test.ts b/src/test/interpreters/pythonPathUpdater.multiroot.test.ts index 05025376fe3d..f110790224d2 100644 --- a/src/test/interpreters/pythonPathUpdater.multiroot.test.ts +++ b/src/test/interpreters/pythonPathUpdater.multiroot.test.ts @@ -1,6 +1,7 @@ import * as assert from 'assert'; import * as path from 'path'; import { ConfigurationTarget, Uri, workspace } from 'vscode'; +import { PythonSettings } from '../../client/common/configSettings'; import { PythonPathUpdaterService } from '../../client/interpreter/configuration/pythonPathUpdaterService'; import { PythonPathUpdaterServiceFactory } from '../../client/interpreter/configuration/pythonPathUpdaterServiceFactory'; import { WorkspaceFolderPythonPathUpdaterService } from '../../client/interpreter/configuration/services/workspaceFolderUpdaterService'; @@ -32,20 +33,43 @@ suite('Multiroot Python Path Settings Updater', () => { test('Updating Workspace Folder Python Path should work', async () => { const workspaceUri = workspace3Uri; - const workspaceUpdater = new WorkspaceFolderPythonPathUpdaterService(workspace.getWorkspaceFolder(workspaceUri).uri); + const workspaceUpdater = new WorkspaceFolderPythonPathUpdaterService(workspace.getWorkspaceFolder(workspaceUri)!.uri); const pythonPath = `xWorkspacePythonPath${new Date().getMilliseconds()}`; await workspaceUpdater.updatePythonPath(pythonPath); - const folderValue = workspace.getConfiguration('python', workspace3Uri).inspect('pythonPath').workspaceFolderValue; + const folderValue = workspace.getConfiguration('python', workspace3Uri).inspect('pythonPath')!.workspaceFolderValue!; assert.equal(folderValue, pythonPath, 'Workspace Python Path not updated'); }); + test('Updating Workspace Folder Python Path when Python Path is in a sub directory of Workspace Folder', async () => { + const workspaceUri = workspace3Uri; + const workspaceFolder = workspace.getWorkspaceFolder(workspaceUri)!.uri; + const workspaceUpdater = new WorkspaceFolderPythonPathUpdaterService(workspaceFolder); + + // Python path within a sub directory of the workspace folder. + const pythonExec = path.join('virtual Envs', 'env1', `xWorkspacePythonPath${new Date().getMilliseconds()}`); + + // Expected path to python executable where ${workspaceFolder} token represents the fully qualified path to executable. + // tslint:disable-next-line:no-invalid-template-strings + const rawPythonPath = path.join('${workspaceFolder}', pythonExec); + + // Fully qualified path to the python executable. + const pythonPath = path.join(workspaceFolder.fsPath, pythonExec); + await workspaceUpdater.updatePythonPath(pythonPath); + PythonSettings.dispose(); + + const folderValue = workspace.getConfiguration('python', workspace3Uri).inspect('pythonPath')!.workspaceFolderValue!; + assert.equal(folderValue, rawPythonPath, 'Raw Workspace Python Path not updated with a path relative to workspace folder'); + const resolvedPythonPath = PythonSettings.getInstance(workspaceUri).pythonPath; + assert.equal(resolvedPythonPath, pythonPath, 'Resolved Workspace Python Path is incorrect'); + }); + test('Updating Workspace Folder Python Path using the factor service should work', async () => { const workspaceUri = workspace3Uri; const factory = new PythonPathUpdaterServiceFactory(); - const workspaceUpdater = factory.getWorkspaceFolderPythonPathConfigurationService(workspace.getWorkspaceFolder(workspaceUri).uri); + const workspaceUpdater = factory.getWorkspaceFolderPythonPathConfigurationService(workspace.getWorkspaceFolder(workspaceUri)!.uri); const pythonPath = `xWorkspacePythonPathFromFactory${new Date().getMilliseconds()}`; await workspaceUpdater.updatePythonPath(pythonPath); - const folderValue = workspace.getConfiguration('python', workspace3Uri).inspect('pythonPath').workspaceFolderValue; + const folderValue = workspace.getConfiguration('python', workspace3Uri).inspect('pythonPath')!.workspaceFolderValue!; assert.equal(folderValue, pythonPath, 'Workspace Python Path not updated'); }); @@ -53,19 +77,38 @@ suite('Multiroot Python Path Settings Updater', () => { const workspaceUri = workspace3Uri; const updaterService = new PythonPathUpdaterService(new PythonPathUpdaterServiceFactory(), new InterpreterVersionService()); const pythonPath = `xWorkspacePythonPathFromUpdater${new Date().getMilliseconds()}`; - await updaterService.updatePythonPath(pythonPath, ConfigurationTarget.WorkspaceFolder, 'ui', workspace.getWorkspaceFolder(workspaceUri).uri); - const folderValue = workspace.getConfiguration('python', workspace3Uri).inspect('pythonPath').workspaceFolderValue; + await updaterService.updatePythonPath(pythonPath, ConfigurationTarget.WorkspaceFolder, 'ui', workspace.getWorkspaceFolder(workspaceUri)!.uri); + const folderValue = workspace.getConfiguration('python', workspace3Uri).inspect('pythonPath')!.workspaceFolderValue!; assert.equal(folderValue, pythonPath, 'Workspace Python Path not updated'); }); - test('Python Path should be relative to workspace', async () => { - const workspaceUri = workspace.getWorkspaceFolder(workspace3Uri).uri; + // tslint:disable-next-line:no-invalid-template-strings + test('Python Paths containing ${workspaceRoot} should be resolved as ${workspaceFolder}', async () => { + const workspaceUri = workspace.getWorkspaceFolder(workspace3Uri)!.uri; + const pythonInterpreter = `xWorkspacePythonPath${new Date().getMilliseconds()}`; + // tslint:disable-next-line:no-invalid-template-strings + const pythonPath = path.join('${workspaceRoot}', 'x', 'y', 'z', pythonInterpreter); + const workspaceUpdater = new WorkspacePythonPathUpdaterService(workspaceUri); + await workspaceUpdater.updatePythonPath(pythonPath); + const workspaceValue = workspace.getConfiguration('python').inspect('pythonPath')!.workspaceValue!; + const resolvedPythonPath = path.join(workspaceUri.fsPath, 'x', 'y', 'z', pythonInterpreter); + // tslint:disable-next-line:no-invalid-template-strings + assert.equal(workspaceValue, pythonPath, 'Workspace Python Path not updated'); + PythonSettings.dispose(); + assert.equal(PythonSettings.getInstance(workspace3Uri).pythonPath, resolvedPythonPath, 'Resolved Workspace Python Path is incorrect'); + }); + + // tslint:disable-next-line:no-invalid-template-strings + test('Python Path should be relative to workspace when using ${workspaceFolder}', async () => { + const workspaceUri = workspace.getWorkspaceFolder(workspace3Uri)!.uri; const pythonInterpreter = `xWorkspacePythonPath${new Date().getMilliseconds()}`; const pythonPath = path.join(workspaceUri.fsPath, 'x', 'y', 'z', pythonInterpreter); const workspaceUpdater = new WorkspacePythonPathUpdaterService(workspaceUri); await workspaceUpdater.updatePythonPath(pythonPath); - const workspaceValue = workspace.getConfiguration('python').inspect('pythonPath').workspaceValue; + const workspaceValue = workspace.getConfiguration('python').inspect('pythonPath')!.workspaceValue!; // tslint:disable-next-line:no-invalid-template-strings - assert.equal(workspaceValue, path.join('${workspaceRoot}', 'x', 'y', 'z', pythonInterpreter), 'Workspace Python Path not updated'); + assert.equal(workspaceValue, path.join('${workspaceFolder}', 'x', 'y', 'z', pythonInterpreter), 'Workspace Python Path not updated'); + PythonSettings.dispose(); + assert.equal(PythonSettings.getInstance(workspace3Uri).pythonPath, pythonPath, 'Resolved Workspace Python Path is incorrect'); }); }); diff --git a/src/test/interpreters/pythonPathUpdater.test.ts b/src/test/interpreters/pythonPathUpdater.test.ts index c74aba47ec07..33099dc8c701 100644 --- a/src/test/interpreters/pythonPathUpdater.test.ts +++ b/src/test/interpreters/pythonPathUpdater.test.ts @@ -1,8 +1,10 @@ import * as assert from 'assert'; import * as path from 'path'; import { ConfigurationTarget, Uri, workspace } from 'vscode'; +import { PythonSettings } from '../../client/common/configSettings'; import { PythonPathUpdaterService } from '../../client/interpreter/configuration/pythonPathUpdaterService'; import { PythonPathUpdaterServiceFactory } from '../../client/interpreter/configuration/pythonPathUpdaterServiceFactory'; +import { GlobalPythonPathUpdaterService } from '../../client/interpreter/configuration/services/globalUpdaterService'; import { WorkspacePythonPathUpdaterService } from '../../client/interpreter/configuration/services/workspaceUpdaterService'; import { InterpreterVersionService } from '../../client/interpreter/interpreterVersion'; import { closeActiveWindows, initialize, initializeTest } from '../initialize'; @@ -76,7 +78,7 @@ suite('Python Path Settings Updater', () => { assert.equal(workspaceValue, pythonPath, 'Workspace Python Path not updated'); }); - test('Python Path should be relative to workspace', async () => { + test('Python Path should be relative to workspaceFolder', async () => { const workspaceUri = workspace.getWorkspaceFolder(Uri.file(workspaceRoot)).uri; const pythonInterpreter = `xWorkspacePythonPath${new Date().getMilliseconds()}`; const pythonPath = path.join(workspaceUri.fsPath, 'x', 'y', 'z', pythonInterpreter); @@ -84,6 +86,9 @@ suite('Python Path Settings Updater', () => { await workspaceUpdater.updatePythonPath(pythonPath); const workspaceValue = workspace.getConfiguration('python').inspect('pythonPath').workspaceValue; // tslint:disable-next-line:no-invalid-template-strings - assert.equal(workspaceValue, path.join('${workspaceRoot}', 'x', 'y', 'z', pythonInterpreter), 'Workspace Python Path not updated'); + assert.equal(workspaceValue, path.join('${workspaceFolder}', 'x', 'y', 'z', pythonInterpreter), 'Workspace Python Path not updated'); + const resolvedPath = PythonSettings.getInstance(Uri.file(workspaceRoot)).pythonPath; + assert.equal(resolvedPath, pythonPath, 'Resolved Workspace Python Path not updated'); }); + }); diff --git a/src/testMultiRootWkspc/workspace2/.vscode/settings.json b/src/testMultiRootWkspc/workspace2/.vscode/settings.json index 750d19764931..3705457b09a7 100644 --- a/src/testMultiRootWkspc/workspace2/.vscode/settings.json +++ b/src/testMultiRootWkspc/workspace2/.vscode/settings.json @@ -1,4 +1,4 @@ { - "python.workspaceSymbols.tagFilePath": "${workspaceRoot}/workspace2.tags.file", + "python.workspaceSymbols.tagFilePath": "${workspaceFolder}/workspace2.tags.file", "python.workspaceSymbols.enabled": false }