github.com/cli/cli@v1.14.1-0.20210902173923-1af6a669e342/pkg/cmd/issue/transfer/transfer.go (about) 1 package transfer 2 3 import ( 4 "context" 5 "fmt" 6 "net/http" 7 8 "github.com/cli/cli/api" 9 "github.com/cli/cli/internal/config" 10 "github.com/cli/cli/internal/ghinstance" 11 "github.com/cli/cli/internal/ghrepo" 12 "github.com/cli/cli/pkg/cmd/issue/shared" 13 "github.com/cli/cli/pkg/cmdutil" 14 "github.com/cli/cli/pkg/iostreams" 15 "github.com/shurcooL/githubv4" 16 "github.com/shurcooL/graphql" 17 "github.com/spf13/cobra" 18 ) 19 20 type TransferOptions struct { 21 HttpClient func() (*http.Client, error) 22 Config func() (config.Config, error) 23 IO *iostreams.IOStreams 24 BaseRepo func() (ghrepo.Interface, error) 25 26 IssueSelector string 27 DestRepoSelector string 28 } 29 30 func NewCmdTransfer(f *cmdutil.Factory, runF func(*TransferOptions) error) *cobra.Command { 31 opts := TransferOptions{ 32 IO: f.IOStreams, 33 HttpClient: f.HttpClient, 34 Config: f.Config, 35 } 36 37 cmd := &cobra.Command{ 38 Use: "transfer {<number> | <url>} <destination-repo>", 39 Short: "Transfer issue to another repository", 40 Args: cmdutil.ExactArgs(2, "issue and destination repository are required"), 41 RunE: func(cmd *cobra.Command, args []string) error { 42 opts.BaseRepo = f.BaseRepo 43 opts.IssueSelector = args[0] 44 opts.DestRepoSelector = args[1] 45 46 if runF != nil { 47 return runF(&opts) 48 } 49 50 return transferRun(&opts) 51 }, 52 } 53 54 return cmd 55 } 56 57 func transferRun(opts *TransferOptions) error { 58 httpClient, err := opts.HttpClient() 59 if err != nil { 60 return err 61 } 62 63 apiClient := api.NewClientFromHTTP(httpClient) 64 issue, _, err := shared.IssueFromArg(apiClient, opts.BaseRepo, opts.IssueSelector) 65 if err != nil { 66 return err 67 } 68 69 destRepo, err := ghrepo.FromFullName(opts.DestRepoSelector) 70 if err != nil { 71 return err 72 } 73 74 url, err := issueTransfer(httpClient, issue.ID, destRepo) 75 if err != nil { 76 return err 77 } 78 79 _, err = fmt.Fprintln(opts.IO.Out, url) 80 return err 81 } 82 83 func issueTransfer(httpClient *http.Client, issueID string, destRepo ghrepo.Interface) (string, error) { 84 var destinationRepoID string 85 if r, ok := destRepo.(*api.Repository); ok { 86 destinationRepoID = r.ID 87 } else { 88 apiClient := api.NewClientFromHTTP(httpClient) 89 r, err := api.GitHubRepo(apiClient, destRepo) 90 if err != nil { 91 return "", err 92 } 93 destinationRepoID = r.ID 94 } 95 96 var mutation struct { 97 TransferIssue struct { 98 Issue struct { 99 URL string 100 } 101 } `graphql:"transferIssue(input: $input)"` 102 } 103 104 variables := map[string]interface{}{ 105 "input": githubv4.TransferIssueInput{ 106 IssueID: issueID, 107 RepositoryID: destinationRepoID, 108 }, 109 } 110 111 gql := graphql.NewClient(ghinstance.GraphQLEndpoint(destRepo.RepoHost()), httpClient) 112 err := gql.MutateNamed(context.Background(), "IssueTransfer", &mutation, variables) 113 return mutation.TransferIssue.Issue.URL, err 114 }