github.com/ungtb10d/cli/v2@v2.0.0-20221110210412-98537dd9d6a1/api/queries_branch_issue_reference.go (about)

     1  package api
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/ungtb10d/cli/v2/internal/ghrepo"
     7  )
     8  
     9  type LinkedBranch struct {
    10  	ID         string
    11  	BranchName string
    12  	RepoUrl    string
    13  }
    14  
    15  // method to return url of linked branch, adds the branch name to the end of the repo url
    16  func (b *LinkedBranch) Url() string {
    17  	return fmt.Sprintf("%s/tree/%s", b.RepoUrl, b.BranchName)
    18  }
    19  
    20  func nameParam(params map[string]interface{}) string {
    21  	if params["name"] != "" {
    22  		return "name: $name,"
    23  	}
    24  	return ""
    25  }
    26  
    27  func nameArg(params map[string]interface{}) string {
    28  	if params["name"] != "" {
    29  		return "$name: String, "
    30  	}
    31  
    32  	return ""
    33  }
    34  
    35  func CreateBranchIssueReference(client *Client, repo *Repository, params map[string]interface{}) (*LinkedBranch, error) {
    36  	query := fmt.Sprintf(`
    37  		mutation CreateLinkedBranch($issueId: ID!, $oid: GitObjectID!, %[1]s$repositoryId: ID) {
    38  			createLinkedBranch(input: {
    39  			  issueId: $issueId,
    40  			  %[2]s
    41  			  oid: $oid,
    42  			  repositoryId: $repositoryId
    43  			}) {
    44  				linkedBranch {
    45  					id
    46  					ref {
    47  						name
    48  					}
    49  				}
    50  			}
    51  		}`, nameArg(params), nameParam(params))
    52  
    53  	inputParams := map[string]interface{}{
    54  		"repositoryId": repo.ID,
    55  	}
    56  	for key, val := range params {
    57  		switch key {
    58  		case "issueId", "name", "oid":
    59  			inputParams[key] = val
    60  		}
    61  	}
    62  
    63  	result := struct {
    64  		CreateLinkedBranch struct {
    65  			LinkedBranch struct {
    66  				ID  string
    67  				Ref struct {
    68  					Name string
    69  				}
    70  			}
    71  		}
    72  	}{}
    73  
    74  	err := client.GraphQL(repo.RepoHost(), query, inputParams, &result)
    75  	if err != nil {
    76  		return nil, err
    77  	}
    78  
    79  	ref := LinkedBranch{
    80  		ID:         result.CreateLinkedBranch.LinkedBranch.ID,
    81  		BranchName: result.CreateLinkedBranch.LinkedBranch.Ref.Name,
    82  	}
    83  	return &ref, nil
    84  
    85  }
    86  
    87  func ListLinkedBranches(client *Client, repo ghrepo.Interface, issueNumber int) ([]LinkedBranch, error) {
    88  	query := `
    89  	query BranchIssueReferenceListLinkedBranches($repositoryName: String!, $repositoryOwner: String!, $issueNumber: Int!) {
    90  		repository(name: $repositoryName, owner: $repositoryOwner) {
    91  			issue(number: $issueNumber) {
    92  				linkedBranches(first: 30) {
    93  					edges {
    94  						node {
    95  							ref {
    96  								name
    97  								repository {
    98  									url
    99  								}
   100  							}
   101  						}
   102  					}
   103  				}
   104  			}
   105  		}
   106  	}
   107  	`
   108  	variables := map[string]interface{}{
   109  		"repositoryName":  repo.RepoName(),
   110  		"repositoryOwner": repo.RepoOwner(),
   111  		"issueNumber":     issueNumber,
   112  	}
   113  
   114  	result := struct {
   115  		Repository struct {
   116  			Issue struct {
   117  				LinkedBranches struct {
   118  					Edges []struct {
   119  						Node struct {
   120  							Ref struct {
   121  								Name       string
   122  								Repository struct {
   123  									NameWithOwner string
   124  									Url           string
   125  								}
   126  							}
   127  						}
   128  					}
   129  				}
   130  			}
   131  		}
   132  	}{}
   133  
   134  	err := client.GraphQL(repo.RepoHost(), query, variables, &result)
   135  	var branchNames []LinkedBranch
   136  	if err != nil {
   137  		return branchNames, err
   138  	}
   139  
   140  	for _, edge := range result.Repository.Issue.LinkedBranches.Edges {
   141  		branch := LinkedBranch{
   142  			BranchName: edge.Node.Ref.Name,
   143  			RepoUrl:    edge.Node.Ref.Repository.Url,
   144  		}
   145  
   146  		branchNames = append(branchNames, branch)
   147  	}
   148  
   149  	return branchNames, nil
   150  
   151  }
   152  
   153  // introspects the schema to see if we expose the LinkedBranch type
   154  func CheckLinkedBranchFeature(client *Client, host string) (err error) {
   155  	var featureDetection struct {
   156  		Name struct {
   157  			Fields []struct {
   158  				Name string
   159  			}
   160  		} `graphql:"LinkedBranch: __type(name: \"LinkedBranch\")"`
   161  	}
   162  
   163  	err = client.Query(host, "LinkedBranch_fields", &featureDetection, nil)
   164  
   165  	if err != nil {
   166  		return err
   167  	}
   168  
   169  	if len(featureDetection.Name.Fields) == 0 {
   170  		return fmt.Errorf("the `gh issue develop` command is not currently available")
   171  	}
   172  	return nil
   173  }
   174  
   175  // This fetches the oids for the repo's default branch (`main`, etc) and the name the user might have provided in one shot.
   176  func FindBaseOid(client *Client, repo *Repository, ref string) (string, string, error) {
   177  	query := `
   178  	query BranchIssueReferenceFindBaseOid($repositoryName: String!, $repositoryOwner: String!, $ref: String!) {
   179  		repository(name: $repositoryName, owner: $repositoryOwner) {
   180  			defaultBranchRef {
   181  				target {
   182  					oid
   183  				}
   184  			}
   185  			ref(qualifiedName: $ref) {
   186  				target {
   187  					oid
   188  				}
   189  			}
   190  		}
   191  	}`
   192  
   193  	variables := map[string]interface{}{
   194  		"repositoryName":  repo.Name,
   195  		"repositoryOwner": repo.RepoOwner(),
   196  		"ref":             ref,
   197  	}
   198  
   199  	result := struct {
   200  		Repository struct {
   201  			DefaultBranchRef struct {
   202  				Target struct {
   203  					Oid string
   204  				}
   205  			}
   206  			Ref struct {
   207  				Target struct {
   208  					Oid string
   209  				}
   210  			}
   211  		}
   212  	}{}
   213  
   214  	err := client.GraphQL(repo.RepoHost(), query, variables, &result)
   215  	if err != nil {
   216  		return "", "", err
   217  	}
   218  	return result.Repository.Ref.Target.Oid, result.Repository.DefaultBranchRef.Target.Oid, nil
   219  }