forked from DonJayamanne/pythonVSCode
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Expand file tree
/
Copy pathreportIssueCommand.ts
More file actions
121 lines (110 loc) · 6.1 KB
/
reportIssueCommand.ts
File metadata and controls
121 lines (110 loc) · 6.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
'use strict';
import * as fs from 'fs-extra';
import * as os from 'os';
import * as path from 'path';
import { inject, injectable } from 'inversify';
import { isEqual } from 'lodash';
import { IExtensionSingleActivationService } from '../../../activation/types';
import { IApplicationEnvironment, ICommandManager, IWorkspaceService } from '../types';
import { EXTENSION_ROOT_DIR } from '../../../constants';
import { IInterpreterService } from '../../../interpreter/contracts';
import { Commands } from '../../constants';
import { IConfigurationService, IPythonSettings } from '../../types';
import { sendTelemetryEvent } from '../../../telemetry';
import { EventName } from '../../../telemetry/constants';
import { EnvironmentType } from '../../../pythonEnvironments/info';
import { PythonSettings } from '../../configSettings';
import { SystemVariables } from '../../variables/systemVariables';
/**
* Allows the user to report an issue related to the Python extension using our template.
*/
@injectable()
export class ReportIssueCommandHandler implements IExtensionSingleActivationService {
public readonly supportedWorkspaceTypes = { untrustedWorkspace: false, virtualWorkspace: true };
// eslint-disable-next-line @typescript-eslint/no-explicit-any
private readonly packageJSONSettings: any;
constructor(
@inject(ICommandManager) private readonly commandManager: ICommandManager,
@inject(IWorkspaceService) private readonly workspaceService: IWorkspaceService,
@inject(IInterpreterService) private readonly interpreterService: IInterpreterService,
@inject(IConfigurationService) protected readonly configurationService: IConfigurationService,
@inject(IApplicationEnvironment) appEnvironment: IApplicationEnvironment,
) {
this.packageJSONSettings = appEnvironment.packageJson?.contributes?.configuration?.properties;
}
public async activate(): Promise<void> {
this.commandManager.registerCommand(Commands.ReportIssue, this.openReportIssue, this);
}
private argSettingsPath = path.join(EXTENSION_ROOT_DIR, 'resources', 'report_issue_user_settings.json');
private templatePath = path.join(EXTENSION_ROOT_DIR, 'resources', 'report_issue_template.md');
public async openReportIssue(): Promise<void> {
const settings: IPythonSettings = this.configurationService.getSettings();
const argSettings = JSON.parse(await fs.readFile(this.argSettingsPath, 'utf8'));
let userSettings = '';
const keys: [keyof IPythonSettings] = Object.keys(settings) as [keyof IPythonSettings];
keys.forEach((property) => {
const argSetting = argSettings[property];
if (argSetting) {
if (typeof argSetting === 'object') {
let propertyHeaderAdded = false;
const argSettingsDict = (settings[property] as unknown) as Record<string, unknown>;
if (typeof argSettingsDict === 'object') {
Object.keys(argSetting).forEach((item) => {
const prop = argSetting[item];
if (prop) {
const defaultValue = this.getDefaultValue(`${property}.${item}`);
if (defaultValue === undefined || !isEqual(defaultValue, argSettingsDict[item])) {
if (!propertyHeaderAdded) {
userSettings = userSettings.concat(os.EOL, property, os.EOL);
propertyHeaderAdded = true;
}
const value =
prop === true ? JSON.stringify(argSettingsDict[item]) : '"<placeholder>"';
userSettings = userSettings.concat('• ', item, ': ', value, os.EOL);
}
}
});
}
} else {
const defaultValue = this.getDefaultValue(property);
if (defaultValue === undefined || !isEqual(defaultValue, settings[property])) {
const value = argSetting === true ? JSON.stringify(settings[property]) : '"<placeholder>"';
userSettings = userSettings.concat(os.EOL, property, ': ', value, os.EOL);
}
}
}
});
const template = await fs.readFile(this.templatePath, 'utf8');
const interpreter = await this.interpreterService.getActiveInterpreter();
const pythonVersion = interpreter?.version?.raw ?? '';
const languageServer =
this.workspaceService.getConfiguration('python').get<string>('languageServer') || 'Not Found';
const virtualEnvKind = interpreter?.envType || EnvironmentType.Unknown;
const hasMultipleFolders = (this.workspaceService.workspaceFolders?.length ?? 0) > 1;
const hasMultipleFoldersText =
hasMultipleFolders && userSettings !== ''
? `Multiroot scenario, following user settings may not apply:${os.EOL}`
: '';
await this.commandManager.executeCommand('workbench.action.openIssueReporter', {
extensionId: 'ms-python.python',
issueBody: template.format(
pythonVersion,
virtualEnvKind,
languageServer,
hasMultipleFoldersText,
userSettings,
),
});
sendTelemetryEvent(EventName.USE_REPORT_ISSUE_COMMAND, undefined, {});
}
private getDefaultValue(settingKey: string) {
if (!this.packageJSONSettings) {
return undefined;
}
const resource = PythonSettings.getSettingsUriAndTarget(undefined, this.workspaceService).uri;
const systemVariables = new SystemVariables(resource, undefined, this.workspaceService);
return systemVariables.resolveAny(this.packageJSONSettings[`python.${settingKey}`]?.default);
}
}