From baa52680ea60a464ee0ae95a29c47acd72862da2 Mon Sep 17 00:00:00 2001 From: Sal Date: Sun, 16 Aug 2026 10:30:57 +0100 Subject: [PATCH] fix: preserve init defaults under SH_WORD_SPLIT --- public/checksum.txt | 4 ++-- public/sh/install.sh | 2 +- public/zsh/init.zsh | 22 +++++++++++----------- tests/installers.sh | 36 +++++++++++++++++++++++++++++++++++- 4 files changed, 49 insertions(+), 15 deletions(-) diff --git a/public/checksum.txt b/public/checksum.txt index 26ac375..899313f 100644 --- a/public/checksum.txt +++ b/public/checksum.txt @@ -1,4 +1,4 @@ 0140801e80b2d8767e95d215850b6feab3642ee2b6fd70fbf4aab09afcfe7fca public/sh/install_zpmod.sh -f9d8ef697ba682bdfe66fdd67d4517caa4e62bb8baf2868ec8ed9932809b76aa public/sh/install.sh +6ee1ced1b73ab9d6f8a17e26505dd5de588b2a0af2832603ae04eb2866763ed9 public/sh/install.sh 08cc893ceb982fc99d17db1966c6c30790cc571e16e4f5392352d995f5252952 public/sh/sync-init.sh -5c7af31d7fc848d80f9fedf69c75e6844503f550a3d5e020bc7cdfdaca624763 public/zsh/init.zsh +424d66dca9bc26dd225afa45ccf15e42c8cf1f9e5e68fa51b469969bb5d51901 public/zsh/init.zsh diff --git a/public/sh/install.sh b/public/sh/install.sh index 2062910..bd911bc 100755 --- a/public/sh/install.sh +++ b/public/sh/install.sh @@ -118,7 +118,7 @@ if [ "${AOPT}" = loader ]; then exit 1 fi # shellcheck disable=SC2016 - command sed 's|: ${ZI\[STREAM\]:="main"}|: ${ZI[STREAM]:="'"${BOPT}"'"}|' "${ZI_CONFIG_DIR}/init.zsh" >"${loader_tmp}" && + command sed 's|: "${ZI\[STREAM\]:=main}"|: "${ZI[STREAM]:='"${BOPT}"'}"|' "${ZI_CONFIG_DIR}/init.zsh" >"${loader_tmp}" && command mv "${loader_tmp}" "${ZI_CONFIG_DIR}/init.zsh" command chmod go-w "${ZI_CONFIG_DIR}" && command chmod a+x "${ZI_CONFIG_DIR}/init.zsh" fi diff --git a/public/zsh/init.zsh b/public/zsh/init.zsh index 74544ef..c72db20 100755 --- a/public/zsh/init.zsh +++ b/public/zsh/init.zsh @@ -13,21 +13,21 @@ typeset -ghA ZI # https://wiki.zshell.dev/docs/guides/customization -: ${ZI[REPOSITORY]:="https://github.com/z-shell/zi.git"} -: ${ZI[STREAM]:="main"} -: ${ZI[HOME_DIR]:="${XDG_DATA_HOME:-$HOME/.local/share}/zi"} -: ${ZI[BIN_DIR]:="${ZI[HOME_DIR]}/bin"} -: ${ZI[CACHE_DIR]:="${XDG_CACHE_HOME:-$HOME/.cache}/zi"} -: ${ZI[CONFIG_DIR]:="${XDG_CONFIG_HOME:-$HOME/.config}/zi"} +: "${ZI[REPOSITORY]:=https://github.com/z-shell/zi.git}" +: "${ZI[STREAM]:=main}" +: "${ZI[HOME_DIR]:=${XDG_DATA_HOME:-$HOME/.local/share}/zi}" +: "${ZI[BIN_DIR]:=${ZI[HOME_DIR]}/bin}" +: "${ZI[CACHE_DIR]:=${XDG_CACHE_HOME:-$HOME/.cache}/zi}" +: "${ZI[CONFIG_DIR]:=${XDG_CONFIG_HOME:-$HOME/.config}/zi}" # https://wiki.zshell.dev/community/zsh_plugin_standard#global-parameter-with-prefix -: ${ZPFX:=${ZI[HOME_DIR]}/polaris} -: ${ZI[ZMODULES_DIR]:=${ZI[HOME_DIR]}/zmodules} -: ${ZI[ZCOMPDUMP_PATH]:=${ZI[CACHE_DIR]}/.zcompdump} -: ${ZI[MUTE_WARNINGS]:=0} +: "${ZPFX:=${ZI[HOME_DIR]}/polaris}" +: "${ZI[ZMODULES_DIR]:=${ZI[HOME_DIR]}/zmodules}" +: "${ZI[ZCOMPDUMP_PATH]:=${ZI[CACHE_DIR]}/.zcompdump}" +: "${ZI[MUTE_WARNINGS]:=0}" # History defaults -: ${HISTFILE:=${XDG_STATE_HOME:-$HOME/.local/state}/zsh/history} +: "${HISTFILE:=${XDG_STATE_HOME:-$HOME/.local/state}/zsh/history}" [[ -e "$HISTFILE" ]] || { command mkdir -p "${HISTFILE:h}"; command touch "$HISTFILE"; } [[ -w "$HISTFILE" ]] && typeset -gx SAVEHIST=440000 HISTSIZE=441000 diff --git a/tests/installers.sh b/tests/installers.sh index 26a8418..48a0a27 100755 --- a/tests/installers.sh +++ b/tests/installers.sh @@ -64,6 +64,39 @@ check_checksums() { pass "checksums" } +test_init_defaults_are_single_arguments() { + capture_log="${TMP_ROOT}/init-default-arguments" + values_log="${TMP_ROOT}/init-default-values" + + zsh -f -c ' + capture_colon() { print -r -- "argc:$#" >>"$CAPTURE_LOG"; } + alias ":=capture_colon" + setopt aliases sh_word_split + typeset -A ZI + ZI[REPOSITORY]="repository with spaces" + export HOME="$4/home with spaces" + export XDG_DATA_HOME="$4/data root" + export XDG_CACHE_HOME="$4/cache root" + export XDG_CONFIG_HOME="$4/config root" + export XDG_STATE_HOME="$4/state root" + export CAPTURE_LOG="$2" + source "$1" + { + print -r -- "repository:${ZI[REPOSITORY]}" + print -r -- "home:${ZI[HOME_DIR]}" + print -r -- "history:${HISTFILE}" + } >"$3" + ' zsh "${ROOT}/public/zsh/init.zsh" "${capture_log}" "${values_log}" "${TMP_ROOT}" + + if grep -Fv 'argc:1' "${capture_log}" >/dev/null 2>&1; then + fail "init defaults were split into multiple arguments under SH_WORD_SPLIT" + fi + contains "${values_log}" 'repository:repository with spaces' + contains "${values_log}" "home:${TMP_ROOT}/data root/zi" + contains "${values_log}" "history:${TMP_ROOT}/state root/zsh/history" + pass "init defaults preserve argument and value boundaries" +} + write_fake_tools() { FAKE_BIN="${TMP_ROOT}/bin" command mkdir -p "${FAKE_BIN}" @@ -202,7 +235,7 @@ test_loader_install() { sh "${ROOT}/public/sh/install.sh" -a loader -b feature/test >/dev/null # shellcheck disable=SC2016 - contains "${config}/zi/init.zsh" ': ${ZI[STREAM]:="feature/test"}' + contains "${config}/zi/init.zsh" ': "${ZI[STREAM]:=feature/test}"' # shellcheck disable=SC2016 contains "${home}/.zshrc" 'source "${XDG_CONFIG_HOME:-${HOME}/.config}/zi/init.zsh" && zzinit' [ -f "${data}/zi/bin/zi.zsh" ] || fail "loader install did not clone Zi into XDG data home" @@ -344,6 +377,7 @@ test_sync_init() { check_syntax check_checksums +test_init_defaults_are_single_arguments write_fake_tools test_loader_install test_xdg_data_home_install