Skip to content

revert deploy steps #9557

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

Merged
merged 2 commits into from
Jul 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Extension/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,3 @@ localized_string_ids.h
# ignore generate files. It will be generated when building
src/nativeStrings.ts

vscode*.d.ts
1 change: 0 additions & 1 deletion Extension/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

## Version 1.11.1 (pre-release): July 7, 2022
### Enhancements
* Add deploySteps and variables to cppdbg. [PR #9418](https://github.com/microsoft/vscode-cpptools/pull/9418)
* Move "auto" inlay hints to the right by default and add `C_Cpp.inlayHints.autoDeclarationTypes.showOnLeft`. [#9478](https://github.com/microsoft/vscode-cpptools/issues/9478)
* Allow breakpoints for Rust debugging. [PR #9484](https://github.com/microsoft/vscode-cpptools/pull/9484)
* Remove `_` from the start of parameter inlay hints and add `C_Cpp.inlayHints.parameterNames.hideLeadingUnderscores`. [#9485](https://github.com/microsoft/vscode-cpptools/issues/9485)
Expand Down
903 changes: 27 additions & 876 deletions Extension/package.json

Large diffs are not rendered by default.

29 changes: 0 additions & 29 deletions Extension/package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -301,35 +301,6 @@
"c_cpp.debuggers.hardwareBreakpoints.description": "Explicit control of hardware breakpoint behavior for remote targets.",
"c_cpp.debuggers.hardwareBreakpoints.require.description": "If true, always use hardware breakpoints. Defaults to false.",
"c_cpp.debuggers.hardwareBreakpoints.limit.description": "Optional limit on the number of available hardware breakpoints to use. Only enforced when \"require\" is true and \"limit\" is greater than 0. Defaults to 0.",
"c_cpp.debuggers.variables.description": "Variables for recursive substitution in this launch configuration. Each variable may refer to others.",
"c_cpp.debuggers.variables.properties.description": "Variable for recursive substitution in this launch configuration. The value may refer to other variables.",
"c_cpp.debuggers.host.description": "Host information.",
"c_cpp.debuggers.host.user.description": "User logging into the host.",
"c_cpp.debuggers.host.hostName.description": "Host name.",
"c_cpp.debuggers.host.port.description": "SSH port on the host. Default is 22.",
"c_cpp.debuggers.host.jumpHost.description": "Connect to the target host by first making a connection to the jump hosts.",
"c_cpp.debuggers.host.localForward.description": "Forward connections to the given TCP port or Unix socket on the local (client) host to the given host and port, or Unix socket, on the remote side",
"c_cpp.debuggers.host.localForward.bindAddress.description": "Local address",
"c_cpp.debuggers.host.localForward.port.description": "Local port",
"c_cpp.debuggers.host.localForward.host.description": "Host name",
"c_cpp.debuggers.host.localForward.hostPort.description": "Host port",
"c_cpp.debuggers.host.localForward.localSocket.description": "Local socket",
"c_cpp.debuggers.host.localForward.remoteSocket.description": "Remote socket",
"c_cpp.debuggers.deploySteps.description": "Steps needed to deploy the application. Order matters.",
"c_cpp.debuggers.deploySteps.scp.description": "Copy files using SCP.",
"c_cpp.debuggers.deploySteps.scp.files.description": "Files to be copied via SCP. Supports path pattern.",
"c_cpp.debuggers.deploySteps.scp.targetDir.description": "Target directory.",
"c_cpp.debuggers.deploySteps.scp.scpPath.description": "Optional full path to SCP. Assumes SCP is on PATH if not specified",
"c_cpp.debuggers.deploySteps.debug": "If true, skip when starting without debugging. If false, skip when starting debugging. If undefined, never skip.",
"c_cpp.debuggers.deploySteps.ssh.description": "SSH command step.",
"c_cpp.debuggers.deploySteps.ssh.command.description": "Command to be executed via SSH. The command after '-c' in SSH command.",
"c_cpp.debuggers.deploySteps.ssh.sshPath.description": "Optional full path to SSH. Assumes SSH is on PATH if not specified",
"c_cpp.debuggers.deploySteps.continueOn.description": "An optional finish pattern in output. When this pattern is seen in the output, continue the deploy procedures regardless of whether this step returns.",
"c_cpp.debuggers.deploySteps.shell.description": "Shell command step.",
"c_cpp.debuggers.deploySteps.shell.command.description": "Shell command to be executed.",
"c_cpp.debuggers.vsCodeCommand.description": "VS Code command to be invoked. Can be a command in VS Code or an active extension.",
"c_cpp.debuggers.vsCodeCommand.command.description": "VS Code command to be invoked.",
"c_cpp.debuggers.vsCodeCommand.args.description": "Arguments to the VS Code command.",
"c_cpp.taskDefinitions.name.description": "The name of the task.",
"c_cpp.taskDefinitions.command.description": "The path to either a compiler or script that performs compilation.",
"c_cpp.taskDefinitions.args.description": "Additional arguments to pass to the compiler or compilation script.",
Expand Down
157 changes: 9 additions & 148 deletions Extension/src/Debugger/configurationProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,24 +23,10 @@ import { PlatformInformation } from '../platform';
import { Environment, ParsedEnvironmentFile } from './ParsedEnvironmentFile';
import { CppSettings, OtherSettings } from '../LanguageServer/settings';
import { configPrefix } from '../LanguageServer/extension';
import { expandAllStrings, ExpansionOptions, ExpansionVars } from '../expand';
import { scp, ssh } from '../SSH/commands';
import * as glob from 'glob';
import { promisify } from 'util';

nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })();
const localize: nls.LocalizeFunc = nls.loadMessageBundle();

enum StepType {
scp = 'scp',
ssh = 'ssh',
shell = 'shell',
remoteShell = 'remoteShell',
command = 'command'
}

const globAsync: (pattern: string, options?: glob.IOptions | undefined) => Promise<string[]> = promisify(glob);

/*
* Retrieves configurations from a provider and displays them in a quickpick menu to be selected.
* Ensures that the selected configuration's preLaunchTask (if existent) is populated in the user's task.json.
Expand Down Expand Up @@ -219,11 +205,11 @@ export class DebugConfigurationProvider implements vscode.DebugConfigurationProv
* This hook is directly called after 'resolveDebugConfiguration' but with all variables substituted.
* This is also ran after the tasks.json has completed.
*
* Try to add all missing attributes to the debug configuration being launched.
* Try to add all missing attributes to the debug configuration being launched.
* If return "undefined", the debugging will be aborted silently.
* If return "null", the debugging will be aborted and launch.json will be opened.
*/
async resolveDebugConfigurationWithSubstitutedVariables(folder: vscode.WorkspaceFolder | undefined, config: CppDebugConfiguration, token?: vscode.CancellationToken): Promise<CppDebugConfiguration | null | undefined> {
*/
resolveDebugConfigurationWithSubstitutedVariables(folder: vscode.WorkspaceFolder | undefined, config: CppDebugConfiguration, token?: vscode.CancellationToken): vscode.ProviderResult<CppDebugConfiguration> {
if (!config || !config.type) {
return undefined; // Abort debugging silently.
}
Expand All @@ -246,7 +232,7 @@ export class DebugConfigurationProvider implements vscode.DebugConfigurationProv

// Disable debug heap by default, enable if 'enableDebugHeap' is set.
if (!config.enableDebugHeap) {
const disableDebugHeapEnvSetting: Environment = { "name": "_NO_DEBUG_HEAP", "value": "1" };
const disableDebugHeapEnvSetting: Environment = {"name" : "_NO_DEBUG_HEAP", "value" : "1"};

if (config.environment && util.isArray(config.environment)) {
config.environment.push(disableDebugHeapEnvSetting);
Expand All @@ -259,8 +245,6 @@ export class DebugConfigurationProvider implements vscode.DebugConfigurationProv
// Add environment variables from .env file
this.resolveEnvFile(config, folder);

await this.expand(config, folder);

this.resolveSourceFileMapVariables(config);

// Modify WSL config for OpenDebugAD7
Expand Down Expand Up @@ -323,19 +307,6 @@ export class DebugConfigurationProvider implements vscode.DebugConfigurationProv
// logger.showOutputChannel();
}

// Run deploy steps
if (config.deploySteps && config.deploySteps.length !== 0) {
const codeVersion: number[] = vscode.version.split('.').map(num => parseInt(num, undefined));
if ((util.isNumber(codeVersion[0]) && codeVersion[0] < 1) || (util.isNumber(codeVersion[0]) && codeVersion[0] === 1 && util.isNumber(codeVersion[1]) && codeVersion[1] < 69)) {
logger.getOutputChannelLogger().showErrorMessage(localize("vs.code.1.69+.required", "'deploySteps' require VS Code 1.69+."));
return undefined;
}
const deploySucceeded: boolean = await this.deploySteps(config, token);
if (!deploySucceeded || token?.isCancellationRequested) {
return undefined;
}
}

return config;
}

Expand Down Expand Up @@ -624,17 +595,17 @@ export class DebugConfigurationProvider implements vscode.DebugConfigurationProv
const newSourceFileMapTarget: string = util.resolveVariables(sourceFileMapTarget, undefined);
if (sourceFileMapTarget !== newSourceFileMapTarget) {
// Add a space if source was changed, else just tab the target message.
message += (message ? ' ' : '\t');
message += (message ? ' ' : '\t');
message += localize("replacing.targetpath", "Replacing {0} '{1}' with '{2}'.", "targetPath", sourceFileMapTarget, newSourceFileMapTarget);
target = newSourceFileMapTarget;
}
} else if (util.isObject(sourceFileMapTarget)) {
const newSourceFileMapTarget: { "editorPath": string; "useForBreakpoints": boolean } = sourceFileMapTarget;
const newSourceFileMapTarget: {"editorPath": string; "useForBreakpoints": boolean } = sourceFileMapTarget;
newSourceFileMapTarget["editorPath"] = util.resolveVariables(sourceFileMapTarget["editorPath"], undefined);

if (sourceFileMapTarget !== newSourceFileMapTarget) {
// Add a space if source was changed, else just tab the target message.
message += (message ? ' ' : '\t');
message += (message ? ' ' : '\t');
message += localize("replacing.editorPath", "Replacing {0} '{1}' with '{2}'.", "editorPath", sourceFileMapTarget, newSourceFileMapTarget["editorPath"]);
target = newSourceFileMapTarget;
}
Expand Down Expand Up @@ -873,7 +844,7 @@ export class DebugConfigurationProvider implements vscode.DebugConfigurationProv
}
selectedConfig.debugType = debugModeOn ? DebugType.debug : DebugType.run;
// startDebugging will trigger a call to resolveDebugConfiguration.
await vscode.debug.startDebugging(folder, selectedConfig, { noDebug: !debugModeOn });
await vscode.debug.startDebugging(folder, selectedConfig, {noDebug: !debugModeOn});
}

private async selectConfiguration(textEditor: vscode.TextEditor, pickDefault: boolean = true, onlyWorkspaceFolder: boolean = false): Promise<CppDebugConfiguration | undefined> {
Expand Down Expand Up @@ -941,116 +912,6 @@ export class DebugConfigurationProvider implements vscode.DebugConfigurationProv
}
}
}

