Extract the runner logic into its own file so the stubs can be minimal

This commit is contained in:
David Heinemeier Hansson
2026-05-22 17:37:43 +02:00
parent 32bfddefc5
commit bbdf873aec
4 changed files with 207 additions and 126 deletions
+6 -60
View File
@@ -1,76 +1,22 @@
#!/bin/bash
# omarchy:summary=Install a pnpm dlx wrapper for a given npm package.
# omarchy:args=<package> [command-name]
# omarchy:summary=Install a small pnpm dlx wrapper for a given npm package.
# omarchy:args=<package> [command-name [bin-name]]
if [[ -z $1 ]]; then
echo "Usage: omarchy-npm-install <package> [command-name]"
echo "Usage: omarchy-npm-install <package> [command-name [bin-name]]"
exit 1
fi
package=$1
command=${2:-$1}
bin=${3:-$command}
mkdir -p "$HOME/.local/bin"
cat > "$HOME/.local/bin/$command" <<EOF
cat >"$HOME/.local/bin/$command" <<EOF
#!/bin/bash
package="$package"
command="$command"
if ! node_root="\$(mise where node@latest 2>/dev/null)"; then
mise use -g node@latest >/dev/null
node_root="\$(mise where node@latest)"
fi
if omarchy-cmd-missing pnpm; then
echo "Installing pnpm for \$package..."
omarchy-pkg-add pnpm
hash -r
fi
# pnpm reads npm_config_* env vars for CLI configuration.
export npm_config_minimum_release_age=7200
export npm_config_dlx_cache_max_age=7200
ensure_bin_runtime() {
local bin_path=\$1
local shebang
IFS= read -r shebang < "\$bin_path"
if [[ \$shebang == "#!"*"/bun"* || \$shebang == "#!"*"/env bun"* ]]; then
if omarchy-cmd-missing bun; then
echo "Installing bun runtime for \$package..."
omarchy-pkg-add bun
hash -r
fi
fi
}
exec_package_bin() {
local package_bin_path=\$1
shift
if [[ -n \$package_bin_path ]]; then
ensure_bin_runtime "\$package_bin_path"
PATH="\$node_root/bin:\$PATH" exec "\$package_bin_path" "\$@"
fi
}
# Resolve the package bin inside pnpm dlx, then run it with node@latest available for node shebangs.
# Some wrappers are aliases, e.g. playwright-cli wraps the playwright bin.
PATH="\$node_root/bin:\$PATH" pnpm dlx --package "\$package" true
package_bin_path=\$(PATH="\$node_root/bin:\$PATH" pnpm dlx --package "\$package" which "\$package" 2>/dev/null)
exec_package_bin "\$package_bin_path" "\$@"
# Scoped packages like @openai/codex expose an unscoped bin like codex.
package_bin_path=\$(PATH="\$node_root/bin:\$PATH" pnpm dlx --package "\$package" which "\$command" 2>/dev/null)
exec_package_bin "\$package_bin_path" "\$@"
echo "Could not resolve npm bin for \$package / \$command" >&2
exit 127
exec omarchy-npm-run "$package" "$command" "$bin" "\$@"
EOF
chmod +x "$HOME/.local/bin/$command"
+76
View File
@@ -0,0 +1,76 @@
#!/bin/bash
# omarchy:summary=Run a pnpm dlx-backed npm package wrapper.
# omarchy:args=<package> <command-name> <bin-name> [args...]
# omarchy:hidden=true
if (($# < 3)); then
echo "Usage: omarchy-npm-run <package> <command-name> <bin-name> [args...]"
exit 1
fi
package=$1
command=$2
bin=$3
shift 3
package_spec=$package
state_dir="${XDG_STATE_HOME:-$HOME/.local/state}/omarchy/npm-wrappers"
version_file="$state_dir/$command.version"
pin_ttl=7200
uses_pinned_version=0
if [[ -s $version_file ]]; then
now=$(date +%s)
pinned_at=$(stat -c %Y "$version_file" 2>/dev/null || printf '0\n')
if ((now - pinned_at < pin_ttl)); then
pinned_version=$(<"$version_file")
package_spec="$package@$pinned_version"
uses_pinned_version=1
else
rm -f "$version_file"
fi
fi
if ! node_root=$(mise where node@latest 2>/dev/null); then
mise use -g node@latest >/dev/null
node_root=$(mise where node@latest)
fi
export PATH="$node_root/bin:$PATH"
if omarchy-cmd-missing pnpm; then
echo "Installing pnpm for $package..."
omarchy-pkg-add pnpm
hash -r
fi
# pnpm reads npm_config_* env vars for CLI configuration.
export npm_config_minimum_release_age=$pin_ttl
export npm_config_dlx_cache_max_age=$pin_ttl
if (( uses_pinned_version )); then
export npm_config_minimum_release_age=0
fi
if (($# == 1)) && [[ $1 == "update" ]]; then
export npm_config_minimum_release_age=0
export npm_config_dlx_cache_max_age=0
if ! latest_version=$(env -u npm_config_minimum_release_age -u npm_config_dlx_cache_max_age pnpm view "$package@latest" version); then
echo "Could not resolve latest npm version for $package" >&2
exit 1
fi
mkdir -p "$state_dir"
printf '%s\n' "$latest_version" >"$version_file"
package_spec="$package@$latest_version"
pnpm dlx --package "$package_spec" true
echo "Updated $command to $latest_version"
exit 0
fi
exec pnpm dlx --package "$package_spec" "$bin" "$@"
+1 -1
View File
@@ -2,7 +2,7 @@ omarchy-npm-install @openai/codex codex
omarchy-npm-install @google/gemini-cli gemini
omarchy-npm-install @github/copilot copilot
omarchy-npm-install opencode-ai opencode
omarchy-npm-install playwright playwright-cli
omarchy-npm-install playwright playwright-cli playwright
omarchy-npm-install @earendil-works/pi-coding-agent pi
omarchy-npm-install @kitlangton/ghui ghui
omarchy-npm-install hunkdiff hunk
+124 -65
View File
@@ -16,6 +16,21 @@ fail() {
exit 1
}
assert_file_contains() {
local description="$1"
local file="$2"
local expected="$3"
if ! grep -Fq "$expected" "$file"; then
printf 'Expected %s to contain: %s\n' "$file" "$expected" >&2
printf 'Actual file:\n' >&2
sed -n '1,120p' "$file" >&2
fail "$description"
fi
pass "$description"
}
cleanup() {
[[ -n $TMPDIR && -d $TMPDIR ]] && rm -rf "$TMPDIR"
}
@@ -24,60 +39,51 @@ trap cleanup EXIT
TMPDIR=$(mktemp -d)
HOME="$TMPDIR/home" "$ROOT/bin/omarchy-npm-install" @openai/codex codex
wrapper="$TMPDIR/home/.local/bin/codex"
runtime="$ROOT/bin/omarchy-npm-run"
[[ -x $wrapper ]] || fail "npm wrapper is generated"
pass "npm wrapper is generated"
if ! grep -q "npm_config_minimum_release_age=7200" "$wrapper"; then
fail "npm wrapper configures pnpm minimum release age"
fi
pass "npm wrapper configures pnpm minimum release age"
assert_file_contains "npm wrapper defaults bin to command name" "$wrapper" 'exec omarchy-npm-run "@openai/codex" "codex" "codex" "$@"'
if ! grep -q "npm_config_dlx_cache_max_age=7200" "$wrapper"; then
fail "npm wrapper configures pnpm dlx cache max age"
if grep -q "pnpm dlx" "$wrapper"; then
fail "npm wrapper does not inline pnpm runtime"
fi
pass "npm wrapper configures pnpm dlx cache max age"
pass "npm wrapper does not inline pnpm runtime"
if grep -q "PNPM_CONFIG_MINIMUM_RELEASE_AGE" "$wrapper"; then
fail "npm wrapper does not use ignored PNPM_CONFIG env vars"
HOME="$TMPDIR/home" "$ROOT/bin/omarchy-npm-install" playwright playwright-cli playwright
assert_file_contains "npm wrapper records explicit package bin" "$TMPDIR/home/.local/bin/playwright-cli" 'exec omarchy-npm-run "playwright" "playwright-cli" "playwright" "$@"'
assert_file_contains "npm runtime defines pin ttl" "$runtime" "pin_ttl=7200"
assert_file_contains "npm runtime configures pnpm minimum release age" "$runtime" 'npm_config_minimum_release_age=$pin_ttl'
assert_file_contains "npm runtime configures pnpm dlx cache max age" "$runtime" 'npm_config_dlx_cache_max_age=$pin_ttl'
if grep -q "PNPM_CONFIG_MINIMUM_RELEASE_AGE" "$runtime"; then
fail "npm runtime does not use ignored PNPM_CONFIG env vars"
fi
pass "npm wrapper does not use ignored PNPM_CONFIG env vars"
pass "npm runtime does not use ignored PNPM_CONFIG env vars"
removed_flag="--force""-update"
if grep -q -- "$removed_flag" "$wrapper"; then
fail "npm wrapper does not expose removed force update flag"
if grep -q -- "$removed_flag" "$runtime"; then
fail "npm runtime does not expose removed force update flag"
fi
pass "npm wrapper does not expose removed force update flag"
pass "npm runtime does not expose removed force update flag"
if ! grep -q "npm_config_dlx_cache_max_age=0" "$wrapper"; then
fail "npm wrapper update bypasses dlx cache"
if grep -q " which " "$runtime"; then
fail "npm runtime does not discover package bins dynamically"
fi
pass "npm wrapper update bypasses dlx cache"
if ! grep -q "npm_config_minimum_release_age=0" "$wrapper"; then
fail "npm wrapper update bypasses minimum release age"
fi
pass "npm wrapper update bypasses minimum release age"
if ! grep -q "wrapper_update=1" "$wrapper"; then
fail "npm wrapper maps update to wrapper update"
fi
pass "npm wrapper maps update to wrapper update"
if ! grep -q "version_file=" "$wrapper"; then
fail "npm wrapper persists update version"
fi
pass "npm wrapper persists update version"
pass "npm runtime does not discover package bins dynamically"
stub_bin="$TMPDIR/bin"
node_root="$TMPDIR/node"
package_bin="$TMPDIR/package-bin"
state_home="$TMPDIR/state"
pnpm_log="$TMPDIR/pnpm.log"
package_args="$TMPDIR/package-args"
version_file="$state_home/omarchy/npm-wrappers/codex.version"
mkdir -p "$stub_bin" "$node_root/bin"
cat > "$stub_bin/mise" <<'SH'
cat >"$stub_bin/mise" <<'SH'
#!/bin/bash
if [[ $1 == "where" && $2 == "node@latest" ]]; then
printf '%s\n' "$OMARCHY_NPM_TEST_NODE_ROOT"
@@ -87,12 +93,12 @@ fi
exit 1
SH
cat > "$stub_bin/omarchy-cmd-missing" <<'SH'
cat >"$stub_bin/omarchy-cmd-missing" <<'SH'
#!/bin/bash
exit 1
SH
cat > "$stub_bin/pnpm" <<'SH'
cat >"$stub_bin/pnpm" <<'SH'
#!/bin/bash
printf 'min_age=%s dlx_cache=%s args=%s\n' "${npm_config_minimum_release_age:-}" "${npm_config_dlx_cache_max_age:-}" "$*" >>"$OMARCHY_NPM_TEST_PNPM_LOG"
@@ -101,57 +107,79 @@ if [[ $1 == "view" ]]; then
exit 0
fi
if [[ $1 == "dlx" && $4 == "true" ]]; then
exit 0
fi
if [[ $1 == "dlx" ]]; then
if [[ $4 == "true" ]]; then
exit 0
fi
if [[ $1 == "dlx" && $4 == "which" ]]; then
printf '%s\n' "$OMARCHY_NPM_TEST_PACKAGE_BIN"
shift 4
printf '%s\n' "$*" >"$OMARCHY_NPM_TEST_PACKAGE_ARGS"
exit 0
fi
exit 1
SH
cat > "$package_bin" <<'SH'
#!/bin/bash
printf '%s\n' "$*" >"$OMARCHY_NPM_TEST_PACKAGE_ARGS"
SH
chmod +x "$stub_bin/mise" "$stub_bin/omarchy-cmd-missing" "$stub_bin/pnpm" "$package_bin"
chmod +x "$stub_bin/mise" "$stub_bin/omarchy-cmd-missing" "$stub_bin/pnpm"
OMARCHY_NPM_TEST_NODE_ROOT="$node_root" \
OMARCHY_NPM_TEST_PACKAGE_BIN="$package_bin" \
OMARCHY_NPM_TEST_PACKAGE_ARGS="$package_args" \
OMARCHY_NPM_TEST_PNPM_LOG="$pnpm_log" \
HOME="$TMPDIR/home" \
XDG_STATE_HOME="$state_home" \
PATH="$stub_bin:$PATH" \
"$wrapper" -s danger-full-access update alpha beta
if ! grep -q "dlx_cache=0" "$pnpm_log"; then
fail "update sets pnpm dlx cache age to zero"
if ! grep -Fq "args=dlx --package @openai/codex codex -s danger-full-access update alpha beta" "$pnpm_log"; then
fail "non-leading update is forwarded to package bin"
fi
pass "update sets pnpm dlx cache age to zero"
pass "non-leading update is forwarded to package bin"
if ! grep -q "min_age=0" "$pnpm_log"; then
fail "update sets pnpm minimum release age to zero"
if ! grep -q "dlx_cache=7200" "$pnpm_log"; then
fail "normal run uses pnpm dlx cache age"
fi
pass "update sets pnpm minimum release age to zero"
pass "normal run uses pnpm dlx cache age"
if ! grep -q "args=dlx --package @openai/codex@1.2.3 true" "$pnpm_log"; then
fail "update uses resolved latest package version"
if ! grep -q "min_age=7200" "$pnpm_log"; then
fail "normal run uses pnpm minimum release age"
fi
pass "update uses resolved latest package version"
pass "normal run uses pnpm minimum release age"
if [[ -f $package_args ]]; then
fail "update does not run the package bin"
if [[ $(<"$package_args") != "-s danger-full-access update alpha beta" ]]; then
fail "normal run forwards package args"
fi
pass "update does not run the package bin"
pass "normal run forwards package args"
if [[ -f $version_file ]]; then
fail "non-leading update does not pin wrapper version"
fi
pass "non-leading update does not pin wrapper version"
rm -f "$pnpm_log" "$package_args"
OMARCHY_NPM_TEST_NODE_ROOT="$node_root" \
OMARCHY_NPM_TEST_PACKAGE_BIN="$package_bin" \
OMARCHY_NPM_TEST_PACKAGE_ARGS="$package_args" \
OMARCHY_NPM_TEST_PNPM_LOG="$pnpm_log" \
HOME="$TMPDIR/home" \
XDG_STATE_HOME="$state_home" \
PATH="$stub_bin:$PATH" \
"$wrapper" update alpha
if ! grep -Fq "args=dlx --package @openai/codex codex update alpha" "$pnpm_log"; then
fail "update with extra args is forwarded to package bin"
fi
pass "update with extra args is forwarded to package bin"
if [[ -f $version_file ]]; then
fail "update with extra args does not pin wrapper version"
fi
pass "update with extra args does not pin wrapper version"
rm -f "$pnpm_log" "$package_args"
OMARCHY_NPM_TEST_NODE_ROOT="$node_root" \
OMARCHY_NPM_TEST_PACKAGE_ARGS="$package_args" \
OMARCHY_NPM_TEST_PNPM_LOG="$pnpm_log" \
HOME="$TMPDIR/home" \
XDG_STATE_HOME="$state_home" \
PATH="$stub_bin:$PATH" \
"$wrapper" update
@@ -165,25 +193,31 @@ if ! grep -q "min_age=0" "$pnpm_log"; then
fi
pass "wrapper update bypasses pnpm minimum release age"
if ! grep -q "args=dlx --package @openai/codex@1.2.3 true" "$pnpm_log"; then
if ! grep -Fq "args=dlx --package @openai/codex@1.2.3 true" "$pnpm_log"; then
fail "wrapper update uses resolved latest package version"
fi
pass "wrapper update uses resolved latest package version"
if [[ -f $package_args ]]; then
fail "wrapper update does not run package self-updater"
fail "wrapper update does not run package bin"
fi
pass "wrapper update does not run package self-updater"
pass "wrapper update does not run package bin"
if [[ $(<"$version_file") != "1.2.3" ]]; then
fail "wrapper update persists resolved version"
fi
pass "wrapper update persists resolved version"
rm -f "$pnpm_log" "$package_args"
OMARCHY_NPM_TEST_NODE_ROOT="$node_root" \
OMARCHY_NPM_TEST_PACKAGE_BIN="$package_bin" \
OMARCHY_NPM_TEST_PACKAGE_ARGS="$package_args" \
OMARCHY_NPM_TEST_PNPM_LOG="$pnpm_log" \
HOME="$TMPDIR/home" \
XDG_STATE_HOME="$state_home" \
PATH="$stub_bin:$PATH" \
"$wrapper" gamma
if ! grep -q "args=dlx --package @openai/codex@1.2.3 true" "$pnpm_log"; then
if ! grep -Fq "args=dlx --package @openai/codex@1.2.3 codex gamma" "$pnpm_log"; then
fail "wrapper reuses pinned update version"
fi
pass "wrapper reuses pinned update version"
@@ -197,3 +231,28 @@ if [[ $(<"$package_args") != "gamma" ]]; then
fail "wrapper forwards args after pinned update"
fi
pass "wrapper forwards args after pinned update"
rm -f "$pnpm_log" "$package_args"
touch -d "@$(($(date +%s) - 7201))" "$version_file"
OMARCHY_NPM_TEST_NODE_ROOT="$node_root" \
OMARCHY_NPM_TEST_PACKAGE_ARGS="$package_args" \
OMARCHY_NPM_TEST_PNPM_LOG="$pnpm_log" \
HOME="$TMPDIR/home" \
XDG_STATE_HOME="$state_home" \
PATH="$stub_bin:$PATH" \
"$wrapper" delta
if ! grep -Fq "args=dlx --package @openai/codex codex delta" "$pnpm_log"; then
fail "wrapper drops expired pinned update version"
fi
pass "wrapper drops expired pinned update version"
if ! grep -q "min_age=7200" "$pnpm_log"; then
fail "wrapper restores minimum release age after pin expiry"
fi
pass "wrapper restores minimum release age after pin expiry"
if [[ -f $version_file ]]; then
fail "wrapper removes expired pinned version file"
fi
pass "wrapper removes expired pinned version file"