From 68fc8ca212a17a55b5bbec79c47af1d4cef6ffb7 Mon Sep 17 00:00:00 2001 From: NagIzaazShaik <176337212+shaikn6@users.noreply.github.com> Date: Thu, 10 Sep 2026 11:03:24 -0400 Subject: [PATCH] cli: pick next -seq version by numeric max, not lexical last nextSeqVersion took the sequence prefix from the last element of the filepath.Glob result, which is sorted lexically. Once a project has both single- and multi-digit versions (e.g. 9_ and 10_), '9_...' sorts after '10_...', so 'migrate create -seq' derived the next version from 9 and produced a duplicate version error. Scan every match and keep the numeric maximum instead. Malformed-filename and parse errors are still reported per element, so behaviour is unchanged for well-formed inputs. Fixes #1109 --- internal/cli/commands.go | 13 ++++++++----- internal/cli/commands_test.go | 1 + 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/internal/cli/commands.go b/internal/cli/commands.go index e37ca313e..5a52df4c3 100644 --- a/internal/cli/commands.go +++ b/internal/cli/commands.go @@ -27,8 +27,10 @@ func nextSeqVersion(matches []string, seqDigits int) (string, error) { nextSeq := uint64(1) - if len(matches) > 0 { - filename := matches[len(matches)-1] + // filepath.Glob returns matches in lexical order, so the highest sequence + // number is not necessarily last (e.g. "9_" sorts after "10_"). Scan every + // match and use the numeric maximum. + for _, filename := range matches { matchSeqStr := filepath.Base(filename) idx := strings.Index(matchSeqStr, "_") @@ -36,15 +38,16 @@ func nextSeqVersion(matches []string, seqDigits int) (string, error) { return "", fmt.Errorf("malformed migration filename: %s", filename) } - var err error matchSeqStr = matchSeqStr[0:idx] - nextSeq, err = strconv.ParseUint(matchSeqStr, 10, 64) + matchSeq, err := strconv.ParseUint(matchSeqStr, 10, 64) if err != nil { return "", err } - nextSeq++ + if matchSeq >= nextSeq { + nextSeq = matchSeq + 1 + } } version := fmt.Sprintf("%0[2]*[1]d", nextSeq, seqDigits) diff --git a/internal/cli/commands_test.go b/internal/cli/commands_test.go index 798e2df77..e912bdb8b 100644 --- a/internal/cli/commands_test.go +++ b/internal/cli/commands_test.go @@ -88,6 +88,7 @@ func (s *CreateCmdSuite) TestNextSeqVersion() { {"Single digit no int", []string{"bad_bad"}, 1, "", errors.New(`strconv.ParseUint: parsing "bad": invalid syntax`)}, {"Single digit negative seq", []string{"-5_test"}, 1, "", errors.New(`strconv.ParseUint: parsing "-5": invalid syntax`)}, {"Single digit increment", []string{"3_test", "4_test"}, 1, "5", nil}, + {"Multi digit lexical order", []string{"0_x", "10_x", "11_x", "1_x", "2_x", "9_x"}, 6, "000012", nil}, {"Single digit overflow", []string{"9_test"}, 1, "", errors.New("next sequence number 10 too large, at most 1 digits are allowed")}, {"Zero-pad initialize", []string{}, 6, "000001", nil}, {"Zero-pad malformed", []string{"bad"}, 6, "", errors.New("malformed migration filename: bad")},