Skip to content

Commit c69b646

Browse files
mfb2ktrysmt
authored andcommitted
Add file support (#65)
This commit adds the ability to list files and retrieve blobs from Bitbucket.
1 parent 85aa0d8 commit c69b646

File tree

3 files changed

+109
-12
lines changed

3 files changed

+109
-12
lines changed

bitbucket.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ type repository interface {
4545
UpdatePipelineConfig(opt RepositoryPipelineOptions) (*Pipeline, error)
4646
AddPipelineVariable(opt RepositoryPipelineVariableOptions) (*PipelineVariable, error)
4747
AddPipelineKeyPair(opt RepositoryPipelineKeyPairOptions) (*PipelineKeyPair, error)
48+
ListFiles(opt RepositoryFilesOptions) (*[]RepositoryFile, error)
49+
GetFileBlob(opt RepositoryBlobOptions) (*RepositoryBlob, error)
4850
}
4951

5052
type repositories interface {
@@ -114,6 +116,19 @@ type RepositoryOptions struct {
114116
Project string `json:"project"`
115117
}
116118

119+
type RepositoryFilesOptions struct {
120+
Owner string `json:"owner"`
121+
RepoSlug string `json:"repo_slug"`
122+
Ref string `json:"ref"`
123+
}
124+
125+
type RepositoryBlobOptions struct {
126+
Owner string `json:"owner"`
127+
RepoSlug string `json:"repo_slug"`
128+
Ref string `json:"ref"`
129+
Path string `json:"path"`
130+
}
131+
117132
type PullRequestsOptions struct {
118133
ID string `json:"id"`
119134
CommentID string `json:"comment_id"`

client.go

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,21 @@ func injectClient(a *auth) *Client {
140140
return c
141141
}
142142

143+
func (c *Client) executeRaw(method string, urlStr string, text string) ([]byte, error) {
144+
body := strings.NewReader(text)
145+
146+
req, err := http.NewRequest(method, urlStr, body)
147+
if err != nil {
148+
return nil, err
149+
}
150+
if text != "" {
151+
req.Header.Set("Content-Type", "application/json")
152+
}
153+
154+
c.authenticateRequest(req)
155+
return c.doRawRequest(req, false)
156+
}
157+
143158
func (c *Client) execute(method string, urlStr string, text string) (interface{}, error) {
144159
// Use pagination if changed from default value
145160
const DEC_RADIX = 10
@@ -263,7 +278,22 @@ func (c *Client) authenticateRequest(req *http.Request) {
263278
}
264279

265280
func (c *Client) doRequest(req *http.Request, emptyResponse bool) (interface{}, error) {
281+
resBodyBytes, err := c.doRawRequest(req, emptyResponse)
282+
if err != nil {
283+
return nil, err
284+
}
266285

286+
var result interface{}
287+
err = json.Unmarshal(resBodyBytes, &result)
288+
if err != nil {
289+
log.Println("Could not unmarshal JSON payload, returning raw response")
290+
return resBodyBytes, err
291+
}
292+
293+
return result, nil
294+
}
295+
296+
func (c *Client) doRawRequest(req *http.Request, emptyResponse bool) ([]byte, error) {
267297
resp, err := c.HttpClient.Do(req)
268298
if err != nil {
269299
return nil, err
@@ -284,18 +314,7 @@ func (c *Client) doRequest(req *http.Request, emptyResponse bool) (interface{},
284314
return nil, fmt.Errorf("response body is nil")
285315
}
286316

287-
resBodyBytes, err := ioutil.ReadAll(resp.Body)
288-
if err != nil {
289-
return nil, err
290-
}
291-
292-
var result interface{}
293-
err = json.Unmarshal(resBodyBytes, &result)
294-
if err != nil {
295-
return nil, err
296-
}
297-
298-
return result, nil
317+
return ioutil.ReadAll(resp.Body)
299318
}
300319

301320
func (c *Client) requestUrl(template string, args ...interface{}) string {

repository.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package bitbucket
33
import (
44
"encoding/json"
55
"os"
6+
"path"
67

78
"github.com/k0kubun/pp"
89
"github.com/mitchellh/mapstructure"
@@ -26,6 +27,20 @@ type Repository struct {
2627
Links map[string]interface{}
2728
}
2829

30+
type RepositoryFile struct {
31+
Mimetype string
32+
Links map[string]interface{}
33+
Path string
34+
Commit map[string]interface{}
35+
Attributes []string
36+
Type string
37+
Size int
38+
}
39+
40+
type RepositoryBlob struct {
41+
Content []byte
42+
}
43+
2944
type Pipeline struct {
3045
Type string
3146
Enabled bool
@@ -68,6 +83,30 @@ func (r *Repository) Get(ro *RepositoryOptions) (*Repository, error) {
6883
return decodeRepository(response)
6984
}
7085

86+
func (r *Repository) ListFiles(ro *RepositoryFilesOptions) ([]RepositoryFile, error) {
87+
filePath := path.Join("/repositories", ro.Owner, ro.RepoSlug, "src")
88+
urlStr := r.c.requestUrl(filePath)
89+
response, err := r.c.execute("GET", urlStr, "")
90+
if err != nil {
91+
return nil, err
92+
}
93+
94+
return decodeRepositoryFiles(response)
95+
}
96+
97+
func (r *Repository) GetFileBlob(ro *RepositoryBlobOptions) (*RepositoryBlob, error) {
98+
filePath := path.Join("/repositories", ro.Owner, ro.RepoSlug, "src", ro.Ref, ro.Path)
99+
urlStr := r.c.requestUrl(filePath)
100+
response, err := r.c.executeRaw("GET", urlStr, "")
101+
if err != nil {
102+
return nil, err
103+
}
104+
105+
blob := RepositoryBlob{Content: response}
106+
107+
return &blob, nil
108+
}
109+
71110
func (r *Repository) Delete(ro *RepositoryOptions) (interface{}, error) {
72111
urlStr := r.c.requestUrl("/repositories/%s/%s", ro.Owner, ro.RepoSlug)
73112
return r.c.execute("DELETE", urlStr, "")
@@ -219,6 +258,22 @@ func decodeRepository(repoResponse interface{}) (*Repository, error) {
219258
return repository, nil
220259
}
221260

261+
func decodeRepositoryFiles(repoResponse interface{}) ([]RepositoryFile, error) {
262+
repoFileMap := repoResponse.(map[string]interface{})
263+
264+
if repoFileMap["type"] == "error" {
265+
return nil, DecodeError(repoFileMap)
266+
}
267+
268+
var repositoryFiles = new([]RepositoryFile)
269+
err := mapstructure.Decode(repoFileMap["values"], repositoryFiles)
270+
if err != nil {
271+
return nil, err
272+
}
273+
274+
return *repositoryFiles, nil
275+
}
276+
222277
func decodePipelineRepository(repoResponse interface{}) (*Pipeline, error) {
223278
repoMap := repoResponse.(map[string]interface{})
224279

@@ -266,3 +321,11 @@ func decodePipelineKeyPairRepository(repoResponse interface{}) (*PipelineKeyPair
266321

267322
return pipelineKeyPair, nil
268323
}
324+
325+
func (rf RepositoryFile) String() string {
326+
return rf.Path
327+
}
328+
329+
func (rb RepositoryBlob) String() string {
330+
return string(rb.Content)
331+
}

0 commit comments

Comments
 (0)