Skip to content

Commit ca82fb7

Browse files
Implement issue report (#260)
* Add template * Add report command * Ass telemetry * add tests * fix extension root * prettier * fix tests
1 parent ce50793 commit ca82fb7

File tree

14 files changed

+273
-5
lines changed

14 files changed

+273
-5
lines changed

package.json

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
"version": "2024.3.0-dev",
66
"publisher": "ms-python",
77
"enabledApiProposals": [
8-
"portsAttributes"
8+
"portsAttributes",
9+
"contribIssueReporter"
910
],
1011
"license": "MIT",
1112
"homepage": "https://github.com/Microsoft/vscode-python-debugger",
@@ -63,9 +64,19 @@
6364
"light": "resources/light/repl.svg"
6465
},
6566
"title": "%debugpy.command.viewOutput.title%"
67+
},
68+
{
69+
"category": "Python Debugger",
70+
"command": "debugpy.reportIssue",
71+
"title": "%debugpy.command.reportIssue.title%"
6672
}
6773
],
6874
"menus": {
75+
"issue/reporter": [
76+
{
77+
"command": "debugpy.reportIssue"
78+
}
79+
],
6980
"commandPalette": [
7081
{
7182
"category": "Python Debugger",
@@ -90,6 +101,12 @@
90101
"category": "Python Debugger",
91102
"command": "debugpy.viewOutput",
92103
"title": "%debugpy.command.viewOutput.title%"
104+
},
105+
{
106+
"category": "Python Debugger",
107+
"command": "debugpy.reportIssue",
108+
"title": "%debugpy.command.reportIssue.title%",
109+
"when": "!virtualWorkspace && shellExecutionSupported"
93110
}
94111
],
95112
"editor/title/run": [

package.nls.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
{
2+
"debugpy.command.clearCacheAndReload.title": "Clear Cache and Reload Window",
23
"debugpy.command.debugInTerminal.title": "Python Debugger: Debug Python File",
34
"debugpy.command.debugUsingLaunchConfig.title": "Python Debugger: Debug using launch.json",
4-
"debugpy.command.clearCacheAndReload.title": "Clear Cache and Reload Window",
5+
"debugpy.command.reportIssue.title": "Report Issue...",
56
"debugpy.command.viewOutput.title": "Show Output",
67
"debugpy.debugJustMyCode": "When debugging only step through user-written code. Disable this to allow stepping into library code."
78
}

resources/report_issue_template.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<!-- Please fill in all XXX markers -->
2+
# Behaviour
3+
4+
XXX
5+
6+
## Steps to reproduce:
7+
8+
1. XXX
9+
10+
<!--
11+
**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.
12+
-->
13+
14+
<!-- **NOTE**: Please do provide logs from the Python and Python Debugger Output panel. -->
15+
# Diagnostic data
16+
<details>
17+
18+
<summary><code>launch.json</code> configuration
19+
</summary>
20+
21+
<p>
22+
23+
```
24+
XXX
25+
```
26+
27+
</p>
28+
</details>
29+
30+
<details>
31+
32+
<summary>Output for <code>Python</code> in the <code>Output</code> panel (<code>View</code>→<code>Output</code>, change the drop-down the upper-right of the <code>Output</code> panel to <code>Python</code>)
33+
</summary>
34+
35+
<p>
36+
37+
```
38+
XXX
39+
```
40+
41+
</p>
42+
</details>
43+
44+
<details>
45+
46+
<summary>Output for <code>Python Debugger</code> in the <code>Output</code> panel (<code>View</code>→<code>Output</code>, change the drop-down the upper-right of the <code>Output</code> panel to <code>Python Debugger</code>)
47+
</summary>
48+
49+
<p>
50+
51+
```
52+
XXX
53+
```
54+
55+
</p>
56+
</details>
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
- Python version (& distribution if applicable, e.g. Anaconda): {0}
2+
- Type of virtual environment used (e.g. conda, venv, virtualenv, etc.): {1}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
'use strict';
5+
6+
import * as fs from 'fs-extra';
7+
import * as path from 'path';
8+
import { executeCommand } from '../../vscodeapi';
9+
import { getActiveEnvironmentPath, resolveEnvironment } from '../../python';
10+
import { EXTENSION_ROOT_DIR } from '../../constants';
11+
import { getRawVersion } from '../../settings';
12+
import { sendTelemetryEvent } from '../../../telemetry';
13+
import { EventName } from '../../../telemetry/constants';
14+
15+
/**
16+
* Allows the user to report an issue related to the Python Debugger extension using our template.
17+
*/
18+
export async function openReportIssue(): Promise<void> {
19+
const templatePath = path.join(EXTENSION_ROOT_DIR, 'resources', 'report_issue_template.md');
20+
const userDataTemplatePath = path.join(EXTENSION_ROOT_DIR, 'resources', 'report_issue_user_data_template.md');
21+
const template = await fs.readFile(templatePath, 'utf8');
22+
const userTemplate = await fs.readFile(userDataTemplatePath, 'utf8');
23+
const interpreterPath = await getActiveEnvironmentPath();
24+
const interpreter = await resolveEnvironment(interpreterPath);
25+
const virtualEnvKind = interpreter?.environment?.type || 'Unknown';
26+
27+
const pythonVersion = getRawVersion(interpreter?.version);
28+
await executeCommand('workbench.action.openIssueReporter', {
29+
extensionId: 'ms-python.debugpy',
30+
issueBody: template,
31+
data: userTemplate.replace('{0}', pythonVersion).replace('{1}', virtualEnvKind),
32+
});
33+
sendTelemetryEvent(EventName.USE_REPORT_ISSUE_COMMAND, undefined, {});
34+
}

src/extension/common/constants.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import * as path from 'path';
77
export const PYTHON_LANGUAGE = 'python';
88
const folderName = path.basename(__dirname);
99
export const EXTENSION_ROOT_DIR =
10-
folderName === 'common' ? path.dirname(path.dirname(__dirname)) : path.dirname(__dirname);
10+
folderName === 'common' ? path.dirname(path.dirname(path.dirname(__dirname))) : path.dirname(__dirname);
1111
export const BUNDLED_PYTHON_SCRIPTS_DIR = path.join(EXTENSION_ROOT_DIR, 'bundled');
1212
export const SERVER_SCRIPT_PATH = path.join(BUNDLED_PYTHON_SCRIPTS_DIR, 'tool', `server.py`);
1313
export const DEBUG_SERVER_SCRIPT_PATH = path.join(BUNDLED_PYTHON_SCRIPTS_DIR, 'tool', `_debug_server.py`);
@@ -39,6 +39,7 @@ export namespace Commands {
3939
export const Enable_SourceMap_Support = 'debugpy.enableSourceMapSupport';
4040
export const SelectDebugConfig = 'debugpy.SelectAndInsertDebugConfiguration';
4141
export const Set_Interpreter = 'python.setInterpreter';
42+
export const ReportIssue = 'debugpy.reportIssue';
4243
}
4344

4445
export type Channel = 'stable' | 'insiders';

src/extension/common/settings.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { ConfigurationChangeEvent, ConfigurationTarget, Uri, WorkspaceConfigurat
55
import { getInterpreterDetails } from './python';
66
import { getConfiguration, getWorkspaceFolder, getWorkspaceFolders } from './vscodeapi';
77
import { isUnitTestExecution } from './constants';
8+
import { VersionInfo } from '@vscode/python-extension';
89

910
export interface ISettings {
1011
workspace: string;
@@ -15,7 +16,6 @@ export interface ISettings {
1516
export async function getExtensionSettings(namespace: string, includeInterpreter?: boolean): Promise<ISettings[]> {
1617
const settings: ISettings[] = [];
1718
const workspaces = getWorkspaceFolders();
18-
1919
for (const workspace of workspaces) {
2020
const workspaceSetting = await getWorkspaceSettings(namespace, workspace, includeInterpreter);
2121
settings.push(workspaceSetting);
@@ -149,3 +149,10 @@ export async function verifySetting(
149149
} while (retries < 20);
150150
}
151151
}
152+
153+
export function getRawVersion(version: VersionInfo | undefined) {
154+
if (version) {
155+
return `${version.major}.${version.minor}.${version.micro}`;
156+
}
157+
return ``;
158+
}

src/extension/extensionInit.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import { pickArgsInput } from './common/utils/localize';
3434
import { DebugPortAttributesProvider } from './debugger/debugPort/portAttributesProvider';
3535
import { getConfigurationsByUri } from './debugger/configuration/launch.json/launchJsonReader';
3636
import { DebugpySocketsHandler } from './debugger/hooks/debugpySocketsHandler';
37+
import { openReportIssue } from './common/application/commands/reportIssueCommand';
3738

3839
export async function registerDebugger(context: IExtensionContext): Promise<void> {
3940
const childProcessAttachService = new ChildProcessAttachService();
@@ -63,6 +64,8 @@ export async function registerDebugger(context: IExtensionContext): Promise<void
6364
),
6465
);
6566

67+
context.subscriptions.push(registerCommand(Commands.ReportIssue, () => openReportIssue()));
68+
6669
context.subscriptions.push(
6770
registerCommand(Commands.Debug_In_Terminal, async (file?: Uri) => {
6871
sendTelemetryEvent(EventName.DEBUG_IN_TERMINAL_BUTTON);

src/extension/telemetry/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,5 @@ export enum EventName {
1919
DEBUGGER_CONFIGURATION_PROMPTS = 'DEBUGGER.CONFIGURATION.PROMPTS',
2020
DEBUGGER_CONFIGURATION_PROMPTS_IN_LAUNCH_JSON = 'DEBUGGER.CONFIGURATION.PROMPTS.IN.LAUNCH.JSON',
2121
ENVFILE_VARIABLE_SUBSTITUTION = 'ENVFILE_VARIABLE_SUBSTITUTION',
22+
USE_REPORT_ISSUE_COMMAND = 'USE_REPORT_ISSUE_COMMAND',
2223
}

src/extension/telemetry/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -660,4 +660,11 @@ export interface IEventNamePropertyMapping {
660660
"envfile_variable_substitution" : { "owner": "karthiknadig" }
661661
*/
662662
[EventName.ENVFILE_VARIABLE_SUBSTITUTION]: never | undefined;
663+
/**
664+
* Telemetry event sent when the user use the report issue command.
665+
*/
666+
/* __GDPR__
667+
"use_report_issue_command" : { "owner": "paulacamargo25" }
668+
*/
669+
[EventName.USE_REPORT_ISSUE_COMMAND]: unknown;
663670
}

0 commit comments

Comments
 (0)