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.

51 lines
1.5 KiB

  1. import { env, Uri } from 'vscode';
  2. import type { Container } from '../container';
  3. import { PullRequestNode } from '../views/nodes';
  4. import { Command, command, CommandContext, Commands } from './common';
  5. export interface OpenPullRequestOnRemoteCommandArgs {
  6. clipboard?: boolean;
  7. ref?: string;
  8. repoPath?: string;
  9. pr?: { url: string };
  10. }
  11. @command()
  12. export class OpenPullRequestOnRemoteCommand extends Command {
  13. constructor(private readonly container: Container) {
  14. super([Commands.OpenPullRequestOnRemote, Commands.CopyRemotePullRequestUrl]);
  15. }
  16. protected override preExecute(context: CommandContext, args?: OpenPullRequestOnRemoteCommandArgs) {
  17. if (context.type === 'viewItem' && context.node instanceof PullRequestNode) {
  18. args = {
  19. ...args,
  20. pr: { url: context.node.pullRequest.url },
  21. clipboard: context.command === Commands.CopyRemotePullRequestUrl,
  22. };
  23. }
  24. return this.execute(args);
  25. }
  26. async execute(args?: OpenPullRequestOnRemoteCommandArgs) {
  27. if (args?.pr == null) {
  28. if (args?.repoPath == null || args?.ref == null) return;
  29. const remote = await this.container.git.getRichRemoteProvider(args.repoPath);
  30. if (remote?.provider == null) return;
  31. const pr = await this.container.git.getPullRequestForCommit(args.ref, remote.provider);
  32. if (pr == null) return;
  33. args = { ...args };
  34. args.pr = pr;
  35. }
  36. if (args.clipboard) {
  37. void (await env.clipboard.writeText(args.pr.url));
  38. } else {
  39. void env.openExternal(Uri.parse(args.pr.url));
  40. }
  41. }
  42. }