-
Notifications
You must be signed in to change notification settings - Fork 234
/
content.go
146 lines (131 loc) · 4.57 KB
/
content.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
// Copyright 2017 Drone.IO Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package gitlab
import (
"context"
"encoding/base64"
"fmt"
"net/url"
"strconv"
"github.com/drone/go-scm/scm"
)
type contentService struct {
client *wrapper
}
func (s *contentService) Find(ctx context.Context, repo, path, ref string) (*scm.Content, *scm.Response, error) {
urlEncodedRef := url.QueryEscape(ref)
endpoint := fmt.Sprintf("api/v4/projects/%s/repository/files/%s?ref=%s", encode(repo), encodePath(path), urlEncodedRef)
out := new(content)
res, err := s.client.do(ctx, "GET", endpoint, nil, out)
raw, berr := base64.StdEncoding.DecodeString(out.Content)
if berr != nil {
// samples in the gitlab documentation use RawStdEncoding
// so we fallback if StdEncoding returns an error.
raw, berr = base64.RawStdEncoding.DecodeString(out.Content)
if berr != nil {
return nil, res, err
}
}
return &scm.Content{
Path: out.FilePath,
Data: raw,
Sha: out.LastCommitID,
BlobID: out.BlobID,
}, res, err
}
func (s *contentService) Create(ctx context.Context, repo, path string, params *scm.ContentParams) (*scm.Response, error) {
endpoint := fmt.Sprintf("api/v4/projects/%s/repository/files/%s", encode(repo), encodePath(path))
in := &createUpdateContent{
Branch: params.Branch,
Content: params.Data,
CommitMessage: params.Message,
Encoding: "base64",
AuthorName: params.Signature.Name,
AuthorEmail: params.Signature.Email,
}
res, err := s.client.do(ctx, "POST", endpoint, in, nil)
return res, err
}
func (s *contentService) Update(ctx context.Context, repo, path string, params *scm.ContentParams) (*scm.Response, error) {
endpoint := fmt.Sprintf("api/v4/projects/%s/repository/files/%s", encode(repo), encodePath(path))
in := &createUpdateContent{
Branch: params.Branch,
Content: params.Data,
CommitMessage: params.Message,
Encoding: "base64",
AuthorName: params.Signature.Name,
AuthorEmail: params.Signature.Email,
LastCommitID: params.Sha,
}
res, err := s.client.do(ctx, "PUT", endpoint, in, nil)
return res, err
}
func (s *contentService) Delete(ctx context.Context, repo, path string, params *scm.ContentParams) (*scm.Response, error) {
endpoint := fmt.Sprintf("api/v4/projects/%s/repository/files/%s", encode(repo), encodePath(path))
in := &createUpdateContent{
Branch: params.Branch,
CommitMessage: params.Message,
Encoding: "base64",
AuthorName: params.Signature.Name,
AuthorEmail: params.Signature.Email,
LastCommitID: params.Sha,
}
res, err := s.client.do(ctx, "DELETE", endpoint, in, nil)
return res, err
}
func (s *contentService) List(ctx context.Context, repo, path, ref string, opts scm.ListOptions) ([]*scm.ContentInfo, *scm.Response, error) {
endpoint := fmt.Sprintf("api/v4/projects/%s/repository/tree?path=%s&ref=%s&%s", encode(repo), url.QueryEscape(path), ref, encodeListOptions(opts))
out := []*object{}
res, err := s.client.do(ctx, "GET", endpoint, nil, &out)
return convertContentInfoList(out), res, err
}
type content struct {
FileName string `json:"file_name"`
FilePath string `json:"file_path"`
Size int `json:"size"`
Encoding string `json:"encoding"`
Content string `json:"content"`
Ref string `json:"ref"`
BlobID string `json:"blob_id"`
CommitID string `json:"commit_id"`
LastCommitID string `json:"last_commit_id"`
}
type createUpdateContent struct {
Branch string `json:"branch"`
Content []byte `json:"content"`
CommitMessage string `json:"commit_message"`
Encoding string `json:"encoding"`
AuthorEmail string `json:"author_email"`
AuthorName string `json:"author_name"`
LastCommitID string `json:"last_commit_id"`
}
type object struct {
Path string `json:"path"`
Mode string `json:"mode"`
}
func convertContentInfoList(from []*object) []*scm.ContentInfo {
to := []*scm.ContentInfo{}
for _, v := range from {
to = append(to, convertContentInfo(v))
}
return to
}
func convertContentInfo(from *object) *scm.ContentInfo {
to := &scm.ContentInfo{Path: from.Path}
// See the following link for supported file modes:
// https://godoc.org/gopkg.in/src-d/go-git.v4/plumbing/filemode
switch mode, _ := strconv.ParseInt(from.Mode, 8, 32); mode {
case 0100644, 0100664, 0100755:
to.Kind = scm.ContentKindFile
case 0040000:
to.Kind = scm.ContentKindDirectory
case 0120000:
to.Kind = scm.ContentKindSymlink
case 0160000:
to.Kind = scm.ContentKindGitlink
default:
to.Kind = scm.ContentKindUnsupported
}
return to
}