Skip to content

Commit 3648e64

Browse files
committed
src/goExplorer.ts: make workspace go env editable via commands
Added commands for editing and resetting go env values. The commands are available from the command palette or as context items within the explorer view. When invoked from the explorer on an env tree item, the command will apply only to that item. The edit command invoked from the palette will present the user with a list of editable go env variables. Screencast: https://drive.google.com/file/d/19KcTYcYACpL-8R5pW9z_XMaaCnliqSZj/view?usp=sharing For #2049. Change-Id: Ic13944437f300d3616d8b98533842c4da914c080 Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/391515 Trust: Jamal Carvalho <[email protected]> Run-TryBot: Jamal Carvalho <[email protected]> TryBot-Result: kokoro <[email protected]> Reviewed-by: Hyang-Ah Hana Kim <[email protected]>
1 parent 7ab6cc5 commit 3648e64

File tree

4 files changed

+108
-21
lines changed

4 files changed

+108
-21
lines changed

docs/commands.md

+8
Original file line numberDiff line numberDiff line change
@@ -250,3 +250,11 @@ Refresh the Go explorer. Only available as a menu item in the explorer.
250250
### `Go Explorer: Open File`
251251

252252
Open a file from the Go explorer. Only available as a menu item in the explorer.
253+
254+
### `Go: Edit Workspace Env`
255+
256+
Edit the Go Env for the active workspace.
257+
258+
### `Go: Reset Workspace Env`
259+
260+
Reset the Go Env for the active workspace.

package.json

+24-1
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,20 @@
502502
"description": "Open a file from the Go explorer. Only available as a menu item in the explorer.",
503503
"category": "Explorer",
504504
"icon": "$(go-to-file)"
505+
},
506+
{
507+
"command": "go.workspace.editEnv",
508+
"title": "Go: Edit Workspace Env",
509+
"description": "Edit the Go Env for the active workspace.",
510+
"icon": "$(settings-edit)",
511+
"enablement": "workspaceFolderCount > 0"
512+
},
513+
{
514+
"command": "go.workspace.resetEnv",
515+
"title": "Go: Reset Workspace Env",
516+
"description": "Reset the Go Env for the active workspace.",
517+
"icon": "$(settings-remove)",
518+
"enablement": "workspaceFolderCount > 0"
505519
}
506520
],
507521
"breakpoints": [
@@ -2692,8 +2706,17 @@
26922706
},
26932707
{
26942708
"command": "go.explorer.open",
2695-
"when": "view == go.explorer && viewItem == go:explorer:envitem:file",
2709+
"when": "viewItem == go:explorer:envfile",
26962710
"group": "inline"
2711+
},
2712+
{
2713+
"command": "go.workspace.editEnv",
2714+
"when": "viewItem =~ /(go:explorer:envtree|go:explorer:envitem)/ && workspaceFolderCount > 0",
2715+
"group": "inline"
2716+
},
2717+
{
2718+
"command": "go.workspace.resetEnv",
2719+
"when": "viewItem =~ /go:explorer:env/ && workspaceFolderCount > 0"
26972720
}
26982721
]
26992722
},

src/goExplorer.ts

+75-19
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,17 @@ export class GoExplorerProvider implements vscode.TreeDataProvider<vscode.TreeIt
2222
private activeFolder?: vscode.WorkspaceFolder;
2323
private activeDocument?: vscode.TextDocument;
2424

25-
static setup(ctx: vscode.ExtensionContext) {
25+
static setup({ subscriptions }: vscode.ExtensionContext) {
2626
const provider = new this();
27-
ctx.subscriptions.push(vscode.window.registerTreeDataProvider('go.explorer', provider));
28-
ctx.subscriptions.push(vscode.commands.registerCommand('go.explorer.refresh', () => provider.update(true)));
29-
ctx.subscriptions.push(
30-
vscode.commands.registerCommand('go.explorer.open', (item: EnvTreeItem) => provider.open(item))
31-
);
27+
const {
28+
window: { registerTreeDataProvider },
29+
commands: { registerCommand }
30+
} = vscode;
31+
subscriptions.push(registerTreeDataProvider('go.explorer', provider));
32+
subscriptions.push(registerCommand('go.explorer.refresh', () => provider.update(true)));
33+
subscriptions.push(registerCommand('go.explorer.open', (item) => provider.open(item)));
34+
subscriptions.push(registerCommand('go.workspace.editEnv', (item) => provider.editEnv(item)));
35+
subscriptions.push(registerCommand('go.workspace.resetEnv', (item) => provider.resetEnv(item)));
3236
return provider;
3337
}
3438

@@ -89,6 +93,39 @@ export class GoExplorerProvider implements vscode.TreeDataProvider<vscode.TreeIt
8993
await vscode.window.showTextDocument(doc);
9094
}
9195

