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 (ViewOutput, 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 (ViewOutput, 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 (ViewOutput, 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');