forked from knqyf263/pet
/
gitlab.go
162 lines (138 loc) · 4.33 KB
/
gitlab.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
package sync
import (
"context"
"fmt"
"os"
"strconv"
"time"
"github.com/briandowns/spinner"
"github.com/knqyf263/pet/config"
"github.com/pkg/errors"
"github.com/xanzy/go-gitlab"
)
const (
gitlabTokenEnvVariable = "PET_GITLAB_ACCESS_TOKEN"
)
// GitLabClient manages communication with GitLab Snippets
type GitLabClient struct {
Client *gitlab.Client
ID int
}
// NewGitLabClient returns GitLabClient
func NewGitLabClient() (Client, error) {
accessToken, err := getGitlabAccessToken()
if err != nil {
return nil, fmt.Errorf(`access_token is empty.
Go https://gitlab.com/profile/personal_access_tokens and create access_token.
Write access_token in config file (pet configure) or export $%v.
`, gitlabTokenEnvVariable)
}
client := GitLabClient{
Client: gitlab.NewClient(nil, accessToken),
ID: 0,
}
if config.Conf.GitLab.Url != "" {
client.Client.SetBaseURL(config.Conf.GitLab.Url)
}
if config.Conf.GitLab.ID == "" {
return client, nil
}
id, err := strconv.Atoi(config.Conf.GitLab.ID)
if err != nil {
return nil, errors.Wrapf(err, "Invalid GitLab Snippet ID: %d", id)
}
client.ID = id
return client, nil
}
func getGitlabAccessToken() (string, error) {
if config.Conf.GitLab.AccessToken != "" {
return config.Conf.GitLab.AccessToken, nil
} else if os.Getenv(gitlabTokenEnvVariable) != "" {
return os.Getenv(gitlabTokenEnvVariable), nil
}
return "", errors.New("GitLab AccessToken not found in any source")
}
// GetSnippet returns the remote snippet
func (g GitLabClient) GetSnippet() (*Snippet, error) {
s := spinner.New(spinner.CharSets[14], 100*time.Millisecond)
s.Start()
s.Suffix = " Getting GitLab Snippet..."
defer s.Stop()
if g.ID == 0 {
return &Snippet{}, nil
}
snippet, res, err := g.Client.Snippets.GetSnippet(g.ID)
if err != nil {
if res.StatusCode == 404 {
return nil, errors.Wrapf(err, "No GitLab Snippet ID (%d)", g.ID)
}
return nil, errors.Wrapf(err, "Failed to get GitLab Snippet (ID: %d)", g.ID)
}
filename := config.Conf.GitLab.FileName
if snippet.FileName != filename {
return nil, fmt.Errorf("No snippet file in GitLab Snippet (ID: %d)", g.ID)
}
contentByte, _, err := g.Client.Snippets.SnippetContent(g.ID)
if err != nil {
return nil, errors.Wrapf(err, "Failed to get GitLab Snippet content (ID: %d)", g.ID)
}
content := string(contentByte)
if content == "" {
return nil, fmt.Errorf("%s is empty", filename)
}
return &Snippet{
Content: content,
UpdatedAt: *snippet.UpdatedAt,
}, nil
}
// UploadSnippet uploads local snippets to GitLab Snippet
func (g GitLabClient) UploadSnippet(content string) error {
if g.ID == 0 {
id, err := g.createSnippet(context.Background(), content)
if err != nil {
return errors.Wrap(err, "Failed to create GitLab Snippet")
}
fmt.Printf("GitLab Snippet ID: %d\n", id)
} else {
if err := g.updateSnippet(context.Background(), content); err != nil {
return errors.Wrap(err, "Failed to update GitLab Snippet")
}
}
return nil
}
func (g GitLabClient) createSnippet(ctx context.Context, content string) (id int, err error) {
s := spinner.New(spinner.CharSets[14], 100*time.Millisecond)
s.Start()
s.Suffix = " Creating GitLab Snippet..."
defer s.Stop()
opt := &gitlab.CreateSnippetOptions{
Title: gitlab.String("pet-snippet"),
FileName: gitlab.String(config.Conf.GitLab.FileName),
Description: gitlab.String("Snippet file generated by pet"),
Content: gitlab.String(content),
Visibility: gitlab.Visibility(gitlab.VisibilityValue(config.Conf.GitLab.Visibility)),
}
ret, _, err := g.Client.Snippets.CreateSnippet(opt)
if err != nil {
return -1, errors.Wrap(err, "Failed to create GitLab Snippet")
}
return ret.ID, nil
}
func (g GitLabClient) updateSnippet(ctx context.Context, content string) (err error) {
s := spinner.New(spinner.CharSets[14], 100*time.Millisecond)
s.Start()
s.Suffix = " Updating GitLab Snippet..."
defer s.Stop()
opt := &gitlab.UpdateSnippetOptions{
Title: gitlab.String("pet-snippet"),
FileName: gitlab.String(config.Conf.GitLab.FileName),
Description: gitlab.String("Snippet file generated by pet"),
Content: gitlab.String(content),
Visibility: gitlab.Visibility(gitlab.VisibilityValue(config.Conf.GitLab.Visibility)),
}
_, _, err = g.Client.Snippets.UpdateSnippet(g.ID, opt)
if err != nil {
return errors.Wrap(err, "Failed to update GitLab Snippet")
}
return nil
}