private async expand(config: vscode.DebugConfiguration, folder: vscode.WorkspaceFolder | undefined): Promise<void> {
const folderPath: string | undefined = folder?.uri.fsPath || vscode.workspace.workspaceFolders?.[0].uri.fsPath;
const vars: ExpansionVars = config.variables ? config.variables : {};
vars.workspaceFolder = folderPath || '{workspaceFolder}';
vars.workspaceFolderBasename = folderPath ? path.basename(folderPath) : '{workspaceFolderBasename}';
const expansionOptions: ExpansionOptions = { vars, recursive: true };
return expandAllStrings(config, expansionOptions);
}

// Returns true when ALL steps succeed; stop all subsequent steps if one fails
private async deploySteps(config: vscode.DebugConfiguration, cancellationToken?: vscode.CancellationToken): Promise<boolean> {
let succeeded: boolean = true;
const deployStart: number = new Date().getTime();

for (const step of config.deploySteps) {
succeeded = await this.singleDeployStep(config, step, cancellationToken);
if (!succeeded) {
break;
}
}

const deployEnd: number = new Date().getTime();

const telemetryProperties: { [key: string]: string } = {
Succeeded: `${succeeded}`,
IsDebugging: `${!config.noDebug || false}`
};
const telemetryMetrics: { [key: string]: number } = {
NumSteps: config.deploySteps.length,
Duration: deployEnd - deployStart
};
Telemetry.logDebuggerEvent('deploy', telemetryProperties, telemetryMetrics);

return succeeded;
}

