mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-28 12:33:35 +01:00
Improvements to canonical URI API (#182667)
* Improve API names * Allow requesting a specific scheme * Implement ile uri support
This commit is contained in:
@@ -1,37 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { CancellationToken, CanonicalUriIdentityProvider, Disposable, Uri, workspace } from 'vscode';
|
||||
|
||||
const SUPPORTED_SCHEMES = ['ssh', 'https'];
|
||||
|
||||
export class GitHubCanonicalUriIdentityProvider implements CanonicalUriIdentityProvider {
|
||||
|
||||
private disposables: Disposable[] = [];
|
||||
constructor() {
|
||||
this.disposables.push(...SUPPORTED_SCHEMES.map((scheme) => workspace.registerCanonicalUriIdentityProvider(scheme, this)));
|
||||
}
|
||||
|
||||
dispose() { this.disposables.forEach((disposable) => disposable.dispose()); }
|
||||
|
||||
async provideCanonicalUriIdentity(uri: Uri, _token: CancellationToken): Promise<Uri | undefined> {
|
||||
switch (uri.scheme) {
|
||||
case 'ssh':
|
||||
// if this is a git@github.com URI, return the HTTPS equivalent
|
||||
if (uri.authority === 'git@github.com') {
|
||||
const [owner, repo] = (uri.path.endsWith('.git') ? uri.path.slice(0, -4) : uri.path).split('/').filter((segment) => segment.length > 0);
|
||||
return Uri.parse(`https://github.com/${owner}/${repo}`);
|
||||
}
|
||||
break;
|
||||
case 'https':
|
||||
if (uri.authority === 'github.com') {
|
||||
return uri;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
49
extensions/github/src/canonicalUriProvider.ts
Normal file
49
extensions/github/src/canonicalUriProvider.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { CancellationToken, CanonicalUriProvider, CanonicalUriRequestOptions, Disposable, ProviderResult, Uri, workspace } from 'vscode';
|
||||
import { API } from './typings/git';
|
||||
|
||||
const SUPPORTED_SCHEMES = ['ssh', 'https', 'file'];
|
||||
|
||||
export class GitHubCanonicalUriProvider implements CanonicalUriProvider {
|
||||
|
||||
private disposables: Disposable[] = [];
|
||||
constructor(private gitApi: API) {
|
||||
this.disposables.push(...SUPPORTED_SCHEMES.map((scheme) => workspace.registerCanonicalUriProvider(scheme, this)));
|
||||
}
|
||||
|
||||
dispose() { this.disposables.forEach((disposable) => disposable.dispose()); }
|
||||
|
||||
provideCanonicalUri(uri: Uri, options: CanonicalUriRequestOptions, _token: CancellationToken): ProviderResult<Uri> {
|
||||
if (options.targetScheme !== 'https') {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (uri.scheme) {
|
||||
case 'file': {
|
||||
const repository = this.gitApi.getRepository(uri);
|
||||
const remote = repository?.state.remotes.find((remote) => remote.name === repository.state.HEAD?.remote)?.pushUrl?.replace(/^(git@[^\/:]+)(:)/i, 'ssh://$1/');
|
||||
if (remote) {
|
||||
return toHttpsGitHubRemote(uri);
|
||||
}
|
||||
}
|
||||
default:
|
||||
return toHttpsGitHubRemote(uri);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function toHttpsGitHubRemote(uri: Uri) {
|
||||
if (uri.scheme === 'ssh' && uri.authority === 'git@github.com') {
|
||||
// if this is a git@github.com URI, return the HTTPS equivalent
|
||||
const [owner, repo] = (uri.path.endsWith('.git') ? uri.path.slice(0, -4) : uri.path).split('/').filter((segment) => segment.length > 0);
|
||||
return Uri.parse(`https://github.com/${owner}/${repo}`);
|
||||
}
|
||||
if (uri.scheme === 'https' && uri.authority === 'github.com') {
|
||||
return uri;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
@@ -13,7 +13,7 @@ import { GithubPushErrorHandler } from './pushErrorHandler';
|
||||
import { GitBaseExtension } from './typings/git-base';
|
||||
import { GithubRemoteSourcePublisher } from './remoteSourcePublisher';
|
||||
import { GithubBranchProtectionProviderManager } from './branchProtection';
|
||||
import { GitHubCanonicalUriIdentityProvider } from './canonicalUriIdentityProvider';
|
||||
import { GitHubCanonicalUriProvider } from './canonicalUriProvider';
|
||||
|
||||
export function activate(context: ExtensionContext): void {
|
||||
const disposables: Disposable[] = [];
|
||||
@@ -30,7 +30,6 @@ export function activate(context: ExtensionContext): void {
|
||||
|
||||
disposables.push(initializeGitBaseExtension());
|
||||
disposables.push(initializeGitExtension(context, logger));
|
||||
disposables.push(new GitHubCanonicalUriIdentityProvider());
|
||||
}
|
||||
|
||||
function initializeGitBaseExtension(): Disposable {
|
||||
@@ -95,6 +94,7 @@ function initializeGitExtension(context: ExtensionContext, logger: LogOutputChan
|
||||
disposables.add(new GithubBranchProtectionProviderManager(gitAPI, context.globalState, logger));
|
||||
disposables.add(gitAPI.registerPushErrorHandler(new GithubPushErrorHandler()));
|
||||
disposables.add(gitAPI.registerRemoteSourcePublisher(new GithubRemoteSourcePublisher(gitAPI)));
|
||||
disposables.add(new GitHubCanonicalUriProvider(gitAPI));
|
||||
setGitHubContext(gitAPI, disposables);
|
||||
|
||||
commands.executeCommand('setContext', 'git-base.gitEnabled', true);
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
declare module 'vscode' {
|
||||
|
||||
// https://github.com/microsoft/vscode/issues/180582
|
||||
|
||||
export namespace workspace {
|
||||
/**
|
||||
*
|
||||
* @param scheme The URI scheme that this provider can provide canonical URI identities for.
|
||||
* A canonical URI represents the conversion of a resource's alias into a source of truth URI.
|
||||
* Multiple aliases may convert to the same source of truth URI.
|
||||
* @param provider A provider which can convert URIs for workspace folders of scheme @param scheme to
|
||||
* a canonical URI identifier which is stable across machines.
|
||||
*/
|
||||
export function registerCanonicalUriIdentityProvider(scheme: string, provider: CanonicalUriIdentityProvider): Disposable;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param uri The URI to provide a canonical URI identity for.
|
||||
* @param token A cancellation token for the request.
|
||||
*/
|
||||
export function provideCanonicalUriIdentity(uri: Uri, token: CancellationToken): ProviderResult<Uri>;
|
||||
}
|
||||
|
||||
export interface CanonicalUriIdentityProvider {
|
||||
/**
|
||||
*
|
||||
* @param uri The URI to provide a canonical URI identity for.
|
||||
* @param token A cancellation token for the request.
|
||||
* @returns The canonical URI identity for the requested URI.
|
||||
*/
|
||||
provideCanonicalUriIdentity(uri: Uri, token: CancellationToken): ProviderResult<Uri>;
|
||||
}
|
||||
}
|
||||
47
extensions/github/src/typings/vscode.proposed.canonicalUriProvider.d.ts
vendored
Normal file
47
extensions/github/src/typings/vscode.proposed.canonicalUriProvider.d.ts
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
declare module 'vscode' {
|
||||
|
||||
// https://github.com/microsoft/vscode/issues/180582
|
||||
|
||||
export namespace workspace {
|
||||
/**
|
||||
*
|
||||
* @param scheme The URI scheme that this provider can provide canonical URIs for.
|
||||
* A canonical URI represents the conversion of a resource's alias into a source of truth URI.
|
||||
* Multiple aliases may convert to the same source of truth URI.
|
||||
* @param provider A provider which can convert URIs of scheme @param scheme to
|
||||
* a canonical URI which is stable across machines.
|
||||
*/
|
||||
export function registerCanonicalUriProvider(scheme: string, provider: CanonicalUriProvider): Disposable;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param uri The URI to provide a canonical URI for.
|
||||
* @param token A cancellation token for the request.
|
||||
*/
|
||||
export function getCanonicalUri(uri: Uri, options: CanonicalUriRequestOptions, token: CancellationToken): ProviderResult<Uri>;
|
||||
}
|
||||
|
||||
export interface CanonicalUriProvider {
|
||||
/**
|
||||
*
|
||||
* @param uri The URI to provide a canonical URI for.
|
||||
* @param options Options that the provider should honor in the URI it returns.
|
||||
* @param token A cancellation token for the request.
|
||||
* @returns The canonical URI for the requested URI or undefined if no canonical URI can be provided.
|
||||
*/
|
||||
provideCanonicalUri(uri: Uri, options: CanonicalUriRequestOptions, token: CancellationToken): ProviderResult<Uri>;
|
||||
}
|
||||
|
||||
export interface CanonicalUriRequestOptions {
|
||||
/**
|
||||
*
|
||||
* The desired scheme of the canonical URI.
|
||||
*/
|
||||
targetScheme: string;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user