Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle preLaunch task explicitly #304

Merged
merged 13 commits into from
Sep 23, 2020
9 changes: 6 additions & 3 deletions src/debugger/configuration/resolvers/attach.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,19 @@ export class AttachResolver implements vscode.DebugConfigurationProvider {
"Python",
];

public async resolveDebugConfiguration(folder: vscode.WorkspaceFolder | undefined, config: requests.IAttachRequest, token?: vscode.CancellationToken): Promise<vscode.DebugConfiguration> {
public async resolveDebugConfigurationWithSubstitutedVariables(folder: vscode.WorkspaceFolder | undefined, config: requests.IAttachRequest, token?: vscode.CancellationToken): Promise<vscode.DebugConfiguration> {
// ${command:} variables only get resolved before passed to debug adapter, need to be manually resolve here
// all ${action:} variables need to be resolved before our resolver propagates the configuration to actual debugger

await this.resolveRuntimeIfNeeded(this.supportedRuntimeTypes, config);
await this.resolveProcessIdIfNeeded(config);
await this.resolveCommandLineIfNeeded(config);

// propagate debug configuration to Python or C++ debugger depending on the chosen runtime type
this.launchAttachSession(config as IResolvedAttachRequest);
return config;

// Return null as we have spawned new debug session
return null;
}

private async launchAttachSession(config: IResolvedAttachRequest) {
Expand Down Expand Up @@ -79,7 +82,7 @@ export class AttachResolver implements vscode.DebugConfigurationProvider {
if (os.platform() === "win32") {
const processOptions: child_process.ExecOptions = {
cwd: extension.baseDir,
env: extension.env,
env: await extension.resolvedEnv(),
};

// "ptvsd --pid" works with child_process.exec() on Windows
Expand Down
13 changes: 9 additions & 4 deletions src/debugger/configuration/resolvers/launch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import * as vscode from "vscode";

import * as extension from "../../../extension";
import * as requests from "../../requests";
import * as utils from "../../utils";

const promisifiedExec = util.promisify(child_process.exec);

Expand All @@ -27,13 +28,13 @@ interface ILaunchRequest {

export class LaunchResolver implements vscode.DebugConfigurationProvider {
// tslint:disable-next-line: max-line-length
public async resolveDebugConfiguration(folder: vscode.WorkspaceFolder | undefined, config: requests.ILaunchRequest, token?: vscode.CancellationToken) {
public async resolveDebugConfigurationWithSubstitutedVariables(folder: vscode.WorkspaceFolder | undefined, config: requests.ILaunchRequest, token?: vscode.CancellationToken) {
if (!path.isAbsolute(config.target) || path.extname(config.target) !== ".launch") {
throw new Error("Launch request requires an absolute path as target.");
}

const rosExecOptions: child_process.ExecOptions = {
env: extension.env,
env: await extension.resolvedEnv(),
};

let result = await promisifiedExec(`roslaunch --dump-params ${config.target}`, rosExecOptions);
Expand Down Expand Up @@ -63,6 +64,7 @@ export class LaunchResolver implements vscode.DebugConfigurationProvider {
} else if (result.stdout.length == 0) {
throw (new Error(`roslaunch unexpectedly produced no output, please test by running \"roslaunch --dump-params ${config.target}\" in a ros terminal.`));
}

const nodes = result.stdout.trim().split(os.EOL);
await Promise.all(nodes.map((node: string) => {
return promisifiedExec(`roslaunch --args ${node} ${config.target}`, rosExecOptions);
Expand All @@ -73,9 +75,12 @@ export class LaunchResolver implements vscode.DebugConfigurationProvider {
});
});
// @todo: error handling for Promise.all
return config;

// Return null as we have spawned new debug requests
return null;
}


private generateLaunchRequest(nodeName: string, command: string): ILaunchRequest {
let parsedArgs: shell_quote.ParseEntry[];
const isWindows = os.platform() === "win32";
Expand Down
6 changes: 3 additions & 3 deletions src/debugger/manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ class RosDebugManager implements vscode.DebugConfigurationProvider {
return this.configProvider.provideDebugConfigurations(folder, token);
}

public async resolveDebugConfiguration(folder: vscode.WorkspaceFolder | undefined, config: vscode.DebugConfiguration, token?: vscode.CancellationToken): Promise<vscode.DebugConfiguration> {
public async resolveDebugConfigurationWithSubstitutedVariables(folder: vscode.WorkspaceFolder | undefined, config: vscode.DebugConfiguration, token?: vscode.CancellationToken): Promise<vscode.DebugConfiguration> {
if (config.request === "attach") {
return this.attachResolver.resolveDebugConfiguration(folder, config as requests.IAttachRequest, token);
return this.attachResolver.resolveDebugConfigurationWithSubstitutedVariables(folder, config as requests.IAttachRequest, token);
} else if (config.request === "launch") {
return this.launchResolver.resolveDebugConfiguration(folder, config as requests.ILaunchRequest, token);
return this.launchResolver.resolveDebugConfigurationWithSubstitutedVariables(folder, config as requests.ILaunchRequest, token);
}
}
}
Expand Down
15 changes: 15 additions & 0 deletions src/debugger/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,25 @@
// Licensed under the MIT License.

import * as vscode from "vscode";
import * as util from "util";

import * as extension from "../extension";
import * as telemetry from "../telemetry-helper";

export async function oneTimePromiseFromEvent(eventCall, filter = undefined) : Promise<any> {
return new Promise(resolve => {
let disposable: vscode.Disposable;
disposable = eventCall(event => {
if (filter && !filter(event)) {
return;
}

disposable.dispose();
resolve(event);
});
});
}

/**
* Gets stringified settings to pass to the debug server.
*/
Expand Down
7 changes: 7 additions & 0 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ let onEnvChanged = new vscode.EventEmitter<void>();
*/
export let onDidChangeEnv = onEnvChanged.event;

export async function resolvedEnv() {
if (env === undefined) { // Env reload in progress
await debug_utils.oneTimePromiseFromEvent(onDidChangeEnv, () => env !== undefined);
}
return env
}

/**
* Subscriptions to dispose when the environment is changed.
*/
Expand Down