Skip to content

Commit 1ef6a70

Browse files
committed
debug: allow vscode.startDebug to pass full json config
fixes microsoft#4615
1 parent fabda7b commit 1ef6a70

File tree

5 files changed

+72
-65
lines changed

5 files changed

+72
-65
lines changed

src/vs/workbench/api/node/extHostApiCommands.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -189,12 +189,12 @@ class ExtHostApiCommands {
189189
]
190190
});
191191

192-
this._register('vscode.startDebug', (configurationName?: string) => {
193-
return this._commands.executeCommand('_workbench.startDebug', configurationName);
192+
this._register('vscode.startDebug', (configuration?: any) => {
193+
return this._commands.executeCommand('_workbench.startDebug', configuration);
194194
}, {
195195
description: 'Start a debugging session.',
196196
args: [
197-
{ name: 'configurationName', description: '(optional) Name of the debug configuration from \'launch.json\' to use.' }
197+
{ name: 'configuration', description: '(optional) Name of the debug configuration from \'launch.json\' to use. Or a configuration json object to use.' }
198198
]
199199
});
200200
}

src/vs/workbench/parts/debug/common/debug.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ export interface IDebugService {
372372
/**
373373
* Creates a new debug session. Depending on the configuration will either 'launch' or 'attach'.
374374
*/
375-
createSession(noDebug: boolean): TPromise<any>;
375+
createSession(noDebug: boolean, configuration?: IConfig): TPromise<any>;
376376

377377
/**
378378
* Restarts an active debug session or creates a new one if there is no active session.

src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,7 @@
66
import 'vs/css!../browser/media/debug.contribution';
77
import 'vs/css!../browser/media/debugHover';
88
import nls = require('vs/nls');
9-
import { TPromise } from 'vs/base/common/winjs.base';
109
import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';
11-
import errors = require('vs/base/common/errors');
1210
import editorcommon = require('vs/editor/common/editorCommon');
1311
import { CommonEditorRegistry, ContextKey, EditorActionDescriptor } from 'vs/editor/common/editorCommonExtensions';
1412
import { EditorBrowserRegistry } from 'vs/editor/browser/editorBrowserExtensions';
@@ -119,10 +117,14 @@ registry.registerWorkbenchAction(new SyncActionDescriptor(dbgactions.RunAction,
119117
KeybindingsRegistry.registerCommandDesc({
120118
id: '_workbench.startDebug',
121119
weight: KeybindingsRegistry.WEIGHT.workbenchContrib(0),
122-
handler(accessor: ServicesAccessor, configurationName: string) {
120+
handler(accessor: ServicesAccessor, configuration: any) {
123121
const debugService = accessor.get(debug.IDebugService);
124-
(configurationName ? debugService.getConfigurationManager().setConfiguration(configurationName) : TPromise.as(null))
125-
.done(() => debugService.createSession(false), errors.onUnexpectedError);
122+
if (typeof configuration === 'string') {
123+
return debugService.getConfigurationManager().setConfiguration(configuration)
124+
.then(() => debugService.createSession(false));
125+
}
126+
127+
return debugService.createSession(false, configuration);
126128
},
127129
when: KbExpr.not(debug.CONTEXT_IN_DEBUG_MODE),
128130
primary: undefined

src/vs/workbench/parts/debug/electron-browser/debugService.ts

Lines changed: 52 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -486,58 +486,59 @@ export class DebugService implements debug.IDebugService {
486486
this.model.removeWatchExpressions(id);
487487
}
488488

489-
public createSession(noDebug: boolean, changeViewState = !this.partService.isSideBarHidden()): TPromise<any> {
489+
public createSession(noDebug: boolean, configuration?: debug.IConfig, changeViewState = !this.partService.isSideBarHidden()): TPromise<any> {
490490
this.removeReplExpressions();
491491

492-
return this.textFileService.saveAll() // make sure all dirty files are saved
492+
return this.textFileService.saveAll() // make sure all dirty files are saved
493493
.then(() => this.configurationService.loadConfiguration() // make sure configuration is up to date
494-
.then(() => this.extensionService.onReady()
495-
.then(() => this.configurationManager.setConfiguration((this.configurationManager.configurationName))
496-
.then(() => {
497-
const configuration = this.configurationManager.configuration;
498-
if (!configuration) {
499-
return this.configurationManager.openConfigFile(false).then(openend => {
500-
if (openend) {
501-
this.messageService.show(severity.Info, nls.localize('NewLaunchConfig', "Please set up the launch configuration file for your application."));
502-
}
503-
});
504-
}
505-
506-
configuration.noDebug = noDebug;
507-
if (!this.configurationManager.adapter) {
508-
return configuration.type ? TPromise.wrapError(new Error(nls.localize('debugTypeNotSupported', "Configured debug type '{0}' is not supported.", configuration.type)))
509-
: TPromise.wrapError(errors.create(nls.localize('debugTypeMissing', "Missing property 'type' for the selected configuration in launch.json."),
510-
{ actions: [CloseAction, this.instantiationService.createInstance(debugactions.ConfigureAction, debugactions.ConfigureAction.ID, debugactions.ConfigureAction.LABEL)] }));
511-
}
512-
513-
return this.runPreLaunchTask(configuration.preLaunchTask).then((taskSummary: ITaskSummary) => {
514-
const errorCount = configuration.preLaunchTask ? this.markerService.getStatistics().errors : 0;
515-
const successExitCode = taskSummary && taskSummary.exitCode === 0;
516-
const failureExitCode = taskSummary && taskSummary.exitCode !== undefined && taskSummary.exitCode !== 0;
517-
if (successExitCode || (errorCount === 0 && !failureExitCode)) {
518-
return this.doCreateSession(configuration, changeViewState);
519-
}
520-
521-
this.messageService.show(severity.Error, {
522-
message: errorCount > 1 ? nls.localize('preLaunchTaskErrors', "Build errors have been detected during preLaunchTask '{0}'.", configuration.preLaunchTask) :
523-
errorCount === 1 ? nls.localize('preLaunchTaskError', "Build error has been detected during preLaunchTask '{0}'.", configuration.preLaunchTask) :
524-
nls.localize('preLaunchTaskExitCode', "The preLaunchTask '{0}' terminated with exit code {1}.", configuration.preLaunchTask, taskSummary.exitCode),
525-
actions: [CloseAction, new Action('debug.continue', nls.localize('debugAnyway', "Debug Anyway"), null, true, () => {
526-
this.messageService.hideAll();
527-
return this.doCreateSession(configuration, changeViewState);
528-
})]
529-
});
530-
}, (err: TaskError) => {
531-
if (err.code !== TaskErrors.NotConfigured) {
532-
throw err;
533-
}
534-
535-
this.messageService.show(err.severity, {
536-
message: err.message,
537-
actions: [CloseAction, this.taskService.configureAction()]
538-
});
539-
});
540-
}))));
494+
.then(() => this.extensionService.onReady()
495+
.then(() => this.configurationManager.setConfiguration((this.configurationManager.configurationName))
496+
.then(() => {
497+
this.configurationManager.resloveConfiguration(configuration);
498+
configuration = configuration || this.configurationManager.configuration;
499+
if (!configuration) {
500+
return this.configurationManager.openConfigFile(false).then(openend => {
501+
if (openend) {
502+
this.messageService.show(severity.Info, nls.localize('NewLaunchConfig', "Please set up the launch configuration file for your application."));
503+
}
504+
});
505+
}
506+
507+
configuration.noDebug = noDebug;
508+
if (!this.configurationManager.adapter) {
509+
return configuration.type ? TPromise.wrapError(new Error(nls.localize('debugTypeNotSupported', "Configured debug type '{0}' is not supported.", configuration.type)))
510+
: TPromise.wrapError(errors.create(nls.localize('debugTypeMissing', "Missing property 'type' for the selected configuration in launch.json."),
511+
{ actions: [CloseAction, this.instantiationService.createInstance(debugactions.ConfigureAction, debugactions.ConfigureAction.ID, debugactions.ConfigureAction.LABEL)] }));
512+
}
513+
514+
return this.runPreLaunchTask(configuration.preLaunchTask).then((taskSummary: ITaskSummary) => {
515+
const errorCount = configuration.preLaunchTask ? this.markerService.getStatistics().errors : 0;
516+
const successExitCode = taskSummary && taskSummary.exitCode === 0;
517+
const failureExitCode = taskSummary && taskSummary.exitCode !== undefined && taskSummary.exitCode !== 0;
518+
if (successExitCode || (errorCount === 0 && !failureExitCode)) {
519+
return this.doCreateSession(configuration, changeViewState);
520+
}
521+
522+
this.messageService.show(severity.Error, {
523+
message: errorCount > 1 ? nls.localize('preLaunchTaskErrors', "Build errors have been detected during preLaunchTask '{0}'.", configuration.preLaunchTask) :
524+
errorCount === 1 ? nls.localize('preLaunchTaskError', "Build error has been detected during preLaunchTask '{0}'.", configuration.preLaunchTask) :
525+
nls.localize('preLaunchTaskExitCode', "The preLaunchTask '{0}' terminated with exit code {1}.", configuration.preLaunchTask, taskSummary.exitCode),
526+
actions: [CloseAction, new Action('debug.continue', nls.localize('debugAnyway', "Debug Anyway"), null, true, () => {
527+
this.messageService.hideAll();
528+
return this.doCreateSession(configuration, changeViewState);
529+
})]
530+
});
531+
}, (err: TaskError) => {
532+
if (err.code !== TaskErrors.NotConfigured) {
533+
throw err;
534+
}
535+
536+
this.messageService.show(err.severity, {
537+
message: err.message,
538+
actions: [CloseAction, this.taskService.configureAction()]
539+
});
540+
});
541+
}))));
541542
}
542543

543544
private doCreateSession(configuration: debug.IConfig, changeViewState: boolean): TPromise<any> {
@@ -679,10 +680,10 @@ export class DebugService implements debug.IDebugService {
679680
return this.session ? this.session.disconnect(true).then(() =>
680681
new TPromise<void>((c, e) => {
681682
setTimeout(() => {
682-
this.createSession(false, false).then(() => c(null), err => e(err));
683+
this.createSession(false, null, false).then(() => c(null), err => e(err));
683684
}, 300);
684685
})
685-
) : this.createSession(false, false);
686+
) : this.createSession(false, null, false);
686687
}
687688

688689
public getActiveSession(): debug.IRawDebugSession {

src/vs/workbench/parts/debug/node/debugConfigurationManager.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -241,16 +241,20 @@ export class ConfigurationManager implements debug.IConfigurationManager {
241241
// massage configuration attributes - append workspace path to relatvie paths, substitute variables in paths.
242242
this.configuration = filtered.length === 1 ? objects.deepClone(filtered[0]) : null;
243243
if (this.configuration) {
244-
if (this.systemVariables) {
245-
Object.keys(this.configuration).forEach(key => {
246-
this.configuration[key] = this.systemVariables.resolveAny(this.configuration[key]);
247-
});
248-
}
244+
this.resloveConfiguration(this.configuration);
249245
this.configuration.debugServer = config.debugServer;
250246
}
251247
}).then(() => this._onDidConfigurationChange.fire(this.configurationName));
252248
}
253249

250+
public resloveConfiguration(configuration: debug.IConfig) {
251+
if (this.systemVariables && configuration) {
252+
Object.keys(configuration).forEach(key => {
253+
configuration[key] = this.systemVariables.resolveAny(configuration[key]);
254+
});
255+
}
256+
}
257+
254258
public openConfigFile(sideBySide: boolean): TPromise<boolean> {
255259
const resource = uri.file(paths.join(this.contextService.getWorkspace().resource.fsPath, '/.vscode/launch.json'));
256260

0 commit comments

Comments
 (0)