Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion scripts/linux/build_deb.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ if ! command -v dpkg-deb >/dev/null 2>&1; then
fi

VERSION="$(grep '^version:' "$ROOT/pubspec.yaml" | sed 's/^version: //; s/+.*//')"
# The file keeps the tag form; the package version sorts a beta before its
# final release (0.5.0~beta.1, #1494).
DEB_VERSION="$("$ROOT/scripts/linux/package_version.sh" "$VERSION")"
OUT="${2:-$ROOT/Querya-Desktop-${VERSION}-linux.deb}"
ARCH="$(dpkg --print-architecture 2>/dev/null || echo amd64)"

Expand Down Expand Up @@ -61,7 +64,7 @@ INSTALLED_SIZE="$(du -sk "$PKG" | awk '{print $1}')"

cat > "$PKG/DEBIAN/control" <<EOF
Package: querya-desktop
Version: ${VERSION}
Version: ${DEB_VERSION}
Section: database
Priority: optional
Architecture: ${ARCH}
Expand Down
7 changes: 4 additions & 3 deletions scripts/linux/build_rpm.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@ if ! command -v rpmbuild >/dev/null 2>&1; then
fi

VERSION="$(grep '^version:' "$ROOT/pubspec.yaml" | sed 's/^version: //; s/+.*//')"
# RPM Version must not contain '-' (it separates Version from Release).
# Keep artifact filename as the pubspec/marketing version (e.g. 0.4.11-b).
RPM_VERSION="${VERSION//-/.}"
# RPM Version must not contain '-' (it separates Version from Release), and a
# beta must sort before its final release: 0.5.0-beta.1 -> 0.5.0~beta.1 (#1494).
# The artifact file name keeps the pubspec / tag form.
RPM_VERSION="$("$ROOT/scripts/linux/package_version.sh" "$VERSION")"
OUT="${2:-$ROOT/Querya-Desktop-${VERSION}-linux.rpm}"

WORKDIR="$(mktemp -d "${TMPDIR:-/tmp}/querya-rpm.XXXXXX")"
Expand Down
22 changes: 22 additions & 0 deletions scripts/linux/package_version.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env bash
# The version string a .deb / .rpm carries for a pubspec version (#1494).
#
# ./scripts/linux/package_version.sh 0.5.0-beta.1 # -> 0.5.0~beta.1
#
# or `source` it and call `package_version`.
#
# A SemVer pre-release must sort *before* its final release. As is, dpkg reads
# `0.5.0-beta.1` as upstream 0.5.0 with revision `beta.1`, newer than `0.5.0`,
# and rpm's `0.5.0.beta.1` is newer too, so beta users would never be upgraded
# to the final package. Both sort `~` before anything, even the end of the
# string: `0.5.0~beta.1 < 0.5.0`. Any further `-` becomes `.`, since `-`
# separates the Debian revision and the RPM release.

package_version() {
printf '%s\n' "$1" | sed 's/-/~/; s/-/./g'
}

if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
set -euo pipefail
package_version "${1:?usage: package_version.sh <version>}"
fi
60 changes: 60 additions & 0 deletions test/packaging/package_version_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import 'dart:io';

import 'package:flutter_test/flutter_test.dart';

/// `.deb` / `.rpm` versions sort a beta before its final release (#1494).
void main() {
final skipNonPosix = Platform.isWindows ? 'needs bash' : null;

String packageVersion(String version) {
final r = Process.runSync(
'bash',
['scripts/linux/package_version.sh', version],
);
expect(r.exitCode, 0, reason: '${r.stderr}');
return (r.stdout as String).trim();
}

bool has(String tool) =>
Process.runSync('sh', ['-c', 'command -v $tool']).exitCode == 0;

test('a pre-release gets ~ before its label; a final version is unchanged',
() {
expect(packageVersion('0.5.0'), '0.5.0');
expect(packageVersion('0.5.0-beta.1'), '0.5.0~beta.1');
expect(packageVersion('0.5.0-rc-2'), '0.5.0~rc.2');
}, skip: skipNonPosix);

// Pairs that must sort as given: older first.
final ordered = [
('0.4.19', '0.5.0-beta.1'),
('0.5.0-beta.1', '0.5.0-beta.2'),
('0.5.0-beta.2', '0.5.0-beta.10'),
('0.5.0-beta.2', '0.5.0'),
('0.5.0', '0.5.1'),
];

test('dpkg upgrades a beta to the final release', () {
for (final (older, newer) in ordered) {
final r = Process.runSync('dpkg', [
'--compare-versions',
packageVersion(older),
'lt',
packageVersion(newer),
]);
expect(r.exitCode, 0, reason: '$older should sort before $newer');
}
}, skip: skipNonPosix ?? (has('dpkg') ? null : 'dpkg is not installed'));

test('rpm upgrades a beta to the final release', () {
for (final (older, newer) in ordered) {
final a = packageVersion(older), b = packageVersion(newer);
final r = Process.runSync(
'rpm',
['--eval', '%{lua: print(rpm.vercmp("$a", "$b"))}'],
);
expect((r.stdout as String).trim(), '-1',
reason: '$older should sort before $newer');
}
}, skip: skipNonPosix ?? (has('rpm') ? null : 'rpm is not installed'));
}
Loading