/
hub.go
188 lines (174 loc) · 5.74 KB
/
hub.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
package hub
import (
"context"
"errors"
"fmt"
"net/http"
"net/url"
"strings"
"github.com/google/go-github/v29/github"
"github.com/kyoh86/gogh/gogh"
"golang.org/x/oauth2"
)
// New builds GitHub Client with GitHub API token that is configured.
func New(authContext context.Context, ev gogh.Env) (*Client, error) {
if host := ev.GithubHost(); host != "" && host != "github.com" {
url := fmt.Sprintf("https://%s/api/v3", host)
httpClient, err := oauth2Client(authContext, ev)
if err != nil {
return nil, err
}
client, err := github.NewEnterpriseClient(url, url, httpClient)
if err != nil {
return nil, err
}
return &Client{client}, nil
}
httpClient, err := oauth2Client(authContext, ev)
if err != nil {
return nil, err
}
return &Client{github.NewClient(httpClient)}, nil
}
func oauth2Client(authContext context.Context, ev gogh.Env) (*http.Client, error) {
token, err := GetGithubToken(ev.GithubHost(), ev.GithubUser())
if err != nil {
return nil, err
}
if token == "" {
return nil, errors.New("github.token is empty")
}
ts := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: token})
return oauth2.NewClient(authContext, ts), nil
}
type Client struct {
client *github.Client
}
// Repos will get a list of repositories for a user.
// Parameters:
// * user: Who has the repositories. Empty means the token user
// * own: Include repositories that are owned by the user
// * collaborate: Include repositories that the user has been added to as a collaborator
// * member: Include repositories that the user has access to through being a member of an organization. This includes every repository on every team that the user is on
// * archived: Include archived repositories.
// * fork: Include forked repositories.
// * visibility: Can be one of all, public, or private
// * sort: Can be one of created, updated, pushed, full_name
// * direction: Can be one of asc or desc default. Default means asc when using full_name, otherwise desc
// Returns:
// List of the url for repoisitories
func (i *Client) Repos(ctx context.Context, ev gogh.Env, user string, own, collaborate, member, fork, archived bool, visibility, sort, direction string) ([]string, error) {
/*
Build GitHub requests.
See: https://developer.github.com/v3/repos/#parameters
- affiliation string Comma-separated list of values. Can include:
- owner: Repositories that are owned by the token user.
- collaborator: Repositories that the user has been added to as a collaborator.
- organization_member: Repositories that the user has access to through being a member of an organization. This includes every repository on every team that the user is on.
*/
var affs []string
if own {
affs = append(affs, "owner")
}
if collaborate {
affs = append(affs, "collaborator")
}
if member {
affs = append(affs, "organization_member")
}
opts := &github.RepositoryListOptions{
Visibility: visibility,
Affiliation: strings.Join(affs, ","),
Sort: sort,
Direction: direction,
ListOptions: github.ListOptions{
Page: 1,
PerPage: 100,
},
}
var list []string
last := 1
for page := 1; page <= last; page++ {
opts.ListOptions.Page = page
repos, res, err := i.client.Repositories.List(ctx, user, opts)
if err != nil {
return nil, err
}
last = res.LastPage
for _, repo := range repos {
if !archived && repo.GetArchived() {
continue
}
if !fork && repo.GetFork() {
continue
}
list = append(list, repo.GetHTMLURL())
}
}
return list, nil
}
// Fork will fork a repository for yours (or for the organization).
func (i *Client) Fork(
ctx context.Context,
ev gogh.Env,
repo *gogh.Repo,
organization string,
) (result *gogh.Repo, retErr error) {
/*
Build GitHub requests.
See: https://developer.github.com/v3/repos/forks/#parameters-1
- organization string
Optional parameter to specify the organization name if forking into an organization.
*/
opts := &github.RepositoryCreateForkOptions{
Organization: organization,
}
newRepo, _, err := i.client.Repositories.CreateFork(ctx, repo.Owner(), repo.Name(), opts)
if newRepo != nil {
result, retErr = gogh.ParseRepo(ev, newRepo.GetHTMLURL())
}
if err != nil {
retErr = fmt.Errorf("creating fork: %w", err)
}
return result, retErr
}
// Create new repository.
func (i *Client) Create(
ctx context.Context,
ev gogh.Env,
repo *gogh.Repo,
description string,
homepage *url.URL,
private bool,
) (newRepo *github.Repository, retErr error) {
// Build request parameters.
// See: https://developer.github.com/v3/repos/#create
// Parameters
// - name string
// Required. The name of the repository.
// - description string
// A short description of the repository.
// - homepage string
// A URL with more information about the repository.
// - private boolean
// Either true to create a private repository or false to create a public one. Creating private repositories requires a paid GitHub account. Default: false
// - visibility string
// Can be public or private. If your organization is associated with an enterprise account using GitHub Enterprise Cloud, visibility can also be internal. For more information, see "Creating an internal repository" in the GitHub Help documentation.
// The visibility parameter overrides the private parameter when you use both parameters with the nebula-preview preview header.
name := repo.Name()
newRepo = &github.Repository{
Name: &name,
Description: &description,
Private: &private,
}
if homepage != nil {
page := homepage.String()
newRepo.Homepage = &page
}
organization := repo.Owner()
if organization == ev.GithubUser() {
organization = ""
}
newRepo, _, err := i.client.Repositories.Create(ctx, organization, newRepo)
return newRepo, err
}