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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ and the project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.
- Binary-probe fallback in `guide.sh` when the post-install snapshot refresh is stale.

### Fixed
- difftastic 0.71.0 puts the version into its release file names (`difft-0.71.0-x86_64-unknown-linux-gnu.tar.gz`); the catalog download URL now includes it. byobu is tagged `trustmux-v7.19` since the trustmux rename, and those tags fill the first page of the tags API, so the installer found no stable tag; it now accepts both tag forms.
- `cmd_update_local` in MERGE mode now refreshes multi-version cycle entries (`python@3.14`, …) instead of only the base-tool entry. Resolved false-negative "Upgrade did not succeed" messages after successful uv installs.

### Changed
Expand Down
4 changes: 2 additions & 2 deletions catalog/difftastic.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"homepage": "https://github.com/Wilfred/difftastic",
"github_repo": "Wilfred/difftastic",
"binary_name": "difft",
"download_url_template": "https://github.com/Wilfred/difftastic/releases/download/{version}/difft-{arch}-unknown-linux-gnu.tar.gz",
"download_url_template": "https://github.com/Wilfred/difftastic/releases/download/{version}/difft-{version}-{arch}-unknown-linux-gnu.tar.gz",
"arch_map": {
"x86_64": "x86_64",
"aarch64": "aarch64"
Expand All @@ -17,7 +17,7 @@
"priority": 1,
"config": {
"repo": "Wilfred/difftastic",
"asset_pattern": "difft-x86_64-unknown-linux-gnu.tar.gz"
"asset_pattern": "difft-.*-x86_64-unknown-linux-gnu.tar.gz"
}
},
{
Expand Down
48 changes: 33 additions & 15 deletions scripts/install_byobu.sh
Original file line number Diff line number Diff line change
Expand Up @@ -53,18 +53,22 @@
fi
}

get_target_version() {
# Print the newest stable release tag. Upstream tags releases both as "7.19"
# and, since the trustmux rename, as "trustmux-v7.19"; the prefixed tags fill
# the first page of the tags API, so accept both forms. For equal versions
# the plain tag wins.
get_target_tag() {
local tags_json=""
local version=""

tags_json="$(github_api_get "repos/$GITHUB_REPO/tags?per_page=100")" || tags_json=""

version="$(printf '%s' "$tags_json" |
printf '%s' "$tags_json" |
jq -r 'if type == "array" then .[].name else empty end' |
grep -E '^[0-9]+([.][0-9]+)+$' |
sort -V |
tail -1)"
printf '%s' "$version"
grep -E '^(trustmux-v)?[0-9]+([.][0-9]+)+$' |
awk '{ v = $0; sub(/^trustmux-v/, "", v); print v "\t" ($0 == v ? 1 : 0) "\t" $0 }' |
sort -t "$(printf '\t')" -k1,1V -k2,2n |
tail -1 |
cut -f3 || true
}

