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 }