private async singleDeployStep(config: vscode.DebugConfiguration, step: any, cancellationToken?: vscode.CancellationToken): Promise<boolean> {
if ((config.noDebug && step.debug === true) || (!config.noDebug && step.debug === false)) {
// Skip steps that doesn't match current launch mode. Explicit true/false check, since a step is always run when debug is undefined.
return true;
}
switch (step.type) {
case StepType.command: {
// VS Code commands are the same regardless of which extension invokes them, so just invoke them here.
if (step.args && !Array.isArray(step.args)) {
logger.getOutputChannelLogger().showErrorMessage(localize('command.args.must.be.array', '"args" in command deploy step must be an array.'));
return false;
}
const returnCode: unknown = await vscode.commands.executeCommand(step.command, ...step.args);
return !returnCode;
}
case StepType.scp: {
if (!step.files || !step.targetDir || !step.host) {
logger.getOutputChannelLogger().showErrorMessage(localize('missing.properties.scp', '"host", "files", and "targetDir" are required in scp steps.'));
return false;
}
const host: util.ISshHostInfo = { hostName: step.host.hostName, user: step.host.user, port: step.host.port };
const jumpHosts: util.ISshHostInfo[] = step.host.jumpHosts;
let files: vscode.Uri[] = [];
if (util.isString(step.files)) {
files = files.concat((await globAsync(step.files)).map(file => vscode.Uri.file(file)));
} else if (util.isArrayOfString(step.files)) {
for (const fileGlob of (step.files as string[])) {
files = files.concat((await globAsync(fileGlob)).map(file => vscode.Uri.file(file)));
}
} else {
logger.getOutputChannelLogger().showErrorMessage(localize('incorrect.files.type.scp', '"files" must be a string or an array of strings in scp steps.'));
return false;
}
const scpResult: util.ProcessReturnType = await scp(files, host, step.targetDir, config.scpPath, jumpHosts, cancellationToken);
if (!scpResult.succeeded || cancellationToken?.isCancellationRequested) {
return false;
}
break;
}
case StepType.ssh: {
if (!step.host || !step.command) {
logger.getOutputChannelLogger().showErrorMessage(localize('missing.properties.ssh', '"host" and "command" are required for ssh steps.'));
return false;
}
const host: util.ISshHostInfo = { hostName: step.host.hostName, user: step.host.user, port: step.host.port };
const jumpHosts: util.ISshHostInfo[] = step.host.jumpHosts;
const localForwards: util.ISshLocalForwardInfo[] = step.host.localForwards;
const continueOn: string = step.continueOn;
const sshResult: util.ProcessReturnType = await ssh(host, step.command, config.sshPath, jumpHosts, localForwards, continueOn, cancellationToken);
if (!sshResult.succeeded || cancellationToken?.isCancellationRequested) {
return false;
}
break;
}
case StepType.shell: {
if (!step.command) {
logger.getOutputChannelLogger().showErrorMessage(localize('missing.properties.shell', '"command" is required for shell steps.'));
return false;
}
const taskResult: util.ProcessReturnType = await util.spawnChildProcess(step.command, undefined, step.continueOn);
if (!taskResult.succeeded || cancellationToken?.isCancellationRequested) {
logger.getOutputChannelLogger().showErrorMessage(taskResult.output);
return false;
}
break;
}
default: {
logger.getOutputChannelLogger().appendLine(localize('deploy.step.type.not.supported', 'Deploy step type {0} is not supported.', step.type));
return false;
}
}
return true;
}
}

export interface IConfigurationAssetProvider {
Expand Down Expand Up @@ -1203,7 +1064,7 @@ export class ConfigurationSnippetProvider implements vscode.CompletionItemProvid
items = [];

// Make a copy of each snippet since we are adding a comma to the end of the insertText.
this.snippets.forEach((item) => items.push({ ...item }));
this.snippets.forEach((item) => items.push({...item}));

items.map((item) => {
item.insertText = item.insertText + ','; // Add comma
Expand Down
Loading