finished, also added cobra cli
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
package walker
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"dirmd/internal/config"
|
||||
"dirmd/internal/filter"
|
||||
)
|
||||
|
||||
type Entry struct {
|
||||
RelPath string
|
||||
Size int64
|
||||
}
|
||||
|
||||
type Result struct {
|
||||
Entries []Entry
|
||||
AbsRoot string
|
||||
SingleFile bool
|
||||
}
|
||||
|
||||
func Run(cfg *config.Config) (*Result, error) {
|
||||
if cfg.SingleFile {
|
||||
return processSingleFile(cfg)
|
||||
}
|
||||
return walkDirectory(cfg)
|
||||
}
|
||||
|
||||
func processSingleFile(cfg *config.Config) (*Result, error) {
|
||||
info, err := os.Stat(cfg.AbsRoot)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot access %s: %w", cfg.AbsRoot, err)
|
||||
}
|
||||
|
||||
if info.IsDir() {
|
||||
return walkDirectory(cfg)
|
||||
}
|
||||
|
||||
flt := &filter.Filter{
|
||||
MaxSize: cfg.MaxSize,
|
||||
Extensions: cfg.Extensions,
|
||||
Ignores: cfg.Ignores,
|
||||
}
|
||||
|
||||
if flt.ShouldSkipFile(cfg.AbsRoot, filepath.Base(cfg.AbsRoot), info) {
|
||||
return nil, fmt.Errorf("file %s filtered out", cfg.AbsRoot)
|
||||
}
|
||||
|
||||
return &Result{
|
||||
Entries: []Entry{{RelPath: filepath.Base(cfg.AbsRoot), Size: info.Size()}},
|
||||
AbsRoot: filepath.Dir(cfg.AbsRoot),
|
||||
SingleFile: true,
|
||||
}, nil
|
||||
|
||||
}
|
||||
|
||||
func walkDirectory(cfg *config.Config) (*Result, error) {
|
||||
flt := &filter.Filter{
|
||||
MaxSize: cfg.MaxSize,
|
||||
Extensions: cfg.Extensions,
|
||||
Ignores: cfg.Ignores,
|
||||
}
|
||||
|
||||
result := &Result{AbsRoot: cfg.AbsRoot}
|
||||
|
||||
err := filepath.WalkDir(cfg.AbsRoot, func(path string, d fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "warning: %v\n", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
rel, err := filepath.Rel(cfg.AbsRoot, path)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
depth := strings.Count(rel, string(filepath.Separator))
|
||||
if rel != "." {
|
||||
depth++
|
||||
}
|
||||
|
||||
if depth > cfg.MaxDepth {
|
||||
if d.IsDir() {
|
||||
return filepath.SkipDir
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if filter.IsSymlink(path) {
|
||||
if d.IsDir() {
|
||||
return filepath.SkipDir
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
base := filepath.Base(path)
|
||||
|
||||
if d.IsDir() {
|
||||
if rel != "." && flt.ShouldSkipDir(base) {
|
||||
return filepath.SkipDir
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
info, err := d.Info()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "warning: cannot stat %s: %v\n", rel, err)
|
||||
return nil
|
||||
}
|
||||
|
||||
if flt.ShouldSkipFile(path, base, info) {
|
||||
return nil
|
||||
}
|
||||
|
||||
result.Entries = append(result.Entries, Entry{RelPath: rel, Size: info.Size()})
|
||||
return nil
|
||||
})
|
||||
|
||||
return result, err
|
||||
}
|
||||
Reference in New Issue
Block a user