2016-05-18 10:43:42 +00:00
|
|
|
// Package api provides the interface for querying LFS servers (metadata)
|
|
|
|
// NOTE: Subject to change, do not rely on this package from outside git-lfs source
|
2016-05-17 11:21:42 +00:00
|
|
|
package api
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"strconv"
|
|
|
|
|
2016-11-15 17:01:18 +00:00
|
|
|
"github.com/git-lfs/git-lfs/config"
|
|
|
|
"github.com/git-lfs/git-lfs/errors"
|
|
|
|
"github.com/git-lfs/git-lfs/httputil"
|
|
|
|
"github.com/git-lfs/git-lfs/tools"
|
2016-05-17 11:21:42 +00:00
|
|
|
|
2016-05-23 18:02:27 +00:00
|
|
|
"github.com/rubyist/tracerx"
|
2016-05-17 11:21:42 +00:00
|
|
|
)
|
|
|
|
|
2016-11-08 18:22:29 +00:00
|
|
|
// BatchSingle calls the batch API with just a single object.
|
|
|
|
func BatchSingle(cfg *config.Configuration, inobj *ObjectResource, operation string, transferAdapters []string) (obj *ObjectResource, transferAdapter string, e error) {
|
|
|
|
objs, adapterName, err := Batch(cfg, []*ObjectResource{inobj}, operation, transferAdapters)
|
2016-05-27 16:41:20 +00:00
|
|
|
if err != nil {
|
2016-06-02 11:11:45 +00:00
|
|
|
return nil, "", err
|
2016-05-27 16:41:20 +00:00
|
|
|
}
|
2016-06-02 11:11:45 +00:00
|
|
|
if len(objs) > 0 {
|
|
|
|
return objs[0], adapterName, nil
|
2016-05-27 16:41:20 +00:00
|
|
|
}
|
2016-06-02 11:11:45 +00:00
|
|
|
return nil, "", fmt.Errorf("Object not found")
|
2016-05-27 16:41:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Batch calls the batch API and returns object results
|
2016-08-09 19:18:18 +00:00
|
|
|
func Batch(cfg *config.Configuration, objects []*ObjectResource, operation string, transferAdapters []string) (objs []*ObjectResource, transferAdapter string, e error) {
|
2016-05-17 11:21:42 +00:00
|
|
|
if len(objects) == 0 {
|
2016-06-02 11:11:45 +00:00
|
|
|
return nil, "", nil
|
2016-05-17 11:21:42 +00:00
|
|
|
}
|
|
|
|
|
2016-07-22 15:37:40 +00:00
|
|
|
// Compatibility; omit transfers list when only basic
|
|
|
|
// older schemas included `additionalproperties=false`
|
|
|
|
if len(transferAdapters) == 1 && transferAdapters[0] == "basic" {
|
|
|
|
transferAdapters = nil
|
|
|
|
}
|
|
|
|
|
2016-06-02 11:11:45 +00:00
|
|
|
o := &batchRequest{Operation: operation, Objects: objects, TransferAdapterNames: transferAdapters}
|
2016-05-17 11:21:42 +00:00
|
|
|
by, err := json.Marshal(o)
|
|
|
|
if err != nil {
|
2016-08-18 21:02:21 +00:00
|
|
|
return nil, "", errors.Wrap(err, "batch request")
|
2016-05-17 11:21:42 +00:00
|
|
|
}
|
|
|
|
|
2016-08-10 17:33:48 +00:00
|
|
|
req, err := NewBatchRequest(cfg, operation)
|
2016-05-17 11:21:42 +00:00
|
|
|
if err != nil {
|
2016-08-18 21:02:21 +00:00
|
|
|
return nil, "", errors.Wrap(err, "batch request")
|
2016-05-17 11:21:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
req.Header.Set("Content-Type", MediaType)
|
|
|
|
req.Header.Set("Content-Length", strconv.Itoa(len(by)))
|
|
|
|
req.ContentLength = int64(len(by))
|
|
|
|
req.Body = tools.NewReadSeekCloserWrapper(bytes.NewReader(by))
|
|
|
|
|
|
|
|
tracerx.Printf("api: batch %d files", len(objects))
|
|
|
|
|
2016-08-10 17:33:48 +00:00
|
|
|
res, bresp, err := DoBatchRequest(cfg, req)
|
2016-05-17 11:21:42 +00:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
if res == nil {
|
2016-08-18 20:20:33 +00:00
|
|
|
return nil, "", errors.NewRetriableError(err)
|
2016-05-17 11:21:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if res.StatusCode == 0 {
|
2016-08-18 20:20:33 +00:00
|
|
|
return nil, "", errors.NewRetriableError(err)
|
2016-05-17 11:21:42 +00:00
|
|
|
}
|
|
|
|
|
2016-08-18 20:20:33 +00:00
|
|
|
if errors.IsAuthError(err) {
|
2016-07-22 00:07:23 +00:00
|
|
|
httputil.SetAuthType(cfg, req, res)
|
2016-08-09 19:18:18 +00:00
|
|
|
return Batch(cfg, objects, operation, transferAdapters)
|
2016-05-17 11:21:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
tracerx.Printf("api error: %s", err)
|
2016-08-18 21:02:21 +00:00
|
|
|
return nil, "", errors.Wrap(err, "batch response")
|
2016-05-17 11:21:42 +00:00
|
|
|
}
|
2016-07-22 00:07:23 +00:00
|
|
|
httputil.LogTransfer(cfg, "lfs.batch", res)
|
2016-05-17 11:21:42 +00:00
|
|
|
|
|
|
|
if res.StatusCode != 200 {
|
2016-08-18 21:02:21 +00:00
|
|
|
return nil, "", errors.Errorf("Invalid status for %s: %d", httputil.TraceHttpReq(req), res.StatusCode)
|
2016-05-17 11:21:42 +00:00
|
|
|
}
|
|
|
|
|
2016-06-02 11:11:45 +00:00
|
|
|
return bresp.Objects, bresp.TransferAdapterName, nil
|
2016-05-17 11:21:42 +00:00
|
|
|
}
|