From 3bce79a8d8097fa7c50c792a2f57251dc9abbfe7 Mon Sep 17 00:00:00 2001 From: Eric Amodio Date: Tue, 10 Oct 2023 17:47:17 -0400 Subject: [PATCH] Splits out new `getFirstCommitSha` Aligns with eventual cloud patch changes --- src/env/node/git/localGitProvider.ts | 12 ++-- src/git/gitProvider.ts | 2 +- src/git/gitProviderService.ts | 16 +++-- src/plus/github/githubGitProvider.ts | 5 -- src/telemetry/usageTracker.ts | 6 +- src/uris/deepLinks/deepLink.ts | 106 ++++++++++++++++++---------------- src/uris/deepLinks/deepLinkService.ts | 26 ++++----- 7 files changed, 87 insertions(+), 86 deletions(-) diff --git a/src/env/node/git/localGitProvider.ts b/src/env/node/git/localGitProvider.ts index 3fdf452..c3509b9 100644 --- a/src/env/node/git/localGitProvider.ts +++ b/src/env/node/git/localGitProvider.ts @@ -2917,6 +2917,12 @@ export class LocalGitProvider implements GitProvider, Disposable { return files[0]; } + @log() + async getFirstCommitSha(repoPath: string): Promise { + const data = await this.git.rev_list(repoPath, 'HEAD', { maxParents: 0 }); + return data?.[0]; + } + @gate() @debug() async getGitDir(repoPath: string): Promise { @@ -4442,12 +4448,6 @@ export class LocalGitProvider implements GitProvider, Disposable { return GitTreeParser.parse(data) ?? []; } - @log() - async getUniqueRepositoryId(repoPath: string): Promise { - const data = await this.git.rev_list(repoPath, 'HEAD', { maxParents: 0 }); - return data?.[0]; - } - @log({ args: { 1: false } }) async hasBranchOrTag( repoPath: string | undefined, diff --git a/src/git/gitProvider.ts b/src/git/gitProvider.ts index 8ad2b5c..508f976 100644 --- a/src/git/gitProvider.ts +++ b/src/git/gitProvider.ts @@ -308,6 +308,7 @@ export interface GitProvider extends Disposable { options?: { filters?: GitDiffFilter[] | undefined; similarityThreshold?: number | undefined }, ): Promise; getFileStatusForCommit(repoPath: string, uri: Uri, ref: string): Promise; + getFirstCommitSha?(repoPath: string): Promise; getGitDir?(repoPath: string): Promise; getLastFetchedTimestamp(repoPath: string): Promise; getLog( @@ -406,7 +407,6 @@ export interface GitProvider extends Disposable { ): Promise>; getTreeEntryForRevision(repoPath: string, path: string, ref: string): Promise; getTreeForRevision(repoPath: string, ref: string): Promise; - getUniqueRepositoryId(repoPath: string): Promise; hasBranchOrTag( repoPath: string | undefined, options?: { diff --git a/src/git/gitProviderService.ts b/src/git/gitProviderService.ts index ec811ed..0eb207a 100644 --- a/src/git/gitProviderService.ts +++ b/src/git/gitProviderService.ts @@ -97,8 +97,6 @@ const weightedDefaultBranches = new Map([ ['development', 1], ]); -const missingRepositoryId = '-'; - export type GitProvidersChangeEvent = { readonly added: readonly GitProvider[]; readonly removed: readonly GitProvider[]; @@ -2438,12 +2436,18 @@ export class GitProviderService implements Disposable { } @log() - async getUniqueRepositoryId(repoPath: string | Uri): Promise { + async getFirstCommitSha(repoPath: string | Uri): Promise { const { provider, path } = this.getProvider(repoPath); - const id = await provider.getUniqueRepositoryId(path); - if (id != null) return id; + try { + return await provider.getFirstCommitSha?.(path); + } catch { + return undefined; + } + } - return missingRepositoryId; + @log() + getUniqueRepositoryId(repoPath: string | Uri): Promise { + return this.getFirstCommitSha(repoPath); } @log({ args: { 1: false } }) diff --git a/src/plus/github/githubGitProvider.ts b/src/plus/github/githubGitProvider.ts index 5c73bea..c057f66 100644 --- a/src/plus/github/githubGitProvider.ts +++ b/src/plus/github/githubGitProvider.ts @@ -2771,11 +2771,6 @@ export class GitHubGitProvider implements GitProvider, Disposable { return []; } - async getUniqueRepositoryId(_repoPath: string): Promise { - // TODO@ramint implement this if there is a way. - return undefined; - } - @log() async hasBranchOrTag( repoPath: string | undefined, diff --git a/src/telemetry/usageTracker.ts b/src/telemetry/usageTracker.ts index 8981deb..6d520e6 100644 --- a/src/telemetry/usageTracker.ts +++ b/src/telemetry/usageTracker.ts @@ -11,11 +11,13 @@ export interface TrackedUsage { } export type TrackedUsageFeatures = + | 'accountView' | 'branchesView' | 'commitDetailsView' | 'commitsView' | 'contributorsView' | 'fileHistoryView' + | 'focusWebview' | 'graphDetailsView' | 'graphView' | 'graphWebview' @@ -31,9 +33,7 @@ export type TrackedUsageFeatures = | 'timelineWebview' | 'timelineView' | 'welcomeWebview' - | 'workspaceView' - | 'focusWebview' - | 'accountView'; + | 'workspaceView'; export type TrackedUsageKeys = `${TrackedUsageFeatures}:shown`; export type UsageChangeEvent = { diff --git a/src/uris/deepLinks/deepLink.ts b/src/uris/deepLinks/deepLink.ts index 4b7910d..901f32b 100644 --- a/src/uris/deepLinks/deepLink.ts +++ b/src/uris/deepLinks/deepLink.ts @@ -62,65 +62,69 @@ export function parseDeepLinkUri(uri: Uri): DeepLink | undefined { // For example, if the uri is /link/r/{repoId}/b/{branchName}?url={remoteUrl}, // the link target id is {branchName} const [, type, prefix, mainId, target, ...rest] = uri.path.split('/'); - if (type !== 'link' || (prefix !== DeepLinkType.Repository && prefix !== DeepLinkType.Workspace)) { - return undefined; - } + if (type !== 'link') return undefined; const urlParams = new URLSearchParams(uri.query); - let remoteUrl = urlParams.get('url') ?? undefined; - if (remoteUrl != null) { - remoteUrl = decodeURIComponent(remoteUrl); - } - let repoPath = urlParams.get('path') ?? undefined; - if (repoPath != null) { - repoPath = decodeURIComponent(repoPath); - } - if (!remoteUrl && !repoPath && prefix !== DeepLinkType.Workspace) return undefined; - if (prefix === DeepLinkType.Workspace) { - return { - type: DeepLinkType.Workspace, - mainId: mainId, - }; - } + switch (prefix) { + case DeepLinkType.Repository: { + let remoteUrl = urlParams.get('url') ?? undefined; + if (remoteUrl != null) { + remoteUrl = decodeURIComponent(remoteUrl); + } + let repoPath = urlParams.get('path') ?? undefined; + if (repoPath != null) { + repoPath = decodeURIComponent(repoPath); + } + if (!remoteUrl && !repoPath) return undefined; - if (target == null) { - return { - type: DeepLinkType.Repository, - mainId: mainId, - remoteUrl: remoteUrl, - repoPath: repoPath, - }; - } + if (target == null) { + return { + type: DeepLinkType.Repository, + mainId: mainId, + remoteUrl: remoteUrl, + repoPath: repoPath, + }; + } - if (rest == null || rest.length === 0) return undefined; + if (rest == null || rest.length === 0) return undefined; - let targetId: string; - let secondaryTargetId: string | undefined; - let secondaryRemoteUrl: string | undefined; - const joined = rest.join('/'); + let targetId: string; + let secondaryTargetId: string | undefined; + let secondaryRemoteUrl: string | undefined; + const joined = rest.join('/'); - if (target === DeepLinkType.Comparison) { - const split = joined.split(/(\.\.\.|\.\.)/); - if (split.length !== 3) return undefined; - targetId = split[0]; - secondaryTargetId = split[2]; - secondaryRemoteUrl = urlParams.get('prRepoUrl') ?? undefined; - if (secondaryRemoteUrl != null) { - secondaryRemoteUrl = decodeURIComponent(secondaryRemoteUrl); + if (target === DeepLinkType.Comparison) { + const split = joined.split(/(\.\.\.|\.\.)/); + if (split.length !== 3) return undefined; + targetId = split[0]; + secondaryTargetId = split[2]; + secondaryRemoteUrl = urlParams.get('prRepoUrl') ?? undefined; + if (secondaryRemoteUrl != null) { + secondaryRemoteUrl = decodeURIComponent(secondaryRemoteUrl); + } + } else { + targetId = joined; + } + + return { + type: target as DeepLinkType, + mainId: mainId, + remoteUrl: remoteUrl, + repoPath: repoPath, + targetId: targetId, + secondaryTargetId: secondaryTargetId, + secondaryRemoteUrl: secondaryRemoteUrl, + }; } - } else { - targetId = joined; - } + case DeepLinkType.Workspace: + return { + type: DeepLinkType.Workspace, + mainId: mainId, + }; - return { - type: target as DeepLinkType, - mainId: mainId, - remoteUrl: remoteUrl, - repoPath: repoPath, - targetId: targetId, - secondaryTargetId: secondaryTargetId, - secondaryRemoteUrl: secondaryRemoteUrl, - }; + default: + return undefined; + } } export const enum DeepLinkServiceState { diff --git a/src/uris/deepLinks/deepLinkService.ts b/src/uris/deepLinks/deepLinkService.ts index 3a9cfd2..cc54404 100644 --- a/src/uris/deepLinks/deepLinkService.ts +++ b/src/uris/deepLinks/deepLinkService.ts @@ -25,18 +25,18 @@ import { parseDeepLinkUri, } from './deepLink'; +const missingRepositoryId = '-'; + export class DeepLinkService implements Disposable { private readonly _disposables: Disposable[] = []; private _context: DeepLinkServiceContext; - private readonly _onDeepLinkProgressUpdated: EventEmitter; + private readonly _onDeepLinkProgressUpdated = new EventEmitter(); constructor(private readonly container: Container) { this._context = { state: DeepLinkServiceState.Idle, }; - this._onDeepLinkProgressUpdated = new EventEmitter(); - this._disposables.push( container.uri.onDidReceiveUri(async (uri: Uri) => { const link = parseDeepLinkUri(uri); @@ -426,10 +426,13 @@ export class DeepLinkService implements Disposable { return; } case DeepLinkServiceState.TypeMatch: { - if (targetType === DeepLinkType.Workspace) { - action = DeepLinkServiceAction.LinkIsWorkspaceType; - } else { - action = DeepLinkServiceAction.LinkIsRepoType; + switch (targetType) { + case DeepLinkType.Workspace: + action = DeepLinkServiceAction.LinkIsWorkspaceType; + break; + default: + action = DeepLinkServiceAction.LinkIsRepoType; + break; } break; @@ -471,7 +474,7 @@ export class DeepLinkService implements Disposable { } } - if (mainId != null && mainId !== '-') { + if (mainId != null && mainId !== missingRepositoryId) { // Repo ID can be any valid SHA in the repo, though standard practice is to use the // first commit SHA. if (await this.container.git.validateReference(repo.path, mainId)) { @@ -945,7 +948,6 @@ export class DeepLinkService implements Disposable { compareRef?: StoredNamedRef, compareWithRef?: StoredNamedRef, ): Promise { - let repoId: string | undefined; let targetType: DeepLinkType | undefined; let targetId: string | undefined; let compareWithTargetId: string | undefined; @@ -963,11 +965,7 @@ export class DeepLinkService implements Disposable { } const repoPath = typeof refOrIdOrRepoPath !== 'string' ? refOrIdOrRepoPath.repoPath : refOrIdOrRepoPath; - try { - repoId = await this.container.git.getUniqueRepositoryId(repoPath); - } catch { - repoId = '-'; - } + const repoId = (await this.container.git.getUniqueRepositoryId(repoPath)) ?? missingRepositoryId; if (typeof refOrIdOrRepoPath !== 'string') { switch (refOrIdOrRepoPath.refType) {