1package main 2 3import ( 4 "context" 5 6 "github.com/shurcooL/githubv4" 7) 8 9var reposQuery struct { 10 User struct { 11 Login githubv4.String 12 Repositories struct { 13 TotalCount githubv4.Int 14 Edges []struct { 15 Cursor githubv4.String 16 Node struct { 17 QLRepository 18 } 19 } 20 } `graphql:"repositories(first: 100, after:$after isFork: false, ownerAffiliations: OWNER, orderBy: {field: CREATED_AT, direction: DESC})"` 21 } `graphql:"repositoryOwner(login:$username)"` 22} 23 24var repoQuery struct { 25 Repository QLRepository `graphql:"repository(owner: $owner, name: $name)"` 26} 27 28type QLRepository struct { 29 Owner struct { 30 Login githubv4.String 31 } 32 Name githubv4.String 33 NameWithOwner githubv4.String 34 URL githubv4.String 35 Description githubv4.String 36 IsPrivate githubv4.Boolean 37 ForkCount githubv4.Int 38 StargazerCount githubv4.Int 39 40 Watchers struct { 41 TotalCount githubv4.Int 42 } 43 44 BranchEntity struct { 45 Commits struct { 46 History struct { 47 TotalCount githubv4.Int 48 } 49 } `graphql:"... on Commit"` 50 } `graphql:"object(expression: \"HEAD\")"` 51 52 Releases QLRelease `graphql:"releases(first: 10, orderBy: {field: CREATED_AT, direction: DESC})"` 53} 54 55type Repo struct { 56 Owner string 57 Name string 58 NameWithOwner string 59 URL string 60 Description string 61 Stargazers int 62 Watchers int 63 Forks int 64 Commits int 65 LastRelease Release 66} 67 68func repository(owner string, name string) (Repo, error) { 69 variables := map[string]interface{}{ 70 "owner": githubv4.String(owner), 71 "name": githubv4.String(name), 72 } 73 74 if err := queryWithRetry(context.Background(), &repoQuery, variables); err != nil { 75 return Repo{}, err 76 } 77 78 repo := RepoFromQL(repoQuery.Repository) 79 if len(repoQuery.Repository.Releases.Nodes) > 0 { 80 repo.LastRelease = ReleaseFromQL(repoQuery.Repository.Releases) 81 } 82 83 return repo, nil 84} 85 86func repositories(owner string) ([]Repo, error) { 87 var after *githubv4.String 88 var repos []Repo 89 90 for { 91 variables := map[string]interface{}{ 92 "username": githubv4.String(owner), 93 "after": after, 94 } 95 96 if err := queryWithRetry(context.Background(), &reposQuery, variables); err != nil { 97 return nil, err 98 } 99 if len(reposQuery.User.Repositories.Edges) == 0 { 100 break 101 } 102 103 for _, v := range reposQuery.User.Repositories.Edges { 104 repo := RepoFromQL(v.Node.QLRepository) 105 if len(v.Node.Releases.Nodes) > 0 { 106 repo.LastRelease = ReleaseFromQL(v.Node.Releases) 107 } 108 109 repos = append(repos, repo) 110 111 after = &v.Cursor 112 } 113 } 114 115 return repos, nil 116} 117 118func RepoFromQL(repo QLRepository) Repo { 119 return Repo{ 120 Owner: string(repo.Owner.Login), 121 Name: string(repo.Name), 122 NameWithOwner: string(repo.NameWithOwner), 123 URL: string(repo.URL), 124 Description: string(repo.Description), 125 Stargazers: int(repo.StargazerCount), 126 Watchers: int(repo.Watchers.TotalCount), 127 Forks: int(repo.ForkCount), 128 Commits: int(repo.BranchEntity.Commits.History.TotalCount), 129 } 130} 131