Skip to content

Commit a3bbaa9

Browse files
h9jianggopherbot
authored andcommitted
extension/src: collecting telemetry for command and trigger
Third party tools like gotests/gomodifytags can be triggered from either commnad palette and context menu. Gopls command can be triggered from command palette, context menu and code action. Differentiate between source trigger: - Code Action: in language client middle ware, resolve code action will resolve the code action to a command. Increase the counter if the resolved command name is add test or modify tags. - Context Menu: vscode will pass uri (of type vscode.Uri) to the command handler if it's triggered from context menu. The uri is the uri to the file where the context menu is triggered. - Command Palette: vscode will pass in undefined uri to the command handler. For golang/go#74869 Change-Id: I3a8b0cc46b916f72cbb59b7c2f764334d5d93e41 Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/693015 Reviewed-by: Robert Findley <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Auto-Submit: Hongxiang Jiang <[email protected]>
1 parent f1c5335 commit a3bbaa9

File tree

4 files changed

+100
-26
lines changed

4 files changed

+100
-26
lines changed

extension/src/goGenerateTests.ts

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import { TelemetryKey, telemetryReporter } from './goTelemetry';
2323

2424
const generatedWord = 'Generated ';
2525

26-
const COMMAND = 'gopls.add_test';
26+
export const COMMAND = 'gopls.add_test';
2727

