Skip to content

Commit

Permalink
sorting by name, item count and size
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniel Milde committed Jan 1, 2021
1 parent 9336457 commit 699affc
Show file tree
Hide file tree
Showing 4 changed files with 337 additions and 4 deletions.
19 changes: 19 additions & 0 deletions analyze/sort.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package analyze

func (f Files) Len() int { return len(f) }
func (f Files) Swap(i, j int) { f[i], f[j] = f[j], f[i] }
func (f Files) Less(i, j int) bool { return f[i].Size > f[j].Size }

// ByItemCount sorts files by item count
type ByItemCount Files

func (f ByItemCount) Len() int { return len(f) }
func (f ByItemCount) Swap(i, j int) { f[i], f[j] = f[j], f[i] }
func (f ByItemCount) Less(i, j int) bool { return f[i].ItemCount > f[j].ItemCount }

// ByName sorts files by name
type ByName Files

func (f ByName) Len() int { return len(f) }
func (f ByName) Swap(i, j int) { f[i], f[j] = f[j], f[i] }
func (f ByName) Less(i, j int) bool { return f[i].Name > f[j].Name }
88 changes: 88 additions & 0 deletions analyze/sort_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package analyze

import (
"sort"
"testing"

"github.com/stretchr/testify/assert"
)

func TestSortBySize(t *testing.T) {
files := Files{
&File{
Size: 1,
},
&File{
Size: 2,
},
&File{
Size: 3,
},
}

sort.Sort(files)

assert.Equal(t, int64(3), files[0].Size)
assert.Equal(t, int64(2), files[1].Size)
assert.Equal(t, int64(1), files[2].Size)
}

func TestSortBySizeAsc(t *testing.T) {
files := Files{
&File{
Size: 1,
},
&File{
Size: 2,
},
&File{
Size: 3,
},
}

sort.Sort(sort.Reverse(files))

assert.Equal(t, int64(1), files[0].Size)
assert.Equal(t, int64(2), files[1].Size)
assert.Equal(t, int64(3), files[2].Size)
}

func TestSortByItemCount(t *testing.T) {
files := Files{
&File{
ItemCount: 1,
},
&File{
ItemCount: 2,
},
&File{
ItemCount: 3,
},
}

sort.Sort(ByItemCount(files))

assert.Equal(t, 3, files[0].ItemCount)
assert.Equal(t, 2, files[1].ItemCount)
assert.Equal(t, 1, files[2].ItemCount)
}

func TestSortByName(t *testing.T) {
files := Files{
&File{
Name: "aa",
},
&File{
Name: "bb",
},
&File{
Name: "cc",
},
}

sort.Sort(ByName(files))

assert.Equal(t, "cc", files[0].Name)
assert.Equal(t, "bb", files[1].Name)
assert.Equal(t, "aa", files[2].Name)
}
64 changes: 60 additions & 4 deletions cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ const helpText = `
[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]n [white]Sort by name (asc/desc)
[red]s [white]Sort by size (asc/desc)
[red]c [white]Sort by items (asc/desc)
`

// UI struct
Expand All @@ -36,12 +39,16 @@ type UI struct {
currentDirPath string
askBeforeDelete bool
ignorePaths []string
sortBy string
sortOrder string
}

