From 2e18c449b73651b62a2cc0a7662747f091182be5 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Fri, 3 May 2019 17:15:51 -0700 Subject: [PATCH 1/5] Ensure using request: launch item in launch.json for debugging sends pathMappings --- .../configuration/resolvers/launch.ts | 10 + src/client/debugger/types.ts | 3 + .../resolvers/launch.unit.test.ts | 10 + .../testing/common/debugLauncher.unit.test.ts | 498 +++++++++--------- 4 files changed, 277 insertions(+), 244 deletions(-) diff --git a/src/client/debugger/extension/configuration/resolvers/launch.ts b/src/client/debugger/extension/configuration/resolvers/launch.ts index 4efb111655ba..780dcae9985c 100644 --- a/src/client/debugger/extension/configuration/resolvers/launch.ts +++ b/src/client/debugger/extension/configuration/resolvers/launch.ts @@ -122,6 +122,16 @@ export class LaunchConfigurationResolver extends BaseConfigurationResolver; envFile: string; console?: ConsoleType; + localRoot?: string; + remoteRoot?: string; + pathMappings?: { localRoot: string; remoteRoot: string }[]; } // tslint:disable-next-line:interface-name export interface LaunchRequestArguments extends DebugProtocol.LaunchRequestArguments, IKnownLaunchRequestArguments, DebugConfiguration { diff --git a/src/test/debugger/extension/configuration/resolvers/launch.unit.test.ts b/src/test/debugger/extension/configuration/resolvers/launch.unit.test.ts index d56264d86b55..b9e075ca10dd 100644 --- a/src/test/debugger/extension/configuration/resolvers/launch.unit.test.ts +++ b/src/test/debugger/extension/configuration/resolvers/launch.unit.test.ts @@ -373,6 +373,16 @@ suite('Debugging - Config Resolver Launch', () => { expect(debugConfig).to.have.property('justMyCode', testParams.expectedResult); }); }); + test('Ensure pathMappings property is correctly derived', async () => { + const pythonPath = `PythonPath_${new Date().toString()}`; + const workspaceFolder = createMoqWorkspaceFolder(__dirname); + const pythonFile = 'xyz.py'; + setupIoc(pythonPath); + setupActiveEditor(pythonFile, PYTHON_LANGUAGE); + const debugConfig = await debugProvider.resolveDebugConfiguration!(workspaceFolder, { localRoot: 'abc', remoteRoot: 'remoteabc' } as LaunchRequestArguments); + expect(debugConfig).to.have.property('pathMappings'); + expect(debugConfig!.pathMappings).to.deep.equal([{ localRoot: 'abc', remoteRoot: 'remoteabc' }]); + }); async function testFixFilePathCase(isWindows: boolean, isMac: boolean, isLinux: boolean) { const pythonPath = `PythonPath_${new Date().toString()}`; const workspaceFolder = createMoqWorkspaceFolder(__dirname); diff --git a/src/test/testing/common/debugLauncher.unit.test.ts b/src/test/testing/common/debugLauncher.unit.test.ts index 90987785c0ce..0c75b54b6c07 100644 --- a/src/test/testing/common/debugLauncher.unit.test.ts +++ b/src/test/testing/common/debugLauncher.unit.test.ts @@ -232,6 +232,16 @@ suite('Unit Tests - Debug Launcher', () => { if (isOs(OSType.Windows)) { expected.debugOptions.push(DebugOptions.FixFilePathCase); } + if (!expected.pathMappings) { + expected.pathMappings = []; + } + // This is for backwards compatibility. + if (expected.localRoot && expected.remoteRoot) { + expected.pathMappings!.push({ + localRoot: expected.localRoot, + remoteRoot: expected.remoteRoot + }); + } setupDebugManager( workspaceFolders[0], @@ -240,177 +250,177 @@ suite('Unit Tests - Debug Launcher', () => { ); } - const testProviders: TestProvider[] = ['nosetest', 'pytest', 'unittest']; - // tslint:disable-next-line:max-func-body-length - testProviders.forEach(testProvider => { - const testTitleSuffix = `(Test Framework '${testProvider}')`; - - test(`Must launch debugger ${testTitleSuffix}`, async () => { - const options = { - cwd: 'one/two/three', - args: ['/one/two/three/testfile.py'], - testProvider - }; - setupSuccess(options, testProvider); - - await debugLauncher.launchDebugger(options); + const testProviders: TestProvider[] = ['nosetest', 'pytest', 'unittest']; + // tslint:disable-next-line:max-func-body-length + testProviders.forEach(testProvider => { + const testTitleSuffix = `(Test Framework '${testProvider}')`; - debugService.verifyAll(); - }); - test(`Must launch debugger with arguments ${testTitleSuffix}`, async () => { - const options = { - cwd: 'one/two/three', - args: ['/one/two/three/testfile.py', '--debug', '1'], - testProvider - }; - setupSuccess(options, testProvider); - - await debugLauncher.launchDebugger(options); - - debugService.verifyAll(); - }); - test(`Must not launch debugger if cancelled ${testTitleSuffix}`, async () => { - debugService.setup(d => d.startDebugging(TypeMoq.It.isAny(), TypeMoq.It.isAny())) - .returns(() => { - return Promise.resolve(undefined as any); - }) - .verifiable(TypeMoq.Times.never()); - - const cancellationToken = new CancellationTokenSource(); - cancellationToken.cancel(); - const token = cancellationToken.token; - const options: LaunchOptions = { cwd: '', args: [], token, testProvider }; - - await expect( - debugLauncher.launchDebugger(options) - ).to.be.eventually.equal(undefined, 'not undefined'); - - debugService.verifyAll(); - }); - test(`Must throw an exception if there are no workspaces ${testTitleSuffix}`, async () => { - hasWorkspaceFolders = false; - debugService.setup(d => d.startDebugging(TypeMoq.It.isAny(), TypeMoq.It.isAny())) - .returns(() => Promise.resolve(undefined as any)) - .verifiable(TypeMoq.Times.never()); - - const options: LaunchOptions = { cwd: '', args: [], testProvider }; - - await expect( - debugLauncher.launchDebugger(options) - ).to.eventually.rejectedWith('Please open a workspace'); - - debugService.verifyAll(); - }); - }); - - test('Tries launch.json first', async () => { - const options: LaunchOptions = { + test(`Must launch debugger ${testTitleSuffix}`, async () => { + const options = { cwd: 'one/two/three', args: ['/one/two/three/testfile.py'], - testProvider: 'unittest' + testProvider }; - const expected = getDefaultDebugConfig(); - expected.name = 'spam'; - setupSuccess(options, 'unittest', expected, [ - { name: 'spam', type: DebuggerTypeName, request: 'test' } - ]); + setupSuccess(options, testProvider); await debugLauncher.launchDebugger(options); debugService.verifyAll(); }); - - test('Full debug config', async () => { - const options: LaunchOptions = { + test(`Must launch debugger with arguments ${testTitleSuffix}`, async () => { + const options = { cwd: 'one/two/three', - args: ['/one/two/three/testfile.py'], - testProvider: 'unittest' - }; - const expected = { - name: 'my tests', - type: DebuggerTypeName, - request: 'launch', - pythonPath: 'some/dir/bin/py3', - stopOnEntry: true, - showReturnValue: true, - console: 'integratedTerminal', - cwd: 'some/dir', - env: { - SPAM: 'EGGS' - }, - envFile: 'some/dir/.env', - redirectOutput: false, - debugStdLib: true, - justMyCode: false, - // added by LaunchConfigurationResolver: - internalConsoleOptions: 'neverOpen' + args: ['/one/two/three/testfile.py', '--debug', '1'], + testProvider }; - setupSuccess(options, 'unittest', expected, [ - { - name: 'my tests', - type: DebuggerTypeName, - request: 'test', - pythonPath: expected.pythonPath, - stopOnEntry: expected.stopOnEntry, - showReturnValue: expected.showReturnValue, - console: expected.console, - cwd: expected.cwd, - env: expected.env, - envFile: expected.envFile, - redirectOutput: expected.redirectOutput, - debugStdLib: expected.debugStdLib, - justMyCode: undefined - } - ]); + setupSuccess(options, testProvider); await debugLauncher.launchDebugger(options); debugService.verifyAll(); }); - - test('Uses first entry', async () => { - const options: LaunchOptions = { - cwd: 'one/two/three', - args: ['/one/two/three/testfile.py'], - testProvider: 'unittest' - }; - const expected = getDefaultDebugConfig(); - expected.name = 'spam1'; - setupSuccess(options, 'unittest', expected, [ - { name: 'spam1', type: DebuggerTypeName, request: 'test' }, - { name: 'spam2', type: DebuggerTypeName, request: 'test' }, - { name: 'spam3', type: DebuggerTypeName, request: 'test' } - ]); - - await debugLauncher.launchDebugger(options); + test(`Must not launch debugger if cancelled ${testTitleSuffix}`, async () => { + debugService.setup(d => d.startDebugging(TypeMoq.It.isAny(), TypeMoq.It.isAny())) + .returns(() => { + return Promise.resolve(undefined as any); + }) + .verifiable(TypeMoq.Times.never()); + + const cancellationToken = new CancellationTokenSource(); + cancellationToken.cancel(); + const token = cancellationToken.token; + const options: LaunchOptions = { cwd: '', args: [], token, testProvider }; + + await expect( + debugLauncher.launchDebugger(options) + ).to.be.eventually.equal(undefined, 'not undefined'); debugService.verifyAll(); }); + test(`Must throw an exception if there are no workspaces ${testTitleSuffix}`, async () => { + hasWorkspaceFolders = false; + debugService.setup(d => d.startDebugging(TypeMoq.It.isAny(), TypeMoq.It.isAny())) + .returns(() => Promise.resolve(undefined as any)) + .verifiable(TypeMoq.Times.never()); - test('Handles bad JSON', async () => { - const options: LaunchOptions = { - cwd: 'one/two/three', - args: ['/one/two/three/testfile.py'], - testProvider: 'unittest' - }; - const expected = getDefaultDebugConfig(); - setupSuccess(options, 'unittest', expected, ']'); + const options: LaunchOptions = { cwd: '', args: [], testProvider }; - await debugLauncher.launchDebugger(options); + await expect( + debugLauncher.launchDebugger(options) + ).to.eventually.rejectedWith('Please open a workspace'); debugService.verifyAll(); }); + }); + + test('Tries launch.json first', async () => { + const options: LaunchOptions = { + cwd: 'one/two/three', + args: ['/one/two/three/testfile.py'], + testProvider: 'unittest' + }; + const expected = getDefaultDebugConfig(); + expected.name = 'spam'; + setupSuccess(options, 'unittest', expected, [ + { name: 'spam', type: DebuggerTypeName, request: 'test' } + ]); + + await debugLauncher.launchDebugger(options); + + debugService.verifyAll(); + }); + + test('Full debug config', async () => { + const options: LaunchOptions = { + cwd: 'one/two/three', + args: ['/one/two/three/testfile.py'], + testProvider: 'unittest' + }; + const expected = { + name: 'my tests', + type: DebuggerTypeName, + request: 'launch', + pythonPath: 'some/dir/bin/py3', + stopOnEntry: true, + showReturnValue: true, + console: 'integratedTerminal', + cwd: 'some/dir', + env: { + SPAM: 'EGGS' + }, + envFile: 'some/dir/.env', + redirectOutput: false, + debugStdLib: true, + justMyCode: false, + // added by LaunchConfigurationResolver: + internalConsoleOptions: 'neverOpen' + }; + setupSuccess(options, 'unittest', expected, [ + { + name: 'my tests', + type: DebuggerTypeName, + request: 'test', + pythonPath: expected.pythonPath, + stopOnEntry: expected.stopOnEntry, + showReturnValue: expected.showReturnValue, + console: expected.console, + cwd: expected.cwd, + env: expected.env, + envFile: expected.envFile, + redirectOutput: expected.redirectOutput, + debugStdLib: expected.debugStdLib, + justMyCode: undefined + } + ]); + + await debugLauncher.launchDebugger(options); + + debugService.verifyAll(); + }); + + test('Uses first entry', async () => { + const options: LaunchOptions = { + cwd: 'one/two/three', + args: ['/one/two/three/testfile.py'], + testProvider: 'unittest' + }; + const expected = getDefaultDebugConfig(); + expected.name = 'spam1'; + setupSuccess(options, 'unittest', expected, [ + { name: 'spam1', type: DebuggerTypeName, request: 'test' }, + { name: 'spam2', type: DebuggerTypeName, request: 'test' }, + { name: 'spam3', type: DebuggerTypeName, request: 'test' } + ]); + + await debugLauncher.launchDebugger(options); + + debugService.verifyAll(); + }); + + test('Handles bad JSON', async () => { + const options: LaunchOptions = { + cwd: 'one/two/three', + args: ['/one/two/three/testfile.py'], + testProvider: 'unittest' + }; + const expected = getDefaultDebugConfig(); + setupSuccess(options, 'unittest', expected, ']'); - const malformedFiles = [ - '// test 1', - '// test 2 \n\ + await debugLauncher.launchDebugger(options); + + debugService.verifyAll(); + }); + + const malformedFiles = [ + '// test 1', + '// test 2 \n\ { \n\ "name": "spam", \n\ "type": "python", \n\ "request": "test" \n\ } \n\ ', - '// test 3 \n\ + '// test 3 \n\ [ \n\ { \n\ "name": "spam", \n\ @@ -419,7 +429,7 @@ suite('Unit Tests - Debug Launcher', () => { } \n\ ] \n\ ', - '// test 4 \n\ + '// test 4 \n\ { \n\ "configurations": [ \n\ { \n\ @@ -430,129 +440,129 @@ suite('Unit Tests - Debug Launcher', () => { ] \n\ } \n\ ' - ]; - for (const text of malformedFiles) { - const testID = text.split('\n')[0].substring(3).trim(); - test(`Handles malformed launch.json - ${testID}`, async () => { - const options: LaunchOptions = { - cwd: 'one/two/three', - args: ['/one/two/three/testfile.py'], - testProvider: 'unittest' - }; - const expected = getDefaultDebugConfig(); - setupSuccess(options, 'unittest', expected, text); - - await debugLauncher.launchDebugger(options); - - debugService.verifyAll(); - }); - } - - test('Handles bad debug config items', async () => { + ]; + for (const text of malformedFiles) { + const testID = text.split('\n')[0].substring(3).trim(); + test(`Handles malformed launch.json - ${testID}`, async () => { const options: LaunchOptions = { cwd: 'one/two/three', args: ['/one/two/three/testfile.py'], testProvider: 'unittest' }; const expected = getDefaultDebugConfig(); - // tslint:disable:no-object-literal-type-assertion - setupSuccess(options, 'unittest', expected, [ - {} as DebugConfiguration, - { name: 'spam1' } as DebugConfiguration, - { name: 'spam2', type: DebuggerTypeName } as DebugConfiguration, - { name: 'spam3', request: 'test' } as DebugConfiguration, - { type: DebuggerTypeName } as DebugConfiguration, - { type: DebuggerTypeName, request: 'test' } as DebugConfiguration, - { request: 'test' } as DebugConfiguration - ]); - // tslint:enable:no-object-literal-type-assertion + setupSuccess(options, 'unittest', expected, text); await debugLauncher.launchDebugger(options); debugService.verifyAll(); }); + } - test('Handles non-python debug configs', async () => { - const options: LaunchOptions = { - cwd: 'one/two/three', - args: ['/one/two/three/testfile.py'], - testProvider: 'unittest' - }; - const expected = getDefaultDebugConfig(); - setupSuccess(options, 'unittest', expected, [ - { name: 'foo', type: 'other', request: 'bar' } - ]); - - await debugLauncher.launchDebugger(options); + test('Handles bad debug config items', async () => { + const options: LaunchOptions = { + cwd: 'one/two/three', + args: ['/one/two/three/testfile.py'], + testProvider: 'unittest' + }; + const expected = getDefaultDebugConfig(); + // tslint:disable:no-object-literal-type-assertion + setupSuccess(options, 'unittest', expected, [ + {} as DebugConfiguration, + { name: 'spam1' } as DebugConfiguration, + { name: 'spam2', type: DebuggerTypeName } as DebugConfiguration, + { name: 'spam3', request: 'test' } as DebugConfiguration, + { type: DebuggerTypeName } as DebugConfiguration, + { type: DebuggerTypeName, request: 'test' } as DebugConfiguration, + { request: 'test' } as DebugConfiguration + ]); + // tslint:enable:no-object-literal-type-assertion + + await debugLauncher.launchDebugger(options); + + debugService.verifyAll(); + }); - debugService.verifyAll(); - }); + test('Handles non-python debug configs', async () => { + const options: LaunchOptions = { + cwd: 'one/two/three', + args: ['/one/two/three/testfile.py'], + testProvider: 'unittest' + }; + const expected = getDefaultDebugConfig(); + setupSuccess(options, 'unittest', expected, [ + { name: 'foo', type: 'other', request: 'bar' } + ]); - test('Handles bogus python debug configs', async () => { - const options: LaunchOptions = { - cwd: 'one/two/three', - args: ['/one/two/three/testfile.py'], - testProvider: 'unittest' - }; - const expected = getDefaultDebugConfig(); - setupSuccess(options, 'unittest', expected, [ - { name: 'spam', type: DebuggerTypeName, request: 'bogus' } - ]); + await debugLauncher.launchDebugger(options); - await debugLauncher.launchDebugger(options); + debugService.verifyAll(); + }); - debugService.verifyAll(); - }); + test('Handles bogus python debug configs', async () => { + const options: LaunchOptions = { + cwd: 'one/two/three', + args: ['/one/two/three/testfile.py'], + testProvider: 'unittest' + }; + const expected = getDefaultDebugConfig(); + setupSuccess(options, 'unittest', expected, [ + { name: 'spam', type: DebuggerTypeName, request: 'bogus' } + ]); - test('Handles non-test debug config', async () => { - const options: LaunchOptions = { - cwd: 'one/two/three', - args: ['/one/two/three/testfile.py'], - testProvider: 'unittest' - }; - const expected = getDefaultDebugConfig(); - setupSuccess(options, 'unittest', expected, [ - { name: 'spam', type: DebuggerTypeName, request: 'launch' }, - { name: 'spam', type: DebuggerTypeName, request: 'attach' } - ]); + await debugLauncher.launchDebugger(options); - await debugLauncher.launchDebugger(options); + debugService.verifyAll(); + }); - debugService.verifyAll(); - }); + test('Handles non-test debug config', async () => { + const options: LaunchOptions = { + cwd: 'one/two/three', + args: ['/one/two/three/testfile.py'], + testProvider: 'unittest' + }; + const expected = getDefaultDebugConfig(); + setupSuccess(options, 'unittest', expected, [ + { name: 'spam', type: DebuggerTypeName, request: 'launch' }, + { name: 'spam', type: DebuggerTypeName, request: 'attach' } + ]); - test('Handles mixed debug config', async () => { - const options: LaunchOptions = { - cwd: 'one/two/three', - args: ['/one/two/three/testfile.py'], - testProvider: 'unittest' - }; - const expected = getDefaultDebugConfig(); - expected.name = 'spam2'; - setupSuccess(options, 'unittest', expected, [ - { name: 'foo1', type: 'other', request: 'bar' }, - { name: 'foo2', type: 'other', request: 'bar' }, - { name: 'spam1', type: DebuggerTypeName, request: 'launch' }, - { name: 'spam2', type: DebuggerTypeName, request: 'test' }, - { name: 'spam3', type: DebuggerTypeName, request: 'attach' }, - { name: 'xyz', type: 'another', request: 'abc' } - ]); + await debugLauncher.launchDebugger(options); - await debugLauncher.launchDebugger(options); + debugService.verifyAll(); + }); - debugService.verifyAll(); - }); + test('Handles mixed debug config', async () => { + const options: LaunchOptions = { + cwd: 'one/two/three', + args: ['/one/two/three/testfile.py'], + testProvider: 'unittest' + }; + const expected = getDefaultDebugConfig(); + expected.name = 'spam2'; + setupSuccess(options, 'unittest', expected, [ + { name: 'foo1', type: 'other', request: 'bar' }, + { name: 'foo2', type: 'other', request: 'bar' }, + { name: 'spam1', type: DebuggerTypeName, request: 'launch' }, + { name: 'spam2', type: DebuggerTypeName, request: 'test' }, + { name: 'spam3', type: DebuggerTypeName, request: 'attach' }, + { name: 'xyz', type: 'another', request: 'abc' } + ]); + + await debugLauncher.launchDebugger(options); + + debugService.verifyAll(); + }); - test('Handles comments', async () => { - const options: LaunchOptions = { - cwd: 'one/two/three', - args: ['/one/two/three/testfile.py'], - testProvider: 'unittest' - }; - const expected = getDefaultDebugConfig(); - expected.name = 'spam'; - expected.stopOnEntry = true; - setupSuccess(options, 'unittest', expected, ' \n\ + test('Handles comments', async () => { + const options: LaunchOptions = { + cwd: 'one/two/three', + args: ['/one/two/three/testfile.py'], + testProvider: 'unittest' + }; + const expected = getDefaultDebugConfig(); + expected.name = 'spam'; + expected.stopOnEntry = true; + setupSuccess(options, 'unittest', expected, ' \n\ { \n\ "version": "0.1.0", \n\ "configurations": [ \n\ @@ -569,10 +579,10 @@ suite('Unit Tests - Debug Launcher', () => { } \n\ '); - await debugLauncher.launchDebugger(options); + await debugLauncher.launchDebugger(options); - debugService.verifyAll(); - }); + debugService.verifyAll(); + }); test('Ensure trailing commands in JSON are handled', async () => { const workspaceFolder = { name: 'abc', index: 0, uri: Uri.file(__filename) }; const filename = path.join(workspaceFolder.uri.fsPath, '.vscode', 'launch.json'); From 4bb0056640adf49f2275e9b21db50e221fe5f545 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Fri, 3 May 2019 17:16:06 -0700 Subject: [PATCH 2/5] News entry --- news/2 Fixes/3568.md | 1 + src/client/debugger/types.ts | 9 +++------ 2 files changed, 4 insertions(+), 6 deletions(-) create mode 100644 news/2 Fixes/3568.md diff --git a/news/2 Fixes/3568.md b/news/2 Fixes/3568.md new file mode 100644 index 000000000000..2342db710034 --- /dev/null +++ b/news/2 Fixes/3568.md @@ -0,0 +1 @@ +Using "request": "launch" item in launch.json for debugging sends pathMappings diff --git a/src/client/debugger/types.ts b/src/client/debugger/types.ts index 53f7aa129038..8f14cec1c0c4 100644 --- a/src/client/debugger/types.ts +++ b/src/client/debugger/types.ts @@ -36,13 +36,13 @@ interface ICommonDebugArguments { // Show return values of functions while stepping. showReturnValue?: boolean; subProcess?: boolean; -} -export interface IKnownAttachDebugArguments extends ICommonDebugArguments { - workspaceFolder?: string; // An absolute path to local directory with source. localRoot?: string; remoteRoot?: string; pathMappings?: { localRoot: string; remoteRoot: string }[]; +} +export interface IKnownAttachDebugArguments extends ICommonDebugArguments { + workspaceFolder?: string; customDebugger?: boolean; } @@ -62,9 +62,6 @@ export interface IKnownLaunchRequestArguments extends ICommonDebugArguments { env?: Record; envFile: string; console?: ConsoleType; - localRoot?: string; - remoteRoot?: string; - pathMappings?: { localRoot: string; remoteRoot: string }[]; } // tslint:disable-next-line:interface-name export interface LaunchRequestArguments extends DebugProtocol.LaunchRequestArguments, IKnownLaunchRequestArguments, DebugConfiguration { From 2c6022abd6f75d274f10922a68d05f7cd10d0526 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Mon, 20 May 2019 16:01:34 -0700 Subject: [PATCH 3/5] Addressed reviews --- package.json | 30 +++++++++++++++++++ .../configuration/resolvers/launch.ts | 5 +++- .../resolvers/launch.unit.test.ts | 2 +- .../testing/common/debugLauncher.unit.test.ts | 5 +++- 4 files changed, 39 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index a5419480971e..d0db57fed764 100644 --- a/package.json +++ b/package.json @@ -889,6 +889,36 @@ "description": "Debug port (default is 0, resulting in the use of a dynamic port).", "default": 0 }, + "pathMappings": { + "type": "array", + "label": "Path mappings.", + "items": { + "type": "object", + "label": "Path mapping", + "required": [ + "localRoot", + "remoteRoot" + ], + "properties": { + "localRoot": { + "type": "string", + "label": "Local source root.", + "default": "${workspaceFolder}" + }, + "remoteRoot": { + "type": "string", + "label": "Remote source root.", + "default": "." + } + } + }, + "default": [ + { + "localRoot": "${workspaceFolder}", + "remoteRoot": "." + } + ] + }, "host": { "type": "string", "description": "IP address of the of the local debug server (default is localhost).", diff --git a/src/client/debugger/extension/configuration/resolvers/launch.ts b/src/client/debugger/extension/configuration/resolvers/launch.ts index 780dcae9985c..bd596b9163ef 100644 --- a/src/client/debugger/extension/configuration/resolvers/launch.ts +++ b/src/client/debugger/extension/configuration/resolvers/launch.ts @@ -123,7 +123,10 @@ export class LaunchConfigurationResolver extends BaseConfigurationResolver { setupActiveEditor(pythonFile, PYTHON_LANGUAGE); const debugConfig = await debugProvider.resolveDebugConfiguration!(workspaceFolder, { localRoot: 'abc', remoteRoot: 'remoteabc' } as LaunchRequestArguments); expect(debugConfig).to.have.property('pathMappings'); - expect(debugConfig!.pathMappings).to.deep.equal([{ localRoot: 'abc', remoteRoot: 'remoteabc' }]); + expect(debugConfig!.pathMappings).to.deep.equal([{ localRoot: workspaceFolder.uri.fsPath, remoteRoot: '.' }, { localRoot: 'abc', remoteRoot: 'remoteabc' }]); }); async function testFixFilePathCase(isWindows: boolean, isMac: boolean, isLinux: boolean) { const pythonPath = `PythonPath_${new Date().toString()}`; diff --git a/src/test/testing/common/debugLauncher.unit.test.ts b/src/test/testing/common/debugLauncher.unit.test.ts index 0c75b54b6c07..07de0e9e9dc8 100644 --- a/src/test/testing/common/debugLauncher.unit.test.ts +++ b/src/test/testing/common/debugLauncher.unit.test.ts @@ -233,7 +233,10 @@ suite('Unit Tests - Debug Launcher', () => { expected.debugOptions.push(DebugOptions.FixFilePathCase); } if (!expected.pathMappings) { - expected.pathMappings = []; + expected.pathMappings = expected.workspaceFolder ? [{ + localRoot: expected.workspaceFolder.fsPath, + remoteRoot: '.' + }] : []; } // This is for backwards compatibility. if (expected.localRoot && expected.remoteRoot) { From 36d3de2592584ea2918dc35606de77df303e0418 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Tue, 21 May 2019 13:34:07 -0700 Subject: [PATCH 4/5] Resolved tests --- src/test/testing/common/debugLauncher.unit.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/testing/common/debugLauncher.unit.test.ts b/src/test/testing/common/debugLauncher.unit.test.ts index 07de0e9e9dc8..471abaa2dfde 100644 --- a/src/test/testing/common/debugLauncher.unit.test.ts +++ b/src/test/testing/common/debugLauncher.unit.test.ts @@ -234,7 +234,7 @@ suite('Unit Tests - Debug Launcher', () => { } if (!expected.pathMappings) { expected.pathMappings = expected.workspaceFolder ? [{ - localRoot: expected.workspaceFolder.fsPath, + localRoot: expected.workspaceFolder, remoteRoot: '.' }] : []; } From 09674ba9498f397af1b292af555097d8b26a1bab Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Tue, 21 May 2019 14:09:48 -0700 Subject: [PATCH 5/5] Reverted p[ackage.json --- package.json | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/package.json b/package.json index d0db57fed764..a5419480971e 100644 --- a/package.json +++ b/package.json @@ -889,36 +889,6 @@ "description": "Debug port (default is 0, resulting in the use of a dynamic port).", "default": 0 }, - "pathMappings": { - "type": "array", - "label": "Path mappings.", - "items": { - "type": "object", - "label": "Path mapping", - "required": [ - "localRoot", - "remoteRoot" - ], - "properties": { - "localRoot": { - "type": "string", - "label": "Local source root.", - "default": "${workspaceFolder}" - }, - "remoteRoot": { - "type": "string", - "label": "Remote source root.", - "default": "." - } - } - }, - "default": [ - { - "localRoot": "${workspaceFolder}", - "remoteRoot": "." - } - ] - }, "host": { "type": "string", "description": "IP address of the of the local debug server (default is localhost).",