From d186de6bdf029701bdc0db51cd35d610ad881fe5 Mon Sep 17 00:00:00 2001 From: Valentin Kiselev Date: Sat, 7 Oct 2023 12:29:08 +0300 Subject: [PATCH 1/2] fix: correctly sort alphanumeric commands --- internal/lefthook/run/runner.go | 42 ++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/internal/lefthook/run/runner.go b/internal/lefthook/run/runner.go index 37e42c1f..68af34a9 100644 --- a/internal/lefthook/run/runner.go +++ b/internal/lefthook/run/runner.go @@ -11,9 +11,11 @@ import ( "regexp" "slices" "sort" + "strconv" "strings" "sync" "sync/atomic" + "unicode" "github.com/charmbracelet/lipgloss" "github.com/spf13/afero" @@ -330,7 +332,7 @@ func (r *Runner) runCommands(ctx context.Context) { } } - sort.Strings(commands) + sortAlnum(commands) interactiveCommands := make([]string, 0) var wg sync.WaitGroup @@ -529,3 +531,41 @@ func (r *Runner) logExecute(name string, err error, out io.Reader) { log.Infof("%s", err) } } + +func sortAlnum(strs []string) { + sort.SliceStable(strs, func(i, j int) bool { + var numEnds int = -1 + for idx, ch := range strs[i] { + if unicode.IsDigit(ch) { + numEnds = idx + } else { + break + } + } + if numEnds == -1 { + return strs[i] < strs[j] + } + numI, err := strconv.Atoi(strs[i][:numEnds+1]) + if err != nil { + return strs[i] < strs[j] + } + + numEnds = -1 + for idx, ch := range strs[j] { + if unicode.IsDigit(ch) { + numEnds = idx + } else { + break + } + } + if numEnds == -1 { + return true + } + numJ, err := strconv.Atoi(strs[j][:numEnds+1]) + if err != nil { + return true + } + + return numI < numJ + }) +} From f00fd402df8ca259de9056c32fd31b40cb5ef6de Mon Sep 17 00:00:00 2001 From: Valentin Kiselev Date: Sat, 7 Oct 2023 12:37:26 +0300 Subject: [PATCH 2/2] chore: add comment --- internal/lefthook/run/runner.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/internal/lefthook/run/runner.go b/internal/lefthook/run/runner.go index 68af34a9..6a8024ee 100644 --- a/internal/lefthook/run/runner.go +++ b/internal/lefthook/run/runner.go @@ -532,9 +532,13 @@ func (r *Runner) logExecute(name string, err error, out io.Reader) { } } +// sortAlnum sorts the command names by preceding numbers if they occur. +// If the command names starts with letter the command name will be sorted alphabetically. +// +// []string{"1_command", "10command", "3 command", "command5"} // -> 1_command, 3 command, 10command, command5 func sortAlnum(strs []string) { sort.SliceStable(strs, func(i, j int) bool { - var numEnds int = -1 + numEnds := -1 for idx, ch := range strs[i] { if unicode.IsDigit(ch) { numEnds = idx