Path: blob/main/src/vs/workbench/contrib/issue/browser/issueReporterModel.ts
5222 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { mainWindow } from '../../../../base/browser/window.js';6import { isRemoteDiagnosticError, SystemInfo } from '../../../../platform/diagnostics/common/diagnostics.js';7import { ISettingSearchResult, IssueReporterExtensionData, IssueType } from '../common/issue.js';89interface VersionInfo {10vscodeVersion: string;11os: string;12}1314export interface IssueReporterData {15issueType: IssueType;16issueDescription?: string;17issueTitle?: string;18extensionData?: string;1920versionInfo?: VersionInfo;21systemInfo?: SystemInfo;22systemInfoWeb?: string;23processInfo?: string;24workspaceInfo?: string;2526includeSystemInfo: boolean;27includeWorkspaceInfo: boolean;28includeProcessInfo: boolean;29includeExtensions: boolean;30includeExperiments: boolean;31includeExtensionData: boolean;3233numberOfThemeExtesions?: number;34allExtensions: IssueReporterExtensionData[];35enabledNonThemeExtesions?: IssueReporterExtensionData[];36extensionsDisabled?: boolean;37fileOnExtension?: boolean;38fileOnMarketplace?: boolean;39fileOnProduct?: boolean;40selectedExtension?: IssueReporterExtensionData;41actualSearchResults?: ISettingSearchResult[];42query?: string;43filterResultCount?: number;44experimentInfo?: string;45restrictedMode?: boolean;46isUnsupported?: boolean;47}4849export class IssueReporterModel {50private readonly _data: IssueReporterData;5152constructor(initialData?: Partial<IssueReporterData>) {53const defaultData = {54issueType: IssueType.Bug,55includeSystemInfo: true,56includeWorkspaceInfo: true,57includeProcessInfo: true,58includeExtensions: true,59includeExperiments: true,60includeExtensionData: true,61allExtensions: []62};6364this._data = initialData ? Object.assign(defaultData, initialData) : defaultData;6566mainWindow.addEventListener('message', async (event) => {67if (event.data && event.data.sendChannel === 'vscode:triggerIssueData') {68mainWindow.postMessage({69data: { issueBody: this._data.issueDescription, issueTitle: this._data.issueTitle },70replyChannel: 'vscode:triggerIssueDataResponse'71}, '*');72}73});74}7576getData(): IssueReporterData {77return this._data;78}7980update(newData: Partial<IssueReporterData>): void {81Object.assign(this._data, newData);82}8384serialize(): string {85const modes = [];86if (this._data.restrictedMode) {87modes.push('Restricted');88}89if (this._data.isUnsupported) {90modes.push('Unsupported');91}92return `93Type: <b>${this.getIssueTypeTitle()}</b>9495${this._data.issueDescription}96${this.getExtensionVersion()}97VS Code version: ${this._data.versionInfo && this._data.versionInfo.vscodeVersion}98OS version: ${this._data.versionInfo && this._data.versionInfo.os}99Modes:${modes.length ? ' ' + modes.join(', ') : ''}100${this.getRemoteOSes()}101${this.getInfos()}102<!-- generated by issue reporter -->`;103}104105private getRemoteOSes(): string {106if (this._data.systemInfo && this._data.systemInfo.remoteData.length) {107return this._data.systemInfo.remoteData108.map(remote => isRemoteDiagnosticError(remote) ? remote.errorMessage : `Remote OS version: ${remote.machineInfo.os}`).join('\n') + '\n';109}110111return '';112}113114fileOnExtension(): boolean | undefined {115const fileOnExtensionSupported = this._data.issueType === IssueType.Bug116|| this._data.issueType === IssueType.PerformanceIssue117|| this._data.issueType === IssueType.FeatureRequest;118119return fileOnExtensionSupported && this._data.fileOnExtension;120}121122private getExtensionVersion(): string {123if (this.fileOnExtension() && this._data.selectedExtension) {124return `\nExtension version: ${this._data.selectedExtension.version}`;125} else {126return '';127}128}129130private getIssueTypeTitle(): string {131if (this._data.issueType === IssueType.Bug) {132return 'Bug';133} else if (this._data.issueType === IssueType.PerformanceIssue) {134return 'Performance Issue';135} else {136return 'Feature Request';137}138}139140private getInfos(): string {141let info = '';142143if (this._data.fileOnMarketplace) {144return info;145}146147const isBugOrPerformanceIssue = this._data.issueType === IssueType.Bug || this._data.issueType === IssueType.PerformanceIssue;148149if (isBugOrPerformanceIssue) {150if (this._data.includeExtensionData && this._data.extensionData) {151info += this.getExtensionData();152}153154if (this._data.includeSystemInfo && this._data.systemInfo) {155info += this.generateSystemInfoMd();156}157158if (this._data.includeSystemInfo && this._data.systemInfoWeb) {159info += 'System Info: ' + this._data.systemInfoWeb;160}161}162163if (this._data.issueType === IssueType.PerformanceIssue) {164if (this._data.includeProcessInfo) {165info += this.generateProcessInfoMd();166}167168if (this._data.includeWorkspaceInfo) {169info += this.generateWorkspaceInfoMd();170}171}172173if (isBugOrPerformanceIssue) {174if (!this._data.fileOnExtension && this._data.includeExtensions) {175info += this.generateExtensionsMd();176}177178if (this._data.includeExperiments && this._data.experimentInfo) {179info += this.generateExperimentsInfoMd();180}181}182183return info;184}185186private getExtensionData(): string {187return this._data.extensionData ?? '';188}189190private generateSystemInfoMd(): string {191let md = `<details>192<summary>System Info</summary>193194|Item|Value|195|---|---|196`;197198if (this._data.systemInfo) {199200md += `|CPUs|${this._data.systemInfo.cpus}|201|GPU Status|${Object.keys(this._data.systemInfo.gpuStatus).map(key => `${key}: ${this._data.systemInfo!.gpuStatus[key]}`).join('<br>')}|202|Load (avg)|${this._data.systemInfo.load}|203|Memory (System)|${this._data.systemInfo.memory}|204|Process Argv|${this._data.systemInfo.processArgs.replace(/\\/g, '\\\\')}|205|Screen Reader|${this._data.systemInfo.screenReader}|206|VM|${this._data.systemInfo.vmHint}|`;207208if (this._data.systemInfo.linuxEnv) {209md += `\n|DESKTOP_SESSION|${this._data.systemInfo.linuxEnv.desktopSession}|210|XDG_CURRENT_DESKTOP|${this._data.systemInfo.linuxEnv.xdgCurrentDesktop}|211|XDG_SESSION_DESKTOP|${this._data.systemInfo.linuxEnv.xdgSessionDesktop}|212|XDG_SESSION_TYPE|${this._data.systemInfo.linuxEnv.xdgSessionType}|`;213}214215this._data.systemInfo.remoteData.forEach(remote => {216if (isRemoteDiagnosticError(remote)) {217md += `\n\n${remote.errorMessage}`;218} else {219md += `220221|Item|Value|222|---|---|223|Remote|${remote.latency ? `${remote.hostName} (latency: ${remote.latency.current.toFixed(2)}ms last, ${remote.latency.average.toFixed(2)}ms average)` : remote.hostName}|224|OS|${remote.machineInfo.os}|225|CPUs|${remote.machineInfo.cpus}|226|Memory (System)|${remote.machineInfo.memory}|227|VM|${remote.machineInfo.vmHint}|`;228}229});230}231232md += '\n</details>';233234return md;235}236237private generateProcessInfoMd(): string {238return `<details>239<summary>Process Info</summary>240241\`\`\`242${this._data.processInfo}243\`\`\`244245</details>246`;247}248249private generateWorkspaceInfoMd(): string {250return `<details>251<summary>Workspace Info</summary>252253\`\`\`254${this._data.workspaceInfo};255\`\`\`256257</details>258`;259}260261private generateExperimentsInfoMd(): string {262return `<details>263<summary>A/B Experiments</summary>264265\`\`\`266${this._data.experimentInfo}267\`\`\`268269</details>270`;271}272273private generateExtensionsMd(): string {274if (this._data.extensionsDisabled) {275return 'Extensions disabled';276}277278const themeExclusionStr = this._data.numberOfThemeExtesions ? `\n(${this._data.numberOfThemeExtesions} theme extensions excluded)` : '';279280if (!this._data.enabledNonThemeExtesions) {281return 'Extensions: none' + themeExclusionStr;282}283284const tableHeader = `Extension|Author (truncated)|Version285---|---|---`;286const table = this._data.enabledNonThemeExtesions.map(e => {287return `${e.name}|${e.publisher?.substr(0, 3) ?? 'N/A'}|${e.version}`;288}).join('\n');289290return `<details><summary>Extensions (${this._data.enabledNonThemeExtesions.length})</summary>291292${tableHeader}293${table}294${themeExclusionStr}295296</details>`;297}298}299300301