2828
/**
2929
* If current active editor has a Go file, returns the editor.
@@ -74,7 +74,13 @@ export const toggleTestFile: CommandFactory = () => () => {
7474
vscode.commands.executeCommand('vscode.open', vscode.Uri.file(targetFilePath));
7575
};
7676

77-
export const generateTestCurrentPackage: CommandFactory = (ctx, goCtx) => () => {
77+
export const generateTestCurrentPackage: CommandFactory = (ctx, goCtx) => (uri: vscode.Uri) => {
78+
if (uri) {
79+
telemetryReporter.add(TelemetryKey.COMMAND_TRIGGER_GOTESTS_CONTEXT_MENU, 1);
80+
} else {
81+
telemetryReporter.add(TelemetryKey.COMMAND_TRIGGER_GOTESTS_COMMAND_PALETTE, 1);
82+
}
83+
7884
const editor = checkActiveEditor();
7985
if (!editor) {
8086
return false;
@@ -90,7 +96,13 @@ export const generateTestCurrentPackage: CommandFactory = (ctx, goCtx) => () =>
9096
);
9197
};
9298

93-
export const generateTestCurrentFile: CommandFactory = (ctx, goCtx) => () => {
99+
export const generateTestCurrentFile: CommandFactory = (ctx, goCtx) => (uri: vscode.Uri) => {
100+
if (uri) {
101+
telemetryReporter.add(TelemetryKey.COMMAND_TRIGGER_GOTESTS_CONTEXT_MENU, 1);
102+
} else {
103+
telemetryReporter.add(TelemetryKey.COMMAND_TRIGGER_GOTESTS_COMMAND_PALETTE, 1);
104+
}
105+
94106
const editor = checkActiveEditor();
95107
if (!editor) {
96108
return false;
@@ -110,7 +122,16 @@ export const generateTestCurrentFile: CommandFactory = (ctx, goCtx) => () => {
110122
/**
111123
* Generates a test for the selected function using 'gopls.add_test'.
112124
*/
113-
export const goplsGenerateTest: CommandFactory = (_, goCtx) => async () => {
125+
export const goplsGenerateTest: CommandFactory = (_, goCtx) => async (uri: vscode.Uri) => {
126+
// When invoked from command palette, the input uri is undefined.
127+
// When invoked from an editor, the URI of the document is passed in to the
128+
// function.
129+
// https://code.visualstudio.com/api/references/contribution-points#contributes.menus
130+
if (uri) {
131+
telemetryReporter.add(TelemetryKey.COMMAND_TRIGGER_GOPLS_ADD_TEST_CONTEXT_MENU, 1);
132+
} else {
133+
telemetryReporter.add(TelemetryKey.COMMAND_TRIGGER_GOPLS_ADD_TEST_COMMAND_PALETTE, 1);
134+
}
114135
if (!goCtx.serverInfo?.Commands?.includes(COMMAND)) {
115136
vscode.window.showWarningMessage(`Please upgrade gopls to use the '${COMMAND}' command`);
116137
return;
@@ -127,7 +148,13 @@ export const goplsGenerateTest: CommandFactory = (_, goCtx) => async () => {
127148
});
128149
};
129150

130-
export const generateTestCurrentFunction: CommandFactory = (ctx, goCtx) => async () => {
151+
export const generateTestCurrentFunction: CommandFactory = (ctx, goCtx) => async (uri: vscode.Uri) => {
152+
if (uri) {
153+
telemetryReporter.add(TelemetryKey.COMMAND_TRIGGER_GOTESTS_CONTEXT_MENU, 1);
154+
} else {
155+
telemetryReporter.add(TelemetryKey.COMMAND_TRIGGER_GOTESTS_COMMAND_PALETTE, 1);
156+
}
157+
131158
const editor = checkActiveEditor();
132159
if (!editor) {
133160
return false;

extension/src/goModifytags.ts

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { promptForMissingTool, promptForUpdatingTool } from './goInstallTools';
1616
import { byteOffsetAt, getBinPath, getFileArchive } from './util';
1717
import { TelemetryKey, telemetryReporter } from './goTelemetry';
1818

19-
const COMMAND = 'gopls.modify_tags';
19+
export const COMMAND = 'gopls.modify_tags';
2020

2121
// Interface for the output from gomodifytags
2222
interface GomodifytagsOutput {
@@ -50,14 +50,20 @@ interface GoTagsConfig {
5050
template: string;
5151
}
5252

53-
export const addTags: CommandFactory = (_ctx, goCtx) => async (commandArgs: GoTagsConfig) => {
53+
export const addTags: CommandFactory = (_ctx, goCtx) => async (uri: vscode.Uri) => {
5454
const useGoplsCommand = goCtx.serverInfo?.Commands?.includes(COMMAND);
5555
if (useGoplsCommand) {
56+
if (uri) {
57+
telemetryReporter.add(TelemetryKey.COMMAND_TRIGGER_GOPLS_MODIFY_TAGS_CONTEXT_MENU, 1);
58+
} else {
59+
telemetryReporter.add(TelemetryKey.COMMAND_TRIGGER_GOPLS_MODIFY_TAGS_COMMAND_PALETTE, 1);
60+
}
61+
5662
const args = getCommonArgs();
5763
if (!args) {
5864
return;
5965
}
60-
const [tags, options, transformValue, template] = await getTagsAndOptions(getGoConfig()?.addTags, commandArgs);
66+
const [tags, options, transformValue, template] = await getTagsAndOptions(getGoConfig()?.addTags);
6167
if (!tags && !options) {
6268
return;
6369
}
@@ -75,11 +81,17 @@ export const addTags: CommandFactory = (_ctx, goCtx) => async (commandArgs: GoTa
7581
}
7682
await vscode.commands.executeCommand(COMMAND, args);
7783
} else {
84+
if (uri) {
85+
telemetryReporter.add(TelemetryKey.COMMAND_TRIGGER_GOMODIFYTAGS_CONTEXT_MENU, 1);
86+
} else {
87+
telemetryReporter.add(TelemetryKey.COMMAND_TRIGGER_GOMODIFYTAGS_COMMAND_PALETTE, 1);
88+
}
89+
7890
const args = getCommonArgsOld();
7991
if (!args) {
8092
return;
8193
}
82-
const [tags, options, transformValue, template] = await getTagsAndOptions(getGoConfig()?.addTags, commandArgs);
94+
const [tags, options, transformValue, template] = await getTagsAndOptions(getGoConfig()?.addTags);
8395
if (!tags && !options) {
8496
return;
8597
}
@@ -103,14 +115,20 @@ export const addTags: CommandFactory = (_ctx, goCtx) => async (commandArgs: GoTa
103115
}
104116
};
105117

106-
export const removeTags: CommandFactory = (_ctx, goCtx) => async (commandArgs: GoTagsConfig) => {
118+
export const removeTags: CommandFactory = (_ctx, goCtx) => async (uri: vscode.Uri) => {
107119
const useGoplsCommand = goCtx.serverInfo?.Commands?.includes(COMMAND);
108120
if (useGoplsCommand) {
121+
if (uri) {
122+
telemetryReporter.add(TelemetryKey.COMMAND_TRIGGER_GOPLS_MODIFY_TAGS_CONTEXT_MENU, 1);
123+
} else {
124+
telemetryReporter.add(TelemetryKey.COMMAND_TRIGGER_GOPLS_MODIFY_TAGS_COMMAND_PALETTE, 1);
125+
}
126+
109127
const args = getCommonArgs();
110128
if (!args) {
111129
return;
112130
}
113-
const [tags, options] = await getTagsAndOptions(getGoConfig()?.removeTags, commandArgs);
131+
const [tags, options] = await getTagsAndOptions(getGoConfig()?.removeTags);
114132
if (!tags && !options) {
115133
args.clear = true;
116134
args.clearOptions = true;
@@ -123,11 +141,17 @@ export const removeTags: CommandFactory = (_ctx, goCtx) => async (commandArgs: G
123141
}
124142
vscode.commands.executeCommand(COMMAND, args);
125143
} else {
144+
if (uri) {
145+
telemetryReporter.add(TelemetryKey.COMMAND_TRIGGER_GOMODIFYTAGS_CONTEXT_MENU, 1);
146+
} else {
147+
telemetryReporter.add(TelemetryKey.COMMAND_TRIGGER_GOMODIFYTAGS_COMMAND_PALETTE, 1);
148+
}
149+
126150
const args = getCommonArgsOld();
127151
if (!args) {
128152
return;
129153
}
130-
const [tags, options] = await getTagsAndOptions(getGoConfig()?.removeTags, commandArgs);
154+
const [tags, options] = await getTagsAndOptions(getGoConfig()?.removeTags);
131155
if (!tags && !options) {
132156
args.push('--clear-tags');
133157
args.push('--clear-options');
@@ -191,31 +215,25 @@ function getCommonArgs(): GoModifyTagsArgs | undefined {
191215
return args;
192216
}
193217

194-
async function getTagsAndOptions(config: GoTagsConfig, commandArgs: GoTagsConfig): Promise<(string | undefined)[]> {
195-
const tags = commandArgs && commandArgs.tags ? commandArgs.tags : config.tags;
196-
const options = commandArgs && commandArgs.options ? commandArgs.options : config.options;
197-
const promptForTags = commandArgs && commandArgs.promptForTags ? commandArgs.promptForTags : config.promptForTags;
198-
const transformValue: string = commandArgs && commandArgs.transform ? commandArgs.transform : config.transform;
199-
const format: string = commandArgs && commandArgs.template ? commandArgs.template : config.template;
200-
201-
if (!promptForTags) {
202-
return Promise.resolve([tags, options, transformValue, format]);
218+
async function getTagsAndOptions(config: GoTagsConfig): Promise<(string | undefined)[]> {
219+
if (!config.promptForTags) {
220+
return Promise.resolve([config.tags, config.options, config.transform, config.template]);
203221
}
204222

205223
const inputTags = await vscode.window.showInputBox({
206-
value: tags,
224+
value: config.tags,
207225
prompt: 'Enter comma separated tag names'
208226
});
209227
const inputOptions = await vscode.window.showInputBox({
210-
value: options,
228+
value: config.options,
211229
prompt: 'Enter comma separated options'
212230
});
213231
const transformOption = await vscode.window.showInputBox({
214-
value: transformValue,
232+
value: config.transform,
215233
prompt: 'Enter transform value'
216234
});
217235
const template = await vscode.window.showInputBox({
218-
value: format,
236+
value: config.template,
219237
prompt: 'Enter template value'
220238
});
221239
return [inputTags, inputOptions, transformOption, template];

extension/src/goTelemetry.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,23 @@ export enum TelemetryKey {
5454
// Indicates the tools usage.
5555
TOOL_USAGE_GOTESTS = 'vscode-go/tool/usage:gotests',
5656
TOOL_USAGE_GOPLAY = 'vscode-go/tool/usage:goplay',
57-
TOOL_USAGE_GOMODIFYTAGS = 'vscode-go/tool/usage:gomodifytags'
57+
TOOL_USAGE_GOMODIFYTAGS = 'vscode-go/tool/usage:gomodifytags',
58+
59+
// Indicates the command and the source of trigger.
60+
// The bucket have two elements, the command and it's trigger source.
61+
COMMAND_TRIGGER_GOPLS_ADD_TEST_COMMAND_PALETTE = 'vscode-go/command/trigger:gopls.add_test-command_palette',
62+
COMMAND_TRIGGER_GOPLS_ADD_TEST_CONTEXT_MENU = 'vscode-go/command/trigger:gopls.add_test-context_menu',
63+
COMMAND_TRIGGER_GOPLS_ADD_TEST_CODE_ACTION = 'vscode-go/command/trigger:gopls.add_test-code_action',
64+
65+
COMMAND_TRIGGER_GOPLS_MODIFY_TAGS_COMMAND_PALETTE = 'vscode-go/command/trigger:gopls.modify_tags-command_palette',
66+
COMMAND_TRIGGER_GOPLS_MODIFY_TAGS_CONTEXT_MENU = 'vscode-go/command/trigger:gopls.modify_tags-context_menu',
67+
COMMAND_TRIGGER_GOPLS_MODIFY_TAGS_CODE_ACTION = 'vscode-go/command/trigger:gopls.modify_tags-code_action',
68+
69+
COMMAND_TRIGGER_GOTESTS_COMMAND_PALETTE = 'vscode-go/command/trigger:gotests-command_palette',
70+
COMMAND_TRIGGER_GOTESTS_CONTEXT_MENU = 'vscode-go/command/trigger:gotests-context_menu',
71+
72+
COMMAND_TRIGGER_GOMODIFYTAGS_COMMAND_PALETTE = 'vscode-go/command/trigger:gomodifytags-command_palette',
73+
COMMAND_TRIGGER_GOMODIFYTAGS_CONTEXT_MENU = 'vscode-go/command/trigger:gomodifytags-context_menu'
5874
}
5975

6076
/**

extension/src/language/goLanguageServer.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ import { ActiveProgressTerminals, IProgressTerminal, ProgressTerminal } from '..
6565
import { createHash } from 'crypto';
6666
import { GoExtensionContext } from '../context';
6767
import { GoDocumentSelector } from '../goMode';
68+
import { COMMAND as GOPLS_ADD_TEST_COMMAND } from '../goGenerateTests';
69+
import { COMMAND as GOPLS_MODIFY_TAGS_COMMAND } from '../goModifytags';
70+
import { TelemetryKey, telemetryReporter } from '../goTelemetry';
6871

6972
export interface LanguageServerConfig {
7073
serverName: string;
@@ -755,6 +758,16 @@ export async function buildLanguageClient(
755758
}
756759
},
757760
resolveCodeAction: async (item, token, next) => {
761+
if (item.command) {
762+
switch (item.command.command) {
763+
case GOPLS_ADD_TEST_COMMAND:
764+
telemetryReporter.add(TelemetryKey.COMMAND_TRIGGER_GOPLS_ADD_TEST_CODE_ACTION, 1);
765+
break;
766+
case GOPLS_MODIFY_TAGS_COMMAND:
767+
telemetryReporter.add(TelemetryKey.COMMAND_TRIGGER_GOPLS_MODIFY_TAGS_CODE_ACTION, 1);
768+
break;
769+
}
770+
}
758771
try {
759772
return await next(item, token);
760773
} catch (e) {

0 commit comments

Comments
 (0)