Skip to content

Commit cfcf42a

Browse files
authored
ISSUE #166 Update GetDiffStat functionality (#171)
This commit updates the GetDiffStat functionality so that now users can add in a slice of strings named Fields in the DiffStatOptions. Using this option users can exclude or only include certain parts of the JSON response. Note, currently, given how the json decoding is although we remove the specified fields from the JSON response, they get unmarshalled as zero values for the corresponding DiffStatRes fields. Also, a test was added, but we should probably improve it by testing whether or not what we removed/selected is present accordingly.
1 parent 3b8dd11 commit cfcf42a

File tree

3 files changed

+75
-60
lines changed

3 files changed

+75
-60
lines changed

bitbucket.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,7 @@ type DiffStatOptions struct {
377377
PageNum int `json:"page"`
378378
Pagelen int `json:"pagelen"`
379379
MaxDepth int `json:"max_depth"`
380+
Fields []string
380381
}
381382

382383
type WebhooksOptions struct {

diff.go

Lines changed: 30 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,33 @@ package bitbucket
22

33
import (
44
"encoding/json"
5+
"fmt"
56
"io/ioutil"
67
"net/url"
78
"strconv"
8-
9-
"github.com/mitchellh/mapstructure"
9+
"strings"
1010
)
1111

1212
type Diff struct {
1313
c *Client
1414
}
1515

1616
type DiffStatRes struct {
17-
Page int
18-
Pagelen int
19-
MaxDepth int
20-
Size int
21-
Next string
22-
DiffStats []DiffStat
17+
Page int `json:"page,omitempty"`
18+
Pagelen int `json:"pagelen,omitempty"`
19+
Size int `json:"size,omitempty"`
20+
Next string `json:"next,omitempty"`
21+
Previous string `json:"previous,omitempty"`
22+
DiffStats []*DiffStat `json:"values,omitempty"`
2323
}
2424

2525
type DiffStat struct {
26-
Type string
27-
Status string
28-
LinesRemoved int
29-
LinedAdded int
30-
Old map[string]interface{}
31-
New map[string]interface{}
26+
Type string `json:"type,omitempty"`
27+
Status string `json:"status,omitempty"`
28+
LinesRemoved int `json:"lines_removed,omitempty"`
29+
LinedAdded int `json:"lines_added,omitempty"`
30+
Old map[string]interface{} `json:"old,omitempty"`
31+
New map[string]interface{} `json:"new,omitempty"`
3232
}
3333

3434
func (d *Diff) GetDiff(do *DiffOptions) (interface{}, error) {
@@ -72,6 +72,10 @@ func (d *Diff) GetDiffStat(dso *DiffStatOptions) (*DiffStatRes, error) {
7272
params.Add("max_depth", strconv.Itoa(dso.MaxDepth))
7373
}
7474

75+
if len(dso.Fields) > 0 {
76+
params.Add("fields", cleanFields(dso.Fields))
77+
}
78+
7579
urlStr := d.c.requestUrl("/repositories/%s/%s/diffstat/%s?%s", dso.Owner, dso.RepoSlug,
7680
dso.Spec,
7781
params.Encode())
@@ -89,54 +93,20 @@ func (d *Diff) GetDiffStat(dso *DiffStatOptions) (*DiffStatRes, error) {
8993

9094
func decodeDiffStat(diffStatResponseStr string) (*DiffStatRes, error) {
9195

92-
var diffStatResponseMap map[string]interface{}
93-
err := json.Unmarshal([]byte(diffStatResponseStr), &diffStatResponseMap)
94-
if err != nil {
95-
return nil, err
96-
}
97-
98-
diffStatArray := diffStatResponseMap["values"].([]interface{})
99-
var diffStatsSlice []DiffStat
100-
for _, diffStatEntry := range diffStatArray {
101-
var diffStat DiffStat
102-
err = mapstructure.Decode(diffStatEntry, &diffStat)
103-
if err == nil {
104-
diffStatsSlice = append(diffStatsSlice, diffStat)
105-
}
106-
}
107-
108-
page, ok := diffStatResponseMap["page"].(float64)
109-
if !ok {
110-
page = 0
111-
}
112-
113-
pagelen, ok := diffStatResponseMap["pagelen"].(float64)
114-
if !ok {
115-
pagelen = 0
116-
}
117-
118-
max_depth, ok := diffStatResponseMap["max_depth"].(float64)
119-
if !ok {
120-
max_depth = 0
121-
}
96+
var diffStatRes DiffStatRes
12297

123-
size, ok := diffStatResponseMap["size"].(float64)
124-
if !ok {
125-
size = 0
98+
err := json.Unmarshal([]byte(diffStatResponseStr), &diffStatRes)
99+
if err != nil {
100+
return nil, fmt.Errorf("DiffStat decode error: %w", err)
126101
}
127102

128-
next, ok := diffStatResponseMap["next"].(string)
129-
if !ok {
130-
next = ""
131-
}
103+
return &diffStatRes, nil
104+
}
132105

133-
diffStats := DiffStatRes{
134-
Page: int(page),
135-
Pagelen: int(pagelen),
136-
MaxDepth: int(max_depth),
137-
Size: int(size),
138-
Next: next,
139-
DiffStats: diffStatsSlice,
140-
}
141-
return &diffStats, nil
106+
// cleanFields combines all query params in the slice of field strigs into a sigle string
107+
// and removes any whitespace before returing the string.
108+
func cleanFields(fields []string) string {
109+
interS := strings.Join(fields, ",")
110+
s := strings.ReplaceAll(interS, " ", "")
111+
return s
142112
}

tests/diff_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,47 @@ func TestGetDiffStat(t *testing.T) {
7979
t.Error("Cannot get diffstat.")
8080
}
8181
}
82+
83+
func TestGetDiffStatWithFields(t *testing.T) {
84+
85+
user := os.Getenv("BITBUCKET_TEST_USERNAME")
86+
pass := os.Getenv("BITBUCKET_TEST_PASSWORD")
87+
owner := os.Getenv("BITBUCKET_TEST_OWNER")
88+
repo := os.Getenv("BITBUCKET_TEST_REPOSLUG")
89+
90+
if user == "" {
91+
t.Error("BITBUCKET_TEST_USERNAME is empty.")
92+
}
93+
94+
if pass == "" {
95+
t.Error("BITBUCKET_TEST_PASSWORD is empty.")
96+
}
97+
98+
c := bitbucket.NewBasicAuth(user, pass)
99+
100+
spec := "master..develop"
101+
102+
fields := []string{
103+
"-page",
104+
"-values.lines_removed",
105+
"-values.new",
106+
}
107+
108+
opt := &bitbucket.DiffStatOptions{
109+
Owner: owner,
110+
RepoSlug: repo,
111+
Spec: spec,
112+
Fields: fields,
113+
}
114+
115+
res, err := c.Repositories.Diff.GetDiffStat(opt)
116+
if err != nil {
117+
t.Error(err)
118+
}
119+
120+
pp.Println(res)
121+
122+
if res == nil {
123+
t.Error("Cannot get diffstat.")
124+
}
125+
}

0 commit comments

Comments
 (0)