diff --git a/fs/directory.go b/fs/dir.go similarity index 100% rename from fs/directory.go rename to fs/dir.go diff --git a/fs/writer.go b/fs/dir_json.go similarity index 77% rename from fs/writer.go rename to fs/dir_json.go index 63c6a0762..096aae43c 100644 --- a/fs/writer.go +++ b/fs/dir_json.go @@ -18,11 +18,6 @@ newLine = []byte("\n") ) -// Writer allows writing directories. -type Writer interface { - WriteEntry(e *Entry) error -} - type writer struct { lastEntryType EntryType objectWriter io.Writer @@ -89,15 +84,10 @@ func (w *writer) WriteEntry(e *Entry) error { return nil } -// NewWriter creates a Writer object that writes directory contents to the specified underlying writer. -func NewWriter(w io.Writer) Writer { - return &writer{ +func (dir Directory) writeJSON(w io.Writer) error { + dw := &writer{ objectWriter: w, } -} - -func WriteDir(w io.Writer, dir Directory) error { - dw := NewWriter(w) for _, d := range dir.Entries { if err := dw.WriteEntry(d); err != nil { @@ -108,25 +98,25 @@ func WriteDir(w io.Writer, dir Directory) error { return nil } -func ReadDir(r io.Reader) (Directory, error) { +func (dir *Directory) readJSON(r io.Reader) error { var err error s := bufio.NewScanner(r) if !s.Scan() { - return Directory{}, fmt.Errorf("empty file") + return fmt.Errorf("empty file") } if !bytes.Equal(s.Bytes(), header) { - return Directory{}, fmt.Errorf("invalid header: expected '%v' got '%v'", header, s.Bytes()) + return fmt.Errorf("invalid header: expected '%v' got '%v'", header, s.Bytes()) } - l := Directory{} + var entries []*Entry for s.Scan() { line := s.Bytes() var v serializedDirectoryEntryV1 if err := json.Unmarshal(line, &v); err != nil { - return Directory{}, nil + return nil } e := &Entry{} @@ -135,24 +125,26 @@ func ReadDir(r io.Reader) (Directory, error) { e.GroupID = v.GroupID e.ObjectID, err = cas.ParseObjectID(v.ObjectID) if err != nil { - return Directory{}, nil + return nil } m, err := strconv.ParseInt(v.Mode, 8, 16) if err != nil { - return Directory{}, nil + return nil } e.Mode = int16(m) e.ModTime = v.ModTime e.Type = EntryType(v.Type) if e.Type == EntryTypeFile { if v.FileSize == nil { - return Directory{}, fmt.Errorf("missing file size") + return fmt.Errorf("missing file size") } e.Size = *v.FileSize } - l.Entries = append(l.Entries, e) + entries = append(entries, e) } - return l, nil + + dir.Entries = entries + return nil } diff --git a/fs/dir_test.go b/fs/dir_test.go new file mode 100644 index 000000000..fa50a050c --- /dev/null +++ b/fs/dir_test.go @@ -0,0 +1,77 @@ +package fs + +import ( + "bytes" + "strings" + "time" + + "testing" +) + +func TestJSON(t *testing.T) { + dir := Directory{ + Entries: []*Entry{ + &Entry{ + EntryMetadata: EntryMetadata{ + Type: EntryTypeDirectory, + Name: "d1", + Mode: 0555, + ModTime: time.Unix(1458876568, 0), + }, + ObjectID: "foo", + }, + + &Entry{ + EntryMetadata: EntryMetadata{ + Type: EntryTypeDirectory, + Name: "d2", + Mode: 0754, + ModTime: time.Unix(1451871568, 0), + }, + ObjectID: "bar", + }, + + &Entry{ + EntryMetadata: EntryMetadata{ + Type: EntryTypeFile, + Name: "f1", + Mode: 0644, + ModTime: time.Unix(1451871368, 0), + Size: 123456, + }, + ObjectID: "baz", + }, + + &Entry{ + EntryMetadata: EntryMetadata{ + Type: EntryTypeFile, + Name: "f2", + Mode: 0644, + ModTime: time.Unix(1451871331, 123456789), + Size: 12, + }, + ObjectID: "qoo", + }, + }, + } + + b := bytes.NewBuffer(nil) + dir.writeJSON(b) + + assertLines( + t, + string(b.Bytes()), + "DIRECTORY:v1", + `{"name":"d1","type":"d","mode":"555","modified":"2016-03-25T03:29:28Z","objectID":"foo"}`, + `{"name":"d2","type":"d","mode":"754","modified":"2016-01-04T01:39:28Z","objectID":"bar"}`, + `{"name":"f1","type":"f","size":"123456","mode":"644","modified":"2016-01-04T01:36:08Z","objectID":"baz"}`, + `{"name":"f2","type":"f","size":"12","mode":"644","modified":"2016-01-04T01:35:31.123456789Z","objectID":"qoo"}`, + ) +} + +func assertLines(t *testing.T, text string, expectedLines ...string) { + expected := strings.Join(expectedLines, "\n") + "\n" + if text != expected { + t.Errorf("expected: '%v' got '%v'", expected, text) + } +} diff --git a/fs/upload.go b/fs/upload.go index f69273a44..6d629f201 100644 --- a/fs/upload.go +++ b/fs/upload.go @@ -60,7 +60,7 @@ func (u *uploader) UploadDir(path string, previous cas.ObjectID) (cas.ObjectID, return previous, ErrUploadCancelled } - listing, err := u.lister.List(path) + dir, err := u.lister.List(path) if err != nil { return cas.NullObjectID, err } @@ -69,15 +69,15 @@ func (u *uploader) UploadDir(path string, previous cas.ObjectID) (cas.ObjectID, if previous != "" { if r, err := u.mgr.Open(previous); err == nil { - cached, err = ReadDir(r) + err = cached.readJSON(r) if err != nil { log.Printf("WARNING: unable to cached read directory: %v", err) } } } - directoryMatchesCache := len(cached.Entries) == len(listing.Entries) - for _, e := range listing.Entries { + directoryMatchesCache := len(cached.Entries) == len(dir.Entries) + for _, e := range dir.Entries { fullPath := filepath.Join(path, e.Name) // See if we had this name during previous pass. @@ -124,7 +124,7 @@ func (u *uploader) UploadDir(path string, previous cas.ObjectID) (cas.ObjectID, ) defer writer.Close() - WriteDir(writer, listing) + dir.writeJSON(writer) return writer.Result(true) } diff --git a/fs/writer_test.go b/fs/writer_test.go deleted file mode 100644 index 83995de0b..000000000 --- a/fs/writer_test.go +++ /dev/null @@ -1,73 +0,0 @@ -package fs - -import ( - "bytes" - "strings" - "time" - - "testing" -) - -func TestWriter(t *testing.T) { - b := bytes.NewBuffer(nil) - w := NewWriter(b) - - w.WriteEntry(&Entry{ - EntryMetadata: EntryMetadata{ - Type: EntryTypeDirectory, - Name: "d1", - Mode: 0555, - ModTime: time.Unix(1458876568, 0), - }, - ObjectID: "foo", - }) - - w.WriteEntry(&Entry{ - EntryMetadata: EntryMetadata{ - Type: EntryTypeDirectory, - Name: "d2", - Mode: 0754, - ModTime: time.Unix(1451871568, 0), - }, - ObjectID: "bar", - }) - - w.WriteEntry(&Entry{ - EntryMetadata: EntryMetadata{ - Type: EntryTypeFile, - Name: "f1", - Mode: 0644, - ModTime: time.Unix(1451871368, 0), - Size: 123456, - }, - ObjectID: "baz", - }) - - w.WriteEntry(&Entry{ - EntryMetadata: EntryMetadata{ - Type: EntryTypeFile, - Name: "f2", - Mode: 0644, - ModTime: time.Unix(1451871331, 123456789), - Size: 12, - }, - ObjectID: "qoo", - }) - - assertLines( - t, - string(b.Bytes()), - "DIRECTORY:v1", - `{"name":"d1","type":"d","mode":"555","modified":"2016-03-25T03:29:28Z","objectID":"foo"}`, - `{"name":"d2","type":"d","mode":"754","modified":"2016-01-04T01:39:28Z","objectID":"bar"}`, - `{"name":"f1","type":"f","size":"123456","mode":"644","modified":"2016-01-04T01:36:08Z","objectID":"baz"}`, - `{"name":"f2","type":"f","size":"12","mode":"644","modified":"2016-01-04T01:35:31.123456789Z","objectID":"qoo"}`, - ) -} - -func assertLines(t *testing.T, text string, expectedLines ...string) { - expected := strings.Join(expectedLines, "\n") + "\n" - if text != expected { - t.Errorf("expected: '%v' got '%v'", expected, text) - } -}