diff options
Diffstat (limited to 'object/fetch/treefs.go')
| -rw-r--r-- | object/fetch/treefs.go | 45 |
1 files changed, 29 insertions, 16 deletions
diff --git a/object/fetch/treefs.go b/object/fetch/treefs.go index 6a70f98f..d12e3dd6 100644 --- a/object/fetch/treefs.go +++ b/object/fetch/treefs.go @@ -1,17 +1,16 @@ package fetch import ( + "bytes" "errors" "fmt" "io" "io/fs" - "strings" "time" oid "lindenii.org/go/furgit/object/id" "lindenii.org/go/furgit/object/tree" "lindenii.org/go/furgit/object/tree/mode" - "lindenii.org/go/lgo/intconv" ) // TreeFS exposes one Git tree as an fs.FS view backed by a Fetcher. @@ -37,12 +36,24 @@ var ( _ fs.SubFS = (*TreeFS)(nil) ) -func splitPath(path string) []string { +// ErrGitlinkNotFile reports that +// a gitlink (submodule) entry was opened or read as a file. +// It wraps [fs.ErrInvalid] so that +// generic fs consumers classify it correctly. +var ErrGitlinkNotFile = fmt.Errorf("%w: object/fetch: gitlink entries are not readable as files", fs.ErrInvalid) + +// ErrIsDirectory reports that +// a directory entry was read as a file. +// It wraps [fs.ErrInvalid] so that +// generic fs consumers classify it correctly. +var ErrIsDirectory = fmt.Errorf("%w: object/fetch: is a directory", fs.ErrInvalid) + +func splitPath(path string) [][]byte { if len(path) == 0 { return nil } - return strings.Split(path, "/") + return bytes.Split([]byte(path), []byte("/")) } type treeEntryValue struct { @@ -57,7 +68,7 @@ func (entry treeEntryValue) isDir() bool { return entry.mode == mode.Directory } -func (entry treeEntryValue) blobSize(fetcher *Fetcher) (uint64, error) { +func (entry treeEntryValue) blobSize(fetcher *Fetcher) (int, error) { return fetcher.Size(entry.objectID) } @@ -67,7 +78,7 @@ func (entry treeEntryValue) subtreeID() (oid.ObjectID, error) { } if entry.mode != mode.Directory { - return oid.ObjectID{}, fmt.Errorf("object/fetch: path %q is not a tree", entry.name) + return oid.ObjectID{}, fmt.Errorf("object/fetch: path %q is not a tree", entry.name) //nolint:err113 // Never user-visible. } return entry.objectID, nil @@ -186,7 +197,7 @@ func (treeFS *TreeFS) Open(name string) (fs.File, error) { entries := make([]fs.DirEntry, 0, len(tree.Object().Entries())) for _, child := range tree.Object().Entries() { childEntry := treeEntryValue{ - name: child.Name, + name: string(child.Name), mode: child.Mode, objectID: child.ID, treeEntry: &child, @@ -207,7 +218,7 @@ func (treeFS *TreeFS) Open(name string) (fs.File, error) { } if entry.mode == mode.Gitlink { - return nil, treeFSPathError(treeFSOpOpen, name, fmt.Errorf("object/fetch: gitlink entries are not readable as files")) + return nil, treeFSPathError(treeFSOpOpen, name, ErrGitlinkNotFile) } reader, _, err := treeFS.fetcher.ExactBlobReader(entry.objectID) @@ -292,7 +303,12 @@ func (treeFS *TreeFS) ReadDir(name string) ([]fs.DirEntry, error) { return nil, treeFSPathError(treeFSOpReadDir, name, fs.ErrInvalid) } - return readDirFile.ReadDir(-1) + entries, err := readDirFile.ReadDir(-1) + if err != nil { + return nil, treeFSPathError(treeFSOpReadDir, name, err) + } + + return entries, nil } // ReadFile reads the blob contents at name. @@ -305,11 +321,11 @@ func (treeFS *TreeFS) ReadFile(name string) ([]byte, error) { } if entry.isDir() { - return nil, treeFSPathError(treeFSOpReadFile, name, fmt.Errorf("is a directory")) + return nil, treeFSPathError(treeFSOpReadFile, name, ErrIsDirectory) } if entry.mode == mode.Gitlink { - return nil, treeFSPathError(treeFSOpReadFile, name, fmt.Errorf("object/fetch: gitlink entries are not readable as files")) + return nil, treeFSPathError(treeFSOpReadFile, name, ErrGitlinkNotFile) } reader, _, err := treeFS.fetcher.ExactBlobReader(entry.objectID) @@ -385,7 +401,7 @@ func (treeFS *TreeFS) resolvePath(op treeFSOp, name string) (treeEntryValue, err } return treeEntryValue{ - name: entry.Name, + name: string(entry.Name), mode: entry.Mode, objectID: entry.ID, treeEntry: &entry, @@ -417,10 +433,7 @@ func (treeFS *TreeFS) statEntry(entry treeEntryValue) (*treeFSInfo, error) { return nil, err } - size, err = intconv.Uint64ToInt64(sz) - if err != nil { - return nil, err - } + size = int64(sz) } var sys any |
