cli/pkg/cmd/issue/reopen/reopen.go
Mislav Marohnić f99a149eb2 Improve issue reopen re: overfetching, handling PRs
- `issue reopen` no longer fetches all issue fields and thus avoids the
  problem when loading failed due to token not having access to projects

- `issue reopen` now accepts either issue or pull number as argument.
2021-11-23 19:39:40 +01:00

107 lines
2.5 KiB
Go

package reopen
import (
"context"
"fmt"
"net/http"
"github.com/cli/cli/v2/api"
"github.com/cli/cli/v2/internal/config"
"github.com/cli/cli/v2/internal/ghinstance"
"github.com/cli/cli/v2/internal/ghrepo"
"github.com/cli/cli/v2/pkg/cmd/issue/shared"
"github.com/cli/cli/v2/pkg/cmdutil"
"github.com/cli/cli/v2/pkg/iostreams"
graphql "github.com/cli/shurcooL-graphql"
"github.com/shurcooL/githubv4"
"github.com/spf13/cobra"
)
type ReopenOptions struct {
HttpClient func() (*http.Client, error)
Config func() (config.Config, error)
IO *iostreams.IOStreams
BaseRepo func() (ghrepo.Interface, error)
SelectorArg string
}
func NewCmdReopen(f *cmdutil.Factory, runF func(*ReopenOptions) error) *cobra.Command {
opts := &ReopenOptions{
IO: f.IOStreams,
HttpClient: f.HttpClient,
Config: f.Config,
}
cmd := &cobra.Command{
Use: "reopen {<number> | <url>}",
Short: "Reopen issue",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
// support `-R, --repo` override
opts.BaseRepo = f.BaseRepo
if len(args) > 0 {
opts.SelectorArg = args[0]
}
if runF != nil {
return runF(opts)
}
return reopenRun(opts)
},
}
return cmd
}
func reopenRun(opts *ReopenOptions) error {
cs := opts.IO.ColorScheme()
httpClient, err := opts.HttpClient()
if err != nil {
return err
}
issue, baseRepo, err := shared.IssueFromArgWithFields(httpClient, opts.BaseRepo, opts.SelectorArg, []string{"id", "number", "title", "state"})
if err != nil {
return err
}
if issue.State == "OPEN" {
fmt.Fprintf(opts.IO.ErrOut, "%s Issue #%d (%s) is already open\n", cs.Yellow("!"), issue.Number, issue.Title)
return nil
}
err = apiReopen(httpClient, baseRepo, issue)
if err != nil {
return err
}
fmt.Fprintf(opts.IO.ErrOut, "%s Reopened issue #%d (%s)\n", cs.SuccessIconWithColor(cs.Green), issue.Number, issue.Title)
return nil
}
func apiReopen(httpClient *http.Client, repo ghrepo.Interface, issue *api.Issue) error {
if issue.IsPullRequest() {
return api.PullRequestReopen(httpClient, repo, issue.ID)
}
var mutation struct {
ReopenIssue struct {
Issue struct {
ID githubv4.ID
}
} `graphql:"reopenIssue(input: $input)"`
}
variables := map[string]interface{}{
"input": githubv4.ReopenIssueInput{
IssueID: issue.ID,
},
}
gql := graphql.NewClient(ghinstance.GraphQLEndpoint(repo.RepoHost()), httpClient)
return gql.MutateNamed(context.Background(), "IssueReopen", &mutation, variables)
}