remove_manifest_files() {
Expand All @@ -84,6 +88,9 @@

install_byobu() {
local version="${1:-}"
local tag="$version"
local candidate=""
local -a tags=()
local before=""
local after=""
local archive=""
Expand All @@ -96,7 +103,13 @@

if [ -z "$version" ]; then
echo "[$TOOL] Fetching latest stable tag..." >&2
version="$(get_target_version)"
tag="$(get_target_tag)"
fi
version="${tag#trustmux-v}"
# An explicit plain version may exist only as trustmux-v<version>
tags=("$tag")
if [ "$tag" = "$version" ]; then

Check failure on line 111 in scripts/install_byobu.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=netresearch_coding_agent_cli_toolset&issues=AaDDoD0Hho7Mrq980rZ-&open=AaDDoD0Hho7Mrq980rZ-&pullRequest=150
tags+=("trustmux-v$version")
fi
if ! grep -Eq '^[0-9]+([.][0-9]+)+$' <<<"$version"; then
echo "[$TOOL] Error: Invalid stable version: ${version:-<none>}" >&2
Expand All @@ -108,13 +121,18 @@
BUILD_LOG="$BUILD_TMPDIR/build.log"
archive="$BUILD_TMPDIR/byobu-$version.tar.gz"
stage_dir="$BUILD_TMPDIR/stage"
url="https://github.com/$GITHUB_REPO/archive/refs/tags/${version}.tar.gz"

echo "[$TOOL] Downloading $url..." >&2
if ! curl --proto '=https' --proto-redir '=https' -fL \
--retry 3 --retry-delay 1 --connect-timeout 10 \
"$url" -o "$archive"; then
echo "[$TOOL] Error: Failed to download $url" >&2
url=""
for candidate in "${tags[@]}"; do
echo "[$TOOL] Downloading tag $candidate..." >&2
if curl --proto '=https' --proto-redir '=https' -fsSL \
--retry 3 --retry-delay 1 --connect-timeout 10 \
"https://github.com/$GITHUB_REPO/archive/refs/tags/${candidate}.tar.gz" -o "$archive"; then
url="https://github.com/$GITHUB_REPO/archive/refs/tags/${candidate}.tar.gz"
break
fi
done
if [ -z "$url" ]; then

Check failure on line 134 in scripts/install_byobu.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=netresearch_coding_agent_cli_toolset&issues=AaDDoD0Hho7Mrq980rZ_&open=AaDDoD0Hho7Mrq980rZ_&pullRequest=150
echo "[$TOOL] Error: Failed to download tag(s): ${tags[*]}" >&2
return 1
fi
if ! tar -xzf "$archive" -C "$BUILD_TMPDIR"; then
Expand Down
3 changes: 2 additions & 1 deletion tests/test_catalog_and_collectors.py
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,8 @@ def test_byobu_installer_is_executable_and_filters_stable_tags(self):

content = script_path.read_text()
assert "^[0-9]+([.][0-9]+)+$" in content
assert "archive/refs/tags/${version}.tar.gz" in content
# The tag, not the version: releases are tagged "trustmux-v7.19" too
assert "archive/refs/tags/${candidate}.tar.gz" in content
assert './configure --prefix="$INSTALL_PREFIX"' in content
assert "$INSTALL_PREFIX/bin/byobu" in content
assert "uninstall)" in content
Expand Down
44 changes: 42 additions & 2 deletions tests/test_install_gh_fallback.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,18 +92,58 @@ def test_fails_cleanly_when_neither_source_answers(self, fake_bin, tmp_path):
@skip_on_windows
class TestGhErrorBodyFallback:
def test_byobu_falls_back_to_curl_when_gh_fails(self, fake_bin, tmp_path):
proc = _run_sourced("install_byobu.sh", "get_target_version", fake_bin, tmp_path)
proc = _run_sourced("install_byobu.sh", "get_target_tag", fake_bin, tmp_path)
assert proc.returncode == 0, proc.stderr
assert proc.stdout.strip() == "7.18"
assert "Cannot index" not in proc.stderr

def test_byobu_uses_gh_result_when_gh_succeeds(self, fake_bin, tmp_path):
_write_stub(fake_bin, "gh", f"printf '%s' '{BYOBU_TAGS_JSON}'\n")
_write_stub(fake_bin, "curl", "exit 99\n")
proc = _run_sourced("install_byobu.sh", "get_target_version", fake_bin, tmp_path)
proc = _run_sourced("install_byobu.sh", "get_target_tag", fake_bin, tmp_path)
assert proc.returncode == 0, proc.stderr
assert proc.stdout.strip() == "7.18"

def test_byobu_accepts_trustmux_prefixed_tags(self, fake_bin, tmp_path):
# Real first page of the tags API after the trustmux rename: no plain tag on it
tags = (
'[{"name":"trustmux-v7.20rc5"},{"name":"trustmux-v7.19"},'
'{"name":"trustmux-v7.19rc17"},{"name":"trustmux-v7.18"}]'
)
_write_stub(fake_bin, "gh", f"printf '%s' '{tags}'\n")
proc = _run_sourced("install_byobu.sh", "get_target_tag", fake_bin, tmp_path)
assert proc.returncode == 0, proc.stderr
assert proc.stdout.strip() == "trustmux-v7.19"

def test_byobu_prefers_plain_tag_for_equal_versions(self, fake_bin, tmp_path):
tags = '[{"name":"trustmux-v7.19"},{"name":"7.19"},{"name":"7.18"}]'
_write_stub(fake_bin, "gh", f"printf '%s' '{tags}'\n")
proc = _run_sourced("install_byobu.sh", "get_target_tag", fake_bin, tmp_path)
assert proc.returncode == 0, proc.stderr
assert proc.stdout.strip() == "7.19"

def test_byobu_explicit_version_falls_back_to_trustmux_tag(self, fake_bin, tmp_path):
# "install 7.20" when upstream only tagged trustmux-v7.20: the plain tag 404s
for cmd in ("make", "autoreconf", "automake", "autoconf"):
_write_stub(fake_bin, cmd, "exit 0\n")
_write_stub(
fake_bin,
"curl",
"""for arg in "$@"; do
case "$arg" in
*/refs/tags/trustmux-v7.20.tar.gz) echo "archive" > "${@: -1}"; exit 0 ;;
esac
done
exit 22
""",
)
proc = _run_sourced("install_byobu.sh", "install_byobu 7.20", fake_bin, tmp_path)
assert proc.returncode == 1
# Reached the extract step with the prefixed tag; the stub archive is not a tarball
assert "Invalid source archive: https://github.com/dustinkirkland/byobu/archive/refs/tags/trustmux-v7.20.tar.gz" in (
proc.stderr
)

def test_tmux_falls_back_to_release_redirect_when_gh_fails(self, fake_bin, tmp_path):
proc = _run_sourced("install_tmux.sh", "get_target_version", fake_bin, tmp_path)
assert proc.returncode == 0, proc.stderr
Expand Down
Loading