Add configurable sequence numbering command
This commit is contained in:
92
internal/sequence/traversal.go
Normal file
92
internal/sequence/traversal.go
Normal file
@@ -0,0 +1,92 @@
|
||||
package sequence
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io/fs"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/rogeecn/renamer/internal/traversal"
|
||||
)
|
||||
|
||||
type traversalCandidate struct {
|
||||
RelativePath string
|
||||
AbsolutePath string
|
||||
Stem string
|
||||
Extension string
|
||||
IsDir bool
|
||||
Depth int
|
||||
}
|
||||
|
||||
func collectTraversalCandidates(ctx context.Context, opts Options) ([]traversalCandidate, error) {
|
||||
if opts.WorkingDir == "" {
|
||||
return nil, errors.New("working directory must be provided")
|
||||
}
|
||||
|
||||
absRoot, err := filepath.Abs(opts.WorkingDir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
walker := traversal.NewWalker()
|
||||
|
||||
allowedExts := make(map[string]struct{}, len(opts.Extensions))
|
||||
for _, ext := range opts.Extensions {
|
||||
lower := strings.ToLower(ext)
|
||||
allowedExts[lower] = struct{}{}
|
||||
}
|
||||
|
||||
candidates := make([]traversalCandidate, 0)
|
||||
|
||||
emit := func(relPath string, entry fs.DirEntry, depth int) error {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
// Skip the root placeholder emitted by the walker when include dirs is true.
|
||||
if relPath == "." {
|
||||
return nil
|
||||
}
|
||||
|
||||
relSlash := filepath.ToSlash(relPath)
|
||||
absolute := filepath.Join(absRoot, relPath)
|
||||
candidate := traversalCandidate{
|
||||
RelativePath: relSlash,
|
||||
AbsolutePath: absolute,
|
||||
IsDir: entry.IsDir(),
|
||||
Depth: depth,
|
||||
}
|
||||
|
||||
if !entry.IsDir() {
|
||||
rawExt := filepath.Ext(entry.Name())
|
||||
lowerExt := strings.ToLower(rawExt)
|
||||
if len(allowedExts) > 0 {
|
||||
if _, ok := allowedExts[lowerExt]; !ok {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
candidate.Extension = rawExt
|
||||
stem := entry.Name()
|
||||
if rawExt != "" {
|
||||
stem = strings.TrimSuffix(stem, rawExt)
|
||||
}
|
||||
candidate.Stem = stem
|
||||
} else {
|
||||
candidate.Stem = entry.Name()
|
||||
}
|
||||
|
||||
candidates = append(candidates, candidate)
|
||||
return nil
|
||||
}
|
||||
|
||||
err = walker.Walk(absRoot, opts.Recursive, opts.IncludeDirectories, opts.IncludeHidden, 0, emit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return candidates, nil
|
||||
}
|
||||
Reference in New Issue
Block a user