Compare commits

...

2 commits

Author SHA1 Message Date
7aae44048a 🛠 golangci-lint 2025-04-24 14:27:19 -05:00
8d74dc24e5 ♻️ Use ezcache to only remember files for five minutes 2025-04-21 15:19:40 -05:00
11 changed files with 154 additions and 94 deletions

39
.golangci.yaml Normal file
View file

@ -0,0 +1,39 @@
linters:
enable:
- errcheck
- gosimple
- govet
- ineffassign
- staticcheck
- unused
- copyloopvar
- dupl
- err113
- errname
- exptostd
- fatcontext
- funlen
- gocognit
- goconst
- gocritic
- gocyclo
- godot
- godox
- gosec
- perfsprint
- testifylint
linters-settings:
testifylint:
enable-all: true
disable:
- require-error
gocognit:
min-complexity: 16
gocyclo:
min-complexity: 15
gocritic:
enable-all: true
settings:
hugeParam:
sizeThreshold: 255

View file

@ -14,7 +14,7 @@ tasks:
desc: fmt, vet, and build desc: fmt, vet, and build
deps: deps:
- fmt - fmt
- analyze - lint
- build-all - build-all
fmt: fmt:
@ -24,30 +24,12 @@ tasks:
cmds: cmds:
- go fmt ./... - go fmt ./...
vet: lint:
desc: Vet go code desc: Statically analyze code
sources: sources:
- '**/*.go' - '**/*.go'
cmds: cmds:
- go vet ./... - golangci-lint run
critic:
desc: Critique go code
sources:
- '**/*.go'
cmds:
- gocritic check ./...
staticcheck:
desc: Static check go code
sources:
- '**/*.go'
cmds:
- staticcheck ./...
analyze:
desc: Do static analysis
deps:
- vet
- critic
- staticcheck
cmd-build: cmd-build:
internal: true internal: true

View file

@ -42,7 +42,13 @@ func Chill(baseCtx context.Context) context.Context {
return ret(ErrChilledOut) return ret(ErrChilledOut)
} }
go func() { go runChill(current, cancel)
return ctx
}
func runChill(current int, cancel context.CancelCauseFunc) {
var err error
for current >= MaxTemp && err == nil { for current >= MaxTemp && err == nil {
time.Sleep(Sleep) time.Sleep(Sleep)
current, err = getCurrentTemp() current, err = getCurrentTemp()
@ -51,7 +57,5 @@ func Chill(baseCtx context.Context) context.Context {
err = ErrChilledOut err = ErrChilledOut
} }
cancel(err) cancel(err)
}()
return ctx
} }

View file

