Path: blob/main/src/vs/workbench/contrib/issue/browser/issueReporterModel.ts
3296 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';89export interface IssueReporterData {10issueType: IssueType;11issueDescription?: string;12issueTitle?: string;13extensionData?: string;1415versionInfo?: any;16systemInfo?: SystemInfo;17systemInfoWeb?: string;18processInfo?: string;19workspaceInfo?: string;2021includeSystemInfo: boolean;22includeWorkspaceInfo: boolean;23includeProcessInfo: boolean;24includeExtensions: boolean;25includeExperiments: boolean;26includeExtensionData: boolean;2728numberOfThemeExtesions?: number;29allExtensions: IssueReporterExtensionData[];30enabledNonThemeExtesions?: IssueReporterExtensionData[];31extensionsDisabled?: boolean;32fileOnExtension?: boolean;33fileOnMarketplace?: boolean;34fileOnProduct?: boolean;35selectedExtension?: IssueReporterExtensionData;36actualSearchResults?: ISettingSearchResult[];37query?: string;38filterResultCount?: number;39experimentInfo?: string;40restrictedMode?: boolean;41isUnsupported?: boolean;42}4344export class IssueReporterModel {45private readonly _data: IssueReporterData;4647constructor(initialData?: Partial<IssueReporterData>) {48const defaultData = {49issueType: IssueType.Bug,50includeSystemInfo: true,51includeWorkspaceInfo: true,52includeProcessInfo: true,53includeExtensions: true,54includeExperiments: true,55includeExtensionData: true,56allExtensions: []57};5859this._data = initialData ? Object.assign(defaultData, initialData) : defaultData;6061mainWindow.addEventListener('message', async (event) => {62if (event.data && event.data.sendChannel === 'vscode:triggerIssueData') {63mainWindow.postMessage({64data: { issueBody: this._data.issueDescription, issueTitle: this._data.issueTitle },65replyChannel: 'vscode:triggerIssueDataResponse'66}, '*');67}68});69}7071getData(): IssueReporterData {72return this._data;73}7475update(newData: Partial<IssueReporterData>): void {76Object.assign(this._data, newData);77}7879serialize(): string {80const modes = [];81if (this._data.restrictedMode) {82modes.push('Restricted');83}84if (this._data.isUnsupported) {85modes.push('Unsupported');86}87return `88Type: <b>${this.getIssueTypeTitle()}</b>8990${this._data.issueDescription}91${this.getExtensionVersion()}92VS Code version: ${this._data.versionInfo && this._data.versionInfo.vscodeVersion}93OS version: ${this._data.versionInfo && this._data.versionInfo.os}94Modes:${modes.length ? ' ' + modes.join(', ') : ''}95${this.getRemoteOSes()}96${this.getInfos()}97<!-- generated by issue reporter -->`;98}99100private getRemoteOSes(): string {101if (this._data.systemInfo && this._data.systemInfo.remoteData.length) {102return this._data.systemInfo.remoteData103.map(remote => isRemoteDiagnosticError(remote) ? remote.errorMessage : `Remote OS version: ${remote.machineInfo.os}`).join('\n') + '\n';104}105106return '';107}108109fileOnExtension(): boolean | undefined {110const fileOnExtensionSupported = this._data.issueType === IssueType.Bug111|| this._data.issueType === IssueType.PerformanceIssue112|| this._data.issueType === IssueType.FeatureRequest;113114return fileOnExtensionSupported && this._data.fileOnExtension;115}116117private getExtensionVersion(): string {118if (this.fileOnExtension() && this._data.selectedExtension) {119return `\nExtension version: ${this._data.selectedExtension.version}`;120} else {121return '';122}123}124125private getIssueTypeTitle(): string {126if (this._data.issueType === IssueType.Bug) {127return 'Bug';128} else if (this._data.issueType === IssueType.PerformanceIssue) {129return 'Performance Issue';130} else {131return 'Feature Request';132}133}134135private getInfos(): string {136let info = '';137138if (this._data.fileOnMarketplace) {139return info;140}141142const isBugOrPerformanceIssue = this._data.issueType === IssueType.Bug || this._data.issueType === IssueType.PerformanceIssue;143144if (isBugOrPerformanceIssue) {145if (this._data.includeExtensionData && this._data.extensionData) {146info += this.getExtensionData();147}148149if (this._data.includeSystemInfo && this._data.systemInfo) {150info += this.generateSystemInfoMd();151}152153if (this._data.includeSystemInfo && this._data.systemInfoWeb) {154info += 'System Info: ' + this._data.systemInfoWeb;155}156}157158if (this._data.issueType === IssueType.PerformanceIssue) {159if (this._data.includeProcessInfo) {160info += this.generateProcessInfoMd();161}162163if (this._data.includeWorkspaceInfo) {164info += this.generateWorkspaceInfoMd();165}166}167168if (isBugOrPerformanceIssue) {169if (!this._data.fileOnExtension && this._data.includeExtensions) {170info += this.generateExtensionsMd();171}172173if (this._data.includeExperiments && this._data.experimentInfo) {174info += this.generateExperimentsInfoMd();175}176}177178return info;179}180181private getExtensionData(): string {182return this._data.extensionData ?? '';183}184185private generateSystemInfoMd(): string {186let md = `<details>187<summary>System Info</summary>188189|Item|Value|190|---|---|191`;192193if (this._data.systemInfo) {194195md += `|CPUs|${this._data.systemInfo.cpus}|196|GPU Status|${Object.keys(this._data.systemInfo.gpuStatus).map(key => `${key}: ${this._data.systemInfo!.gpuStatus[key]}`).join('<br>')}|197|Load (avg)|${this._data.systemInfo.load}|198|Memory (System)|${this._data.systemInfo.memory}|199|Process Argv|${this._data.systemInfo.processArgs.replace(/\\/g, '\\\\')}|200|Screen Reader|${this._data.systemInfo.screenReader}|201|VM|${this._data.systemInfo.vmHint}|`;202203if (this._data.systemInfo.linuxEnv) {204md += `\n|DESKTOP_SESSION|${this._data.systemInfo.linuxEnv.desktopSession}|205|XDG_CURRENT_DESKTOP|${this._data.systemInfo.linuxEnv.xdgCurrentDesktop}|206|XDG_SESSION_DESKTOP|${this._data.systemInfo.linuxEnv.xdgSessionDesktop}|207|XDG_SESSION_TYPE|${this._data.systemInfo.linuxEnv.xdgSessionType}|`;208}209210this._data.systemInfo.remoteData.forEach(remote => {211if (isRemoteDiagnosticError(remote)) {212md += `\n\n${remote.errorMessage}`;213} else {214md += `215216|Item|Value|217|---|---|218|Remote|${remote.latency ? `${remote.hostName} (latency: ${remote.latency.current.toFixed(2)}ms last, ${remote.latency.average.toFixed(2)}ms average)` : remote.hostName}|219|OS|${remote.machineInfo.os}|220|CPUs|${remote.machineInfo.cpus}|221|Memory (System)|${remote.machineInfo.memory}|222|VM|${remote.machineInfo.vmHint}|`;223}224});225}226227md += '\n</details>';228229return md;230}231232private generateProcessInfoMd(): string {233return `<details>234<summary>Process Info</summary>235236\`\`\`237${this._data.processInfo}238\`\`\`239240</details>241`;242}243244private generateWorkspaceInfoMd(): string {245return `<details>246<summary>Workspace Info</summary>247248\`\`\`249${this._data.workspaceInfo};250\`\`\`251252</details>253`;254}255256private generateExperimentsInfoMd(): string {257return `<details>258<summary>A/B Experiments</summary>259260\`\`\`261${this._data.experimentInfo}262\`\`\`263264</details>265`;266}267268private generateExtensionsMd(): string {269if (this._data.extensionsDisabled) {270return 'Extensions disabled';271}272273const themeExclusionStr = this._data.numberOfThemeExtesions ? `\n(${this._data.numberOfThemeExtesions} theme extensions excluded)` : '';274275if (!this._data.enabledNonThemeExtesions) {276return 'Extensions: none' + themeExclusionStr;277}278279const tableHeader = `Extension|Author (truncated)|Version280---|---|---`;281const table = this._data.enabledNonThemeExtesions.map(e => {282return `${e.name}|${e.publisher?.substr(0, 3) ?? 'N/A'}|${e.version}`;283}).join('\n');284285return `<details><summary>Extensions (${this._data.enabledNonThemeExtesions.length})</summary>286287${tableHeader}288${table}289${themeExclusionStr}290291</details>`;292}293}294295296