pacman-helper: inline a vercmp Bash function into the patched repo-add#714
Open
dscho wants to merge 1 commit into
Open
pacman-helper: inline a vercmp Bash function into the patched repo-add#714dscho wants to merge 1 commit into
vercmp Bash function into the patched repo-add#714dscho wants to merge 1 commit into
Conversation
When `pacman-helper.sh quick_add` is run from the `pacman-packages`
action of `git-for-windows/git-for-windows-automation`, the SDK that
the action sets up is the `build-installers` flavor, which
intentionally ships only a small subset of `/usr/bin`. `vercmp.exe`
is not in that subset, so every `repo-add` invocation prints two lines
of noise of the form:
D:/a/_temp/build-extra/repo-add: line 254: vercmp: command not found
D:/a/_temp/build-extra/repo-add: line 254: ((: > 0 : arithmetic syntax error: operand expected (error token is "> 0 ")
(see e.g.
https://github.com/git-for-windows/git-for-windows-automation/actions/runs/27414389819/job/81026080873,
which produced 64 such pairs before the unrelated `db3` leak bit it).
The errors themselves are benign because we invoke `repo-add` without
`--prevent-downgrade`, so the suppressed "newer version already
present" warning has no functional consequence, but I would rather
not pollute release logs with them.
Adding `vercmp.exe` (or any of the other plausible interpreters that
came up while exploring this -- `awk.exe`, `perl`, `expr.exe`) to
`build-installers` would defeat the point of that minimal SDK.
Instead, extend the existing sed-based patching of `/usr/bin/repo-add`
to also inject a small Bash function called `vercmp`. The patched
copy is what `pacman-helper.sh` invokes, and `repo-add` is itself a
Bash script, so the injected function is in scope at the call site
with no PATH manipulation, no `export -f` gymnastics across process
boundaries, and `pacman-helper.sh` itself stays POSIX `sh`.
The algorithm splits each version string on runs of non-alphanumeric
characters and walks the resulting arrays segment by segment: two
numeric segments compare numerically, a numeric vs. alphanumeric
segment lets the numeric side win (matching pacman's behavior of
treating pre-release suffixes as older), and otherwise it falls back
to lexical comparison. When one string runs out of segments first,
the longer string wins unless its extra segment starts with a letter,
in which case it is treated as a pre-release. This is essentially
the same shape as the prior-art `version_compare` in
`git-extra/git-update-git-for-windows`, and it gets the cases that
the `pacman-packages` action ever encounters right; in particular it
places `2.55.0.rc0.windows.1-1` below `2.55.0.1-1`, which matters
because the RC needs to be considered older than the release. All
nine test cases from `git-update-git-for-windows --test-version-compare`
pass, and I have also verified the failing-run strings and the
strict-equality case (which the prior-art function gets wrong but
which `vercmp`'s contract requires to be `0`).
Within a mixed-alphanumeric segment such as `rc10` vs. `rc2` the
lexical fallback gets the order wrong, but Git for Windows has never
published an RC past single digits, so a full rpm-style
sub-tokenization stays out of scope. `repo-remove` next door is
patched the same way but does not call `vercmp`, so its patching
block is intentionally left alone.
Assisted-by: Opus 4.7
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
When
pacman-helper.sh quick_addis run from thepacman-packagesaction ofgit-for-windows/git-for-windows-automation, the SDK that the action sets up is thebuild-installersflavor, which intentionally ships only a small subset of/usr/bin.vercmp.exeis not in that subset, so everyrepo-addinvocation prints two lines of noise of the form:(see e.g. run 27414389819, which produced 64 such pairs before the unrelated
db3leak bit it; that one is already fixed onmainas 887f246).The errors themselves are benign because we invoke
repo-addwithout--prevent-downgrade, so the suppressed "newer version already present" warning has no functional consequence, but I'd rather not pollute release logs with them.Adding
vercmp.exe(or any of the other plausible interpreters that came up while exploring this:awk.exe,perl,expr.exe) tobuild-installerswould defeat the point of that minimal SDK. Instead, this extends the existing sed-based patching of/usr/bin/repo-addto also inject a small Bash function calledvercmp. The patched copy is whatpacman-helper.shinvokes, andrepo-addis itself a Bash script, so the injected function is in scope at the call site with no PATH manipulation, noexport -fgymnastics across process boundaries, andpacman-helper.shitself stays POSIXsh.The algorithm is essentially the same shape as the prior-art
version_compareingit-extra/git-update-git-for-windows, with one fix (strict equality returns0, whichvercmp's contract requires but the prior art got wrong). It splits each version string on runs of non-alphanumeric characters and walks the resulting arrays segment by segment: two numeric segments compare numerically, a numeric vs. alphanumeric segment lets the numeric side win (matching pacman's behavior of treating pre-release suffixes as older), and otherwise it falls back to lexical comparison. When one string runs out of segments first, the longer string wins unless its extra segment starts with a letter, in which case it is treated as a pre-release.All nine test cases from
git-update-git-for-windows --test-version-comparepass, plus the strict-equality case and the exact strings from the failing run:Known limitation
Within a mixed-alphanumeric segment such as
rc10vs.rc2the lexical fallback gets the order wrong (would sayrc10<rc2), but Git for Windows has never published an RC past single digits, so a full rpm-style sub-tokenization stays out of scope.Scope
repo-removenext door is patched the same way but does not callvercmp(it only takes package names, not versions), so its patching block is intentionally left alone.