summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Milde <daniel.milde@firma.seznam.cz>2021-01-06 23:35:15 +0100
committerDaniel Milde <daniel.milde@firma.seznam.cz>2021-01-06 23:35:15 +0100
commit4268fea3a93d3f9900a09d9c60e293b782a7d001 (patch)
tree8ba040eef5368993e00d748af5c829746e46477d
parent4cd0b6b7c477fd488c9f0e0f4432be650b9c3dcb (diff)
rescan current dirv2.2.0
-rw-r--r--analyze/dir.go6
-rw-r--r--analyze/file.go19
-rw-r--r--analyze/file_test.go54
-rw-r--r--cli/cli.go31
-rw-r--r--cli/cli_test.go39
-rw-r--r--cli/sort_test.go10
-rw-r--r--main.go4
7 files changed, 144 insertions, 19 deletions
diff --git a/analyze/dir.go b/analyze/dir.go
index fc329a8..1123337 100644
--- a/analyze/dir.go
+++ b/analyze/dir.go
@@ -64,10 +64,10 @@ func processDir(path string, progress *CurrentProgress, concurrencyLimitChannel
wait.Add(1)
go func() {
concurrencyLimitChannel <- true
- file = processDir(entryPath, progress, concurrencyLimitChannel, wait, ignoreDir)
- file.Parent = &dir
+ subdir := processDir(entryPath, progress, concurrencyLimitChannel, wait, ignoreDir)
+ subdir.Parent = &dir
mutex.Lock()
- dir.Files = append(dir.Files, file)
+ dir.Files = append(dir.Files, subdir)
mutex.Unlock()
<-concurrencyLimitChannel
wait.Done()
diff --git a/analyze/file.go b/analyze/file.go
index 2678590..7fba388 100644
--- a/analyze/file.go
+++ b/analyze/file.go
@@ -75,6 +75,16 @@ func (s Files) Find(file *File) int {
return -1
}
+// FindByName searches name in Files and returns its index, or -1
+func (s Files) FindByName(name string) int {
+ for i, item := range s {
+ if item.Name == name {
+ return i
+ }
+ }
+ return -1
+}
+
// Remove removes File from Files
func (s Files) Remove(file *File) Files {
index := s.Find(file)
@@ -83,3 +93,12 @@ func (s Files) Remove(file *File) Files {
}
return append(s[:index], s[index+1:]...)
}
+
+// RemoveByName removes File from Files
+func (s Files) RemoveByName(name string) Files {
+ index := s.FindByName(name)
+ if index == -1 {
+ return s
+ }
+ return append(s[:index], s[index+1:]...)
+}
diff --git a/analyze/file_test.go b/analyze/file_test.go
index 0a37ac3..40233b9 100644
--- a/analyze/file_test.go
+++ b/analyze/file_test.go
@@ -58,6 +58,33 @@ func TestRemove(t *testing.T) {
assert.Equal(t, file2, dir.Files[0])
}
+func TestRemoveByName(t *testing.T) {
+ dir := File{
+ Name: "xxx",
+ Size: 5,
+ ItemCount: 2,
+ }
+
+ file := &File{
+ Name: "yyy",
+ Size: 2,
+ ItemCount: 1,
+ Parent: &dir,
+ }
+ file2 := &File{
+ Name: "zzz",
+ Size: 3,
+ ItemCount: 1,
+ Parent: &dir,
+ }
+ dir.Files = []*File{file, file2}
+
+ dir.Files = dir.Files.RemoveByName("yyy")
+
+ assert.Equal(t, 1, len(dir.Files))
+ assert.Equal(t, file2, dir.Files[0])
+}
+
func TestRemoveNotInDir(t *testing.T) {
dir := File{
Name: "xxx",
@@ -85,6 +112,33 @@ func TestRemoveNotInDir(t *testing.T) {
assert.Equal(t, 1, len(dir.Files))
}
+func TestRemoveByNameNotInDir(t *testing.T) {
+ dir := File{
+ Name: "xxx",
+ Size: 5,
+ ItemCount: 2,
+ }
+
+ file := &File{
+ Name: "yyy",
+ Size: 2,
+ ItemCount: 1,
+ Parent: &dir,
+ }
+ file2 := &File{
+ Name: "zzz",
+ Size: 3,
+ ItemCount: 1,
+ }
+ dir.Files = []*File{file}
+
+ assert.Equal(t, -1, dir.Files.Find(file2))
+
+ dir.Files = dir.Files.RemoveByName("zzz")
+
+ assert.Equal(t, 1, len(dir.Files))
+}
+
func TestRemoveFile(t *testing.T) {
dir := &File{
Name: "xxx",
diff --git a/cli/cli.go b/cli/cli.go
index dac9fe5..51c0fd5 100644
--- a/cli/cli.go
+++ b/cli/cli.go
@@ -19,6 +19,7 @@ const helpTextColorized = `
[red]enter, right, l [white]Select directory/device
[red]left, h [white]Go to parent directory
[red]d [white]Delete selected file or directory
+ [red]r [white]Rescan current directory
[red]n [white]Sort by name (asc/desc)
[red]s [white]Sort by size (asc/desc)
[red]c [white]Sort by items (asc/desc)
@@ -28,6 +29,7 @@ const helpText = `
[::b]enter, right, l [white:black:-]Select directory/device
[::b]left, h [white:black:-]Go to parent directory
[::b]d [white:black:-]Delete selected file or directory
+ [::b]r [white:black:-]Rescan current directory
[::b]n [white:black:-]Sort by name (asc/desc)
[::b]s [white:black:-]Sort by size (asc/desc)
[::b]c [white:black:-]Sort by items (asc/desc)
@@ -46,6 +48,7 @@ type UI struct {
currentDir *analyze.File
devices []*analyze.Device
analyzer analyze.Analyzer
+ topDir *analyze.File
topDirPath string
currentDirPath string
askBeforeDelete bool
@@ -152,8 +155,8 @@ func (ui *UI) ListDevices() {
}
// AnalyzePath analyzes recursively disk usage in given path
-func (ui *UI) AnalyzePath(path string, analyzer analyze.Analyzer) {
- ui.topDirPath, _ = filepath.Abs(path)
+func (ui *UI) AnalyzePath(path string, analyzer analyze.Analyzer, parentDir *analyze.File) {
+ abspath, _ := filepath.Abs(path)
ui.progress = tview.NewTextView().SetText("Scanning...")
ui.progress.SetBorder(true).SetBorderPadding(2, 2, 2, 2)
@@ -180,7 +183,17 @@ func (ui *UI) AnalyzePath(path string, analyzer analyze.Analyzer) {
go ui.updateProgress(progress)
go func() {
- ui.currentDir = analyzer(ui.topDirPath, progress, ui.ShouldDirBeIgnored)
+ ui.currentDir = analyzer(abspath, progress, ui.ShouldDirBeIgnored)
+
+ if parentDir != nil {
+ ui.currentDir.Parent = parentDir
+ parentDir.Files = parentDir.Files.RemoveByName(ui.currentDir.Name)
+ parentDir.Files = append(parentDir.Files, ui.currentDir)
+ ui.topDir.UpdateStats()
+ } else {
+ ui.topDirPath = abspath
+ ui.topDir = ui.currentDir
+ }
ui.app.QueueUpdateDraw(func() {
ui.showDir()
@@ -204,6 +217,10 @@ func (ui *UI) SetIgnoreDirPaths(paths []string) {
}
}
+func (ui *UI) rescanDir() {
+ ui.AnalyzePath(ui.currentDirPath, ui.analyzer, ui.currentDir.Parent)
+}
+
// ShouldDirBeIgnored returns true if given path should be ignored
func (ui *UI) ShouldDirBeIgnored(path string) bool {
return ui.ignoreDirPaths[path]
@@ -297,7 +314,7 @@ func (ui *UI) deviceItemSelected(row, column int) {
}
}
- ui.AnalyzePath(selectedDevice.MountPoint, ui.analyzer)
+ ui.AnalyzePath(selectedDevice.MountPoint, ui.analyzer, nil)
}
func (ui *UI) confirmDeletion() {
@@ -393,6 +410,12 @@ func (ui *UI) keyPressed(key *tcell.EventKey) *tcell.EventKey {
ui.deleteSelected()
}
break
+ case 'r':
+ if ui.currentDir == nil {
+ break
+ }
+ ui.rescanDir()
+ break
case 's':
ui.setSorting("size")
break
diff --git a/cli/cli_test.go b/cli/cli_test.go
index ee0ef3f..f8f0d11 100644
--- a/cli/cli_test.go
+++ b/cli/cli_test.go
@@ -99,7 +99,7 @@ func TestDeleteDir(t *testing.T) {
ui := CreateUI(simScreen, true)
ui.askBeforeDelete = false
- ui.AnalyzePath("test_dir", analyze.ProcessDir)
+ ui.AnalyzePath("test_dir", analyze.ProcessDir, nil)
go func() {
time.Sleep(100 * time.Millisecond)
@@ -129,7 +129,7 @@ func TestDeleteDirWithConfirm(t *testing.T) {
ui := CreateUI(simScreen, false)
- ui.AnalyzePath("test_dir", analyze.ProcessDir)
+ ui.AnalyzePath("test_dir", analyze.ProcessDir, nil)
go func() {
time.Sleep(100 * time.Millisecond)
@@ -161,7 +161,7 @@ func TestShowConfirm(t *testing.T) {
ui := CreateUI(simScreen, true)
- ui.AnalyzePath("test_dir", analyze.ProcessDir)
+ ui.AnalyzePath("test_dir", analyze.ProcessDir, nil)
go func() {
time.Sleep(100 * time.Millisecond)
@@ -181,6 +181,35 @@ func TestShowConfirm(t *testing.T) {
assert.FileExists(t, "test_dir/nested/file2")
}
+func TestRescan(t *testing.T) {
+ fin := analyze.CreateTestDir()
+ defer fin()
+
+ simScreen := tcell.NewSimulationScreen("UTF-8")
+ simScreen.Init()
+ simScreen.SetSize(50, 50)
+
+ ui := CreateUI(simScreen, true)
+
+ ui.AnalyzePath("test_dir", analyze.ProcessDir, nil)
+
+ go func() {
+ time.Sleep(100 * time.Millisecond)
+ simScreen.InjectKey(tcell.KeyEnter, '1', 1)
+ time.Sleep(10 * time.Millisecond)
+
+ // rescan subdir
+ simScreen.InjectKey(tcell.KeyRune, 'r', 1)
+ time.Sleep(100 * time.Millisecond)
+
+ time.Sleep(10 * time.Millisecond)
+ simScreen.InjectKey(tcell.KeyRune, 'q', 1)
+ time.Sleep(10 * time.Millisecond)
+ }()
+
+ ui.StartUILoop()
+}
+
func TestShowDevices(t *testing.T) {
if runtime.GOOS != "linux" {
return
@@ -262,7 +291,7 @@ func TestKeys(t *testing.T) {
ui := CreateUI(simScreen, false)
ui.askBeforeDelete = false
- ui.AnalyzePath("test_dir", analyze.ProcessDir)
+ ui.AnalyzePath("test_dir", analyze.ProcessDir, nil)
go func() {
time.Sleep(100 * time.Millisecond)
@@ -304,7 +333,7 @@ func TestSetIgnoreDirPaths(t *testing.T) {
path, _ := filepath.Abs("test_dir/nested/subnested")
ui.SetIgnoreDirPaths([]string{path})
- ui.AnalyzePath("test_dir", analyze.ProcessDir)
+ ui.AnalyzePath("test_dir", analyze.ProcessDir, nil)
go func() {
time.Sleep(100 * time.Millisecond)
diff --git a/cli/sort_test.go b/cli/sort_test.go
index 91afc4f..e0a870a 100644
--- a/cli/sort_test.go
+++ b/cli/sort_test.go
@@ -19,7 +19,7 @@ func TestSortBySizeAsc(t *testing.T) {
ui := CreateUI(simScreen, true)
- ui.AnalyzePath("test_dir", analyze.ProcessDir)
+ ui.AnalyzePath("test_dir", analyze.ProcessDir, nil)
go func() {
time.Sleep(100 * time.Millisecond)
@@ -50,7 +50,7 @@ func TestSortByName(t *testing.T) {
ui := CreateUI(simScreen, false)
- ui.AnalyzePath("test_dir", analyze.ProcessDir)
+ ui.AnalyzePath("test_dir", analyze.ProcessDir, nil)
go func() {
time.Sleep(100 * time.Millisecond)
@@ -81,7 +81,7 @@ func TestSortByNameDesc(t *testing.T) {
ui := CreateUI(simScreen, false)
- ui.AnalyzePath("test_dir", analyze.ProcessDir)
+ ui.AnalyzePath("test_dir", analyze.ProcessDir, nil)
go func() {
time.Sleep(100 * time.Millisecond)
@@ -114,7 +114,7 @@ func TestSortByItemCount(t *testing.T) {
ui := CreateUI(simScreen, true)
- ui.AnalyzePath("test_dir", analyze.ProcessDir)
+ ui.AnalyzePath("test_dir", analyze.ProcessDir, nil)
go func() {
time.Sleep(100 * time.Millisecond)
@@ -145,7 +145,7 @@ func TestSortByItemCountDesc(t *testing.T) {
ui := CreateUI(simScreen, false)
- ui.AnalyzePath("test_dir", analyze.ProcessDir)
+ ui.AnalyzePath("test_dir", analyze.ProcessDir, nil)
go func() {
time.Sleep(100 * time.Millisecond)
diff --git a/main.go b/main.go
index f2e414d..26d3e1d 100644
--- a/main.go
+++ b/main.go
@@ -53,12 +53,12 @@ func main() {
args := flag.Args()
if len(args) == 1 {
- ui.AnalyzePath(args[0], analyze.ProcessDir)
+ ui.AnalyzePath(args[0], analyze.ProcessDir, nil)
} else {
if runtime.GOOS == "linux" {
ui.ListDevices()
} else {
- ui.AnalyzePath(".", analyze.ProcessDir)
+ ui.AnalyzePath(".", analyze.ProcessDir, nil)
}
}