From 3d773487ef85a05e1a8d92913f26df60f8746643 Mon Sep 17 00:00:00 2001 From: Leon Klingele Date: Sat, 14 Jan 2017 13:52:56 +0100 Subject: [PATCH] Report found files & folders while scanning --- core/file_walker.go | 13 ++++++++----- core/file_walker_test.go | 13 +++++++++++-- godu.go | 22 +++++++++++++++++++++- 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/core/file_walker.go b/core/file_walker.go index 44e75e9..728121d 100644 --- a/core/file_walker.go +++ b/core/file_walker.go @@ -40,17 +40,18 @@ func (f *File) UpdateSize() { type ReadDir func(dirname string) ([]os.FileInfo, error) -func GetSubTree(path string, parent *File, readDir ReadDir, ignoredFolders map[string]struct{}) *File { +func GetSubTree(path string, parent *File, readDir ReadDir, ignoredFolders map[string]struct{}, progress chan<- int) *File { var mutex sync.Mutex var wg sync.WaitGroup c := make(chan bool, maxConcurrentScans) - root := getSubTreeConcurrently(path, parent, readDir, ignoredFolders, c, &mutex, &wg) + root := getSubTreeConcurrently(path, parent, readDir, ignoredFolders, progress, c, &mutex, &wg) wg.Wait() + close(progress) root.UpdateSize() return root } -func getSubTreeConcurrently(path string, parent *File, readDir ReadDir, ignoredFolders map[string]struct{}, c chan bool, mutex *sync.Mutex, wg *sync.WaitGroup) *File { +func getSubTreeConcurrently(path string, parent *File, readDir ReadDir, ignoredFolders map[string]struct{}, progress chan<- int, c chan bool, mutex *sync.Mutex, wg *sync.WaitGroup) *File { result := &File{} entries, err := readDir(path) if err != nil { @@ -58,7 +59,9 @@ func getSubTreeConcurrently(path string, parent *File, readDir ReadDir, ignoredF return result } dirName, name := filepath.Split(path) - result.Files = make([]*File, 0, len(entries)) + lenEntries := len(entries) + result.Files = make([]*File, 0, lenEntries) + progress <- lenEntries for _, entry := range entries { if entry.IsDir() { if _, ignored := ignoredFolders[entry.Name()]; ignored { @@ -68,7 +71,7 @@ func getSubTreeConcurrently(path string, parent *File, readDir ReadDir, ignoredF wg.Add(1) go func() { c <- true - subFolder := getSubTreeConcurrently(subFolderPath, result, readDir, ignoredFolders, c, mutex, wg) + subFolder := getSubTreeConcurrently(subFolderPath, result, readDir, ignoredFolders, progress, c, mutex, wg) mutex.Lock() result.Files = append(result.Files, subFolder) mutex.Unlock() diff --git a/core/file_walker_test.go b/core/file_walker_test.go index f46e263..55ddacb 100644 --- a/core/file_walker_test.go +++ b/core/file_walker_test.go @@ -78,7 +78,9 @@ func TestGetSubTreeOnSimpleDir(t *testing.T) { }}, }} ignoredFolders := map[string]struct{}{"g": struct{}{}} - result := GetSubTree("b", nil, createReadDir(testStructure), ignoredFolders) + progress := make(chan int, 0) + go dummyProgressConsumer(progress) + result := GetSubTree("b", nil, createReadDir(testStructure), ignoredFolders, progress) buildExpected := func() *File { b := &File{"b", nil, 180, true, []*File{}} c := &File{"c", b, 100, false, []*File{}} @@ -105,8 +107,15 @@ func TestGetSubTreeHandlesError(t *testing.T) { failing := func(path string) ([]os.FileInfo, error) { return []os.FileInfo{}, errors.New("Not found") } - result := GetSubTree("xyz", nil, failing, map[string]struct{}{}) + progress := make(chan int, 0) + go dummyProgressConsumer(progress) + result := GetSubTree("xyz", nil, failing, map[string]struct{}{}, progress) if !reflect.DeepEqual(*result, File{}) { t.Error("GetSubTree didn't return emtpy file on ReadDir failure") } } + +func dummyProgressConsumer(progress <-chan int) { + for range progress { + } +} diff --git a/godu.go b/godu.go index d07cf70..1384d56 100644 --- a/godu.go +++ b/godu.go @@ -7,6 +7,7 @@ import ( "log" "os" "sync" + "time" "github.com/gdamore/tcell" "github.com/viktomas/godu/core" @@ -22,7 +23,9 @@ func main() { root = args[0] } log.Printf("godu will walk through `%s` that might take up to few minutes\n", root) - tree := core.GetSubTree(root, nil, ioutil.ReadDir, getIgnoredFolders()) + progress := make(chan int, 0) + go reportProgress(progress) + tree := core.GetSubTree(root, nil, ioutil.ReadDir, getIgnoredFolders(), progress) err := core.PrepareTree(tree, *limit*core.MEGABYTE) if err != nil { log.Println(err.Error()) @@ -43,6 +46,23 @@ func main() { printMarkedFiles(lastState) } +func reportProgress(progress <-chan int) { + objs := 0 + ticker := time.NewTicker(time.Second * 2) + go func() { + for i := range progress { + objs += i + } + ticker.Stop() + log.Println("Scanning done") + }() + go func() { + for range ticker.C { + log.Printf("Scanning.. Already found %d objects\n", objs) + } + }() +} + func printMarkedFiles(lastState *core.State) { markedFiles := interactive.QuoteMarkedFiles(lastState.MarkedFiles) for _, quotedFile := range markedFiles {