| 
5 | 5 | 	"encoding/json"  | 
6 | 6 | 	"fmt"  | 
7 | 7 | 	"io"  | 
 | 8 | +	"io/ioutil"  | 
8 | 9 | 	"log"  | 
9 | 10 | 	"mime/multipart"  | 
10 | 11 | 	"net/http"  | 
@@ -53,6 +54,15 @@ type auth struct {  | 
53 | 54 | 	bearerToken    string  | 
54 | 55 | }  | 
55 | 56 | 
 
  | 
 | 57 | +type Response struct {  | 
 | 58 | +	Size     int           `json:"size"`  | 
 | 59 | +	Page     int           `json:"page"`  | 
 | 60 | +	Pagelen  int           `json:"pagelen"`  | 
 | 61 | +	Next     string        `json:"next"`  | 
 | 62 | +	Previous string        `json:"previous"`  | 
 | 63 | +	Values   []interface{} `json:"values"`  | 
 | 64 | +}  | 
 | 65 | + | 
56 | 66 | // Uses the Client Credentials Grant oauth2 flow to authenticate to Bitbucket  | 
57 | 67 | func NewOAuthClientCredentials(i, s string) *Client {  | 
58 | 68 | 	a := &auth{appID: i, secret: s}  | 
@@ -229,44 +239,6 @@ func (c *Client) execute(method string, urlStr string, text string) (interface{}  | 
229 | 239 | 		return nil, err  | 
230 | 240 | 	}  | 
231 | 241 | 
 
  | 
232 |  | -	//autopaginate.  | 
233 |  | -	resultMap, isMap := result.(map[string]interface{})  | 
234 |  | -	if isMap {  | 
235 |  | -		nextIn := resultMap["next"]  | 
236 |  | -		valuesIn := resultMap["values"]  | 
237 |  | -		if nextIn != nil && valuesIn != nil {  | 
238 |  | -			nextUrl := nextIn.(string)  | 
239 |  | -			if nextUrl != "" {  | 
240 |  | -				valuesSlice := valuesIn.([]interface{})  | 
241 |  | -				if valuesSlice != nil {  | 
242 |  | -					nextResult, err := c.execute(method, nextUrl, text)  | 
243 |  | -					if err != nil {  | 
244 |  | -						return nil, err  | 
245 |  | -					}  | 
246 |  | -					nextResultMap, isNextMap := nextResult.(map[string]interface{})  | 
247 |  | -					if !isNextMap {  | 
248 |  | -						return nil, fmt.Errorf("next page result is not map, it's %T", nextResult)  | 
249 |  | -					}  | 
250 |  | -					nextValuesIn := nextResultMap["values"]  | 
251 |  | -					if nextValuesIn == nil {  | 
252 |  | -						return nil, fmt.Errorf("next page result has no values")  | 
253 |  | -					}  | 
254 |  | -					nextValuesSlice, isSlice := nextValuesIn.([]interface{})  | 
255 |  | -					if !isSlice {  | 
256 |  | -						return nil, fmt.Errorf("next page result 'values' is not slice")  | 
257 |  | -					}  | 
258 |  | -					valuesSlice = append(valuesSlice, nextValuesSlice...)  | 
259 |  | -					resultMap["values"] = valuesSlice  | 
260 |  | -					delete(resultMap, "page")  | 
261 |  | -					delete(resultMap, "pagelen")  | 
262 |  | -					delete(resultMap, "max_depth")  | 
263 |  | -					delete(resultMap, "size")  | 
264 |  | -					result = resultMap  | 
265 |  | -				}  | 
266 |  | -			}  | 
267 |  | -		}  | 
268 |  | -	}  | 
269 |  | - | 
270 | 242 | 	return result, nil  | 
271 | 243 | }  | 
272 | 244 | 
 
  | 
@@ -338,12 +310,42 @@ func (c *Client) doRequest(req *http.Request, emptyResponse bool) (interface{},  | 
338 | 310 | 
 
  | 
339 | 311 | 	defer resBody.Close()  | 
340 | 312 | 
 
  | 
 | 313 | +	responseBytes, err := ioutil.ReadAll(resBody)  | 
 | 314 | +	if err != nil {  | 
 | 315 | +		return resBody, err  | 
 | 316 | +	}  | 
 | 317 | + | 
 | 318 | +	responsePaginated := &Response{}  | 
 | 319 | +	err = json.Unmarshal(responseBytes, responsePaginated)  | 
 | 320 | +	if err == nil && len(responsePaginated.Values) > 0 {  | 
 | 321 | +		var values []interface{}  | 
 | 322 | +		for {  | 
 | 323 | +			values = append(values, responsePaginated.Values...)  | 
 | 324 | +			if len(responsePaginated.Next) == 0 {  | 
 | 325 | +				break  | 
 | 326 | +			}  | 
 | 327 | +			newReq, err := http.NewRequest(req.Method, responsePaginated.Next, nil)  | 
 | 328 | +			if err != nil {  | 
 | 329 | +				return resBody, err  | 
 | 330 | +			}  | 
 | 331 | +			resp, err := c.doRawRequest(newReq, false)  | 
 | 332 | +			if err != nil {  | 
 | 333 | +				return resBody, err  | 
 | 334 | +			}  | 
 | 335 | +			json.NewDecoder(resp).Decode(responsePaginated)  | 
 | 336 | +		}  | 
 | 337 | +		responsePaginated.Values = values  | 
 | 338 | +		responseBytes, err = json.Marshal(responsePaginated)  | 
 | 339 | +		if err != nil {  | 
 | 340 | +			return resBody, err  | 
 | 341 | +		}  | 
 | 342 | +	}  | 
 | 343 | + | 
341 | 344 | 	var result interface{}  | 
342 |  | -	if err := json.NewDecoder(resBody).Decode(&result); err != nil {  | 
 | 345 | +	if err := json.Unmarshal(responseBytes, &result); err != nil {  | 
343 | 346 | 		log.Println("Could not unmarshal JSON payload, returning raw response")  | 
344 | 347 | 		return resBody, err  | 
345 | 348 | 	}  | 
346 |  | - | 
347 | 349 | 	return result, nil  | 
348 | 350 | }  | 
349 | 351 | 
 
  | 
 | 
0 commit comments