@ -20,17 +20,17 @@ type errMsg error
type textMessage string type textMessage string
func newModel(text string) model { func newModel(text string) *model {
s := spinner.New() s := spinner.New()
s.Spinner = spinner.Dot s.Spinner = spinner.Dot
return model{spinner: s, text: text} return &model{spinner: s, text: text}
} }
func (m model) Init() tea.Cmd { func (m *model) Init() tea.Cmd {
return m.spinner.Tick return m.spinner.Tick
} }
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { func (m *model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) { switch msg := msg.(type) {
case errMsg: case errMsg:
m.err = msg m.err = msg
@ -47,7 +47,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
} }
} }
func (m model) View() string { func (m *model) View() string {
if m.err != nil { if m.err != nil {
return m.err.Error() return m.err.Error()
} }

20
cmd/test/main.go Normal file
View file

@ -0,0 +1,20 @@
package main
import (
e "codeberg.org/danjones000/utils/cli/err"
cli "codeberg.org/danjones000/utils/internal/cli/convids"
"fmt"
"os"
)
func main() {
flags, err := cli.ParseFlags(os.Args[0], os.Args[1:])
e.HandleErr(err)
if *cli.Help {
flags.Usage()
}
fmt.Println("Help", *cli.Help)
fmt.Println("Loop", *cli.Loop)
fmt.Println("DryRun", *cli.DryRun)
}

View file

@ -10,7 +10,9 @@ import (
fp "path/filepath" fp "path/filepath"
"regexp" "regexp"
"strings" "strings"
"time"
"codeberg.org/danjones000/ezcache"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
) )
@ -82,22 +84,33 @@ func processFile(input processInput) (processed bool, processError, cbError erro
return return
} }
type fileMap map[string][]os.DirEntry func processSource(allFiles ezcache.Cache[string, []os.DirEntry], d *Data, s *Show, source string, stopOnError bool, cb ShowWalker) (count int, err error) {
files, filesErr := allFiles.Get(source)
func (fm fileMap) GetFiles(path string) []os.DirEntry { if filesErr != nil {
files, ok := fm[path] return 0, filesErr
if ok {
return files
} }
fm.ReadPath(path) for _, file := range files {
return fm[path] pIn := processInput{file, source, s, d.Config.extRe, d.Config.Skip, cb}
processed, processErr, cbErr := processFile(pIn)
if processErr != nil {
return 0, processErr
}
if cbErr != nil && stopOnError {
return 0, cbErr
} }
func (fm fileMap) ReadPath(path string) { if errors.Is(processErr, ErrSkipped) || (!processed && processErr == nil && cbErr == nil) {
if _, ok := fm[path]; ok { continue
}
if cbErr == nil && processed {
count++
}
if cbErr != nil {
err = cbErr
}
return return
} }
fm[path], _ = os.ReadDir(path) return
} }
func WalkFiles(d *Data, stopOnError bool, gp GroupPrinter, cb ShowWalker) (err error) { func WalkFiles(d *Data, stopOnError bool, gp GroupPrinter, cb ShowWalker) (err error) {
@ -109,8 +122,10 @@ func WalkFiles(d *Data, stopOnError bool, gp GroupPrinter, cb ShowWalker) (err e
cb = DryRun(os.Stdout) cb = DryRun(os.Stdout)
} }
count := 0 count := 0
allFiles := fileMap{} allFiles, cacheErr := ezcache.New(os.ReadDir, 5*time.Minute)
var files []os.DirEntry if cacheErr != nil {
return err
}
if err != nil { if err != nil {
return return
@ -119,32 +134,13 @@ func WalkFiles(d *Data, stopOnError bool, gp GroupPrinter, cb ShowWalker) (err e
if len(s.Sources) == 0 { if len(s.Sources) == 0 {
s.Sources = []string{d.Config.Source} s.Sources = []string{d.Config.Source}
} }
showstart:
for _, source := range s.Sources { for _, source := range s.Sources {
files = allFiles.GetFiles(source) var c int
for _, file := range files { c, err = processSource(allFiles, d, s, source, stopOnError, cb)
pIn := processInput{file, source, s, d.Config.extRe, d.Config.Skip, cb} if err != nil {
processed, processErr, cbErr := processFile(pIn) break
if !processed && processErr == nil && cbErr == nil {
continue
}
if errors.Is(processErr, ErrSkipped) {
continue
}
if processErr != nil {
return processErr
}
if cbErr != nil && stopOnError {
return cbErr
}
if cbErr == nil && processed {
count++
}
if cbErr != nil {
err = cbErr
}
break showstart
} }
count += c
} }
} }
if err == nil && count < 1 { if err == nil && count < 1 {
@ -165,8 +161,9 @@ func GetShow(ctx context.Context) ShowWalker {
return GetShowWithIO(ctx, os.Stdin, os.Stdout, os.Stderr) return GetShowWithIO(ctx, os.Stdin, os.Stdout, os.Stderr)
} }
func GetShowWithIO(ctx context.Context, stdin io.Reader, stdout io.Writer, stderr io.Writer) ShowWalker { func GetShowWithIO(ctx context.Context, stdin io.Reader, stdout, stderr io.Writer) ShowWalker {
return func(s *Show, path string) error { return func(s *Show, path string) error {
//nolint:gosec // I don't care if this is using user input
cmd := exec.CommandContext(ctx, "get-shows", s.Folder, path) cmd := exec.CommandContext(ctx, "get-shows", s.Folder, path)
cmd.Stdin = stdin cmd.Stdin = stdin
cmd.Stdout = stdout cmd.Stdout = stdout

View file

@ -62,9 +62,17 @@ func (d *Data) AllShows(outputGroup GroupPrinter) iter.Seq[*Show] {
return return
} }
for _, groupName := range d.Config.Groups { for _, groupName := range d.Config.Groups {
if !d.yieldGroup(yield, outputGroup, groupName) {
return
}
}
}
}
func (d *Data) yieldGroup(yield func(*Show) bool, outputGroup GroupPrinter, groupName string) bool {
group := (*d.Shows)[groupName] group := (*d.Shows)[groupName]
if group == nil || len(*group) < 1 { if group == nil || len(*group) < 1 {
continue return true
} }
if outputGroup != nil { if outputGroup != nil {
outputGroup(groupName, *group) outputGroup(groupName, *group)
@ -74,9 +82,8 @@ func (d *Data) AllShows(outputGroup GroupPrinter) iter.Seq[*Show] {
continue continue
} }
if !yield(sh) { if !yield(sh) {
return return false
}
}
} }
} }
return true
} }

3
go.mod
View file

@ -1,8 +1,9 @@
module codeberg.org/danjones000/utils module codeberg.org/danjones000/utils
go 1.23.1 go 1.23.7
require ( require (
codeberg.org/danjones000/ezcache v0.5.2
github.com/charmbracelet/bubbles v0.20.0 github.com/charmbracelet/bubbles v0.20.0
github.com/charmbracelet/bubbletea v1.1.1 github.com/charmbracelet/bubbletea v1.1.1
github.com/spf13/pflag v1.0.5 github.com/spf13/pflag v1.0.5

8
go.sum
View file

@ -1,3 +1,5 @@
codeberg.org/danjones000/ezcache v0.5.2 h1:msWRwbLj+HHCU3dnFbsdedCRuhyPQCOFbT9EgjwN9KM=
codeberg.org/danjones000/ezcache v0.5.2/go.mod h1:wLTvTXfXxaEDUS9dOILqQmhAlB/9lUZCC2yB5CyGBfk=
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
github.com/charmbracelet/bubbles v0.20.0 h1:jSZu6qD8cRQ6k9OMfR1WlM+ruM8fkPWkHvQWD9LIutE= github.com/charmbracelet/bubbles v0.20.0 h1:jSZu6qD8cRQ6k9OMfR1WlM+ruM8fkPWkHvQWD9LIutE=
@ -10,6 +12,8 @@ github.com/charmbracelet/x/ansi v0.2.3 h1:VfFN0NUpcjBRd4DnKfRaIRo53KRgey/nhOoEqo
github.com/charmbracelet/x/ansi v0.2.3/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw= github.com/charmbracelet/x/ansi v0.2.3/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
github.com/charmbracelet/x/term v0.2.0 h1:cNB9Ot9q8I711MyZ7myUR5HFWL/lc3OpU8jZ4hwm0x0= github.com/charmbracelet/x/term v0.2.0 h1:cNB9Ot9q8I711MyZ7myUR5HFWL/lc3OpU8jZ4hwm0x0=
github.com/charmbracelet/x/term v0.2.0/go.mod h1:GVxgxAbjUrmpvIINHIQnJJKpMlHiZ4cktEQCN6GWyF0= github.com/charmbracelet/x/term v0.2.0/go.mod h1:GVxgxAbjUrmpvIINHIQnJJKpMlHiZ4cktEQCN6GWyF0=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
@ -26,11 +30,15 @@ github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELU
github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo= github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo=
github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8= github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

View file

@ -32,7 +32,10 @@ func ParseFlags(name string, args []string) (*pflag.FlagSet, error) {
} }
if *DryRun { if *DryRun {
flags.Set("loop", "false") err := flags.Set("loop", "false")
if err != nil {
return nil, err
}
} }
return flags, nil return flags, nil

View file

@ -2,7 +2,6 @@ package convids
import ( import (
"context" "context"
"fmt"
"io" "io"
"codeberg.org/danjones000/utils/chill" "codeberg.org/danjones000/utils/chill"
@ -18,7 +17,7 @@ func GetWalker(ctx context.Context, dryRun bool, in io.Reader, out, errOut io.Wr
gs := conutils.GetShowWithIO(ctx, in, out, errOut) gs := conutils.GetShowWithIO(ctx, in, out, errOut)
return func(s *conutils.Show, path string) error { return func(s *conutils.Show, path string) error {
ct := chill.Chill(ctx) ct := chill.Chill(ctx)
msg := fmt.Sprintf("Waiting for CPU to cool, for %s", path) msg := "Waiting for CPU to cool, for " + path
sp := spin.Spin(ct, msg) sp := spin.Spin(ct, msg)
err := sp.Wait() err := sp.Wait()
if err != nil { if err != nil {