You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

131 lines
5.1 KiB

  1. 'use strict';
  2. import { TextEditor, Uri } from 'vscode';
  3. import { GlyphChars } from '../constants';
  4. import { GitRemote, GitService, RemoteResource, RemoteResourceType } from '../git/gitService';
  5. import { Logger } from '../logger';
  6. import { Messages } from '../messages';
  7. import { CommandQuickPickItem, OpenRemoteCommandQuickPickItem, RemotesQuickPick } from '../quickpicks';
  8. import { Strings } from '../system';
  9. import { ActiveEditorCommand, command, Commands } from './common';
  10. export interface OpenInRemoteCommandArgs {
  11. remote?: string;
  12. remotes?: GitRemote[];
  13. resource?: RemoteResource;
  14. clipboard?: boolean;
  15. goBackCommand?: CommandQuickPickItem;
  16. }
  17. @command()
  18. export class OpenInRemoteCommand extends ActiveEditorCommand {
  19. constructor() {
  20. super(Commands.OpenInRemote);
  21. }
  22. async execute(editor: TextEditor, uri?: Uri, args: OpenInRemoteCommandArgs = {}) {
  23. args = { ...args };
  24. if (args.remotes === undefined || args.resource === undefined) return undefined;
  25. if (args.remote !== undefined) {
  26. const remotes = args.remotes.filter(r => r.name === args.remote);
  27. // Only filter if we get some results
  28. if (remotes.length > 0) {
  29. args.remotes = remotes;
  30. }
  31. }
  32. try {
  33. let remote: GitRemote | undefined;
  34. if (args.remotes.length > 1) {
  35. remote = args.remotes.find(r => r.default);
  36. }
  37. else if (args.remotes.length === 1) {
  38. remote = args.remotes[0];
  39. }
  40. if (remote != null) {
  41. this.ensureRemoteBranchName(args);
  42. const command = new OpenRemoteCommandQuickPickItem(remote, args.resource, args.clipboard);
  43. return await command.execute();
  44. }
  45. const verb = args.clipboard ? 'Copy url for' : 'Open';
  46. const suffix = args.clipboard ? `to clipboard from${GlyphChars.Ellipsis}` : `on${GlyphChars.Ellipsis}`;
  47. let placeHolder = '';
  48. switch (args.resource.type) {
  49. case RemoteResourceType.Branch:
  50. this.ensureRemoteBranchName(args);
  51. placeHolder = `${verb} ${args.resource.branch} branch ${suffix}`;
  52. break;
  53. case RemoteResourceType.Commit:
  54. placeHolder = `${verb} commit ${GitService.shortenSha(args.resource.sha)} ${suffix}`;
  55. break;
  56. case RemoteResourceType.File:
  57. placeHolder = `${verb} ${args.resource.fileName} ${suffix}`;
  58. break;
  59. case RemoteResourceType.Revision:
  60. if (args.resource.commit !== undefined && args.resource.commit.isFile) {
  61. if (args.resource.commit.status === 'D') {
  62. args.resource.sha = args.resource.commit.previousSha;
  63. placeHolder = `${verb} ${args.resource.fileName} ${Strings.pad(GlyphChars.Dot, 1, 1)} ${
  64. args.resource.commit.previousShortSha
  65. } ${suffix}`;
  66. }
  67. else {
  68. args.resource.sha = args.resource.commit.sha;
  69. placeHolder = `${verb} ${args.resource.fileName} ${Strings.pad(GlyphChars.Dot, 1, 1)} ${
  70. args.resource.commit.shortSha
  71. } ${suffix}`;
  72. }
  73. }
  74. else {
  75. const shortFileSha =
  76. args.resource.sha === undefined ? '' : GitService.shortenSha(args.resource.sha);
  77. const shaSuffix = shortFileSha ? ` ${Strings.pad(GlyphChars.Dot, 1, 1)} ${shortFileSha}` : '';
  78. placeHolder = `${verb} ${args.resource.fileName}${shaSuffix} ${suffix}`;
  79. }
  80. break;
  81. }
  82. const pick = await RemotesQuickPick.show(
  83. args.remotes,
  84. placeHolder,
  85. args.resource,
  86. args.clipboard,
  87. args.goBackCommand
  88. );
  89. if (pick === undefined) return undefined;
  90. return await pick.execute();
  91. }
  92. catch (ex) {
  93. Logger.error(ex, 'OpenInRemoteCommand');
  94. return Messages.showGenericErrorMessage('Unable to open in remote provider');
  95. }
  96. }
  97. private ensureRemoteBranchName(args: OpenInRemoteCommandArgs) {
  98. if (
  99. args.remotes === undefined ||
  100. args.resource === undefined ||
  101. args.resource.type !== RemoteResourceType.Branch
  102. ) {
  103. return;
  104. }
  105. // Check to see if the remote is in the branch
  106. const [remotePart, branchPart] = Strings.splitSingle(args.resource.branch, '/');
  107. if (branchPart === undefined) return;
  108. const remote = args.remotes.find(r => r.name === remotePart);
  109. if (remote === undefined) return;
  110. args.resource.branch = branchPart;
  111. args.remotes = [remote];
  112. }
  113. }