'use strict'; import { TextEditor, Uri } from 'vscode'; import { GlyphChars } from '../constants'; import { GitRemote, GitService, RemoteResource, RemoteResourceType } from '../git/gitService'; import { Logger } from '../logger'; import { Messages } from '../messages'; import { CommandQuickPickItem, OpenRemoteCommandQuickPickItem, RemotesQuickPick } from '../quickpicks'; import { Strings } from '../system'; import { ActiveEditorCommand, command, Commands } from './common'; export interface OpenInRemoteCommandArgs { remote?: string; remotes?: GitRemote[]; resource?: RemoteResource; clipboard?: boolean; goBackCommand?: CommandQuickPickItem; } @command() export class OpenInRemoteCommand extends ActiveEditorCommand { constructor() { super(Commands.OpenInRemote); } async execute(editor: TextEditor, uri?: Uri, args: OpenInRemoteCommandArgs = {}) { args = { ...args }; if (args.remotes === undefined || args.resource === undefined) return undefined; if (args.remote !== undefined) { const remotes = args.remotes.filter(r => r.name === args.remote); // Only filter if we get some results if (remotes.length > 0) { args.remotes = remotes; } } try { let remote: GitRemote | undefined; if (args.remotes.length > 1) { remote = args.remotes.find(r => r.default); } else if (args.remotes.length === 1) { remote = args.remotes[0]; } if (remote != null) { this.ensureRemoteBranchName(args); const command = new OpenRemoteCommandQuickPickItem(remote, args.resource, args.clipboard); return await command.execute(); } const verb = args.clipboard ? 'Copy url for' : 'Open'; const suffix = args.clipboard ? `to clipboard from${GlyphChars.Ellipsis}` : `on${GlyphChars.Ellipsis}`; let placeHolder = ''; switch (args.resource.type) { case RemoteResourceType.Branch: this.ensureRemoteBranchName(args); placeHolder = `${verb} ${args.resource.branch} branch ${suffix}`; break; case RemoteResourceType.Commit: placeHolder = `${verb} commit ${GitService.shortenSha(args.resource.sha)} ${suffix}`; break; case RemoteResourceType.File: placeHolder = `${verb} ${args.resource.fileName} ${suffix}`; break; case RemoteResourceType.Revision: if (args.resource.commit !== undefined && args.resource.commit.isFile) { if (args.resource.commit.status === 'D') { args.resource.sha = args.resource.commit.previousSha; placeHolder = `${verb} ${args.resource.fileName} ${Strings.pad(GlyphChars.Dot, 1, 1)} ${ args.resource.commit.previousShortSha } ${suffix}`; } else { args.resource.sha = args.resource.commit.sha; placeHolder = `${verb} ${args.resource.fileName} ${Strings.pad(GlyphChars.Dot, 1, 1)} ${ args.resource.commit.shortSha } ${suffix}`; } } else { const shortFileSha = args.resource.sha === undefined ? '' : GitService.shortenSha(args.resource.sha); const shaSuffix = shortFileSha ? ` ${Strings.pad(GlyphChars.Dot, 1, 1)} ${shortFileSha}` : ''; placeHolder = `${verb} ${args.resource.fileName}${shaSuffix} ${suffix}`; } break; } const pick = await RemotesQuickPick.show( args.remotes, placeHolder, args.resource, args.clipboard, args.goBackCommand ); if (pick === undefined) return undefined; return await pick.execute(); } catch (ex) { Logger.error(ex, 'OpenInRemoteCommand'); return Messages.showGenericErrorMessage('Unable to open in remote provider'); } } private ensureRemoteBranchName(args: OpenInRemoteCommandArgs) { if ( args.remotes === undefined || args.resource === undefined || args.resource.type !== RemoteResourceType.Branch ) { return; } // Check to see if the remote is in the branch const [remotePart, branchPart] = Strings.splitSingle(args.resource.branch, '/'); if (branchPart === undefined) return; const remote = args.remotes.find(r => r.name === remotePart); if (remote === undefined) return; args.resource.branch = branchPart; args.remotes = [remote]; } }