List linked branches works
This commit is contained in:
parent
8cf8a16e6a
commit
ac4fc388bf
4 changed files with 144 additions and 8 deletions
|
|
@ -1,5 +1,7 @@
|
|||
package api
|
||||
|
||||
import "github.com/cli/cli/v2/internal/ghrepo"
|
||||
|
||||
type BranchIssueReference struct {
|
||||
ID string
|
||||
BranchName string
|
||||
|
|
@ -58,6 +60,61 @@ func CreateBranchIssueReference(client *Client, repo *Repository, params map[str
|
|||
|
||||
}
|
||||
|
||||
func ListLinkedBranches(client *Client, repo ghrepo.Interface, issueNumber int) ([]string, error) {
|
||||
// query uses name and owner
|
||||
query := `
|
||||
query BranchIssueReferenceListLinkedBranches($repositoryName: String!, $repositoryOwner: String!, $issueNumber: Int!) {
|
||||
repository(name: $repositoryName, owner: $repositoryOwner) {
|
||||
issue(number: $issueNumber) {
|
||||
linkedBranches(first: 30) {
|
||||
edges {
|
||||
node {
|
||||
ref {
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
variables := map[string]interface{}{
|
||||
"repositoryName": repo.RepoName(),
|
||||
"repositoryOwner": repo.RepoOwner(),
|
||||
"issueNumber": issueNumber,
|
||||
}
|
||||
|
||||
result := struct {
|
||||
Repository struct {
|
||||
Issue struct {
|
||||
LinkedBranches struct {
|
||||
Edges []struct {
|
||||
Node struct {
|
||||
Ref struct {
|
||||
Name string
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}{}
|
||||
|
||||
err := client.GraphQL(repo.RepoHost(), query, variables, &result)
|
||||
var branchNames []string
|
||||
if err != nil {
|
||||
return branchNames, err
|
||||
}
|
||||
|
||||
for _, edge := range result.Repository.Issue.LinkedBranches.Edges {
|
||||
branchNames = append(branchNames, edge.Node.Ref.Name)
|
||||
}
|
||||
|
||||
return branchNames, nil
|
||||
|
||||
}
|
||||
|
||||
func FindBaseOid(client *Client, repo *Repository, ref string) (string, string, error) {
|
||||
query := `
|
||||
query BranchIssueReferenceFindBaseOid($repositoryName: String!, $repositoryOwner: String!, $ref: String!) {
|
||||
|
|
|
|||
|
|
@ -24,11 +24,12 @@ type DevelopOptions struct {
|
|||
BaseRepo func() (ghrepo.Interface, error)
|
||||
Remotes func() (context.Remotes, error)
|
||||
|
||||
IssueRepo string
|
||||
IssueSelector string
|
||||
Name string
|
||||
BaseBranch string
|
||||
Checkout bool
|
||||
IssueRepoSelector string
|
||||
IssueSelector string
|
||||
Name string
|
||||
BaseBranch string
|
||||
Checkout bool
|
||||
List bool
|
||||
}
|
||||
|
||||
func NewCmdDevelop(f *cmdutil.Factory, runF func(*DevelopOptions) error) *cobra.Command {
|
||||
|
|
@ -45,23 +46,28 @@ func NewCmdDevelop(f *cmdutil.Factory, runF func(*DevelopOptions) error) *cobra.
|
|||
Short: "Manage linked branches for an issue",
|
||||
Example: heredoc.Doc(`
|
||||
$ gh issue develop --list 123 # list branches for issue 123
|
||||
$ gh issue develop --issue-repo "github/cli" 123 list branches for issue 123 in repo "github/cli"
|
||||
$ gh issue develop --list --issue-repo "github/cli" 123 list branches for issue 123 in repo "github/cli"
|
||||
$ gh issue develop --list https://github.com/github/cli/issues/123 # list branches for issue 123 in repo "github/cli"
|
||||
$ gh issue develop 123 --name "my-branch" --head main
|
||||
$ gh issue develop 123 --checkout # checkout the branch for issue 123 after creating it
|
||||
`),
|
||||
Args: cmdutil.ExactArgs(1, "issue number is required"),
|
||||
Args: cmdutil.ExactArgs(1, "issue number or url is required"),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if runF != nil {
|
||||
return runF(opts)
|
||||
}
|
||||
opts.IssueSelector = args[0]
|
||||
if opts.List {
|
||||
return developRunList(opts)
|
||||
}
|
||||
return developRun(opts)
|
||||
},
|
||||
}
|
||||
fl := cmd.Flags()
|
||||
fl.StringVarP(&opts.BaseBranch, "base-branch", "b", "", "Name of the base branch")
|
||||
fl.BoolVarP(&opts.Checkout, "checkout", "c", false, "Checkout the branch after creating it")
|
||||
fl.StringVarP(&opts.IssueRepo, "issue-repo", "i", "", "Name or URL of the issue's repository")
|
||||
fl.StringVarP(&opts.IssueRepoSelector, "issue-repo", "i", "", "Name or URL of the issue's repository")
|
||||
fl.BoolVarP(&opts.List, "list", "l", false, "List branches for the issue")
|
||||
fl.StringVarP(&opts.Name, "name", "n", "", "Name of the branch to create")
|
||||
return cmd
|
||||
}
|
||||
|
|
@ -120,6 +126,58 @@ func developRun(opts *DevelopOptions) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func developRunList(opts *DevelopOptions) (err error) {
|
||||
httpClient, err := opts.HttpClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
apiClient := api.NewClientFromHTTP(httpClient)
|
||||
baseRepo, err := opts.BaseRepo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
opts.IO.StartProgressIndicator()
|
||||
var issueRepo ghrepo.Interface
|
||||
if opts.IssueRepoSelector != "" {
|
||||
issueRepo, err = ghrepo.FromFullNameWithHost(opts.IssueRepoSelector, baseRepo.RepoHost())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
targetRepo := baseRepo
|
||||
if issueRepo != nil {
|
||||
targetRepo = issueRepo
|
||||
}
|
||||
issueNumber, issueRepo, err := shared.IssueNumberAndRepoFromArg(opts.IssueSelector, targetRepo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
branches, err := api.ListLinkedBranches(apiClient, issueRepo, issueNumber)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
opts.IO.StopProgressIndicator()
|
||||
if len(branches) == 0 {
|
||||
return cmdutil.NewNoResultsError(fmt.Sprintf("no linked branches found for %s/%s#%d", issueRepo.RepoOwner(), issueRepo.RepoName(), issueNumber))
|
||||
}
|
||||
|
||||
if opts.IO.IsStdoutTTY() {
|
||||
fmt.Fprintf(opts.IO.Out, "\nShowing linked branches for %s/%s#%d\n\n", issueRepo.RepoOwner(), issueRepo.RepoName(), issueNumber)
|
||||
}
|
||||
|
||||
for _, branch := range branches {
|
||||
fmt.Fprintf(opts.IO.Out, "%s\n", branch)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func checkoutBranch(opts *DevelopOptions, baseRepo ghrepo.Interface, checkoutBranch string) (err error) {
|
||||
|
||||
remotes, err := opts.Remotes()
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ func listIssues(client *api.Client, repo ghrepo.Interface, filters prShared.Filt
|
|||
}
|
||||
|
||||
fragments := fmt.Sprintf("fragment issue on Issue {%s}", api.PullRequestGraphQL(filters.Fields))
|
||||
// TODO try to paginate like this
|
||||
query := fragments + `
|
||||
query IssueList($owner: String!, $repo: String!, $limit: Int, $endCursor: String, $states: [IssueState!] = OPEN, $assignee: String, $author: String, $mention: String) {
|
||||
repository(owner: $owner, name: $repo) {
|
||||
|
|
|
|||
|
|
@ -60,6 +60,26 @@ func issueMetadataFromURL(s string) (int, ghrepo.Interface) {
|
|||
return issueNumber, repo
|
||||
}
|
||||
|
||||
//TODO: Returns the issue number and base repo if the issue URL is provided, falling back to the
|
||||
// supplied repo if the base repo is not specified in the URL.
|
||||
func IssueNumberAndRepoFromArg(arg string, fallbackRepo ghrepo.Interface) (int, ghrepo.Interface, error) {
|
||||
issueNumber, baseRepo := issueMetadataFromURL(arg)
|
||||
|
||||
if issueNumber == 0 {
|
||||
var err error
|
||||
issueNumber, err = strconv.Atoi(strings.TrimPrefix(arg, "#"))
|
||||
if err != nil {
|
||||
return 0, nil, fmt.Errorf("invalid issue format: %q", arg)
|
||||
}
|
||||
}
|
||||
|
||||
if baseRepo == nil {
|
||||
baseRepo = fallbackRepo
|
||||
}
|
||||
|
||||
return issueNumber, baseRepo, nil
|
||||
}
|
||||
|
||||
type PartialLoadError struct {
|
||||
error
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue