diff --git a/src/vs/code/electron-browser/issue/issueReporterMain.ts b/src/vs/code/electron-browser/issue/issueReporterMain.ts index 83392e33bd6..c0539a469d7 100644 --- a/src/vs/code/electron-browser/issue/issueReporterMain.ts +++ b/src/vs/code/electron-browser/issue/issueReporterMain.ts @@ -40,6 +40,7 @@ import { createSpdLogService } from 'vs/platform/log/node/spdlogService'; import { LogLevelSetterChannelClient, FollowerLogService } from 'vs/platform/log/common/logIpc'; import { ILogService, getLogLevel } from 'vs/platform/log/common/log'; import { OcticonLabel } from 'vs/base/browser/ui/octiconLabel/octiconLabel'; +import { normalizeGitHubIssuesUrl } from 'vs/code/electron-browser/issue/issueReporterUtil'; const MAX_URL_LENGTH = platform.isWindows ? 2081 : 5400; @@ -440,6 +441,11 @@ export class IssueReporter extends Disposable { return selectedExtension && selectedExtension.manifest && selectedExtension.manifest.repository && selectedExtension.manifest.repository.url; } + private getExtensionBugsUrl(): string { + const selectedExtension = this.issueReporterModel.getData().selectedExtension; + return selectedExtension && selectedExtension.manifest && selectedExtension.manifest.bugs && selectedExtension.manifest.bugs.url; + } + private searchVSCodeIssues(title: string, issueDescription: string): void { if (title || issueDescription) { this.searchDuplicates(title, issueDescription); @@ -746,10 +752,13 @@ export class IssueReporter extends Disposable { private getIssueUrlWithTitle(issueTitle: string): string { let repositoryUrl = product.reportIssueUrl; if (this.issueReporterModel.getData().fileOnExtension) { + const bugsUrl = this.getExtensionBugsUrl(); const extensionUrl = this.getExtensionRepositoryUrl(); - if (extensionUrl) { - // Remove '.git' suffix - repositoryUrl = `${extensionUrl.indexOf('.git') !== -1 ? extensionUrl.substr(0, extensionUrl.length - 4) : extensionUrl}/issues/new/`; + // If given, try to match the extension's bug url + if (bugsUrl && bugsUrl.match(/^https?:\/\/github\.com\/(.*)/)) { + repositoryUrl = normalizeGitHubIssuesUrl(bugsUrl); + } else if (extensionUrl && extensionUrl.match(/^https?:\/\/github\.com\/(.*)/)) { + repositoryUrl = normalizeGitHubIssuesUrl(extensionUrl); } } diff --git a/src/vs/code/electron-browser/issue/issueReporterUtil.ts b/src/vs/code/electron-browser/issue/issueReporterUtil.ts new file mode 100644 index 00000000000..2212eaf002c --- /dev/null +++ b/src/vs/code/electron-browser/issue/issueReporterUtil.ts @@ -0,0 +1,30 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import { endsWith, rtrim } from 'vs/base/common/strings'; + +export function normalizeGitHubIssuesUrl(url: string): string { + // If the url has a .git suffix, remove it + if (endsWith(url, '.git')) { + url = url.substr(0, url.length - 4); + } + + // Remove trailing slash + url = rtrim(url, '/'); + + // If the url already ends with issues/new, it's beautiful, return it + if (endsWith(url, 'issues/new')) { + return url; + } + + // Add new segment if it does not exist + if (endsWith(url, 'issues')) { + return url + '/new'; + } + + return url + '/issues/new'; +} \ No newline at end of file diff --git a/src/vs/code/electron-browser/issue/test/testReporterModel.test.ts b/src/vs/code/electron-browser/issue/test/testReporterModel.test.ts index 24cc0c7731e..34c7c07e8a5 100644 --- a/src/vs/code/electron-browser/issue/test/testReporterModel.test.ts +++ b/src/vs/code/electron-browser/issue/test/testReporterModel.test.ts @@ -7,6 +7,7 @@ import * as assert from 'assert'; import { IssueReporterModel } from 'vs/code/electron-browser/issue/issueReporterModel'; +import { normalizeGitHubIssuesUrl } from 'vs/code/electron-browser/issue/issueReporterUtil'; suite('IssueReporter', () => { @@ -36,4 +37,18 @@ OS version: undefined `); }); + + test('should normalize GitHub urls', () => { + [ + 'https://github.com/repo', + 'https://github.com/repo/', + 'https://github.com/repo.git', + 'https://github.com/repo/issues', + 'https://github.com/repo/issues/', + 'https://github.com/repo/issues/new', + 'https://github.com/repo/issues/new/' + ].forEach(url => { + assert.equal('https://github.com/repo/issues/new', normalizeGitHubIssuesUrl(url)); + }); + }); }); diff --git a/src/vs/platform/extensionManagement/common/extensionManagement.ts b/src/vs/platform/extensionManagement/common/extensionManagement.ts index 82d0cc35551..973f0262d75 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagement.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagement.ts @@ -120,6 +120,9 @@ export interface IExtensionManifest { repository?: { url: string; }; + bugs?: { + url: string; + }; } export interface IGalleryExtensionProperties {