Skip to content

Commit bf9bd58

Browse files
committed
[release] prepare v0.19.0 release, part 2
455e1a9 snippets: add snippet for TestMain bf1225f src/goEnv: unset GOOS/GOARCH/GOROOT/... from tool installation env d7563f6 src/goInstallTools: use GOROOT/bin for gocode-gomod build too 3493cfe src/goDebug: respect user cwd debug configuration in noDebug ec9a5f8 src/goDebugConfiguration: remove user set '--gcflags' from config 3c7e4da package.json: add missing transform variants for go.addTags c13bcfe src/testUtils: fix test streaming output handling 2c5a0b9 src/testUtils: hide running test StatusBarItem after cancelling tests a4e523d src/testUtils: convert a goTest promise chain to async-await Change-Id: I5bcbf26cf7119e02f23e72937e73dc647f392ddd
2 parents d5dddfa + 455e1a9 commit bf9bd58

File tree

16 files changed

+755
-164
lines changed

16 files changed

+755
-164
lines changed

docs/debugging.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ This document explains how to debug your Go programs in VS Code. The Go debugger
99
* [Configuration](#configuration)
1010
* [Launch Configurations](#launch-configurations)
1111
* [Specifying build tags](#specifying-build-tags)
12+
* [Specifying other build flags](#specifying-other-build-flags)
1213
* [Using VS Code Variables](#using-vs-code-variables)
1314
* [Snippets](#snippets)
1415
* [Debugging on Windows Subsystem for Linux (WSL)](#debugging-on-windows-subsystem-for-linux-wsl)
@@ -135,6 +136,22 @@ in your launch configuration. This property supports multiple tags, which you ca
135136

136137
<!--TODO(rstambler): Confirm that the extension works with a comma (not space) separated list.-->
137138

139+
### Specifying other build flags
140+
141+
The flags specified in `buildFlags` and `env.GOFLAGS` are passed to the Go compiler when building your program for debugging. Delve adds `--gcflags='all=-N -l'` to the list of build flags to disable optimizations. User specified buildFlags conflict with this setting, so the extension removes them ([Issue #117](https://github.com/golang/vscode-go/issues/117)). If you wish to debug a program using custom `--gcflags`, build the program using `go build` and launch using `exec` mode:
142+
143+
```json
144+
{
145+
"name": "Launch executable",
146+
"type": "go",
147+
"request": "launch",
148+
"mode": "exec",
149+
"program": "/absolute/path/to/executable"
150+
}
151+
```
152+
153+
Note that it is not recommended to debug optimized executables as Delve may not have the information necessary to properly debug your program.
154+
138155
### Using [VS Code variables]
139156

140157
Any property in the launch configuration that requires a file path can be specified in terms of [VS Code variables]. Here are some useful ones to know:

package-lock.json

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
},
4747
"extensionDependencies": [],
4848
"dependencies": {
49+
"@types/yargs-parser": "^15.0.0",
4950
"deep-equal": "^2.0.2",
5051
"diff": "^4.0.2",
5152
"glob": "^7.1.6",
@@ -1689,7 +1690,10 @@
16891690
"type": "string",
16901691
"enum": [
16911692
"snakecase",
1692-
"camelcase"
1693+
"camelcase",
1694+
"lispcase",
1695+
"pascalcase",
1696+
"keep"
16931697
],
16941698
"default": "snakecase",
16951699
"description": "Transformation rule used by Go: Add Tags command to add tags"

snippets/go.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,11 @@
215215
"body": "func Test$1(t *testing.T) {\n\t$0\n}",
216216
"description": "Snippet for Test function"
217217
},
218+
"test main": {
219+
"prefix": "tm",
220+
"body": "func TestMain(m *testing.M) {\n\t$1\n\n\tos.Exit(m.Run())\n}",
221+
"description": "Snippet for TestMain function"
222+
},
218223
"benchmark function": {
219224
"prefix": "bf",
220225
"body": "func Benchmark$1(b *testing.B) {\n\tfor ${2:i} := 0; ${2:i} < b.N; ${2:i}++ {\n\t\t$0\n\t}\n}",

src/debugAdapter/goDebug.ts

Lines changed: 55 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Licensed under the MIT License. See LICENSE in the project root for license information.
44
*--------------------------------------------------------*/
55

6-
import { ChildProcess, execFile, spawn } from 'child_process';
6+
import { ChildProcess, execFile, spawn, spawnSync } from 'child_process';
77
import { EventEmitter } from 'events';
88
import * as fs from 'fs';
99
import { existsSync, lstatSync } from 'fs';
@@ -481,25 +481,68 @@ export class Delve {
481481
if (!!launchArgs.noDebug) {
482482
if (mode === 'debug') {
483483
this.noDebug = true;
484-
const runArgs = ['run'];
485-
const runOptions: { [key: string]: any } = { cwd: dirname, env };
484+
const build = ['build'];
485+
486+
const output = path.join(os.tmpdir(), 'out');
487+
build.push(`-o=${output}`);
488+
489+
const buildOptions: { [key: string]: any } = { cwd: dirname, env };
486490
if (launchArgs.buildFlags) {
487-
runArgs.push(launchArgs.buildFlags);
491+
build.push(launchArgs.buildFlags);
488492
}
493+
489494
if (isProgramDirectory) {
490-
runArgs.push('.');
495+
build.push('.');
491496
} else {
492-
runArgs.push(program);
493-
}
494-
if (launchArgs.args) {
495-
runArgs.push(...launchArgs.args);
497+
build.push(program);
496498
}
497499

498500
const goExe = getBinPathWithPreferredGopathGoroot('go', []);
499501
log(`Current working directory: ${dirname}`);
500-
log(`Running: ${goExe} ${runArgs.join(' ')}`);
502+
log(`Building: ${goExe} ${build.join(' ')}`);
503+
504+
// Use spawnSync to ensure that the binary exists before running it.
505+
const buffer = spawnSync(goExe, build, buildOptions);
506+
if (buffer.stderr && buffer.stderr.length > 0) {
507+
const str = buffer.stderr.toString();
508+
if (this.onstderr) {
509+
this.onstderr(str);
510+
}
511+
}
512+
if (buffer.stdout && buffer.stdout.length > 0) {
513+
const str = buffer.stdout.toString();
514+
if (this.onstdout) {
515+
this.onstdout(str);
516+
}
517+
}
518+
if (buffer.status) {
519+
logError(`Build process exiting with code: ${buffer.status} signal: ${buffer.signal}`);
520+
if (this.onclose) {
521+
this.onclose(buffer.status);
522+
}
523+
} else {
524+
log(`Build process exiting normally ${buffer.signal}`);
525+
}
526+
if (buffer.error) {
527+
reject(buffer.error);
528+
}
501529

502-
this.debugProcess = spawn(goExe, runArgs, runOptions);
530+
// Run the built binary
531+
let wd = dirname;
532+
if (!!launchArgs.cwd) {
533+
wd = launchArgs.cwd;
534+
}
535+
const runOptions: { [key: string]: any } = { cwd: wd, env };
536+
537+
const run = [];
538+
if (launchArgs.args) {
539+
run.push(...launchArgs.args);
540+
}
541+
542+
log(`Current working directory: ${wd}`);
543+
log(`Running: ${output} ${run.join(' ')}`);
544+
545+
this.debugProcess = spawn(output, run, runOptions);
503546
this.debugProcess.stderr.on('data', (chunk) => {
504547
const str = chunk.toString();
505548
if (this.onstderr) {
@@ -525,6 +568,7 @@ export class Delve {
525568
this.debugProcess.on('error', (err) => {
526569
reject(err);
527570
});
571+
528572
resolve();
529573
return;
530574
}

src/goDebugConfiguration.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
import path = require('path');
99
import vscode = require('vscode');
10+
import parse = require('yargs-parser');
11+
import unparse = require('yargs-unparser');
1012
import { toolExecutionEnvironment } from './goEnv';
1113
import { promptForMissingTool } from './goInstallTools';
1214
import { packagePathToGoModPathMap } from './goModules';
@@ -92,6 +94,28 @@ export class GoDebugConfigurationProvider implements vscode.DebugConfigurationPr
9294
debugConfiguration['cwd'] = resolvePath(debugConfiguration['cwd']);
9395
}
9496

97+
// Remove any '--gcflags' entries and show a warning
98+
if (debugConfiguration['buildFlags']) {
99+
const resp = this.removeFlag(debugConfiguration['buildFlags'], 'gcflags');
100+
if (resp.removed) {
101+
debugConfiguration['buildFlags'] = resp.args;
102+
this.showWarning(
103+
'ignoreDebugGCFlagsWarning',
104+
`User specified build flag '--gcflags' in 'buildFlags' is being ignored (see [debugging with build flags](https://github.com/golang/vscode-go/blob/master/docs/debugging.md#specifying-other-build-flags) documentation)`
105+
);
106+
}
107+
}
108+
if (debugConfiguration['env'] && debugConfiguration['env']['GOFLAGS']) {
109+
const resp = this.removeFlag(debugConfiguration['env']['GOFLAGS'], 'gcflags');
110+
if (resp.removed) {
111+
debugConfiguration['env']['GOFLAGS'] = resp.args;
112+
this.showWarning(
113+
'ignoreDebugGCFlagsWarning',
114+
`User specified build flag '--gcflags' in 'GOFLAGS' is being ignored (see [debugging with build flags](https://github.com/golang/vscode-go/blob/master/docs/debugging.md#specifying-other-build-flags) documentation)`
115+
);
116+
}
117+
}
118+
95119
debugConfiguration['dlvToolPath'] = getBinPath('dlv');
96120
if (!path.isAbsolute(debugConfiguration['dlvToolPath'])) {
97121
promptForMissingTool('dlv');
@@ -156,4 +180,13 @@ export class GoDebugConfigurationProvider implements vscode.DebugConfigurationPr
156180
}
157181
});
158182
}
183+
184+
private removeFlag(args: string, flag: string): {args: string, removed: boolean} {
185+
const argv = parse(args, {configuration: {'short-option-groups': false}});
186+
if (argv[flag]) {
187+
delete argv[flag];
188+
return { args: unparse(argv).join(' '), removed: true };
189+
}
190+
return {args, removed: false};
191+
}
159192
}

src/goEnv.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,15 @@ export function toolInstallationEnvironment(): NodeJS.Dict<string> {
3939
}
4040
env['GOPATH'] = toolsGopath;
4141

42+
// Unset env vars that would affect tool build process: 'GOROOT', 'GOOS', 'GOARCH', ...
43+
// Tool installation should be done for the host OS/ARCH (GOHOSTOS/GOHOSTARCH) with
44+
// the default setup.
45+
delete env['GOOS'];
46+
delete env['GOARCH'];
47+
delete env['GOROOT'];
48+
delete env['GOFLAGS'];
49+
delete env['GOENV'];
50+
4251
return env;
4352
}
4453

src/goInstallTools.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -242,15 +242,15 @@ export async function installTool(
242242

243243
// TODO(rstambler): Figure out why this happens and maybe delete it.
244244
if (stderr.indexOf('unexpected directory layout:') > -1) {
245-
await execFile(goVersion.binaryPath, args, opts);
245+
await execFile(goBinary, args, opts);
246246
} else if (hasModSuffix(tool)) {
247247
const gopath = env['GOPATH'];
248248
if (!gopath) {
249249
return `GOPATH not configured in environment`;
250250
}
251251
const destDir = gopath.split(path.delimiter)[0];
252252
const outputFile = path.join(destDir, 'bin', process.platform === 'win32' ? `${tool.name}.exe` : tool.name);
253-
await execFile(goVersion.binaryPath, ['build', '-o', outputFile, importPath], opts);
253+
await execFile(goBinary, ['build', '-o', outputFile, importPath], opts);
254254
}
255255
const toolInstallPath = getBinPath(tool.name);
256256
outputChannel.appendLine(`Installing ${toolImportPath} (${toolInstallPath}) SUCCEEDED`);

0 commit comments

Comments
 (0)