96+
private async editEnv(item?: EnvTreeItem) {
97+
const uri = this.activeFolder?.uri;
98+
if (!uri) {
99+
return;
100+
}
101+
let pick: { label?: string; description?: string };
102+
if (isEnvTreeItem(item)) {
103+
pick = { label: item.key, description: item.value };
104+
} else {
105+
const items = Object.entries<string>(await runGoEnv(uri))
106+
.filter(([label]) => !GoEnv.readonlyVars.has(label))
107+
.map(([label, description]) => ({
108+
label,
109+
description
110+
}));
111+
pick = await vscode.window.showQuickPick(items, { title: 'Go: Edit Workspace Env' });
112+
}
113+
if (!pick) return;
114+
const { label, description } = pick;
115+
const value = await vscode.window.showInputBox({ title: label, value: description });
116+
if (typeof value !== 'undefined') {
117+
await GoEnv.edit({ [label]: value });
118+
}
119+
}
120+
121+
private async resetEnv(item?: EnvTreeItem) {
122+
if (item?.key) {
123+
await GoEnv.reset([item.key]);
124+
return;
125+
}
126+
await GoEnv.reset();
127+
}
128+
92129
private envTree() {
93130
if (this.activeFolder) {
94131
const { name, uri } = this.activeFolder;
@@ -130,14 +167,14 @@ export class GoExplorerProvider implements vscode.TreeDataProvider<vscode.TreeIt
130167

131168
class EnvTree implements vscode.TreeItem {
132169
label = 'env';
133-
contextValue = 'go:explorer:env';
170+
contextValue = 'go:explorer:envtree';
134171
collapsibleState = vscode.TreeItemCollapsibleState.Expanded;
135172
iconPath = new vscode.ThemeIcon('symbol-folder');
136173
constructor(public description = '', public workspace?: vscode.Uri) {}
137174
}
138175

139176
function isEnvTree(item?: vscode.TreeItem): item is EnvTree {
140-
return item?.contextValue === 'go:explorer:env';
177+
return item?.contextValue === 'go:explorer:envtree';
141178
}
142179

143180
class EnvTreeItem implements vscode.TreeItem {
@@ -148,14 +185,18 @@ class EnvTreeItem implements vscode.TreeItem {
148185
constructor(public key: string, public value: string) {
149186
this.label = `${key}=${replaceHome(value)}`;
150187
this.contextValue = 'go:explorer:envitem';
151-
if (GoEnv.fileVars.includes(key)) {
152-
this.contextValue = 'go:explorer:envitem:file';
188+
if (GoEnv.fileVars.has(key)) {
189+
this.contextValue = 'go:explorer:envfile';
153190
this.file = vscode.Uri.file(value);
154191
}
155192
this.tooltip = `${key}=${value}`;
156193
}
157194
}
158195

196+
function isEnvTreeItem(item?: vscode.TreeItem): item is EnvTreeItem {
197+
return item?.contextValue === 'go:explorer:envitem';
198+
}
199+
159200
class GoEnv {
160201
/**
161202
* get returns a subset of go env vars, the union of this.vars and values
@@ -173,7 +214,7 @@ class GoEnv {
173214
* update writes to toolsEnvVars in the go workspace config.
174215
* @param vars a record of env vars to update.
175216
*/
176-
static async update(vars: Record<string, string>) {
217+
static async edit(vars: Record<string, string>) {
177218
const config = getGoConfig();
178219
await config.update('toolsEnvVars', { ...config['toolsEnvVars'], ...vars });
179220
}
@@ -182,19 +223,34 @@ class GoEnv {
182223
* reset removes entries from toolsEnvVars in the go workspace config.
183224
* @param vars env vars to reset.
184225
*/
185-
static async reset(vars: string[]) {
226+
static async reset(vars?: string[]) {
186227
const config = getGoConfig();
187-
const env = { ...config['toolsEnvVars'] };
188-
for (const v of vars) {
189-
delete env[v];
228+
let env: Record<string, string> = {};
229+
if (vars) {
230+
env = { ...config['toolsEnvVars'] };
231+
for (const v of vars) {
232+
delete env[v];
233+
}
190234
}
191235
await config.update('toolsEnvVars', env);
192236
}
193237

194-
/** A list of env vars that point to files. */
195-
static fileVars = ['GOMOD', 'GOWORK', 'GOENV'];
196-
197-
/** The list of env vars that should always be visible if they contain a value. */
238+
/** Vars that point to files. */
239+
static fileVars = new Set(['GOMOD', 'GOWORK', 'GOENV']);
240+
241+
/** Vars available from 'go env' but not read from the environment */
242+
static readonlyVars = new Set([
243+
'GOEXE',
244+
'GOGCCFLAGS',
245+
'GOHOSTARCH',
246+
'GOHOSTOS',
247+
'GOMOD',
248+
'GOTOOLDIR',
249+
'GOVERSION',
250+
'GOWORK'
251+
]);
252+
253+
/** Vars that should always be visible if they contain a value. */
198254
private static vars = ['GOPRIVATE', 'GOMOD', 'GOWORK', 'GOENV'];
199255
}
200256

test/integration/goExplorer.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ suite('GoExplorerProvider', () => {
3333
test('env tree', async () => {
3434
const [env] = await explorer.getChildren();
3535
assert.strictEqual(env.label, 'env');
36-
assert.strictEqual(env.contextValue, 'go:explorer:env');
36+
assert.strictEqual(env.contextValue, 'go:explorer:envtree');
3737
});
3838

3939
test('env tree items', async () => {

0 commit comments

Comments
 (0)