feat: refactor relative path function for git walker

Signed-off-by: Brian McGee <brian@bmcgee.ie>
This commit is contained in:
Brian McGee 2024-07-09 19:45:38 +01:00
parent 0a8ffe0c63
commit 0953dd58f2
No known key found for this signature in database
GPG Key ID: D49016E76AD1E8C0

View File

@ -13,26 +13,26 @@ import (
)
type gitWalker struct {
root string
paths chan string
repo *git.Repository
root string
paths chan string
repo *git.Repository
relPathOffset int
}
func (g *gitWalker) Root() string {
func (g gitWalker) Root() string {
return g.root
}
func (g *gitWalker) Walk(ctx context.Context, fn WalkFunc) error {
// for quick relative paths
relPathOffset := len(g.root) + 1
relPathFn := func(path string) (relPath string) {
if len(path) >= relPathOffset {
relPath = path[relPathOffset:]
}
return
func (g gitWalker) relPath(path string) (string, error) {
// quick optimization for the majority of use cases
if len(path) >= g.relPathOffset && path[:len(g.root)] == g.root {
return path[g.relPathOffset:], nil
}
// fallback to proper relative path resolution
return filepath.Rel(g.root, path)
}
func (g gitWalker) Walk(ctx context.Context, fn WalkFunc) error {
idx, err := g.repo.Storer.Index()
if err != nil {
return fmt.Errorf("failed to open git index: %w", err)
@ -57,11 +57,21 @@ func (g *gitWalker) Walk(ctx context.Context, fn WalkFunc) error {
// stat the file
path := filepath.Join(g.root, entry.Name)
info, err := os.Lstat(path)
if err != nil {
return fmt.Errorf("failed to stat %s: %w", path, err)
}
// determine a relative path
relPath, err := g.relPath(path)
if err != nil {
return fmt.Errorf("failed to determine a relative path for %s: %w", path, err)
}
file := File{
Path: path,
RelPath: relPathFn(path),
RelPath: relPath,
Info: info,
}
@ -97,9 +107,9 @@ func (g *gitWalker) Walk(ctx context.Context, fn WalkFunc) error {
return nil
}
relPath, err := filepath.Rel(g.root, path)
relPath, err := g.relPath(path)
if err != nil {
return err
return fmt.Errorf("failed to determine a relative path for %s: %w", path, err)
}
if _, ok := cache[relPath]; !ok {
@ -109,7 +119,7 @@ func (g *gitWalker) Walk(ctx context.Context, fn WalkFunc) error {
file := File{
Path: path,
RelPath: relPathFn(path),
RelPath: relPath,
Info: info,
}
@ -125,5 +135,10 @@ func NewGit(root string, paths chan string) (Walker, error) {
if err != nil {
return nil, fmt.Errorf("failed to open git repo: %w", err)
}
return &gitWalker{root, paths, repo}, nil
return &gitWalker{
root: root,
paths: paths,
repo: repo,
relPathOffset: len(root) + 1,
}, nil
}