From 8d3863ba9ddb1b69d1490999492d054cb6e6a295 Mon Sep 17 00:00:00 2001 From: danilaverbena Date: Tue, 21 Jul 2026 01:58:57 +0300 Subject: [PATCH] fix(arcup): honor SemVer prerelease precedence in version_gt version_gt stripped the prerelease suffix from both operands before comparing, so versions differing only in prerelease (e.g. 0.3.0 vs 0.3.0-rc.1) compared as equal and the installer's self-update check failed to see a stable release as newer than a prerelease. Implement SemVer section 11 precedence: compare core numerically, then apply prerelease rules (no-prerelease outranks prerelease; dot-separated identifiers compared numerically/lexically; more identifiers outrank fewer). Fixes #205. --- arcup/arcup | 51 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/arcup/arcup b/arcup/arcup index 3590cd3..4dff8dc 100755 --- a/arcup/arcup +++ b/arcup/arcup @@ -262,16 +262,24 @@ version_gt() { [ "$1" = "$2" ] && return 1 # Remove 'v' prefix if present - local ver1="${1#v}" - local ver2="${2#v}" - ver1="${ver1%%-*}" - ver2="${ver2%%-*}" - + local v1="${1#v}" + local v2="${2#v}" + + # Split into core "major.minor.patch" and prerelease; drop build metadata (+...), + # which SemVer ignores for precedence. + local core1="${v1%%-*}" pre1="" + [ "$v1" = "$core1" ] || pre1="${v1#*-}" + local core2="${v2%%-*}" pre2="" + [ "$v2" = "$core2" ] || pre2="${v2#*-}" + core1="${core1%%+*}"; core2="${core2%%+*}" + pre1="${pre1%%+*}"; pre2="${pre2%%+*}" + + local major1 minor1 patch1 major2 minor2 patch2 IFS=. read -r major1 minor1 patch1 < lower precedence + [ -z "$id2" ] && return 0 # more identifiers -> higher precedence + [ "$id1" = "$id2" ] && continue + if [[ "$id1" =~ ^[0-9]+$ ]] && [[ "$id2" =~ ^[0-9]+$ ]]; then + [ "$id1" -gt "$id2" ] && return 0 + [ "$id1" -lt "$id2" ] && return 1 + elif [[ "$id1" =~ ^[0-9]+$ ]]; then + return 1 # numeric identifiers rank lower than alphanumeric + elif [[ "$id2" =~ ^[0-9]+$ ]]; then + return 0 + else + [[ "$id1" > "$id2" ]] && return 0 + [[ "$id1" < "$id2" ]] && return 1 + fi + done return 1 }