fix(parser): keep the pre-release label when normalizing versions - #626
fix(parser): keep the pre-release label when normalizing versions#626pucedoteth wants to merge 1 commit into
Conversation
719b839 to
bda9ed5
Compare
|
Verification update, closing the caveat in the PR description. I said there that I could only run these in an isolated module, because the full dependency download kept timing out on my machine, and that CI would be the first run against the real tree. That has now completed locally. The full package builds and passes: 31 tests pass, 0 fail, against the real Nothing about the change moved; this only replaces the isolated-module result with a real one. |
|
@pucedoteth Thanks for the clean follow-up. The approach is correct and an improvement over #588:
Behavior change to confirm: inputs #588 already handled now normalize differently — One ask: this PR is currently based on Looks good otherwise. Ready to merge after the rebase. (Review comment only — not merging.) |
Follow-up to Tencent#588, which fixed the digit-splicing case. This handles the bare-suffix case that PR deliberately left out. `versionCheck` deletes every letter from a version string. Tencent#588 stopped "3.11.0rc2" from collapsing into "3.11.02" (= 3.11.2) by rewriting a letter run between two digits as a pre-release separator. A label with no trailing digit never matched `([0-9])[A-Za-z]+([0-9])`, so it still falls through to the letter-stripping step: versionCheck("3.11.0rc") => "3.11.0" versionCheck("3.11.0alpha") => "3.11.0" versionCheck("3.11.0beta") => "3.11.0" A release candidate is then indistinguishable from its own release, so a rule of `version < "3.11.0"` reports a target running 3.11.0rc as unaffected. That is a false negative on exactly the pre-release builds most likely to still carry the bug. Simply widening the match to make the trailing digits optional emits a dangling "3.11.0-", so instead the label is lifted out before the letters are stripped and re-appended afterwards: versionCheck("3.11.0rc") => "3.11.0-rc" versionCheck("3.11.0alpha") => "3.11.0-alpha" Keeping the label rather than only its number also fixes ordering *between* labels, which the previous form could not express: "3.11.0a1" and "3.11.0rc1" both normalized to "3.11.0-1" and compared equal. They now order correctly: 3.11.0-a1 < 3.11.0-rc1 3.11.0-alpha < 3.11.0-beta < 3.11.0-rc < 3.11.0 < 3.11.1 Two deliberate limits on the match: - The separator may be "-" but not ".", so "1.2.3.RELEASE" keeps normalizing to "1.2.3.0". That spelling denotes a final release, and treating it as a pre-release would sort it before "1.2.3". - The match is anchored at the end, so only a trailing label is treated as a pre-release. This changes output for versions Tencent#588 already handled ("3.11.0rc2" now gives "3.11.0-rc2" rather than "3.11.0-2"). Relative ordering against the release is unchanged; the label is simply preserved. The existing expectations are updated and kept as regression guards. It also fixes "1.2.3-rc", which previously normalized to the degenerate "1.2.3-". Tests: the value table gains the bare-suffix labels, the already-hyphenated spellings and the ".RELEASE" guard, and a new ordering test asserts each normalized pre-release parses and sorts before 3.11.0 and 3.11.1, with alpha < beta < rc. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
bda9ed5 to
633e186
Compare
|
Rebased onto It reduces to the single follow-up commit you asked for; The One note, since the file diff moved even though my commit did not.
|
|
Rebase confirmed, thanks. Head The diff itself is unchanged from what I reviewed, so nothing needs a second look:
Behavior change to note for the changelog: versions #588 already handled now normalize with the label kept ( LGTM — ready to merge after #588. (Review comment only, not merging.) |
Follow-up to #588, as invited there. That PR fixed the digit-splicing case and deliberately left the bare suffix out of scope; this handles it.
Addresses the issue behind #588.
The bug
versionCheckstrips every letter from a version string. #588 stopped3.11.0rc2from collapsing into3.11.02(= 3.11.2) by rewriting a letter run between two digits as a pre-release separator. A label with no trailing digit never matches([0-9])[A-Za-z]+([0-9]), so it still falls through to the letter-stripping step:A release candidate becomes indistinguishable from its own release. An advisory rule of
version < "3.11.0"therefore reports a target running3.11.0rcas unaffected — a false negative on exactly the pre-release builds most likely to still carry the bug.The fix
As you noted, widening the match to make the trailing digits optional would emit a dangling
3.11.0-. Instead the label is lifted out before the letters are stripped, then re-appended:Keeping the label itself, rather than only its number, also fixes ordering between labels — something the previous form could not express, since
3.11.0a1and3.11.0rc1both normalized to3.11.0-1and compared equal:Two deliberate limits on the match:
-but not., so1.2.3.RELEASEkeeps normalizing to1.2.3.0. That spelling denotes a final release; treating it as a pre-release would wrongly sort it before1.2.3.One behaviour change to flag
This changes output for versions #588 already handled:
3.11.0rc23.11.0-23.11.0-rc21.2.3b11.2.3-11.2.3-b11.2.3-rc11.2.3-11.2.3-rc1Ordering relative to the release is unchanged in every case — the label is simply preserved rather than discarded. The existing expectations are updated and kept as regression guards, per your request. This also fixes
1.2.3-rc, which previously normalized to the degenerate1.2.3-.Tests
As requested, the bare-suffix cases (
rc,alpha,beta) plus the existing digit-suffixed cases are all present as regression guards, with ordering assertions against3.11.0and3.11.1:TestVersionCheckPreRelease— value table, extended with bare-suffix labels, the already-hyphenated spellings, and the.RELEASEguard.TestVersionCheckPreReleaseOrdering— new. Asserts every normalized pre-release parses underhashicorp/go-versionand sorts before3.11.0and3.11.1, includingalpha < beta < rc.TestAdvisoryEvalPreRelease— unchanged from fix(parser): keep pre-release versions below their release in versionCheck #588, still passing.All pass, along with
go vetandgofmt.One note on how I verified: the full module's dependency download kept timing out on this machine, so I ran
synax.goandsynax_test.goin an isolated module with onlyhashicorp/go-versionand a stubbedgologger(whichversionCheckdoes not touch). Every test in the file passes there, and I separately cross-checked the value and ordering tables against the realhashicorp/go-version. CI will be the first run against the full tree.