compareAppVersions function
Compares a to b as semver strings, per this policy:
- Major/minor/patch compare numerically first.
- Equal core version: a prerelease tag (
-beta,-rc.1, ...) sorts BEFORE the same core version with no prerelease (1.2.3-beta<1.2.3) — a prerelease is not yet the real release. - Build metadata (
+001) is ignored entirely, never affects ordering. - Either string failing to parse (not
x.y.z[-pre][+build]) returnsnull— never throws, never guesses an order for invalid input.
Implementation
int? compareAppVersions(String a, String b) {
final va = _Semver.tryParse(a);
final vb = _Semver.tryParse(b);
if (va == null || vb == null) return null;
final coreCompare = [
va.major.compareTo(vb.major),
va.minor.compareTo(vb.minor),
va.patch.compareTo(vb.patch),
].firstWhere((c) => c != 0, orElse: () => 0);
if (coreCompare != 0) return coreCompare;
if (va.prerelease == vb.prerelease) return 0;
if (va.prerelease == null) return 1; // a is a release, b is a prerelease
if (vb.prerelease == null) return -1; // a is a prerelease, b is a release
return _comparePrerelease(va.prerelease!, vb.prerelease!);
}