Skip to content

Commit 9fa871b

Browse files
committed
src/goMain: warn users if go.goroot is set
Warn users if this is an obviously invalid value (binary). Show information popup if go.goroot is configured. And, fixes a bug in v0.25.0 - missing await when checking whether the go.goroot value is a valid directory. Fixes #1501 Change-Id: I3487f4b089c9ba4fe34f36e5e033ae19d63537e2 Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/320429 Trust: Hyang-Ah Hana Kim <[email protected]> Run-TryBot: Hyang-Ah Hana Kim <[email protected]> TryBot-Result: kokoro <[email protected]> Reviewed-by: Suzy Mueller <[email protected]>
1 parent 0f4b38f commit 9fa871b

File tree

2 files changed

+79
-12
lines changed

2 files changed

+79
-12
lines changed

src/goMain.ts

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -151,11 +151,11 @@ export async function activate(ctx: vscode.ExtensionContext) {
151151

152152
const configGOROOT = getGoConfig()['goroot'];
153153
if (configGOROOT) {
154-
const goroot = resolvePath(configGOROOT);
155-
if (dirExists(goroot)) {
156-
logVerbose(`setting GOROOT = ${goroot} because "go.goroot": "${configGOROOT}"`);
157-
process.env['GOROOT'] = goroot;
158-
}
154+
// We don't support unsetting go.goroot because we don't know whether
155+
// !configGOROOT case indicates the user wants to unset process.env['GOROOT']
156+
// or the user wants the extension to use the current process.env['GOROOT'] value.
157+
// TODO(hyangah): consider utilizing an empty value to indicate unset?
158+
await setGOROOTEnvVar(configGOROOT);
159159
}
160160

161161
// Present a warning about the deprecation of the go.documentLink setting.
@@ -440,7 +440,7 @@ If you would like additional configuration for diagnostics from gopls, please se
440440
);
441441

442442
ctx.subscriptions.push(
443-
vscode.workspace.onDidChangeConfiguration((e: vscode.ConfigurationChangeEvent) => {
443+
vscode.workspace.onDidChangeConfiguration(async (e: vscode.ConfigurationChangeEvent) => {
444444
if (!e.affectsConfiguration('go')) {
445445
return;
446446
}
@@ -449,12 +449,7 @@ If you would like additional configuration for diagnostics from gopls, please se
449449
if (e.affectsConfiguration('go.goroot')) {
450450
const configGOROOT = updatedGoConfig['goroot'];
451451
if (configGOROOT) {
452-
const goroot = resolvePath(configGOROOT);
453-
const oldGoroot = process.env['GOROOT'];
454-
if (oldGoroot !== goroot && dirExists(goroot)) {
455-
logVerbose(`setting GOROOT = ${goroot} because "go.goroot": "${configGOROOT}"`);
456-
process.env['GOROOT'] = goroot;
457-
}
452+
await setGOROOTEnvVar(configGOROOT);
458453
}
459454
}
460455
if (
@@ -997,3 +992,42 @@ function lintDiagnosticCollectionName(lintToolName: string) {
997992
}
998993
return `go-${lintToolName}`;
999994
}
995+
996+
// set GOROOT env var. If necessary, shows a warning.
997+
export async function setGOROOTEnvVar(configGOROOT: string) {
998+
if (!configGOROOT) {
999+
return;
1000+
}
1001+
const goroot = configGOROOT ? resolvePath(configGOROOT) : undefined;
1002+
1003+
const currentGOROOT = process.env['GOROOT'];
1004+
if (goroot === currentGOROOT) {
1005+
return;
1006+
}
1007+
if (!(await dirExists(goroot))) {
1008+
vscode.window.showWarningMessage(`go.goroot setting is ignored. ${goroot} is not a valid GOROOT directory.`);
1009+
return;
1010+
}
1011+
const neverAgain = { title: "Don't Show Again" };
1012+
const ignoreGOROOTSettingWarningKey = 'ignoreGOROOTSettingWarning';
1013+
const ignoreGOROOTSettingWarning = getFromGlobalState(ignoreGOROOTSettingWarningKey);
1014+
if (!ignoreGOROOTSettingWarning) {
1015+
vscode.window
1016+
.showInformationMessage(
1017+
`"go.goroot" setting (${goroot}) will be applied and set the GOROOT environment variable.`,
1018+
neverAgain
1019+
)
1020+
.then((result) => {
1021+
if (result === neverAgain) {
1022+
updateGlobalState(ignoreGOROOTSettingWarningKey, true);
1023+
}
1024+
});
1025+
}
1026+
1027+
logVerbose(`setting GOROOT = ${goroot} (old value: ${currentGOROOT}) because "go.goroot": "${configGOROOT}"`);
1028+
if (goroot) {
1029+
process.env['GOROOT'] = goroot;
1030+
} else {
1031+
delete process.env.GOROOT;
1032+
}
1033+
}

test/integration/statusbar.test.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import { getWorkspaceState, setWorkspaceState } from '../../src/stateUtils';
2626
import { MockMemento } from '../mocks/MockMemento';
2727

2828
import ourutil = require('../../src/util');
29+
import { setGOROOTEnvVar } from '../../src/goMain';
2930

3031
describe('#initGoStatusBar()', function () {
3132
this.beforeAll(async () => {
@@ -52,6 +53,38 @@ describe('#initGoStatusBar()', function () {
5253
});
5354
});
5455

56+
describe('#setGOROOTEnvVar', function () {
57+
let origGOROOT = process.env['GOROOT'];
58+
59+
this.beforeEach(() => {
60+
origGOROOT = process.env['GOROOT'];
61+
});
62+
63+
this.afterEach(() => {
64+
if (origGOROOT) {
65+
process.env['GOROOT'] = origGOROOT;
66+
} else {
67+
delete process.env.GOROOT;
68+
}
69+
});
70+
71+
it('empty goroot does not change GOROOT', async () => {
72+
await setGOROOTEnvVar('');
73+
assert.strictEqual(process.env['GOROOT'], origGOROOT);
74+
});
75+
76+
it('non-directory value is rejected', async () => {
77+
await setGOROOTEnvVar(ourutil.getBinPath('go'));
78+
assert.strictEqual(process.env['GOROOT'], origGOROOT);
79+
});
80+
81+
it('directory value is accepted', async () => {
82+
const goroot = path.join(path.dirname(ourutil.getBinPath('go')), '..');
83+
await setGOROOTEnvVar(goroot);
84+
assert.strictEqual(process.env['GOROOT'], goroot);
85+
});
86+
});
87+
5588
describe('#setSelectedGo()', function () {
5689
this.timeout(40000);
5790
let sandbox: sinon.SinonSandbox | undefined;

0 commit comments

Comments
 (0)