Skip to content

Commit

Permalink
Add pagination examples for RESTClient and GQLClient
Browse files Browse the repository at this point in the history
  • Loading branch information
samcoe committed Feb 13, 2023
1 parent 98bbeb2 commit e8e82da
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 26 deletions.
109 changes: 95 additions & 14 deletions example_gh_test.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
package gh_test

import (
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"os"
"regexp"
"time"

gh "github.com/cli/go-gh"
"github.com/cli/go-gh/pkg/api"
"github.com/cli/go-gh/pkg/tableprinter"
"github.com/cli/go-gh/pkg/term"
graphql "github.com/cli/shurcooL-graphql"
"github.com/shurcooL/githubv4"
)

// Execute 'gh issue list -R cli/cli', and print the output.
Expand Down Expand Up @@ -70,29 +72,66 @@ func ExampleRESTClient_request() {
if err != nil {
log.Fatal(err)
}

// URL to cli/cli release v2.14.2 checksums.txt
assetURL := "repos/cli/cli/releases/assets/71589494"
resp, err := client.Request("GET", assetURL, nil)
response, err := client.Request(http.MethodGet, assetURL, nil)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()

defer response.Body.Close()
f, err := os.CreateTemp("", "*_checksums.txt")
if err != nil {
log.Fatal(err)
}
defer f.Close()

_, err = io.Copy(f, resp.Body)
_, err = io.Copy(f, response.Body)
if err != nil {
log.Fatal(err)
}

fmt.Printf("Asset downloaded to %s\n", f.Name())
}

// Get releases from cli/cli repository using REST API with paginated results.
func ExampleRESTClient_pagination() {
var linkRE = regexp.MustCompile(`<([^>]+)>;\s*rel="([^"]+)"`)
findNextPage := func(response *http.Response) (string, bool) {
for _, m := range linkRE.FindAllStringSubmatch(response.Header.Get("Link"), -1) {
if len(m) > 2 && m[2] == "next" {
return m[1], true
}
}
return "", false
}
client, err := gh.RESTClient(nil)
if err != nil {
log.Fatal(err)
}
requestPath := "repos/cli/cli/releases"
page := 1
hasNextPage := true
for hasNextPage {
response, err := client.Request(http.MethodGet, requestPath, nil)
if err != nil {
log.Fatal(err)
}
body, err := io.ReadAll(response.Body)
if err != nil {
log.Fatal(err)
}
if err := response.Body.Close(); err != nil {
log.Fatal(err)
}
data := []struct{ Name string }{}
if err := json.Unmarshal(body, &data); err != nil {
log.Fatal(err)
}
fmt.Printf("Page: %d\n", page)
fmt.Println(data)
requestPath, hasNextPage = findNextPage(response)
page++
}
}

// Query tags from cli/cli repository using GQL API.
func ExampleGQLClient_simple() {
client, err := gh.GQLClient(nil)
Expand Down Expand Up @@ -155,12 +194,12 @@ func ExampleGQLClient_advanced() {
}

// Add a star to the cli/go-gh repository using the GQL API.
func ExampleGQLClient_Mutate_simple() {
func ExampleGQLClient_mutate_simple() {
client, err := gh.GQLClient(nil)
if err != nil {
log.Fatal(err)
}
var m struct {
var mutation struct {
AddStar struct {
Starrable struct {
Repository struct {
Expand All @@ -172,16 +211,58 @@ func ExampleGQLClient_Mutate_simple() {
}
} `graphql:"addStar(input: $input)"`
}
type AddStarInput struct {
StarrableID string `json:"starrableId"`
}
variables := map[string]interface{}{
"input": githubv4.AddStarInput{
StarrableID: githubv4.NewID("R_kgDOF_MgQQ"),
"input": AddStarInput{
StarrableID: "R_kgDOF_MgQQ",
},
}
err = client.Mutate("AddStar", &m, variables)
err = client.Mutate("AddStar", &mutation, variables)
if err != nil {
log.Fatal(err)
}
fmt.Println(m.AddStar.Starrable.Repository.StargazerCount)
fmt.Println(mutation.AddStar.Starrable.Repository.StargazerCount)
}

// Query releases from cli/cli repository using GQL API with paginated results.
func ExampleGQLClient_pagination() {
client, err := gh.GQLClient(nil)
if err != nil {
log.Fatal(err)
}
var query struct {
Repository struct {
Releases struct {
Nodes []struct {
Name string
}
PageInfo struct {
HasNextPage bool
EndCursor string
}
} `graphql:"releases(first: 30, after: $endCursor)"`
} `graphql:"repository(owner: $owner, name: $name)"`
}
variables := map[string]interface{}{
"owner": graphql.String("cli"),
"name": graphql.String("cli"),
"endCursor": (*graphql.String)(nil),
}
page := 1
for {
if err := client.Query("RepositoryReleases", &query, variables); err != nil {
log.Fatal(err)
}
fmt.Printf("Page: %d\n", page)
fmt.Println(query.Repository.Releases.Nodes)
if !query.Repository.Releases.PageInfo.HasNextPage {
break
}
variables["endCursor"] = graphql.String(query.Repository.Releases.PageInfo.EndCursor)
page++
}
}

// Get repository for the current directory.
Expand Down
3 changes: 0 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ require (
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d
github.com/muesli/reflow v0.3.0
github.com/muesli/termenv v0.12.0
github.com/shurcooL/githubv4 v0.0.0-20221229060216-a8d4a561cc93
github.com/stretchr/testify v1.7.0
github.com/thlib/go-timezone-local v0.0.0-20210907160436-ef149e42d28e
golang.org/x/sys v0.4.0
Expand All @@ -40,10 +39,8 @@ require (
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/shurcooL/graphql v0.0.0-20220606043923-3cf50f8a0a29 // indirect
github.com/yuin/goldmark v1.4.4 // indirect
github.com/yuin/goldmark-emoji v1.0.1 // indirect
golang.org/x/net v0.5.0 // indirect
golang.org/x/oauth2 v0.4.0 // indirect
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
)
9 changes: 0 additions & 9 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E=
github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
Expand Down Expand Up @@ -66,10 +65,6 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/shurcooL/githubv4 v0.0.0-20221229060216-a8d4a561cc93 h1:JNy04upyaTaAGVlUFAL+60/1nphmJtuTu36tLhbaqXk=
github.com/shurcooL/githubv4 v0.0.0-20221229060216-a8d4a561cc93/go.mod h1:hAF0iLZy4td2EX+/8Tw+4nodhlMrwN3HupfaXj3zkGo=
github.com/shurcooL/graphql v0.0.0-20220606043923-3cf50f8a0a29 h1:B1PEwpArrNp4dkQrfxh/abbBAOZBVp0ds+fBEOUOqOc=
github.com/shurcooL/graphql v0.0.0-20220606043923-3cf50f8a0a29/go.mod h1:AuYgA5Kyo4c7HfUmvRGs/6rGlMMV/6B1bVnB9JxJEEg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
Expand All @@ -84,8 +79,6 @@ golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20220923203811-8be639271d50/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw=
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
golang.org/x/oauth2 v0.4.0 h1:NF0gk8LVPg1Ml7SSbGyySuoxdsXitj7TvgvuRxIMc/M=
golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210319071255-635bc2c9138d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand All @@ -106,8 +99,6 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down

0 comments on commit e8e82da

Please sign in to comment.