From 730fe677eb7cd1fe8c2839fe2494c91809d603e3 Mon Sep 17 00:00:00 2001 From: Sal <59910950+ss-o@users.noreply.github.com> Date: Thu, 15 Oct 2026 06:12:18 +0100 Subject: [PATCH 1/2] chore(test): install test tools from z-shell repositories (#142) The native tier, make bin/zunit and the image fetched ZUnit, revolver and color from another organization's repositories, and bin/color and bin/revolver were tracked next to bin/zd although the install steps overwrite them. Build ZUnit from z-shell/zunit at bce183c, the same 0.8.2 release commit as before (the built file is byte-identical), take the helpers from the z-shell/src revision the image already used, point the docs at z-shell/zunit, and ignore the installed tools in bin/. Closes #142 --- .github/workflows/test-native.yml | 11 +- .gitignore | 5 + Makefile | 9 +- bin/color | 29 --- bin/revolver | 318 ------------------------------ docker/Dockerfile | 8 +- docs/writing-tests.md | 2 +- 7 files changed, 26 insertions(+), 356 deletions(-) delete mode 100644 bin/color delete mode 100644 bin/revolver diff --git a/.github/workflows/test-native.yml b/.github/workflows/test-native.yml index 592bd0e..7375f46 100644 --- a/.github/workflows/test-native.yml +++ b/.github/workflows/test-native.yml @@ -69,9 +69,14 @@ jobs: - name: Install zunit run: | mkdir -p bin - curl -fsSL 'https://raw.githubusercontent.com/zdharma/revolver/v0.2.4/revolver' > bin/revolver - curl -fsSL 'https://raw.githubusercontent.com/zdharma/color/d8f91ab5fcfceb623ae45d3333ad0e543775549c/color.zsh' > bin/color - git clone --depth 1 --branch v0.8.2 https://github.com/zdharma/zunit.git zunit.git + curl -fsSL 'https://raw.githubusercontent.com/z-shell/src/9335c8c14e0aaa845277f882969c146755e1241e/lib/zsh/snippets/revolver' > bin/revolver + curl -fsSL 'https://raw.githubusercontent.com/z-shell/src/9335c8c14e0aaa845277f882969c146755e1241e/lib/zsh/snippets/color.zsh' > bin/color + # ZUnit 0.8.2 as released (bce183c). z-shell/zunit's own v0.8.2 tag + # re-evaluates run arguments, which tests/helpers.zsh does not expect yet. + git init zunit.git + git -C zunit.git remote add origin https://github.com/z-shell/zunit.git + git -C zunit.git fetch --depth 1 origin bce183c39a3b51a3dd838835516a37222aad921f + git -C zunit.git checkout --detach FETCH_HEAD cd zunit.git && ./build.zsh && cd .. mv zunit.git/zunit bin/ chmod u+x bin/{color,revolver,zunit} diff --git a/.gitignore b/.gitignore index 897d5e5..502726a 100644 --- a/.gitignore +++ b/.gitignore @@ -133,3 +133,8 @@ NEWS.md Untitled-1.sh CLAUDE.md GEMINI.md + +# Test tools installed by `make bin/zunit` and test-native.yml; never committed. +/bin/color +/bin/revolver +/bin/zunit diff --git a/Makefile b/Makefile index 228eab1..a9a0112 100644 --- a/Makefile +++ b/Makefile @@ -70,12 +70,15 @@ controlled-build: bin/zunit: @echo "Installing zunit into bin/ ..." @mkdir -p bin - @curl -fsSL 'https://raw.githubusercontent.com/zdharma/revolver/v0.2.4/revolver' \ + @curl -fsSL 'https://raw.githubusercontent.com/z-shell/src/9335c8c14e0aaa845277f882969c146755e1241e/lib/zsh/snippets/revolver' \ > bin/revolver - @curl -fsSL 'https://raw.githubusercontent.com/zdharma/color/d8f91ab5fcfceb623ae45d3333ad0e543775549c/color.zsh' \ + @curl -fsSL 'https://raw.githubusercontent.com/z-shell/src/9335c8c14e0aaa845277f882969c146755e1241e/lib/zsh/snippets/color.zsh' \ > bin/color @rm -rf /tmp/zunit.git - @git clone --depth 1 https://github.com/zdharma/zunit.git /tmp/zunit.git + @git init -q /tmp/zunit.git + @git -C /tmp/zunit.git remote add origin https://github.com/z-shell/zunit.git + @git -C /tmp/zunit.git fetch -q --depth 1 origin bce183c39a3b51a3dd838835516a37222aad921f + @git -C /tmp/zunit.git checkout -q --detach FETCH_HEAD @cd /tmp/zunit.git && ./build.zsh @mv /tmp/zunit.git/zunit bin/zunit @chmod u+x bin/color bin/revolver bin/zunit diff --git a/bin/color b/bin/color deleted file mode 100644 index 86f3852..0000000 --- a/bin/color +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env zsh - -function color() { - local color=$1 style=$2 b=0 - - shift - - case $style in - bold|b) b=1; shift ;; - italic|i) b=2; shift ;; - underline|u) b=4; shift ;; - inverse|in) b=7; shift ;; - strikethrough|s) b=9; shift ;; - esac - - case $color in - black|b) echo "\033[${b};30m${@}\033[0;m" ;; - red|r) echo "\033[${b};31m${@}\033[0;m" ;; - green|g) echo "\033[${b};32m${@}\033[0;m" ;; - yellow|y) echo "\033[${b};33m${@}\033[0;m" ;; - blue|bl) echo "\033[${b};34m${@}\033[0;m" ;; - magenta|m) echo "\033[${b};35m${@}\033[0;m" ;; - cyan|c) echo "\033[${b};36m${@}\033[0;m" ;; - white|w) echo "\033[${b};37m${@}\033[0;m" ;; - *) echo "\033[${b};38;5;$(( ${color} ))m${@}\033[0;m" ;; - esac -} - -color "$@" diff --git a/bin/revolver b/bin/revolver deleted file mode 100644 index 51c3dba..0000000 --- a/bin/revolver +++ /dev/null @@ -1,318 +0,0 @@ -#!/usr/bin/env zsh - -local -A _revolver_spinners -_revolver_spinners=( - 'dots' '0.08 ⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏' - 'dots2' '0.08 ⣾ ⣽ ⣻ ⢿ ⡿ ⣟ ⣯ ⣷' - 'dots3' '0.08 ⠋ ⠙ ⠚ ⠞ ⠖ ⠦ ⠴ ⠲ ⠳ ⠓' - 'dots4' '0.08 ⠄ ⠆ ⠇ ⠋ ⠙ ⠸ ⠰ ⠠ ⠰ ⠸ ⠙ ⠋ ⠇ ⠆' - 'dots5' '0.08 ⠋ ⠙ ⠚ ⠒ ⠂ ⠂ ⠒ ⠲ ⠴ ⠦ ⠖ ⠒ ⠐ ⠐ ⠒ ⠓ ⠋' - 'dots6' '0.08 ⠁ ⠉ ⠙ ⠚ ⠒ ⠂ ⠂ ⠒ ⠲ ⠴ ⠤ ⠄ ⠄ ⠤ ⠴ ⠲ ⠒ ⠂ ⠂ ⠒ ⠚ ⠙ ⠉ ⠁' - 'dots7' '0.08 ⠈ ⠉ ⠋ ⠓ ⠒ ⠐ ⠐ ⠒ ⠖ ⠦ ⠤ ⠠ ⠠ ⠤ ⠦ ⠖ ⠒ ⠐ ⠐ ⠒ ⠓ ⠋ ⠉ ⠈' - 'dots8' '0.08 ⠁ ⠁ ⠉ ⠙ ⠚ ⠒ ⠂ ⠂ ⠒ ⠲ ⠴ ⠤ ⠄ ⠄ ⠤ ⠠ ⠠ ⠤ ⠦ ⠖ ⠒ ⠐ ⠐ ⠒ ⠓ ⠋ ⠉ ⠈ ⠈' - 'dots9' '0.08 ⢹ ⢺ ⢼ ⣸ ⣇ ⡧ ⡗ ⡏' - 'dots10' '0.08 ⢄ ⢂ ⢁ ⡁ ⡈ ⡐ ⡠' - 'dots11' '0.1 ⠁ ⠂ ⠄ ⡀ ⢀ ⠠ ⠐ ⠈' - 'dots12' '0.08 "⢀⠀" "⡀⠀" "⠄⠀" "⢂⠀" "⡂⠀" "⠅⠀" "⢃⠀" "⡃⠀" "⠍⠀" "⢋⠀" "⡋⠀" "⠍⠁" "⢋⠁" "⡋⠁" "⠍⠉" "⠋⠉" "⠋⠉" "⠉⠙" "⠉⠙" "⠉⠩" "⠈⢙" "⠈⡙" "⢈⠩" "⡀⢙" "⠄⡙" "⢂⠩" "⡂⢘" "⠅⡘" "⢃⠨" "⡃⢐" "⠍⡐" "⢋⠠" "⡋⢀" "⠍⡁" "⢋⠁" "⡋⠁" "⠍⠉" "⠋⠉" "⠋⠉" "⠉⠙" "⠉⠙" "⠉⠩" "⠈⢙" "⠈⡙" "⠈⠩" "⠀⢙" "⠀⡙" "⠀⠩" "⠀⢘" "⠀⡘" "⠀⠨" "⠀⢐" "⠀⡐" "⠀⠠" "⠀⢀" "⠀⡀"' - 'line' '0.13 - \\ | /' - 'line2' '0.1 ⠂ - – — – -' - 'pipe' '0.1 ┤ ┘ ┴ └ ├ ┌ ┬ ┐' - 'simpleDots' '0.4 ". " ".. " "..." " "' - 'simpleDotsScrolling' '0.2 ". " ".. " "..." " .." " ." " "' - 'star' '0.07 ✶ ✸ ✹ ✺ ✹ ✷' - 'star2' '0.08 + x *' - 'flip' "0.07 _ _ _ - \` \` ' ´ - _ _ _" - 'hamburger' '0.1 ☱ ☲ ☴' - 'growVertical' '0.12 ▁ ▃ ▄ ▅ ▆ ▇ ▆ ▅ ▄ ▃' - 'growHorizontal' '0.12 ▏ ▎ ▍ ▌ ▋ ▊ ▉ ▊ ▋ ▌ ▍ ▎' - 'balloon' '0.14 " " "." "o" "O" "@" "*" " "' - 'balloon2' '0.12 . o O ° O o .' - 'noise' '▓ ▒ ░' - 'bounce' '0.1 ⠁ ⠂ ⠄ ⠂' - 'boxBounce' '0.12 ▖ ▘ ▝ ▗' - 'boxBounce2' '0.1 ▌ ▀ ▐ ▄' - 'triangle' '0.05 ◢ ◣ ◤ ◥' - 'arc' '0.1 ◜ ◠ ◝ ◞ ◡ ◟' - 'circle' '0.12 ◡ ⊙ ◠' - 'squareCorners' '0.18 ◰ ◳ ◲ ◱' - 'circleQuarters' '0.12 ◴ ◷ ◶ ◵' - 'circleHalves' '0.05 ◐ ◓ ◑ ◒' - 'squish' '0.1 ╫ ╪' - 'toggle' '0.25 ⊶ ⊷' - 'toggle2' '0.08 ▫ ▪' - 'toggle3' '0.12 □ ■' - 'toggle4' '0.1 ■ □ ▪ ▫' - 'toggle5' '0.1 ▮ ▯' - 'toggle6' '0.3 ဝ ၀' - 'toggle7' '0.08 ⦾ ⦿' - 'toggle8' '0.1 ◍ ◌' - 'toggle9' '0.1 ◉ ◎' - 'toggle10' '0.1 ㊂ ㊀ ㊁' - 'toggle11' '0.05 ⧇ ⧆' - 'toggle12' '0.12 ☗ ☖' - 'toggle13' '0.08 = * -' - 'arrow' '0.1 ← ↖ ↑ ↗ → ↘ ↓ ↙' - 'arrow2' '0.12 ▹▹▹▹▹ ▸▹▹▹▹ ▹▸▹▹▹ ▹▹▸▹▹ ▹▹▹▸▹ ▹▹▹▹▸' - 'bouncingBar' '0.08 "[ ]" "[ =]" "[ ==]" "[ ===]" "[====]" "[=== ]" "[== ]" "[= ]"' - 'bouncingBall' '0.08 "( ● )" "( ● )" "( ● )" "( ● )" "( ●)" "( ● )" "( ● )" "( ● )" "( ● )" "(● )"' - 'pong' '0.08 "▐⠂ ▌" "▐⠈ ▌" "▐ ⠂ ▌" "▐ ⠠ ▌" "▐ ⡀ ▌" "▐ ⠠ ▌" "▐ ⠂ ▌" "▐ ⠈ ▌" "▐ ⠂ ▌" "▐ ⠠ ▌" "▐ ⡀ ▌" "▐ ⠠ ▌" "▐ ⠂ ▌" "▐ ⠈ ▌" "▐ ⠂▌" "▐ ⠠▌" "▐ ⡀▌" "▐ ⠠ ▌" "▐ ⠂ ▌" "▐ ⠈ ▌" "▐ ⠂ ▌" "▐ ⠠ ▌" "▐ ⡀ ▌" "▐ ⠠ ▌" "▐ ⠂ ▌" "▐ ⠈ ▌" "▐ ⠂ ▌" "▐ ⠠ ▌" "▐ ⡀ ▌" "▐⠠ ▌"' - 'shark' '0.12 "▐|\\____________▌" "▐_|\\___________▌" "▐__|\\__________▌" "▐___|\\_________▌" "▐____|\\________▌" "▐_____|\\_______▌" "▐______|\\______▌" "▐_______|\\_____▌" "▐________|\\____▌" "▐_________|\\___▌" "▐__________|\\__▌" "▐___________|\\_▌" "▐____________|\\▌" "▐____________/|▌" "▐___________/|_▌" "▐__________/|__▌" "▐_________/|___▌" "▐________/|____▌" "▐_______/|_____▌" "▐______/|______▌" "▐_____/|_______▌" "▐____/|________▌" "▐___/|_________▌" "▐__/|__________▌" "▐_/|___________▌" "▐/|____________▌"' -) - -### -# Output usage information and exit -### -function _revolver_usage() { - echo "\033[0;33mUsage:\033[0;m" - echo " revolver [options] " - echo - echo "\033[0;33mOptions:\033[0;m" - echo " -h, --help Output help text and exit" - echo " -v, --version Output version information and exit" - echo " -s, --style Set the spinner style" - echo - echo "\033[0;33mCommands:\033[0;m" - echo " start Start the spinner" - echo " update Update the message" - echo " stop Stop the spinner" - echo " demo Display an demo of each style" -} - -### -# The main revolver process, which contains the loop -### -function _revolver_process() { - local dir statefile state msg pid="$1" spinner_index=0 - - # Find the directory and load the statefile - dir=${REVOLVER_DIR:-"${ZDOTDIR:-$HOME}/.revolver"} - statefile="$dir/$pid" - - # The frames that, when animated, will make up - # our spinning indicator - frames=(${(@z)_revolver_spinners[$style]}) - interval=${(@z)frames[1]} - shift frames - - # Create a never-ending loop - while [[ 1 -eq 1 ]]; do - # If the statefile has been removed, exit the script - # to prevent it from being orphaned - if [[ ! -f $statefile ]]; then - exit 1 - fi - - # Check for the existence of the parent process - $(kill -s 0 $pid 2&>/dev/null) - - # If process doesn't exist, exit the script - # to prevent it from being orphaned - if [[ $? -ne 0 ]]; then - exit 1 - fi - - # Load the current state, and parse it to get - # the message to be displayed - state=($(cat $statefile)) - - msg="${(@)state:1}" - - # Output the current spinner frame, and add a - # slight delay before the next one - _revolver_spin - sleep ${interval:-"0.1"} - done -} - -### -# Output the spinner itself, along with a message -### -function _revolver_spin() { - local dir statefile state pid frame - - # ZSH arrays start at 1, so we need to bump the index if it's 0 - if [[ $spinner_index -eq 0 ]]; then - spinner_index+=1 - fi - - # Calculate the screen width - lim=$(tput cols) - - # Clear the line and move the cursor to the start - printf ' %.0s' {1..$lim} - echo -n "\r" - - # Echo the current frame and message, and overwrite - # the rest of the line with white space - msg="\033[0;38;5;242m${msg}\033[0;m" - frame="${${(@z)frames}[$spinner_index]//\"}" - printf '%*.*b' ${#msg} $lim "$frame $msg$(printf '%0.1s' " "{1..$lim})" - - # Return to the beginning of the line - echo -n "\r" - - # Set the spinner index to the next frame - spinner_index=$(( $(( $spinner_index + 1 )) % $(( ${#frames} + 1 )) )) -} - -### -# Stop the current spinner process -### -function _revolver_stop() { - local dir statefile state pid - - # Find the directory and load the statefile - dir=${REVOLVER_DIR:-"${ZDOTDIR:-$HOME}/.revolver"} - statefile="$dir/$PPID" - - # If the statefile does not exist, raise an error. - # The spinner process itself performs the same check - # and kills itself, so it should never be orphaned - if [[ ! -f $statefile ]]; then - echo '\033[0;31mRevolver process could not be found\033[0;m' - exit 1 - fi - - # Get the current state, and parse it to find the PID - # of the spinner process - state=($(cat $statefile)) - pid="$state[1]" - - # Clear the line and move the cursor to the start - printf ' %.0s' {1..$(tput cols)} - echo -n "\r" - - # If a PID has been found, kill the process - [[ ! -z $pid ]] && kill "$pid" > /dev/null - unset pid - - # Remove the statefile - rm $statefile -} - -### -# Update the message being displayed -function _revolver_update() { - local dir statefile state pid msg="$1" - - # Find the directory and load the statefile - dir=${REVOLVER_DIR:-"${ZDOTDIR:-$HOME}/.revolver"} - statefile="$dir/$PPID" - - # If the statefile does not exist, raise an error. - # The spinner process itself performs the same check - # and kills itself, so it should never be orphaned - if [[ ! -f $statefile ]]; then - echo '\033[0;31mRevolver process could not be found\033[0;m' - exit 1 - fi - - # Get the current state, and parse it to find the PID - # of the spinner process - state=($(cat $statefile)) - pid="$state[1]" - - # Clear the line and move the cursor to the start - printf ' %.0s' {1..$(tput cols)} - echo -n "\r" - - # Echo the new message to the statefile, to be - # picked up by the spinner process - echo "$pid $msg" >! $statefile -} - -### -# Create a new spinner with the specified message -### -function _revolver_start() { - local dir statefile msg="$1" - - # Find the directory and create it if it doesn't exist - dir=${REVOLVER_DIR:-"${ZDOTDIR:-$HOME}/.revolver"} - if [[ ! -d $dir ]]; then - mkdir -p $dir - fi - - # Create the filename for the statefile - statefile="$dir/$PPID" - - touch $statefile - if [[ ! -f $statefile ]]; then - echo '\033[0;31mRevolver process could not create state file\033[0;m' - echo "Check that the directory $dir is writable" - exit 1 - fi - - # Start the spinner process in the background - _revolver_process $PPID &! - - # Save the current state to the statefile - echo "$! $msg" >! $statefile -} - -### -# Demonstrate each of the included spinner styles -### -function _revolver_demo() { - for style in "${(@k)_revolver_spinners[@]}"; do - revolver --style $style start $style - sleep 2 - revolver stop - done -} - -### -# Handle command input -### -function _revolver() { - # Get the context from the first parameter - local help version style ctx="$1" - - # Parse CLI options - zparseopts -D \ - h=help -help=help \ - v=version -version=version \ - s:=style -style:=style - - # Output usage information and exit - if [[ -n $help ]]; then - _revolver_usage - exit 0 - fi - - # Output version information and exit - if [[ -n $version ]]; then - echo '0.2.0' - exit 0 - fi - - if [[ -z $style ]]; then - style='dots' - fi - - if [[ -n $style ]]; then - shift style - ctx="$1" - fi - - if [[ -z $_revolver_spinners[$style] ]]; then - echo $(color red "Spinner '$style' is not recognised") - exit 1 - fi - - case $ctx in - start|update|stop|demo) - # Check if a valid command is passed, - # and if so, run it - _revolver_${ctx} "${(@)@:2}" - ;; - *) - # If the context is not recognised, - # throw an error and exit - echo "Command $ctx is not recognised" - exit 1 - ;; - esac -} - -_revolver "$@" diff --git a/docker/Dockerfile b/docker/Dockerfile index 912562a..da26a68 100755 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -75,8 +75,12 @@ RUN zsh -fc 'reply=$(print -r -- command-substitution-ok); [[ ${reply} = command ENV LANG=C.UTF-8 -# Install zunit and its helpers into /usr/local/bin at build time. -RUN git clone --depth 1 --branch v0.8.2 https://github.com/zdharma/zunit.git /tmp/zunit.git +# Install zunit and its helpers into /usr/local/bin at build time: ZUnit 0.8.2 +# as released (bce183c), from z-shell/zunit, like test-native.yml. +RUN git init -q /tmp/zunit.git \ + && git -C /tmp/zunit.git remote add origin https://github.com/z-shell/zunit.git \ + && git -C /tmp/zunit.git fetch -q --depth 1 origin bce183c39a3b51a3dd838835516a37222aad921f \ + && git -C /tmp/zunit.git checkout -q --detach FETCH_HEAD WORKDIR /tmp/zunit.git RUN set -ex \ && ./build.zsh \ diff --git a/docs/writing-tests.md b/docs/writing-tests.md index d845489..971fb61 100644 --- a/docs/writing-tests.md +++ b/docs/writing-tests.md @@ -1,6 +1,6 @@ # Writing Tests -Tests live in `tests/` as `.zunit` files and are run by [ZUnit](https://github.com/zdharma/zunit). Each file covers a logical group of Zi functionality. The same files run in both the native CI tier and the Docker matrix — no duplication. +Tests live in `tests/` as `.zunit` files and are run by [ZUnit](https://github.com/z-shell/zunit). Each file covers a logical group of Zi functionality. The same files run in both the native CI tier and the Docker matrix — no duplication. ## Test file anatomy From 05d5e3e7bca55d18c0b437759e5406835ff06a0a Mon Sep 17 00:00:00 2001 From: Sal <59910950+ss-o@users.noreply.github.com> Date: Thu, 15 Oct 2026 06:34:36 +0100 Subject: [PATCH 2/2] chore(test): reinstall local test tools when their pins change (#142) make test installed the tools only when bin/zunit was missing, so a checkout that had run it before kept its old zunit after bin/color and bin/revolver stopped being tracked, and zunit then failed on the missing revolver. Key the install on a stamp named after both pinned revisions, kept in Makefile variables, so a pin change reinstalls bin/. Refs #142 --- .gitignore | 1 + Makefile | 19 ++++++++++++++----- docs/local-testing.md | 2 +- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 502726a..4ee62e3 100644 --- a/.gitignore +++ b/.gitignore @@ -138,3 +138,4 @@ GEMINI.md /bin/color /bin/revolver /bin/zunit +/bin/.tools-* diff --git a/Makefile b/Makefile index a9a0112..b2b3627 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,11 @@ IMAGE ?= ghcr.io/z-shell/zd TAG ?= latest TERM ?= xterm-256color TEST_FILES = annexes compat ice packages plugins shell-state snippets utils +# Test tool revisions. The stamp is named after both, so changing either +# reinstalls bin/ on the next `make test`. +ZUNIT_COMMIT := bce183c39a3b51a3dd838835516a37222aad921f +SRC_COMMIT := 9335c8c14e0aaa845277f882969c146755e1241e +TOOLS_STAMP := bin/.tools-$(ZUNIT_COMMIT)-$(SRC_COMMIT) ifdef FILE _SUITES := tests/$(FILE).zunit @@ -17,7 +22,7 @@ endif .PHONY: test run shell build controlled-build help ## test [FILE=] — run ZUnit natively (all suites, or one) -test: bin/zunit +test: $(TOOLS_STAMP) @for f in $(_SUITES); do \ echo "==> $$f"; \ PATH="$(CURDIR)/bin:$$PATH" \ @@ -67,20 +72,24 @@ controlled-build: --tag "$(IMAGE):$(PROFILE)-$(ZSH_VERSION)-$(ZSH_PATCH_SET)" . # Install zunit + helpers into bin/ — mirrors what test-native.yml does in CI. -bin/zunit: +bin/zunit: $(TOOLS_STAMP) + +$(TOOLS_STAMP): @echo "Installing zunit into bin/ ..." @mkdir -p bin - @curl -fsSL 'https://raw.githubusercontent.com/z-shell/src/9335c8c14e0aaa845277f882969c146755e1241e/lib/zsh/snippets/revolver' \ + @rm -f bin/.tools-* + @curl -fsSL 'https://raw.githubusercontent.com/z-shell/src/$(SRC_COMMIT)/lib/zsh/snippets/revolver' \ > bin/revolver - @curl -fsSL 'https://raw.githubusercontent.com/z-shell/src/9335c8c14e0aaa845277f882969c146755e1241e/lib/zsh/snippets/color.zsh' \ + @curl -fsSL 'https://raw.githubusercontent.com/z-shell/src/$(SRC_COMMIT)/lib/zsh/snippets/color.zsh' \ > bin/color @rm -rf /tmp/zunit.git @git init -q /tmp/zunit.git @git -C /tmp/zunit.git remote add origin https://github.com/z-shell/zunit.git - @git -C /tmp/zunit.git fetch -q --depth 1 origin bce183c39a3b51a3dd838835516a37222aad921f + @git -C /tmp/zunit.git fetch -q --depth 1 origin $(ZUNIT_COMMIT) @git -C /tmp/zunit.git checkout -q --detach FETCH_HEAD @cd /tmp/zunit.git && ./build.zsh @mv /tmp/zunit.git/zunit bin/zunit @chmod u+x bin/color bin/revolver bin/zunit @rm -rf /tmp/zunit.git + @touch $@ @echo "Done." diff --git a/docs/local-testing.md b/docs/local-testing.md index 4bebdda..a33af73 100644 --- a/docs/local-testing.md +++ b/docs/local-testing.md @@ -23,7 +23,7 @@ The Makefile provides four targets that cover the full local workflow: running t make test ``` -On the first run, `make test` automatically installs `zunit`, `revolver`, and `color` into `bin/`. This mirrors exactly what the CI workflow does. Subsequent runs skip the install step (the `bin/zunit` file already exists). +On the first run, `make test` automatically installs `zunit`, `revolver`, and `color` into `bin/`. This mirrors exactly what the CI workflow does. Subsequent runs skip the install step while the stamp `bin/.tools--` exists; changing either pinned revision in the `Makefile` reinstalls them. ```text Installing zunit into bin/ ...