From 3775c93b9260f29dfe503e7004393a4d9f1e53eb Mon Sep 17 00:00:00 2001
From: Paula
Date: Wed, 13 Mar 2024 11:19:15 -0700
Subject: [PATCH] Use new report issue command api (#23033)
Use new report issue command api
https://github.com/microsoft/vscode-python-debugger/issues/237
Modify the template, information about the installed extensions was
added
---
package.json | 8 ++-
resources/report_issue_template.md | 20 +------
resources/report_issue_user_data_template.md | 21 +++++++
.../commands/reportIssueCommand.ts | 17 +++++-
src/client/common/vscodeApis/extensionsApi.ts | 5 ++
...issueTemplateVenv2.md => issueTemplate.md} | 26 +--------
.../commands/issueTemplateVenv1.md | 56 -------------------
.../commands/issueUserDataTemplateVenv1.md | 30 ++++++++++
.../commands/issueUserDataTemplateVenv2.md | 27 +++++++++
.../commands/reportIssueCommand.unit.test.ts | 55 +++++++++++++-----
10 files changed, 149 insertions(+), 116 deletions(-)
create mode 100644 resources/report_issue_user_data_template.md
rename src/test/common/application/commands/{issueTemplateVenv2.md => issueTemplate.md} (51%)
delete mode 100644 src/test/common/application/commands/issueTemplateVenv1.md
create mode 100644 src/test/common/application/commands/issueUserDataTemplateVenv1.md
create mode 100644 src/test/common/application/commands/issueUserDataTemplateVenv2.md
diff --git a/package.json b/package.json
index a753336396e4..c57dbd923755 100644
--- a/package.json
+++ b/package.json
@@ -23,7 +23,8 @@
"testObserver",
"quickPickItemTooltip",
"terminalDataWriteEvent",
- "terminalExecuteCommandEvent"
+ "terminalExecuteCommandEvent",
+ "contribIssueReporter"
],
"author": {
"name": "Microsoft Corporation"
@@ -1243,6 +1244,11 @@
}
],
"menus": {
+ "issue/reporter": [
+ {
+ "command": "python.reportIssue"
+ }
+ ],
"commandPalette": [
{
"category": "Python",
diff --git a/resources/report_issue_template.md b/resources/report_issue_template.md
index a0892ecba53b..a95af90ff7fe 100644
--- a/resources/report_issue_template.md
+++ b/resources/report_issue_template.md
@@ -1,6 +1,5 @@
# Behaviour
-## Expected vs. Actual
XXX
@@ -12,13 +11,9 @@ XXX
**After** creating the issue on GitHub, you can add screenshots and GIFs of what is happening. Consider tools like https://www.cockos.com/licecap/, https://github.com/phw/peek or https://www.screentogif.com/ for GIF creation.
-->
-
+
# Diagnostic data
-- Python version (& distribution if applicable, e.g. Anaconda): {0}
-- Type of virtual environment used (e.g. conda, venv, virtualenv, etc.): {1}
-- Value of the `python.languageServer` setting: {2}
-
Output for Python
in the Output
panel (View
→Output
, change the drop-down the upper-right of the Output
panel to Python
)
@@ -32,16 +27,3 @@ XXX
-
-
-
-User Settings
-
-
-
-```
-{3}{4}
-```
-
-
-
diff --git a/resources/report_issue_user_data_template.md b/resources/report_issue_user_data_template.md
new file mode 100644
index 000000000000..037b844511d3
--- /dev/null
+++ b/resources/report_issue_user_data_template.md
@@ -0,0 +1,21 @@
+- Python version (& distribution if applicable, e.g. Anaconda): {0}
+- Type of virtual environment used (e.g. conda, venv, virtualenv, etc.): {1}
+- Value of the `python.languageServer` setting: {2}
+
+
+User Settings
+
+
+```
+{3}{4}
+```
+
+
+
+
+Installed Extensions
+
+|Extension Name|Extension Id|Version|
+|---|---|---|
+{5}
+
diff --git a/src/client/common/application/commands/reportIssueCommand.ts b/src/client/common/application/commands/reportIssueCommand.ts
index d18299e6698e..f5f1f0ac0c0e 100644
--- a/src/client/common/application/commands/reportIssueCommand.ts
+++ b/src/client/common/application/commands/reportIssueCommand.ts
@@ -19,6 +19,7 @@ import { EventName } from '../../../telemetry/constants';
import { EnvironmentType } from '../../../pythonEnvironments/info';
import { PythonSettings } from '../../configSettings';
import { SystemVariables } from '../../variables/systemVariables';
+import { getExtensions } from '../../vscodeApis/extensionsApi';
/**
* Allows the user to report an issue related to the Python extension using our template.
@@ -48,6 +49,8 @@ export class ReportIssueCommandHandler implements IExtensionSingleActivationServ
private templatePath = path.join(EXTENSION_ROOT_DIR, 'resources', 'report_issue_template.md');
+ private userDataTemplatePath = path.join(EXTENSION_ROOT_DIR, 'resources', 'report_issue_user_data_template.md');
+
public async openReportIssue(): Promise {
const settings: IPythonSettings = this.configurationService.getSettings();
const argSettings = JSON.parse(await fs.readFile(this.argSettingsPath, 'utf8'));
@@ -86,6 +89,7 @@ export class ReportIssueCommandHandler implements IExtensionSingleActivationServ
}
});
const template = await fs.readFile(this.templatePath, 'utf8');
+ const userTemplate = await fs.readFile(this.userDataTemplatePath, 'utf8');
const interpreter = await this.interpreterService.getActiveInterpreter();
const pythonVersion = interpreter?.version?.raw ?? '';
const languageServer =
@@ -97,14 +101,25 @@ export class ReportIssueCommandHandler implements IExtensionSingleActivationServ
hasMultipleFolders && userSettings !== ''
? `Multiroot scenario, following user settings may not apply:${os.EOL}`
: '';
+
+ const installedExtensions = getExtensions()
+ .filter((extension) => !extension.id.startsWith('vscode.'))
+ .sort((a, b) => a.packageJSON.displayName.localeCompare(b.packageJSON.displayName))
+ .map(
+ (extension) =>
+ `|${extension.packageJSON.displayName}|${extension.id}|${extension.packageJSON.version}|`,
+ );
+
await this.commandManager.executeCommand('workbench.action.openIssueReporter', {
extensionId: 'ms-python.python',
- issueBody: template.format(
+ issueBody: template,
+ data: userTemplate.format(
pythonVersion,
virtualEnvKind,
languageServer,
hasMultipleFoldersText,
userSettings,
+ installedExtensions.join('\n'),
),
});
sendTelemetryEvent(EventName.USE_REPORT_ISSUE_COMMAND, undefined, {});
diff --git a/src/client/common/vscodeApis/extensionsApi.ts b/src/client/common/vscodeApis/extensionsApi.ts
index ece424847a16..4e1664a3dfae 100644
--- a/src/client/common/vscodeApis/extensionsApi.ts
+++ b/src/client/common/vscodeApis/extensionsApi.ts
@@ -32,3 +32,8 @@ export function isExtensionDisabled(extensionId: string): boolean {
export function isInsider(): boolean {
return vscode.env.appName.includes('Insider');
}
+
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+export function getExtensions(): readonly vscode.Extension[] {
+ return vscode.extensions.all;
+}
diff --git a/src/test/common/application/commands/issueTemplateVenv2.md b/src/test/common/application/commands/issueTemplate.md
similarity index 51%
rename from src/test/common/application/commands/issueTemplateVenv2.md
rename to src/test/common/application/commands/issueTemplate.md
index fa9142e5ca4d..a95af90ff7fe 100644
--- a/src/test/common/application/commands/issueTemplateVenv2.md
+++ b/src/test/common/application/commands/issueTemplate.md
@@ -1,6 +1,5 @@
# Behaviour
-## Expected vs. Actual
XXX
@@ -12,13 +11,9 @@ XXX
**After** creating the issue on GitHub, you can add screenshots and GIFs of what is happening. Consider tools like https://www.cockos.com/licecap/, https://github.com/phw/peek or https://www.screentogif.com/ for GIF creation.
-->
-
+
# Diagnostic data
-- Python version (& distribution if applicable, e.g. Anaconda): 3.9.0
-- Type of virtual environment used (e.g. conda, venv, virtualenv, etc.): Venv
-- Value of the `python.languageServer` setting: Pylance
-
Output for Python
in the Output
panel (View
→Output
, change the drop-down the upper-right of the Output
panel to Python
)
@@ -32,22 +27,3 @@ XXX
-
-
-
-User Settings
-
-
-
-```
-Multiroot scenario, following user settings may not apply:
-
-experiments
-• enabled: false
-
-venvPath: ""
-
-```
-
-
-
diff --git a/src/test/common/application/commands/issueTemplateVenv1.md b/src/test/common/application/commands/issueTemplateVenv1.md
deleted file mode 100644
index 09cdd2c32eb0..000000000000
--- a/src/test/common/application/commands/issueTemplateVenv1.md
+++ /dev/null
@@ -1,56 +0,0 @@
-
-# Behaviour
-## Expected vs. Actual
-
-XXX
-
-## Steps to reproduce:
-
-1. XXX
-
-
-
-
-# Diagnostic data
-
-- Python version (& distribution if applicable, e.g. Anaconda): 3.9.0
-- Type of virtual environment used (e.g. conda, venv, virtualenv, etc.): Venv
-- Value of the `python.languageServer` setting: Pylance
-
-
-
-Output for Python
in the Output
panel (View
→Output
, change the drop-down the upper-right of the Output
panel to Python
)
-
-
-
-
-```
-XXX
-```
-
-
-
-
-
-
-User Settings
-
-
-
-```
-
-experiments
-• enabled: false
-• optInto: []
-• optOutFrom: []
-
-venvPath: ""
-
-pipenvPath: ""
-
-```
-
-
-
diff --git a/src/test/common/application/commands/issueUserDataTemplateVenv1.md b/src/test/common/application/commands/issueUserDataTemplateVenv1.md
new file mode 100644
index 000000000000..9c1aac03cf52
--- /dev/null
+++ b/src/test/common/application/commands/issueUserDataTemplateVenv1.md
@@ -0,0 +1,30 @@
+- Python version (& distribution if applicable, e.g. Anaconda): 3.9.0
+- Type of virtual environment used (e.g. conda, venv, virtualenv, etc.): Venv
+- Value of the `python.languageServer` setting: Pylance
+
+
+User Settings
+
+
+```
+
+experiments
+• enabled: false
+• optInto: []
+• optOutFrom: []
+
+venvPath: ""
+
+pipenvPath: ""
+
+```
+
+
+
+
+Installed Extensions
+
+|Extension Name|Extension Id|Version|
+|---|---|---|
+|Python|ms-python.python|2020.2|
+
diff --git a/src/test/common/application/commands/issueUserDataTemplateVenv2.md b/src/test/common/application/commands/issueUserDataTemplateVenv2.md
new file mode 100644
index 000000000000..fa218fc35b04
--- /dev/null
+++ b/src/test/common/application/commands/issueUserDataTemplateVenv2.md
@@ -0,0 +1,27 @@
+- Python version (& distribution if applicable, e.g. Anaconda): 3.9.0
+- Type of virtual environment used (e.g. conda, venv, virtualenv, etc.): Venv
+- Value of the `python.languageServer` setting: Pylance
+
+
+User Settings
+
+
+```
+Multiroot scenario, following user settings may not apply:
+
+experiments
+• enabled: false
+
+venvPath: ""
+
+```
+
+
+
+
+Installed Extensions
+
+|Extension Name|Extension Id|Version|
+|---|---|---|
+|Python|ms-python.python|2020.2|
+
diff --git a/src/test/common/application/commands/reportIssueCommand.unit.test.ts b/src/test/common/application/commands/reportIssueCommand.unit.test.ts
index 92b4c0725f3f..2a35a6306cd2 100644
--- a/src/test/common/application/commands/reportIssueCommand.unit.test.ts
+++ b/src/test/common/application/commands/reportIssueCommand.unit.test.ts
@@ -30,6 +30,7 @@ import { IConfigurationService } from '../../../../client/common/types';
import { EventName } from '../../../../client/telemetry/constants';
import { EnvironmentType, PythonEnvironment } from '../../../../client/pythonEnvironments/info';
import { EXTENSION_ROOT_DIR_FOR_TESTS } from '../../../constants';
+import * as extensionsApi from '../../../../client/common/vscodeApis/extensionsApi';
suite('Report Issue Command', () => {
let reportIssueCommandHandler: ReportIssueCommandHandler;
@@ -38,6 +39,8 @@ suite('Report Issue Command', () => {
let interpreterService: IInterpreterService;
let configurationService: IConfigurationService;
let appEnvironment: IApplicationEnvironment;
+ let expectedIssueBody: string;
+ let getExtensionsStub: sinon.SinonStub;
setup(async () => {
workspaceService = mock(WorkspaceService);
@@ -45,6 +48,7 @@ suite('Report Issue Command', () => {
interpreterService = mock(InterpreterService);
configurationService = mock(ConfigurationService);
appEnvironment = mock();
+ getExtensionsStub = sinon.stub(extensionsApi, 'getExtensions');
when(cmdManager.executeCommand('workbench.action.openIssueReporter', anything())).thenResolve();
when(workspaceService.getConfiguration('python')).thenReturn(
@@ -79,6 +83,27 @@ suite('Report Issue Command', () => {
instance(appEnvironment),
);
await reportIssueCommandHandler.activate();
+
+ const issueTemplatePath = path.join(
+ EXTENSION_ROOT_DIR_FOR_TESTS,
+ 'src',
+ 'test',
+ 'common',
+ 'application',
+ 'commands',
+ 'issueTemplate.md',
+ );
+ expectedIssueBody = fs.readFileSync(issueTemplatePath, 'utf8');
+
+ getExtensionsStub.returns([
+ {
+ id: 'ms-python.python',
+ packageJSON: {
+ displayName: 'Python',
+ version: '2020.2',
+ },
+ },
+ ]);
});
teardown(() => {
@@ -88,27 +113,28 @@ suite('Report Issue Command', () => {
test('Test if issue body is filled correctly when including all the settings', async () => {
await reportIssueCommandHandler.openReportIssue();
- const templatePath = path.join(
+ const userDataTemplatePath = path.join(
EXTENSION_ROOT_DIR_FOR_TESTS,
'src',
'test',
'common',
'application',
'commands',
- 'issueTemplateVenv1.md',
+ 'issueUserDataTemplateVenv1.md',
);
- const expectedIssueBody = fs.readFileSync(templatePath, 'utf8');
+ const expectedData = fs.readFileSync(userDataTemplatePath, 'utf8');
- const args: [string, { extensionId: string; issueBody: string }] = capture<
+ const args: [string, { extensionId: string; issueBody: string; data: string }] = capture<
AllCommands,
- { extensionId: string; issueBody: string }
+ { extensionId: string; issueBody: string; data: string }
>(cmdManager.executeCommand).last();
verify(cmdManager.registerCommand(Commands.ReportIssue, anything(), anything())).once();
verify(cmdManager.executeCommand('workbench.action.openIssueReporter', anything())).once();
expect(args[0]).to.be.equal('workbench.action.openIssueReporter');
- const actual = args[1].issueBody;
- expect(actual).to.be.equal(expectedIssueBody);
+ const { issueBody, data } = args[1];
+ expect(issueBody).to.be.equal(expectedIssueBody);
+ expect(data).to.be.equal(expectedData);
});
test('Test if issue body is filled when only including settings which are explicitly set', async () => {
@@ -128,26 +154,27 @@ suite('Report Issue Command', () => {
await reportIssueCommandHandler.activate();
await reportIssueCommandHandler.openReportIssue();
- const templatePath = path.join(
+ const userDataTemplatePath = path.join(
EXTENSION_ROOT_DIR_FOR_TESTS,
'src',
'test',
'common',
'application',
'commands',
- 'issueTemplateVenv2.md',
+ 'issueUserDataTemplateVenv2.md',
);
- const expectedIssueBody = fs.readFileSync(templatePath, 'utf8');
+ const expectedData = fs.readFileSync(userDataTemplatePath, 'utf8');
- const args: [string, { extensionId: string; issueBody: string }] = capture<
+ const args: [string, { extensionId: string; issueBody: string; data: string }] = capture<
AllCommands,
- { extensionId: string; issueBody: string }
+ { extensionId: string; issueBody: string; data: string }
>(cmdManager.executeCommand).last();
verify(cmdManager.executeCommand('workbench.action.openIssueReporter', anything())).once();
expect(args[0]).to.be.equal('workbench.action.openIssueReporter');
- const actual = args[1].issueBody;
- expect(actual).to.be.equal(expectedIssueBody);
+ const { issueBody, data } = args[1];
+ expect(issueBody).to.be.equal(expectedIssueBody);
+ expect(data).to.be.equal(expectedData);
});
test('Should send telemetry event when run Report Issue Command', async () => {
const sendTelemetryStub = sinon.stub(Telemetry, 'sendTelemetryEvent');