diff --git a/app/repo/mock.go b/app/repo/mock.go index e5dda55..1cc9cb1 100644 --- a/app/repo/mock.go +++ b/app/repo/mock.go @@ -4,13 +4,15 @@ import ( "fmt" "io" "os" - "strings" + + "github.com/go-git/go-billy/v5" + "github.com/go-git/go-billy/v5/memfs" ) type Mock struct { Files map[string]string - files map[string]string + fs billy.Filesystem inited bool } @@ -18,59 +20,71 @@ func (r *Mock) Init() error { if r.inited { return fmt.Errorf("already initialized") } - r.files = r.Files + r.fs = memfs.New() + for fname, content := range r.Files { + f, err := r.fs.Create(fname) + if err != nil { + return err + } + _, err = f.Write([]byte(content)) + if err != nil { + return err + } + + err = f.Close() + + if err != nil { + return err + } + } r.inited = true return nil } func (r *Mock) Free() { - r.inited = false - r.files = nil -} - -func (r *Mock) Open(file string) (io.ReadCloser, error) { if !r.inited { - return nil, fmt.Errorf("not initialized") - } - if content, ok := r.files[file]; ok { - return io.NopCloser(strings.NewReader(content)), nil + panic("not initialized") } - return nil, os.ErrNotExist + r.inited = false } -func (r *Mock) OpenFile(_ string, _ int, _ os.FileMode) (io.ReadWriteCloser, error) { +func (r *Mock) OpenFile(filename string, flag int, perm os.FileMode) (billy.File, error) { if !r.inited { return nil, fmt.Errorf("not initialized") } - return nil, fmt.Errorf("not implemented") + return r.fs.OpenFile(filename, flag, perm) } -func (r *Mock) OpenForAppend(file string) (io.WriteCloser, error) { - if !r.inited { - return nil, fmt.Errorf("not initialized") - } - if content, ok := r.files[file]; ok { - return &WriteCloserT{r: r, f: file, dt: []byte(content)}, nil - } - return nil, os.ErrNotExist -} -type WriteCloserT struct { - r *Mock - f string - dt []byte +func (r *Mock) Open(filename string) (billy.File, error) { + return r.OpenFile(filename, os.O_RDONLY, 0) } -func (w *WriteCloserT) Write(p []byte) (n int, err error) { - w.dt = append(w.dt, p...) - return len(p), nil +func (r *Mock) OpenForAppend(filename string) (billy.File, error) { + return r.OpenFile(filename, os.O_APPEND|os.O_WRONLY, 0600) } -func (w *WriteCloserT) Close() error { - w.r.files[w.f] = string(w.dt) - return nil -} func (r *Mock) CommitPush(_, _, _ string) error { + for fname, _ := range r.Files { + f, err := r.fs.Open(fname) + if err != nil { + return err + } + fc, err := io.ReadAll(f) + + if err != nil { + return err + } + + r.Files[fname] = string(fc) + + err = f.Close() + + if err != nil { + return err + } + } + return nil } diff --git a/app/repo/repo.go b/app/repo/repo.go index 90e8774..9aa06a1 100644 --- a/app/repo/repo.go +++ b/app/repo/repo.go @@ -2,7 +2,6 @@ package repo import ( "fmt" - "io" "log/slog" "os" "time" @@ -25,9 +24,9 @@ type Service interface { // Release the lock and free resources Free() - Open(file string) (io.ReadCloser, error) - OpenForAppend(file string) (io.WriteCloser, error) - OpenFile(file string, flag int, perm os.FileMode) (io.ReadWriteCloser, error) + OpenFile(file string, flag int, perm os.FileMode) (billy.File, error) + Open(file string) (billy.File, error) + OpenForAppend(file string) (billy.File, error) CommitPush(msg, name, email string) error } @@ -82,37 +81,27 @@ func (imr *InMemoryRepo) Free() { imr.initedMu.Unlock() } -func (imr *InMemoryRepo) Open(file string) (io.ReadCloser, error) { - if !imr.inited { - return nil, fmt.Errorf("not initialized") - } - wtr, err := imr.repo.Worktree() - if err != nil { - return nil, fmt.Errorf("worktree receiving error: %v", err) - } - return wtr.Filesystem.Open(file) +func (imr *InMemoryRepo) Open(filename string) (billy.File, error) { + return imr.OpenFile(filename, os.O_RDONLY, 0) } -type WriteCloser struct { - f *billy.File - r *InMemoryRepo - path string -} -func (w *WriteCloser) Write(p []byte) (n int, err error) { - return (*w.f).Write(p) +func (imr *InMemoryRepo) OpenForAppend(filename string) (billy.File, error) { + return imr.OpenFile(filename, os.O_APPEND|os.O_WRONLY, 0600) } -func (w *WriteCloser) Read(p []byte) (n int, err error) { - return (*w.f).Read(p) +type RepoCloser struct { + billy.File + r *InMemoryRepo + path string } -func (w *WriteCloser) Close() error { +func (w *RepoCloser) Close() error { w.r.dirtyFiles[w.path] = true - return (*w.f).Close() + return w.File.Close() } -func (imr *InMemoryRepo) OpenFile(file string, flag int, perm os.FileMode) (io.ReadWriteCloser, error) { +func (imr *InMemoryRepo) OpenFile(file string, flag int, perm os.FileMode) (billy.File, error) { if !imr.inited { return nil, fmt.Errorf("not initialized") } @@ -121,23 +110,15 @@ func (imr *InMemoryRepo) OpenFile(file string, flag int, perm os.FileMode) (io.R return nil, fmt.Errorf("worktree receiving error: %v", err) } f, err := wtr.Filesystem.OpenFile(file, flag, perm) - wc := WriteCloser{ + wc := RepoCloser{ r: imr, path: file, - f: &f, + File: f, } return &wc, err } -func (imr *InMemoryRepo) OpenForAppend(file string) (io.WriteCloser, error) { - if !imr.inited { - return nil, fmt.Errorf("not initialized") - } - return imr.OpenFile(file, os.O_APPEND|os.O_WRONLY, 0o666) -} - - func (imr *InMemoryRepo) CommitPush(msg, name, email string) error { if !imr.inited { return fmt.Errorf("not initialized")