// CreateUI creates the whole UI app
func CreateUI(screen tcell.Screen) *UI {
ui := &UI{
askBeforeDelete: true,
sortBy: "size",
sortOrder: "desc",
}

ui.app = tview.NewApplication()
Expand Down Expand Up @@ -174,9 +181,7 @@ func (ui *UI) showDir() {
rowIndex++
}

sort.Slice(ui.currentDir.Files, func(i, j int) bool {
return ui.currentDir.Files[i].Size > ui.currentDir.Files[j].Size
})
ui.sortItems()

for i, item := range ui.currentDir.Files {
cell := tview.NewTableCell(formatFileRow(item))
Expand All @@ -185,12 +190,40 @@ func (ui *UI) showDir() {
rowIndex++
}

ui.footer.SetText("Apparent size: " + formatSize(ui.currentDir.Size) + " Items: " + fmt.Sprint(ui.currentDir.ItemCount))
ui.footer.SetText(
"Apparent size: " +
formatSize(ui.currentDir.Size) +
" Items: " + fmt.Sprint(ui.currentDir.ItemCount) +
" Sorting by: " + ui.sortBy + " " + ui.sortOrder)
ui.table.Select(0, 0)
ui.table.ScrollToBeginning()
ui.app.SetFocus(ui.table)
}

func (ui *UI) sortItems() {
if ui.sortBy == "size" {
if ui.sortOrder == "desc" {
sort.Sort(ui.currentDir.Files)
} else {
sort.Sort(sort.Reverse(ui.currentDir.Files))
}
}
if ui.sortBy == "itemCount" {
if ui.sortOrder == "desc" {
sort.Sort(analyze.ByItemCount(ui.currentDir.Files))
} else {
sort.Sort(sort.Reverse(analyze.ByItemCount(ui.currentDir.Files)))
}
}
if ui.sortBy == "name" {
if ui.sortOrder == "desc" {
sort.Sort(analyze.ByName(ui.currentDir.Files))
} else {
sort.Sort(sort.Reverse(analyze.ByName(ui.currentDir.Files)))
}
}
}

func (ui *UI) fileItemSelected(row, column int) {
selectedDir := ui.table.GetCell(row, column).GetReference().(*analyze.File)
if !selectedDir.IsDir {
Expand Down Expand Up @@ -279,10 +312,33 @@ func (ui *UI) keyPressed(key *tcell.EventKey) *tcell.EventKey {
ui.deleteSelected()
}
break
case 's':
ui.setSorting("size")
break
case 'c':
ui.setSorting("itemCount")
break
case 'n':
ui.setSorting("name")
break
}
return key
}

func (ui *UI) setSorting(newOrder string) {
if newOrder == ui.sortBy {
if ui.sortOrder == "asc" {
ui.sortOrder = "desc"
} else {
ui.sortOrder = "asc"
}
} else {
ui.sortBy = newOrder
ui.sortOrder = "asc"
}
ui.showDir()
}

func (ui *UI) updateProgress(progress *analyze.CurrentProgress) {
for {
progress.Mutex.Lock()
Expand Down
170 changes: 170 additions & 0 deletions cli/sort_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
package cli

import (
"testing"
"time"

"github.com/dundee/gdu/analyze"
"github.com/gdamore/tcell/v2"
"github.com/stretchr/testify/assert"
)

func TestSortBySizeAsc(t *testing.T) {
fin := analyze.CreateTestDir()
defer fin()

simScreen := tcell.NewSimulationScreen("UTF-8")
simScreen.Init()
simScreen.SetSize(50, 50)

ui := CreateUI(simScreen)

ui.AnalyzePath("test_dir")

go func() {
time.Sleep(100 * time.Millisecond)
simScreen.InjectKey(tcell.KeyRune, 'j', 1)
time.Sleep(100 * time.Millisecond)
simScreen.InjectKey(tcell.KeyRune, 'l', 1)
time.Sleep(100 * time.Millisecond)
simScreen.InjectKey(tcell.KeyRune, 's', 1)
time.Sleep(100 * time.Millisecond)
simScreen.InjectKey(tcell.KeyRune, 'q', 1)
time.Sleep(100 * time.Millisecond)
}()

ui.StartUILoop()

dir := ui.currentDir

assert.Equal(t, "file2", dir.Files[0].Name)
}

func TestSortByName(t *testing.T) {
fin := analyze.CreateTestDir()
defer fin()

simScreen := tcell.NewSimulationScreen("UTF-8")
simScreen.Init()
simScreen.SetSize(50, 50)

ui := CreateUI(simScreen)

ui.AnalyzePath("test_dir")

go func() {
time.Sleep(100 * time.Millisecond)
simScreen.InjectKey(tcell.KeyRune, 'j', 1)
time.Sleep(100 * time.Millisecond)
simScreen.InjectKey(tcell.KeyRune, 'l', 1)
time.Sleep(100 * time.Millisecond)
simScreen.InjectKey(tcell.KeyRune, 'n', 1)
time.Sleep(100 * time.Millisecond)
simScreen.InjectKey(tcell.KeyRune, 'q', 1)
time.Sleep(100 * time.Millisecond)
}()

ui.StartUILoop()

dir := ui.currentDir

assert.Equal(t, "file2", dir.Files[0].Name)
}

func TestSortByNameDesc(t *testing.T) {
fin := analyze.CreateTestDir()
defer fin()

simScreen := tcell.NewSimulationScreen("UTF-8")
simScreen.Init()
simScreen.SetSize(50, 50)

ui := CreateUI(simScreen)

ui.AnalyzePath("test_dir")

go func() {
time.Sleep(100 * time.Millisecond)
simScreen.InjectKey(tcell.KeyRune, 'j', 1)
time.Sleep(100 * time.Millisecond)
simScreen.InjectKey(tcell.KeyRune, 'l', 1)
time.Sleep(100 * time.Millisecond)
simScreen.InjectKey(tcell.KeyRune, 'n', 1)
time.Sleep(100 * time.Millisecond)
simScreen.InjectKey(tcell.KeyRune, 'n', 1)
time.Sleep(100 * time.Millisecond)
simScreen.InjectKey(tcell.KeyRune, 'q', 1)
time.Sleep(100 * time.Millisecond)
}()

ui.StartUILoop()

dir := ui.currentDir

assert.Equal(t, "subnested", dir.Files[0].Name)
}

func TestSortByItemCount(t *testing.T) {
fin := analyze.CreateTestDir()
defer fin()

simScreen := tcell.NewSimulationScreen("UTF-8")
simScreen.Init()
simScreen.SetSize(50, 50)

ui := CreateUI(simScreen)

ui.AnalyzePath("test_dir")

go func() {
time.Sleep(100 * time.Millisecond)
simScreen.InjectKey(tcell.KeyRune, 'j', 1)
time.Sleep(100 * time.Millisecond)
simScreen.InjectKey(tcell.KeyRune, 'l', 1)
time.Sleep(100 * time.Millisecond)
simScreen.InjectKey(tcell.KeyRune, 'c', 1)
time.Sleep(100 * time.Millisecond)
simScreen.InjectKey(tcell.KeyRune, 'q', 1)
time.Sleep(100 * time.Millisecond)
}()

ui.StartUILoop()

dir := ui.currentDir

assert.Equal(t, "file2", dir.Files[0].Name)
}

func TestSortByItemCountDesc(t *testing.T) {
// fin := analyze.CreateTestDir()
// defer fin()
analyze.CreateTestDir()

simScreen := tcell.NewSimulationScreen("UTF-8")
simScreen.Init()
simScreen.SetSize(50, 50)

ui := CreateUI(simScreen)

ui.AnalyzePath("test_dir")

go func() {
time.Sleep(100 * time.Millisecond)
simScreen.InjectKey(tcell.KeyRune, 'j', 1)
time.Sleep(100 * time.Millisecond)
simScreen.InjectKey(tcell.KeyRune, 'l', 1)
time.Sleep(100 * time.Millisecond)
simScreen.InjectKey(tcell.KeyRune, 'c', 1)
time.Sleep(100 * time.Millisecond)
simScreen.InjectKey(tcell.KeyRune, 'c', 1)
time.Sleep(100 * time.Millisecond)
simScreen.InjectKey(tcell.KeyRune, 'q', 1)
time.Sleep(100 * time.Millisecond)
}()

ui.StartUILoop()

dir := ui.currentDir

assert.Equal(t, "subnested", dir.Files[0].Name)
}

0 comments on commit 699affc

Please sign in to comment.