Skip to content

Commit c9ab963

Browse files
authored
Merge pull request #1 from knbr13/add-bubbletea
add -it flag instead of -delete for interactive deletion
2 parents cd4cfbd + 6fc8558 commit c9ab963

File tree

4 files changed

+381
-38
lines changed

4 files changed

+381
-38
lines changed

go.mod

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,26 @@
11
module github.com/knbr13/dugo
22

33
go 1.24.0
4+
5+
require (
6+
github.com/charmbracelet/bubbletea v1.3.4
7+
github.com/charmbracelet/lipgloss v1.0.0
8+
)
9+
10+
require (
11+
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
12+
github.com/charmbracelet/x/ansi v0.8.0 // indirect
13+
github.com/charmbracelet/x/term v0.2.1 // indirect
14+
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
15+
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
16+
github.com/mattn/go-isatty v0.0.20 // indirect
17+
github.com/mattn/go-localereader v0.0.1 // indirect
18+
github.com/mattn/go-runewidth v0.0.16 // indirect
19+
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
20+
github.com/muesli/cancelreader v0.2.2 // indirect
21+
github.com/muesli/termenv v0.15.2 // indirect
22+
github.com/rivo/uniseg v0.4.7 // indirect
23+
golang.org/x/sync v0.11.0 // indirect
24+
golang.org/x/sys v0.30.0 // indirect
25+
golang.org/x/text v0.3.8 // indirect
26+
)

go.sum

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
2+
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
3+
github.com/charmbracelet/bubbletea v1.3.4 h1:kCg7B+jSCFPLYRA52SDZjr51kG/fMUEoPoZrkaDHyoI=
4+
github.com/charmbracelet/bubbletea v1.3.4/go.mod h1:dtcUCyCGEX3g9tosuYiut3MXgY/Jsv9nKVdibKKRRXo=
5+
github.com/charmbracelet/lipgloss v1.0.0 h1:O7VkGDvqEdGi93X+DeqsQ7PKHDgtQfF8j8/O2qFMQNg=
6+
github.com/charmbracelet/lipgloss v1.0.0/go.mod h1:U5fy9Z+C38obMs+T+tJqst9VGzlOYGj4ri9reL3qUlo=
7+
github.com/charmbracelet/x/ansi v0.8.0 h1:9GTq3xq9caJW8ZrBTe0LIe2fvfLR/bYXKTx2llXn7xE=
8+
github.com/charmbracelet/x/ansi v0.8.0/go.mod h1:wdYl/ONOLHLIVmQaxbIYEC/cRKOQyjTkowiI4blgS9Q=
9+
github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=
10+
github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg=
11+
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
12+
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
13+
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
14+
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
15+
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
16+
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
17+
github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
18+
github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
19+
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
20+
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
21+
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI=
22+
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo=
23+
github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
24+
github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
25+
github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo=
26+
github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8=
27+
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
28+
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
29+
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
30+
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
31+
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
32+
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
33+
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
34+
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
35+
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
36+
golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY=
37+
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=

main.go

Lines changed: 39 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,16 @@ import (
99
"regexp"
1010
"strings"
1111
"sync"
12+
13+
tea "github.com/charmbracelet/bubbletea"
1214
)
1315

1416
func main() {
1517
var ignoreNamesFlag, ignoreRegexFlag string
1618
var workers uint
17-
var deleteFlag bool
1819
flag.StringVar(&ignoreNamesFlag, "ignore-names", "", "Comma-separated list of file/folder names to ignore (exact match)")
1920
flag.StringVar(&ignoreRegexFlag, "ignore-regex", "", "Regex pattern to ignore files by path")
20-
flag.BoolVar(&deleteFlag, "delete", false, "Enable interactive deletion of duplicates")
21+
flag.BoolVar(&interactiveMode, "it", false, "Interactive TUI mode")
2122
flag.UintVar(&workers, "workers", 4, "Number of concurrent workers")
2223
flag.Parse()
2324

@@ -55,53 +56,53 @@ func main() {
5556
sem := make(chan struct{}, workers)
5657
results := make(chan []string)
5758

58-
var wg sync.WaitGroup
59-
for _, v := range m {
60-
if len(v) < 2 {
61-
continue
62-
}
63-
wg.Add(1)
64-
go func(files sameSizeFiles) {
65-
defer wg.Done()
66-
sem <- struct{}{}
67-
defer func() { <-sem }()
68-
69-
res, err := groupByHash(files, workers)
70-
if err != nil {
71-
log.Printf("Skipping due to error: %v", err)
72-
return
59+
go func() {
60+
var wg sync.WaitGroup
61+
for _, v := range m {
62+
if len(v) < 2 {
63+
continue
7364
}
65+
wg.Add(1)
66+
go func(files sameSizeFiles) {
67+
defer wg.Done()
68+
sem <- struct{}{}
69+
defer func() { <-sem }()
7470

75-
for _, v := range res {
76-
groups, err := partitionIntoEqualGroups(v)
71+
res, err := groupByHash(files, workers)
7772
if err != nil {
78-
log.Printf("Error partitioning: %v", err)
73+
log.Printf("Error: %v", err)
7974
return
8075
}
81-
for _, group := range groups {
82-
if len(group) >= 2 {
83-
results <- group
76+
77+
for _, v := range res {
78+
groups, err := partitionIntoEqualGroups(v)
79+
if err != nil {
80+
log.Printf("Error: %v", err)
81+
continue
82+
}
83+
for _, group := range groups {
84+
if len(group) >= 2 {
85+
results <- group
86+
}
8487
}
8588
}
86-
}
87-
}(v)
88-
}
89+
}(v)
90+
}
8991

90-
go func() {
91-
wg.Wait()
92-
close(results)
92+
go func() {
93+
wg.Wait()
94+
close(results)
95+
}()
9396
}()
9497

95-
var allGroups [][]string
96-
for group := range results {
97-
if deleteFlag {
98-
allGroups = append(allGroups, group)
99-
} else {
98+
if interactiveMode {
99+
p := tea.NewProgram(initialModel(results))
100+
if _, err := p.Run(); err != nil {
101+
log.Fatal(err)
102+
}
103+
} else {
104+
for group := range results {
100105
fmt.Println("Equal files:", group)
101106
}
102107
}
103-
104-
if deleteFlag {
105-
handleDeletions(allGroups)
106-
}
107108
}

0 commit comments

Comments
 (0)