Move ObjectResource, ObjectError, LinkRelation to api package

This commit is contained in:
Steve Streeting 2016-05-16 12:31:23 +01:00
parent 983be18c43
commit 70c41ed1cd
8 changed files with 89 additions and 133 deletions

@ -4,7 +4,6 @@ import (
"bytes"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
@ -17,6 +16,7 @@ import (
"strconv"
"strings"
"github.com/github/git-lfs/api"
"github.com/github/git-lfs/config"
"github.com/github/git-lfs/git"
"github.com/github/git-lfs/httputil"
@ -44,59 +44,6 @@ var (
}
)
type ObjectError struct {
Code int `json:"code"`
Message string `json:"message"`
}
func (e *ObjectError) Error() string {
return fmt.Sprintf("[%d] %s", e.Code, e.Message)
}
type ObjectResource struct {
Oid string `json:"oid,omitempty"`
Size int64 `json:"size"`
Actions map[string]*linkRelation `json:"actions,omitempty"`
Links map[string]*linkRelation `json:"_links,omitempty"`
Error *ObjectError `json:"error,omitempty"`
}
func (o *ObjectResource) NewRequest(relation, method string) (*http.Request, error) {
rel, ok := o.Rel(relation)
if !ok {
if relation == "download" {
return nil, errors.New("Object not found on the server.")
}
return nil, fmt.Errorf("No %q action for this object.", relation)
}
req, err := newClientRequest(method, rel.Href, rel.Header)
if err != nil {
return nil, err
}
return req, nil
}
func (o *ObjectResource) Rel(name string) (*linkRelation, bool) {
var rel *linkRelation
var ok bool
if o.Actions != nil {
rel, ok = o.Actions[name]
} else {
rel, ok = o.Links[name]
}
return rel, ok
}
type linkRelation struct {
Href string `json:"href"`
Header map[string]string `json:"header,omitempty"`
}
type ClientError struct {
Message string `json:"message"`
DocumentationUrl string `json:"documentation_url,omitempty"`
@ -122,8 +69,8 @@ func Download(oid string, size int64) (io.ReadCloser, int64, error) {
return DownloadLegacy(oid)
}
objects := []*ObjectResource{
&ObjectResource{Oid: oid, Size: size},
objects := []*api.ObjectResource{
&api.ObjectResource{Oid: oid, Size: size},
}
objs, err := Batch(objects, "download")
@ -173,7 +120,7 @@ type byteCloser struct {
*bytes.Reader
}
func DownloadCheck(oid string) (*ObjectResource, error) {
func DownloadCheck(oid string) (*api.ObjectResource, error) {
req, err := newApiRequest("GET", oid)
if err != nil {
return nil, Error(err)
@ -193,7 +140,7 @@ func DownloadCheck(oid string) (*ObjectResource, error) {
return obj, nil
}
func DownloadObject(obj *ObjectResource) (io.ReadCloser, int64, error) {
func DownloadObject(obj *api.ObjectResource) (io.ReadCloser, int64, error) {
req, err := obj.NewRequest("download", "GET")
if err != nil {
return nil, 0, Error(err)
@ -212,7 +159,7 @@ func (b *byteCloser) Close() error {
return nil
}
func Batch(objects []*ObjectResource, operation string) ([]*ObjectResource, error) {
func Batch(objects []*api.ObjectResource, operation string) ([]*api.ObjectResource, error) {
if len(objects) == 0 {
return nil, nil
}
@ -271,7 +218,7 @@ func Batch(objects []*ObjectResource, operation string) ([]*ObjectResource, erro
return objs, nil
}
func UploadCheck(oidPath string) (*ObjectResource, error) {
func UploadCheck(oidPath string) (*api.ObjectResource, error) {
oid := filepath.Base(oidPath)
stat, err := os.Stat(oidPath)
@ -279,7 +226,7 @@ func UploadCheck(oidPath string) (*ObjectResource, error) {
return nil, Error(err)
}
reqObj := &ObjectResource{
reqObj := &api.ObjectResource{
Oid: oid,
Size: stat.Size(),
}
@ -326,7 +273,7 @@ func UploadCheck(oidPath string) (*ObjectResource, error) {
return obj, nil
}
func UploadObject(o *ObjectResource, cb progress.CopyCallback) error {
func UploadObject(o *api.ObjectResource, cb progress.CopyCallback) error {
path, err := LocalMediaPath(o.Oid)
if err != nil {
return Error(err)
@ -412,14 +359,14 @@ func UploadObject(o *ObjectResource, cb progress.CopyCallback) error {
}
// doLegacyApiRequest runs the request to the LFS legacy API.
func doLegacyApiRequest(req *http.Request) (*http.Response, *ObjectResource, error) {
func doLegacyApiRequest(req *http.Request) (*http.Response, *api.ObjectResource, error) {
via := make([]*http.Request, 0, 4)
res, err := doApiRequestWithRedirects(req, via, true)
if err != nil {
return res, nil, err
}
obj := &ObjectResource{}
obj := &api.ObjectResource{}
err = decodeApiResponse(res, obj)
if err != nil {
@ -443,7 +390,7 @@ func getOperationForHttpRequest(req *http.Request) string {
// 401, the repo will be marked as having private access and the request will be
// re-run. When the repo is marked as having private access, credentials will
// be retrieved.
func doApiBatchRequest(req *http.Request) (*http.Response, []*ObjectResource, error) {
func doApiBatchRequest(req *http.Request) (*http.Response, []*api.ObjectResource, error) {
res, err := doAPIRequest(req, config.Config.PrivateAccess(getOperationForHttpRequest(req)))
if err != nil {
@ -453,7 +400,7 @@ func doApiBatchRequest(req *http.Request) (*http.Response, []*ObjectResource, er
return res, nil, err
}
var objs map[string][]*ObjectResource
var objs map[string][]*api.ObjectResource
err = decodeApiResponse(res, &objs)
if err != nil {

@ -1,18 +1,21 @@
package lfs
import "github.com/github/git-lfs/progress"
import (
"github.com/github/git-lfs/api"
"github.com/github/git-lfs/progress"
)
// The ability to check that a file can be downloaded
type DownloadCheckable struct {
Pointer *WrappedPointer
object *ObjectResource
object *api.ObjectResource
}
func NewDownloadCheckable(p *WrappedPointer) *DownloadCheckable {
return &DownloadCheckable{Pointer: p}
}
func (d *DownloadCheckable) Check() (*ObjectResource, error) {
func (d *DownloadCheckable) Check() (*api.ObjectResource, error) {
return DownloadCheck(d.Pointer.Oid)
}
@ -22,7 +25,7 @@ func (d *DownloadCheckable) Transfer(cb progress.CopyCallback) error {
return nil
}
func (d *DownloadCheckable) Object() *ObjectResource {
func (d *DownloadCheckable) Object() *api.ObjectResource {
return d.object
}
@ -38,7 +41,7 @@ func (d *DownloadCheckable) Name() string {
return d.Pointer.Name
}
func (d *DownloadCheckable) SetObject(o *ObjectResource) {
func (d *DownloadCheckable) SetObject(o *api.ObjectResource) {
d.object = o
}

@ -11,6 +11,7 @@ import (
"strings"
"testing"
"github.com/github/git-lfs/api"
"github.com/github/git-lfs/config"
)
@ -39,11 +40,11 @@ func TestSuccessfulDownload(t *testing.T) {
t.Error("Invalid Authorization")
}
obj := &ObjectResource{
obj := &api.ObjectResource{
Oid: "oid",
Size: 4,
Actions: map[string]*linkRelation{
"download": &linkRelation{
Actions: map[string]*api.LinkRelation{
"download": &api.LinkRelation{
Href: server.URL + "/download",
Header: map[string]string{"A": "1"},
},
@ -173,11 +174,11 @@ func TestSuccessfulDownloadWithRedirects(t *testing.T) {
t.Error("Invalid Authorization")
}
obj := &ObjectResource{
obj := &api.ObjectResource{
Oid: "oid",
Size: 4,
Actions: map[string]*linkRelation{
"download": &linkRelation{
Actions: map[string]*api.LinkRelation{
"download": &api.LinkRelation{
Href: server.URL + "/download",
Header: map[string]string{"A": "1"},
},
@ -276,11 +277,11 @@ func TestSuccessfulDownloadWithAuthorization(t *testing.T) {
t.Error("Invalid Authorization")
}
obj := &ObjectResource{
obj := &api.ObjectResource{
Oid: "oid",
Size: 4,
Actions: map[string]*linkRelation{
"download": &linkRelation{
Actions: map[string]*api.LinkRelation{
"download": &api.LinkRelation{
Href: server.URL + "/download",
Header: map[string]string{
"A": "1",
@ -387,11 +388,11 @@ func TestSuccessfulDownloadFromSeparateHost(t *testing.T) {
t.Error("Invalid Authorization")
}
obj := &ObjectResource{
obj := &api.ObjectResource{
Oid: "oid",
Size: 4,
Actions: map[string]*linkRelation{
"download": &linkRelation{
Actions: map[string]*api.LinkRelation{
"download": &api.LinkRelation{
Href: server2.URL + "/download",
Header: map[string]string{"A": "1"},
},
@ -522,11 +523,11 @@ func TestSuccessfulDownloadFromSeparateRedirectedHost(t *testing.T) {
t.Error("Invalid Authorization")
}
obj := &ObjectResource{
obj := &api.ObjectResource{
Oid: "oid",
Size: 4,
Actions: map[string]*linkRelation{
"download": &linkRelation{
Actions: map[string]*api.LinkRelation{
"download": &api.LinkRelation{
Href: server3.URL + "/download",
Header: map[string]string{"A": "1"},
},
@ -656,11 +657,11 @@ func TestDownloadStorageError(t *testing.T) {
t.Error("Invalid Authorization")
}
obj := &ObjectResource{
obj := &api.ObjectResource{
Oid: "oid",
Size: 4,
Actions: map[string]*linkRelation{
"download": &linkRelation{
Actions: map[string]*api.LinkRelation{
"download": &api.LinkRelation{
Href: server.URL + "/download",
Header: map[string]string{"A": "1"},
},

@ -10,6 +10,7 @@ import (
"os"
"path/filepath"
"github.com/github/git-lfs/api"
"github.com/github/git-lfs/config"
"github.com/github/git-lfs/progress"
"github.com/github/git-lfs/vendor/_nuts/github.com/cheggaaa/pb"
@ -74,7 +75,7 @@ func PointerSmudge(writer io.Writer, ptr *Pointer, workingfile string, download
// PointerSmudgeObject uses a Pointer and ObjectResource to download the object to the
// media directory. It does not write the file to the working directory.
func PointerSmudgeObject(ptr *Pointer, obj *ObjectResource, cb progress.CopyCallback) error {
func PointerSmudgeObject(ptr *Pointer, obj *api.ObjectResource, cb progress.CopyCallback) error {
mediafile, err := LocalMediaPath(obj.Oid)
if err != nil {
return err
@ -101,7 +102,7 @@ func PointerSmudgeObject(ptr *Pointer, obj *ObjectResource, cb progress.CopyCall
return nil
}
func downloadObject(ptr *Pointer, obj *ObjectResource, mediafile string, cb progress.CopyCallback) error {
func downloadObject(ptr *Pointer, obj *api.ObjectResource, mediafile string, cb progress.CopyCallback) error {
reader, size, err := DownloadObject(obj)
if reader != nil {
defer reader.Close()

@ -4,6 +4,7 @@ import (
"sync"
"sync/atomic"
"github.com/github/git-lfs/api"
"github.com/github/git-lfs/config"
"github.com/github/git-lfs/git"
"github.com/github/git-lfs/progress"
@ -15,13 +16,13 @@ const (
)
type Transferable interface {
Check() (*ObjectResource, error)
Check() (*api.ObjectResource, error)
Transfer(progress.CopyCallback) error
Object() *ObjectResource
Object() *api.ObjectResource
Oid() string
Size() int64
Name() string
SetObject(*ObjectResource)
SetObject(*api.ObjectResource)
}
// TransferQueue provides a queue that will allow concurrent transfers.
@ -207,9 +208,9 @@ func (q *TransferQueue) batchApiRoutine() {
tracerx.Printf("tq: sending batch of size %d", len(batch))
transfers := make([]*ObjectResource, 0, len(batch))
transfers := make([]*api.ObjectResource, 0, len(batch))
for _, t := range batch {
transfers = append(transfers, &ObjectResource{Oid: t.Oid(), Size: t.Size()})
transfers = append(transfers, &api.ObjectResource{Oid: t.Oid(), Size: t.Size()})
}
objects, err := Batch(transfers, q.transferKind)

@ -5,6 +5,7 @@ import (
"os"
"path/filepath"
"github.com/github/git-lfs/api"
"github.com/github/git-lfs/config"
"github.com/github/git-lfs/progress"
)
@ -15,7 +16,7 @@ type Uploadable struct {
OidPath string
Filename string
size int64
object *ObjectResource
object *api.ObjectResource
}
// NewUploadable builds the Uploadable from the given information.
@ -40,7 +41,7 @@ func NewUploadable(oid, filename string) (*Uploadable, error) {
return &Uploadable{oid: oid, OidPath: localMediaPath, Filename: filename, size: fi.Size()}, nil
}
func (u *Uploadable) Check() (*ObjectResource, error) {
func (u *Uploadable) Check() (*api.ObjectResource, error) {
return UploadCheck(u.OidPath)
}
@ -53,7 +54,7 @@ func (u *Uploadable) Transfer(cb progress.CopyCallback) error {
return UploadObject(u.object, wcb)
}
func (u *Uploadable) Object() *ObjectResource {
func (u *Uploadable) Object() *api.ObjectResource {
return u.object
}
@ -69,7 +70,7 @@ func (u *Uploadable) Name() string {
return u.Filename
}
func (u *Uploadable) SetObject(o *ObjectResource) {
func (u *Uploadable) SetObject(o *api.ObjectResource) {
u.object = o
}

@ -12,6 +12,7 @@ import (
"strconv"
"testing"
"github.com/github/git-lfs/api"
"github.com/github/git-lfs/config"
)
@ -49,7 +50,7 @@ func TestExistingUpload(t *testing.T) {
buf := &bytes.Buffer{}
tee := io.TeeReader(r.Body, buf)
reqObj := &ObjectResource{}
reqObj := &api.ObjectResource{}
err := json.NewDecoder(tee).Decode(reqObj)
t.Logf("request header: %v", r.Header)
t.Logf("request body: %s", buf.String())
@ -65,15 +66,15 @@ func TestExistingUpload(t *testing.T) {
t.Errorf("invalid size from request: %d", reqObj.Size)
}
obj := &ObjectResource{
obj := &api.ObjectResource{
Oid: reqObj.Oid,
Size: reqObj.Size,
Actions: map[string]*linkRelation{
"upload": &linkRelation{
Actions: map[string]*api.LinkRelation{
"upload": &api.LinkRelation{
Href: server.URL + "/upload",
Header: map[string]string{"A": "1"},
},
"verify": &linkRelation{
"verify": &api.LinkRelation{
Href: server.URL + "/verify",
Header: map[string]string{"B": "2"},
},
@ -191,7 +192,7 @@ func TestUploadWithRedirect(t *testing.T) {
buf := &bytes.Buffer{}
tee := io.TeeReader(r.Body, buf)
reqObj := &ObjectResource{}
reqObj := &api.ObjectResource{}
err := json.NewDecoder(tee).Decode(reqObj)
t.Logf("request header: %v", r.Header)
t.Logf("request body: %s", buf.String())
@ -207,13 +208,13 @@ func TestUploadWithRedirect(t *testing.T) {
t.Errorf("invalid size from request: %d", reqObj.Size)
}
obj := &ObjectResource{
Actions: map[string]*linkRelation{
"upload": &linkRelation{
obj := &api.ObjectResource{
Actions: map[string]*api.LinkRelation{
"upload": &api.LinkRelation{
Href: server.URL + "/upload",
Header: map[string]string{"A": "1"},
},
"verify": &linkRelation{
"verify": &api.LinkRelation{
Href: server.URL + "/verify",
Header: map[string]string{"B": "2"},
},
@ -287,7 +288,7 @@ func TestSuccessfulUploadWithVerify(t *testing.T) {
buf := &bytes.Buffer{}
tee := io.TeeReader(r.Body, buf)
reqObj := &ObjectResource{}
reqObj := &api.ObjectResource{}
err := json.NewDecoder(tee).Decode(reqObj)
t.Logf("request header: %v", r.Header)
t.Logf("request body: %s", buf.String())
@ -303,15 +304,15 @@ func TestSuccessfulUploadWithVerify(t *testing.T) {
t.Errorf("invalid size from request: %d", reqObj.Size)
}
obj := &ObjectResource{
obj := &api.ObjectResource{
Oid: reqObj.Oid,
Size: reqObj.Size,
Actions: map[string]*linkRelation{
"upload": &linkRelation{
Actions: map[string]*api.LinkRelation{
"upload": &api.LinkRelation{
Href: server.URL + "/upload",
Header: map[string]string{"A": "1"},
},
"verify": &linkRelation{
"verify": &api.LinkRelation{
Href: server.URL + "/verify",
Header: map[string]string{"B": "2"},
},
@ -389,7 +390,7 @@ func TestSuccessfulUploadWithVerify(t *testing.T) {
buf := &bytes.Buffer{}
tee := io.TeeReader(r.Body, buf)
reqObj := &ObjectResource{}
reqObj := &api.ObjectResource{}
err := json.NewDecoder(tee).Decode(reqObj)
t.Logf("request header: %v", r.Header)
t.Logf("request body: %s", buf.String())
@ -493,7 +494,7 @@ func TestSuccessfulUploadWithoutVerify(t *testing.T) {
buf := &bytes.Buffer{}
tee := io.TeeReader(r.Body, buf)
reqObj := &ObjectResource{}
reqObj := &api.ObjectResource{}
err := json.NewDecoder(tee).Decode(reqObj)
t.Logf("request header: %v", r.Header)
t.Logf("request body: %s", buf.String())
@ -509,11 +510,11 @@ func TestSuccessfulUploadWithoutVerify(t *testing.T) {
t.Errorf("invalid size from request: %d", reqObj.Size)
}
obj := &ObjectResource{
obj := &api.ObjectResource{
Oid: reqObj.Oid,
Size: reqObj.Size,
Actions: map[string]*linkRelation{
"upload": &linkRelation{
Actions: map[string]*api.LinkRelation{
"upload": &api.LinkRelation{
Href: server.URL + "/upload",
Header: map[string]string{"A": "1"},
},
@ -684,7 +685,7 @@ func TestUploadStorageError(t *testing.T) {
buf := &bytes.Buffer{}
tee := io.TeeReader(r.Body, buf)
reqObj := &ObjectResource{}
reqObj := &api.ObjectResource{}
err := json.NewDecoder(tee).Decode(reqObj)
t.Logf("request header: %v", r.Header)
t.Logf("request body: %s", buf.String())
@ -700,15 +701,15 @@ func TestUploadStorageError(t *testing.T) {
t.Errorf("invalid size from request: %d", reqObj.Size)
}
obj := &ObjectResource{
obj := &api.ObjectResource{
Oid: reqObj.Oid,
Size: reqObj.Size,
Actions: map[string]*linkRelation{
"upload": &linkRelation{
Actions: map[string]*api.LinkRelation{
"upload": &api.LinkRelation{
Href: server.URL + "/upload",
Header: map[string]string{"A": "1"},
},
"verify": &linkRelation{
"verify": &api.LinkRelation{
Href: server.URL + "/verify",
Header: map[string]string{"B": "2"},
},
@ -804,7 +805,7 @@ func TestUploadVerifyError(t *testing.T) {
buf := &bytes.Buffer{}
tee := io.TeeReader(r.Body, buf)
reqObj := &ObjectResource{}
reqObj := &api.ObjectResource{}
err := json.NewDecoder(tee).Decode(reqObj)
t.Logf("request header: %v", r.Header)
t.Logf("request body: %s", buf.String())
@ -820,15 +821,15 @@ func TestUploadVerifyError(t *testing.T) {
t.Errorf("invalid size from request: %d", reqObj.Size)
}
obj := &ObjectResource{
obj := &api.ObjectResource{
Oid: reqObj.Oid,
Size: reqObj.Size,
Actions: map[string]*linkRelation{
"upload": &linkRelation{
Actions: map[string]*api.LinkRelation{
"upload": &api.LinkRelation{
Href: server.URL + "/upload",
Header: map[string]string{"A": "1"},
},
"verify": &linkRelation{
"verify": &api.LinkRelation{
Href: server.URL + "/verify",
Header: map[string]string{"B": "2"},
},

@ -10,6 +10,7 @@ import (
"strconv"
"strings"
"github.com/github/git-lfs/api"
"github.com/github/git-lfs/config"
"github.com/github/git-lfs/lfs"
"github.com/github/git-lfs/test"
@ -242,11 +243,11 @@ func addTest(name string, f func(oidsExist, oidsMissing []TestObject) error) {
tests = append(tests, ServerTest{Name: name, F: f})
}
func callBatchApi(op string, objs []TestObject) ([]*lfs.ObjectResource, error) {
func callBatchApi(op string, objs []TestObject) ([]*api.ObjectResource, error) {
apiobjs := make([]*lfs.ObjectResource, 0, len(objs))
apiobjs := make([]*api.ObjectResource, 0, len(objs))
for _, o := range objs {
apiobjs = append(apiobjs, &lfs.ObjectResource{Oid: o.Oid, Size: o.Size})
apiobjs = append(apiobjs, &api.ObjectResource{Oid: o.Oid, Size: o.Size})
}
return lfs.Batch(apiobjs, op)
}