refactor(tui): use strconv.Atoi in parseIntClamp, drop spurious error return

This commit is contained in:
MDietermann
2026-04-13 22:00:49 +02:00
parent 394fb33d0c
commit e7aa75735d
2 changed files with 27 additions and 20 deletions

View File

@@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"strconv"
"strings"
"github.com/charmbracelet/huh"
@@ -88,12 +89,13 @@ func Run(ctx context.Context, reg *module.Registry, initial tui.WizardState) (tu
return s, false, err
}
// Redundant-but-safe: the DescriptionFunc closure on the plan-review
// screen already kept s.Modules in sync. The MultiSelect group is
// frozen by the time we reach here, so this is idempotent. Kept for
// the case where the form is exited via a path that bypasses the
// plan-review screen in future revisions.
s.Modules = syncSelected(s.Modules, selectedModules)
// Parse parallelism: clamp to 1 on any parse failure, since the wizard
// uses a free-form Input; a stricter schema can come later.
if n, perr := parseIntClamp(parallelismStr, 1); perr == nil {
s.Parallelism = n
}
s.Parallelism = parseIntClamp(parallelismStr, 1)
s.Confirmed = proceed
return s, proceed, nil
}
@@ -149,15 +151,18 @@ func renderPlan(ctx context.Context, reg *module.Registry, selectedIDs []string)
return b.String()
}
// parseIntClamp parses s as int. Empty or invalid input returns fallback.
func parseIntClamp(s string, fallback int) (int, error) {
// parseIntClamp parses s as a positive int. Empty, non-numeric (including
// partial matches like "3abc"), negative, zero, or overflowing input all
// return fallback. strconv.Atoi (not fmt.Sscanf) is used so partial matches
// are rejected and overflow surfaces as an error.
func parseIntClamp(s string, fallback int) int {
s = strings.TrimSpace(s)
if s == "" {
return fallback, nil
return fallback
}
var n int
if _, err := fmt.Sscanf(s, "%d", &n); err != nil || n < 1 {
return fallback, nil
n, err := strconv.Atoi(s)
if err != nil || n < 1 {
return fallback
}
return n, nil
return n
}

View File

@@ -48,13 +48,15 @@ func TestParseIntClamp(t *testing.T) {
"": 1,
" ": 1,
"abc": 1,
"3abc": 1, // partial match is rejected (strconv.Atoi, not Sscanf)
"0": 1,
"-5": 1,
"3": 3,
"12": 12,
"99999999999999999999": 1, // overflow → fallback
}
for in, want := range cases {
got, _ := parseIntClamp(in, 1)
got := parseIntClamp(in, 1)
if got != want {
t.Errorf("parseIntClamp(%q) = %d, want %d", in, got, want)
}