diff --git a/hashing/hashing_test.go b/hashing/hashing_test.go index 67a8e8676..c04b19967 100644 --- a/hashing/hashing_test.go +++ b/hashing/hashing_test.go @@ -24,7 +24,7 @@ var _ = Describe("Hashing", func() { {sha1.New, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "84983e441c3bd26ebaae4aa1f95129e5e54670f1"}, } - var _ = Describe("Reader", func() { + Describe("Reader", func() { Context("Static Strings", func() { It("Should compute digest", func() { for _, t := range static_tests { @@ -47,9 +47,13 @@ var _ = Describe("Hashing", func() { } }) }) + + Context("Random Strings", func() { + + }) }) - var _ = Describe("Writer", func() { + Describe("Writer", func() { Context("Static Strings", func() { It("Should compute digest", func() { for _, t := range static_tests { @@ -59,7 +63,7 @@ var _ = Describe("Hashing", func() { n, err := w.Write([]byte(t.text)) if n != len(t.text) { - Fail("not enough bytes read") + Fail("not enough bytes written") } if err != nil { diff --git a/storage/storage.go b/storage/storage.go index eb44ef210..359d68c65 100644 --- a/storage/storage.go +++ b/storage/storage.go @@ -27,6 +27,7 @@ type Repository interface { PutFile(path string) (ID, error) Get(ID) (io.Reader, error) Test(ID) (bool, error) + Remove(ID) error Link(name string, id ID) error Unlink(name string) error Resolve(name string) (ID, error) @@ -184,6 +185,11 @@ func (r *Dir) Get(id ID) (io.Reader, error) { return file, nil } +// Remove removes the content stored at ID. +func (r *Dir) Remove(id ID) error { + return os.Remove(path.Join(r.path, objectPath, id.String())) +} + // Unlink removes a named ID. func (r *Dir) Unlink(name string) error { return os.Remove(path.Join(r.path, refPath, Name(name).Encode())) @@ -208,7 +214,7 @@ func (r *Dir) Link(name string, id ID) error { return err } - f.Write(id) + f.Write([]byte(hex.EncodeToString(id))) return nil } @@ -220,12 +226,20 @@ func (r *Dir) Resolve(name string) (ID, error) { return nil, err } - id := make([]byte, r.hash().Size()) - _, err = io.ReadFull(f, id) + // read hex string + l := r.hash().Size() + buf := make([]byte, l*2) + _, err = io.ReadFull(f, buf) if err != nil { return nil, err } + id := make([]byte, l) + _, err = hex.Decode(id, buf) + if err != nil { + return nil, err + } + return ID(id), nil } diff --git a/storage/storage_test.go b/storage/storage_test.go index 7bd2414bd..47488bfd9 100644 --- a/storage/storage_test.go +++ b/storage/storage_test.go @@ -91,6 +91,9 @@ var _ = Describe("Storage", func() { // remove link Expect(repo.Unlink(test.data)).NotTo(HaveOccurred()) + + // remove string + Expect(repo.Remove(id)) } }) }) diff --git a/storagetest/main.go b/storagetest/main.go new file mode 100644 index 000000000..efe63a55d --- /dev/null +++ b/storagetest/main.go @@ -0,0 +1,74 @@ +package main + +import ( + "crypto/sha256" + "io" + "log" + "os" + + "github.com/fd0/khepri/storage" +) + +func hash(filename string) (storage.ID, error) { + h := sha256.New() + f, err := os.Open(filename) + if err != nil { + return nil, err + } + + io.Copy(h, f) + return h.Sum([]byte{}), nil +} + +func main() { + repo, err := storage.NewDir("repo") + if err != nil { + log.Fatalf("error: %v", err) + } + + switch os.Args[1] { + case "add": + for _, file := range os.Args[2:] { + f, err := os.Open(file) + if err != nil { + log.Printf("error opening file %q: %v", file, err) + continue + } + id, err := repo.Put(f) + if err != nil { + log.Printf("Put() error: %v", err) + continue + } + + log.Printf("archived file %q as ID %v", file, id) + } + case "link": + file := os.Args[2] + name := os.Args[3] + + id, err := hash(file) + if err != nil { + log.Fatalf("error hashing filq %q: %v", file, err) + } + + present, err := repo.Test(id) + if err != nil { + log.Fatalf("error testing presence of id %v: %v", id, err) + } + + if !present { + log.Printf("adding file to repo as ID %v", id) + _, err = repo.PutFile(file) + if err != nil { + log.Fatalf("error adding file %q: %v", file, err) + } + } + + err = repo.Link(name, id) + if err != nil { + log.Fatalf("error linking name %q to id %v", name, id) + } + default: + log.Fatalf("unknown command: %q", os.Args[1]) + } +}