Skip to content

Commit

Permalink
rescan current dir
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniel Milde committed Jan 6, 2021
1 parent 4cd0b6b commit 4268fea
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 19 deletions.
6 changes: 3 additions & 3 deletions analyze/dir.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
19 changes: 19 additions & 0 deletions analyze/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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:]...)
}
54 changes: 54 additions & 0 deletions analyze/file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down
31 changes: 27 additions & 4 deletions cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand All @@ -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()
Expand All @@ -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]
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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
Expand Down
39 changes: 34 additions & 5 deletions cli/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
10 changes: 5 additions & 5 deletions cli/sort_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}

Expand Down

0 comments on commit 4268fea

Please sign in to comment.