Show sibling projects' versions, and let version update them
shellcheck / shellcheck (push) Failing after 19s
shellcheck / shellcheck (push) Failing after 19s
A sibling's version is its latest git tag (v1.4.0, or v1.4.0+3 for commits after it), or, without tags, its commit's date and short hash, like CoreDesktop's own. The version shown as available is that of the newest commit on the default branch, which is what update installs. sibling list shows each sibling's version. sibling check fetches every sibling at once and shows which have a newer version, and sibling update [name...] updates the named siblings or all of them. 71-siblings.sh now runs sibling update, so update and version share one way of updating. version lists the installed siblings with any newer version and, when run in a terminal, asks for each one whether to update it now. version --check and the update notification still only look at CoreDesktop. The sibling skill docs describe how to release a version by tagging it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
# sibling runs against real git repositories: each sibling is a clone of a
|
||||
# repo in $ORIGINS, which a test can add commits and tags to.
|
||||
|
||||
setup() {
|
||||
common_setup
|
||||
export GIT_AUTHOR_NAME=Test GIT_AUTHOR_EMAIL=test@example.com
|
||||
export GIT_COMMITTER_NAME=Test GIT_COMMITTER_EMAIL=test@example.com
|
||||
ORIGINS="$BATS_TEST_TMPDIR/origins"
|
||||
SIBLINGS="$HOME/.local/share/siblings"
|
||||
mkdir -p "$ORIGINS" "$SIBLINGS"
|
||||
}
|
||||
|
||||
# origin NAME: make a repo with one commit, and clone it as a sibling
|
||||
origin() {
|
||||
git init -q -b main "$ORIGINS/$1"
|
||||
commit "$1" first
|
||||
git clone -q "$ORIGINS/$1" "$SIBLINGS/$1"
|
||||
}
|
||||
|
||||
# commit NAME MESSAGE: add a commit to NAME's origin
|
||||
commit() {
|
||||
echo "$2" >> "$ORIGINS/$1/log"
|
||||
git -C "$ORIGINS/$1" add -A
|
||||
git -C "$ORIGINS/$1" commit -qm "$2"
|
||||
}
|
||||
|
||||
@test "sibling list shows a tagged sibling's tag, and an untagged one's date and hash" {
|
||||
origin tagged
|
||||
git -C "$ORIGINS/tagged" tag v1.0.0
|
||||
git -C "$SIBLINGS/tagged" pull -q
|
||||
origin plain
|
||||
|
||||
run bash "$REPO/sibling" list
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"tagged v1.0.0 "*"$ORIGINS/tagged"* ]]
|
||||
[[ "$output" =~ plain\ +[0-9]{4}\.[0-9]{2}\.[0-9]{2}\ \([0-9a-f]+\) ]]
|
||||
}
|
||||
|
||||
@test "sibling list counts the commits since the latest tag" {
|
||||
origin tools
|
||||
git -C "$ORIGINS/tools" tag v1.0.0
|
||||
commit tools second
|
||||
commit tools third
|
||||
git -C "$SIBLINGS/tools" pull -q
|
||||
|
||||
run bash "$REPO/sibling" list
|
||||
[[ "$output" == *"tools v1.0.0+2 "* ]]
|
||||
}
|
||||
|
||||
@test "sibling check shows what's newer, what's up to date, and what it couldn't reach" {
|
||||
origin newer
|
||||
git -C "$ORIGINS/newer" tag v1.0.0
|
||||
git -C "$SIBLINGS/newer" pull -q
|
||||
commit newer second
|
||||
git -C "$ORIGINS/newer" tag v1.1.0
|
||||
origin current
|
||||
origin gone
|
||||
rm -rf "$ORIGINS/gone"
|
||||
|
||||
run bash "$REPO/sibling" check
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"newer v1.0.0"*"v1.1.0 is available"* ]]
|
||||
[[ "$output" == *"current "*"up to date"* ]]
|
||||
[[ "$output" == *"gone "*"couldn't check"* ]]
|
||||
|
||||
run bash "$REPO/sibling" check --porcelain
|
||||
[[ "$output" == *$'newer\tv1.0.0\tv1.1.0'* ]]
|
||||
[[ "$output" == *$'gone\t'*$'\t?'* ]]
|
||||
}
|
||||
|
||||
@test "sibling check exits 1 when nothing is newer" {
|
||||
origin current
|
||||
run bash "$REPO/sibling" check
|
||||
[ "$status" -eq 1 ]
|
||||
[[ "$output" == *"up to date"* ]]
|
||||
}
|
||||
|
||||
@test "sibling update updates only the siblings named" {
|
||||
origin one
|
||||
origin two
|
||||
echo 'echo ran >> "$HOME/one-updated"' > "$ORIGINS/one/update.sh"
|
||||
commit one second
|
||||
git -C "$ORIGINS/one" tag v2.0.0
|
||||
commit two second
|
||||
|
||||
run bash "$REPO/sibling" update one
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"one is at v2.0.0."* ]]
|
||||
[ "$(cat "$HOME/one-updated")" = ran ]
|
||||
[ "$(git -C "$SIBLINGS/two" rev-list --count HEAD)" -eq 1 ]
|
||||
}
|
||||
|
||||
@test "sibling update with no names updates them all, and reports a failing update.sh" {
|
||||
origin one
|
||||
origin two
|
||||
echo 'exit 1' > "$ORIGINS/one/update.sh"
|
||||
commit one second
|
||||
commit two second
|
||||
|
||||
run bash "$REPO/sibling" update
|
||||
[ "$status" -eq 1 ]
|
||||
[[ "$output" == *"one's update.sh failed"* ]]
|
||||
[ "$(git -C "$SIBLINGS/two" rev-list --count HEAD)" -eq 2 ]
|
||||
}
|
||||
|
||||
@test "sibling update refuses a sibling that isn't installed" {
|
||||
run bash "$REPO/sibling" update nope
|
||||
[ "$status" -eq 1 ]
|
||||
[[ "$output" == *"No sibling named 'nope' is installed."* ]]
|
||||
}
|
||||
+47
-3
@@ -4,15 +4,19 @@ load test_helper
|
||||
|
||||
# version runs from a fake checkout with fake git, uname, pacman and
|
||||
# checkupdates. The running kernel's modules never exist here, so the kernel
|
||||
# line always also says a newer one is installed.
|
||||
# line always also says a newer one is installed. Sibling projects are real git
|
||||
# repositories: only git commands on the fake checkout are faked.
|
||||
|
||||
setup() {
|
||||
common_setup
|
||||
CD="$HOME/.local/share/coredesktop"
|
||||
mkdir -p "$CD"
|
||||
cp "$REPO/version" "$REPO/utils.sh" "$CD/"
|
||||
cp "$REPO/version" "$REPO/utils.sh" "$REPO/sibling" "$CD/"
|
||||
|
||||
stub git 'case "$3" in
|
||||
export CD REAL_GIT
|
||||
REAL_GIT="$(command -v git)"
|
||||
stub git '[ "$2" = "$CD" ] || exec "$REAL_GIT" "$@"
|
||||
case "$3" in
|
||||
rev-parse) exit 0 ;;
|
||||
log) echo "2026.10.31 (6bc4fdc)" ;;
|
||||
fetch) exit 1 ;;
|
||||
@@ -89,3 +93,43 @@ setup() {
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" != *"mirror"* ]]
|
||||
}
|
||||
|
||||
# sibling_repo NAME: a sibling at v1.0.0 whose origin has a newer v1.1.0
|
||||
sibling_repo() {
|
||||
export GIT_AUTHOR_NAME=Test GIT_AUTHOR_EMAIL=test@example.com
|
||||
export GIT_COMMITTER_NAME=Test GIT_COMMITTER_EMAIL=test@example.com
|
||||
local origin="$BATS_TEST_TMPDIR/origins/$1"
|
||||
git init -q -b main "$origin"
|
||||
echo 'echo "$PWD" >> "$HOME/updated"' > "$origin/update.sh"
|
||||
git -C "$origin" add -A
|
||||
git -C "$origin" commit -qm first
|
||||
git -C "$origin" tag v1.0.0
|
||||
git clone -q "$origin" "$HOME/.local/share/siblings/$1"
|
||||
git -C "$origin" commit -q --allow-empty -m second
|
||||
git -C "$origin" tag v1.1.0
|
||||
}
|
||||
|
||||
@test "version leaves out sibling projects when none are installed" {
|
||||
run bash "$CD/version"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" != *"Sibling"* ]]
|
||||
}
|
||||
|
||||
@test "version lists sibling projects, and doesn't ask to update without a terminal" {
|
||||
sibling_repo tools
|
||||
run bash "$CD/version" < /dev/null
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"Sibling projects"$'\n'" tools v1.0.0, v1.1.0 is available"* ]]
|
||||
[[ "$output" != *"Update tools"* ]]
|
||||
[ ! -f "$HOME/updated" ]
|
||||
}
|
||||
|
||||
@test "version updates the sibling projects the user says yes to" {
|
||||
sibling_repo keep
|
||||
sibling_repo tools
|
||||
run script -qec "bash '$CD/version'" /dev/null <<< $'n\ny'
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"Update keep to v1.1.0? [y/N]"* ]]
|
||||
[[ "$output" == *"tools is at v1.1.0."* ]]
|
||||
[ "$(cat "$HOME/updated")" = "$HOME/.local/share/siblings/tools" ]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user