mirror of
https://github.com/soulis-1256/assemblrr.git
synced 2026-08-29 01:21:45 +00:00
Make PATH assemblrr a wrapper around the install CLI
Stop copying cli.sh and a lib subset to ~/.local/bin. Setup and upgrade write a short wrapper that execs $INSTALL_DIR/cli.sh. Leftover PATH libs are removed. update-cli now points at upgrade.
This commit is contained in:
parent
962e322fdb
commit
ea26dc794e
9 changed files with 143 additions and 122 deletions
|
|
@ -88,7 +88,6 @@ After install, the CLI is on your `PATH` as `assemblrr`. Run `assemblrr <command
|
|||
| `backup /target/dir` | Snapshot configuration |
|
||||
| `restore /backup.tar.gz` | Restore from a backup archive |
|
||||
| `update-containers` | Pull latest images and restart (offers a backup first) |
|
||||
| `update-cli` | Update the CLI to the latest version |
|
||||
| `upgrade` | Upgrade from git `main` (or `--from DIR`): files, migrations, stack restart, service wiring |
|
||||
| `upgrade --skip-stack` | Apply files and CLI without restarting containers |
|
||||
| `upgrade --check` | Dry-run: show which managed files and migrations would run |
|
||||
|
|
|
|||
101
bin/cli.sh
101
bin/cli.sh
|
|
@ -1,27 +1,44 @@
|
|||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# assemblrr CLI — manages your media server
|
||||
# This file is installed to ~/.local/bin/<APP_CLI_NAME> during setup
|
||||
# assemblrr CLI — lives in the install tree (or repo bin/). PATH is a wrapper.
|
||||
|
||||
# Source shared library (safe_source, find_install_directory, logging, colors)
|
||||
# CLI is installed to ~/.local/bin, lib/ lives next to it or in the install dir
|
||||
_cli_self="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
# Locate lib directory (repo: lib/ sibling of bin/; installed: lib/ next to CLI)
|
||||
# Leftover full copies in ~/.local/bin must not run; exec the install-tree CLI.
|
||||
if [ "$_cli_self" = "$HOME/.local/bin" ] || [ "$_cli_self" = "/usr/local/bin" ]; then
|
||||
_wrap_dir="${ASSEMBLRR_DIR:-}"
|
||||
if [ -z "$_wrap_dir" ]; then
|
||||
for _wrap_f in \
|
||||
/opt/assemblrr/.assemblrr-config \
|
||||
"$HOME/.assemblrr-config" \
|
||||
"$HOME/assemblrr/.assemblrr-config"
|
||||
do
|
||||
if [ -f "$_wrap_f" ]; then
|
||||
_wrap_dir=$(grep -E '^INSTALL_DIRECTORY=' "$_wrap_f" | head -1 || true)
|
||||
_wrap_dir="${_wrap_dir#INSTALL_DIRECTORY=}"
|
||||
_wrap_dir="${_wrap_dir%$'\r'}"
|
||||
_wrap_dir="${_wrap_dir#\"}"
|
||||
_wrap_dir="${_wrap_dir%\"}"
|
||||
[ -n "$_wrap_dir" ] && break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
if [ -n "${_wrap_dir:-}" ] && [ -f "$_wrap_dir/cli.sh" ]; then
|
||||
exec bash "$_wrap_dir/cli.sh" "$@"
|
||||
fi
|
||||
echo "assemblrr: could not find the install. Run setup, or set ASSEMBLRR_DIR." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Locate lib (repo: sibling of bin/; install: lib/ next to cli.sh)
|
||||
if [ -f "$_cli_self/../lib/core.sh" ]; then
|
||||
_lib_dir="$_cli_self/../lib"
|
||||
elif [ -f "$_cli_self/lib/core.sh" ]; then
|
||||
_lib_dir="$_cli_self/lib"
|
||||
else
|
||||
# Fallback: find install dir first, then source from there
|
||||
_tmp_install=$(grep -r "^INSTALL_DIRECTORY=" /opt/assemblrr/.assemblrr-config "$HOME/assemblrr/.assemblrr-config" "$HOME/.assemblrr-config" 2>/dev/null | head -1 | cut -d= -f2 | tr -d '"' || true)
|
||||
if [ -n "$_tmp_install" ] && [ -f "$_tmp_install/lib/core.sh" ]; then
|
||||
_lib_dir="$_tmp_install/lib"
|
||||
else
|
||||
echo -e "\033[0;31mError: lib/core.sh not found. Re-run setup.\033[0m" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo -e "\033[0;31mError: lib/core.sh not found. Re-run setup.\033[0m" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
source "$_lib_dir/core.sh"
|
||||
|
|
@ -92,7 +109,6 @@ declare -A COMMANDS=(
|
|||
["backup"]="backs up to the destination location"
|
||||
["restore"]="restores from a backup archive"
|
||||
["update-containers"]="updates all containers"
|
||||
["update-cli"]="updates the CLI script to the latest version"
|
||||
["upgrade"]="upgrade install files from git (or --from DIR); runs migrations"
|
||||
["logs"]="shows container logs (optionally specify service name)"
|
||||
["health"]="checks health status of all services"
|
||||
|
|
@ -129,7 +145,6 @@ show_help() {
|
|||
echo " ${APP_CLI_NAME} logs # View all container logs"
|
||||
echo " ${APP_CLI_NAME} logs jellyfin # View specific service logs"
|
||||
echo " ${APP_CLI_NAME} health # Check health of all services"
|
||||
echo " ${APP_CLI_NAME} update-cli # Update CLI to latest version"
|
||||
echo " ${APP_CLI_NAME} upgrade # Upgrade from git main (backup first)"
|
||||
echo " ${APP_CLI_NAME} upgrade --from DIR # Upgrade from a local source tree"
|
||||
echo " ${APP_CLI_NAME} upgrade --check # Dry-run upgrade plan"
|
||||
|
|
@ -309,18 +324,6 @@ backup_app() {
|
|||
|
||||
echo -e "\nBacking up ${APP_DISPLAY_NAME} to $destination..."
|
||||
|
||||
# Copy current CLI script and lib modules, create backup (skip copy if running from install dir)
|
||||
local running_cli; running_cli="$(realpath "${BASH_SOURCE[0]}" 2>/dev/null || echo "${_cli_self}/cli.sh")"
|
||||
local target_cli; target_cli="$(realpath "$INSTALL_DIR/cli.sh" 2>/dev/null || echo "$INSTALL_DIR/cli.sh")"
|
||||
if [ -f "$running_cli" ] && [ "$running_cli" != "$target_cli" ]; then
|
||||
cp "$running_cli" "$INSTALL_DIR/cli.sh" 2>/dev/null || log_warning "Failed to backup CLI script"
|
||||
fi
|
||||
|
||||
# Copy lib modules if they exist outside target dir
|
||||
if [ -d "$HOME/.local/bin/lib" ] && [ "$(realpath "$HOME/.local/bin/lib" 2>/dev/null)" != "$(realpath "$INSTALL_DIR/lib" 2>/dev/null)" ]; then
|
||||
cp -r "$HOME/.local/bin/lib" "$INSTALL_DIR/" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Run tar inside an alpine container bound to the INSTALL_DIR and the destination (excluding temp/cache and sockets)
|
||||
if ! wait_while "Creating backup archive" run_docker run --rm \
|
||||
-v "$INSTALL_DIR:/source" \
|
||||
|
|
@ -482,16 +485,12 @@ uninstall_app() {
|
|||
if [ -n "${APP_CLI_NAME:-}" ]; then
|
||||
rm -f "$HOME/.local/bin/$APP_CLI_NAME" "/usr/local/bin/$APP_CLI_NAME" 2>/dev/null || true
|
||||
fi
|
||||
local _lib_module
|
||||
if type list_cli_lib_modules >/dev/null 2>&1; then
|
||||
while IFS= read -r _lib_module; do
|
||||
[ -z "$_lib_module" ] && continue
|
||||
rm -f "$HOME/.local/bin/lib/${_lib_module}.sh" 2>/dev/null || true
|
||||
done < <(list_cli_lib_modules)
|
||||
if type remove_stale_user_cli_libs >/dev/null 2>&1; then
|
||||
remove_stale_user_cli_libs
|
||||
else
|
||||
rm -f "$HOME/.local/bin/lib/"*.sh 2>/dev/null || true
|
||||
rmdir "$HOME/.local/bin/lib" 2>/dev/null || true
|
||||
fi
|
||||
rmdir "$HOME/.local/bin/lib" 2>/dev/null || true
|
||||
|
||||
# Setup writes this cheat-sheet under $HOME (outside the install dir)
|
||||
# Legacy setup wrote ~/assemblrr_services.txt — remove if present
|
||||
|
|
@ -944,38 +943,6 @@ check_health() {
|
|||
return 0
|
||||
}
|
||||
|
||||
update_cli() {
|
||||
echo "Updating ${APP_DISPLAY_NAME} CLI..."
|
||||
local tmp_dir
|
||||
tmp_dir=$(mktemp -d)
|
||||
|
||||
if ! wait_while "Updating CLI from git" git clone --depth=1 "${APP_REPO_URL}" "$tmp_dir/assemblrr"; then
|
||||
log_error "Failed to clone ${APP_REPO_URL}. Check your internet connection and repository access."
|
||||
fi
|
||||
|
||||
mkdir -p "$HOME/.local/bin/lib"
|
||||
if [ -f "$tmp_dir/assemblrr/lib/managed_files.sh" ]; then
|
||||
# shellcheck source=/dev/null
|
||||
source "$tmp_dir/assemblrr/lib/managed_files.sh"
|
||||
fi
|
||||
local _m
|
||||
while IFS= read -r _m; do
|
||||
[ -z "$_m" ] && continue
|
||||
if [ -f "$tmp_dir/assemblrr/lib/${_m}.sh" ]; then
|
||||
cp "$tmp_dir/assemblrr/lib/${_m}.sh" "$HOME/.local/bin/lib/${_m}.sh"
|
||||
fi
|
||||
done < <(list_cli_lib_modules)
|
||||
cp "$tmp_dir/assemblrr/bin/cli.sh" "$HOME/.local/bin/$APP_CLI_NAME" && chmod +x "$HOME/.local/bin/$APP_CLI_NAME"
|
||||
# Remove old system-wide install if it exists
|
||||
[ -n "${APP_CLI_NAME:-}" ] && rm -f "/usr/local/bin/$APP_CLI_NAME" 2>/dev/null
|
||||
if type ensure_local_bin_on_path >/dev/null 2>&1; then
|
||||
ensure_local_bin_on_path
|
||||
fi
|
||||
log_success "CLI updated successfully!"
|
||||
|
||||
[ -n "$tmp_dir" ] && rm -rf "$tmp_dir"
|
||||
}
|
||||
|
||||
main() {
|
||||
local command=${1:-"--help"}
|
||||
local destination=${2:-.}
|
||||
|
|
@ -1020,7 +987,7 @@ main() {
|
|||
update_containers "${@:2}"
|
||||
;;
|
||||
update-cli)
|
||||
update_cli
|
||||
log_info "The CLI is ${INSTALL_DIR}/cli.sh. Update with: ${APP_CLI_NAME} upgrade"
|
||||
;;
|
||||
upgrade)
|
||||
if ! type upgrade_app >/dev/null 2>&1; then
|
||||
|
|
|
|||
19
bin/setup.sh
19
bin/setup.sh
|
|
@ -569,23 +569,12 @@ EOF
|
|||
# Usage: build_compose_args "$install_directory" "${setup_vpn,,}"
|
||||
|
||||
install_cli() {
|
||||
# Copy from install directory (persistent), not SCRIPT_DIR (may be /tmp)
|
||||
local cli_source="$install_directory/cli.sh"
|
||||
if [ ! -f "$cli_source" ]; then
|
||||
log_warning "CLI source missing at $cli_source — skip install"
|
||||
if [ ! -f "$install_directory/cli.sh" ]; then
|
||||
log_warning "CLI source missing at $install_directory/cli.sh — skip install"
|
||||
return 1
|
||||
fi
|
||||
|
||||
mkdir -p "$HOME/.local/bin/lib"
|
||||
local _lib_module
|
||||
while IFS= read -r _lib_module; do
|
||||
[ -z "$_lib_module" ] && continue
|
||||
if [ -f "$install_directory/lib/${_lib_module}.sh" ]; then
|
||||
cp "$install_directory/lib/${_lib_module}.sh" "$HOME/.local/bin/lib/${_lib_module}.sh"
|
||||
fi
|
||||
done < <(list_cli_lib_modules)
|
||||
cp "$cli_source" "$HOME/.local/bin/$APP_CLI_NAME" && chmod +x "$HOME/.local/bin/$APP_CLI_NAME"
|
||||
ensure_local_bin_on_path
|
||||
write_install_pointer "$install_directory" "${media_directory:-}"
|
||||
install_user_cli_wrapper
|
||||
log_debug "CLI installed to $HOME/.local/bin/$APP_CLI_NAME"
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,8 +17,7 @@ root-owned; plain `rm -rf` then fails — use the Docker removal step in Option
|
|||
| Docker network | `assemblrr_network` |
|
||||
| Install directory (config, secrets, compose files) | `~/assemblrr` (or the path you chose) |
|
||||
| Media directory (your movies/TV/downloads) | `~/assemblrr-media` (or the path you chose) |
|
||||
| CLI command | `~/.local/bin/assemblrr` |
|
||||
| CLI library modules | `~/.local/bin/lib/*.sh` |
|
||||
| CLI command | `~/.local/bin/assemblrr` (wrapper → install `cli.sh`) |
|
||||
| Runtime config | `<install>/.assemblrr-config` (written when the install tree is first bootstrapped — early in setup, not only at the end) |
|
||||
| Discovery pointer | `~/.assemblrr-config` (points at `INSTALL_DIRECTORY` so the CLI can find non-default paths) |
|
||||
| Logs | `/tmp/assemblrr-*.log` |
|
||||
|
|
@ -133,7 +132,7 @@ rm -rf ~/assemblrr-media # WARNING: this is your movies/TV/downloads
|
|||
|
||||
```bash
|
||||
rm -f ~/.local/bin/assemblrr
|
||||
rm -f ~/.local/bin/lib/*.sh
|
||||
rm -f ~/.local/bin/lib/*.sh # leftover from older installs
|
||||
rmdir ~/.local/bin/lib 2>/dev/null # only removed if now empty
|
||||
rm -f ~/assemblrr_services.txt 2>/dev/null # legacy cheat-sheet
|
||||
rm -f ~/.assemblrr-config 2>/dev/null # discovery pointer
|
||||
|
|
|
|||
66
lib/core.sh
66
lib/core.sh
|
|
@ -398,6 +398,72 @@ probe_writable_path() {
|
|||
return 0
|
||||
}
|
||||
|
||||
# PATH entry (~/.local/bin/<cli>) is a wrapper that execs $INSTALL_DIR/cli.sh.
|
||||
# Older installs copied cli.sh plus a lib/ subset there; those leftovers are removed.
|
||||
|
||||
remove_stale_user_cli_libs() {
|
||||
local lib="$HOME/.local/bin/lib"
|
||||
local m
|
||||
[ -d "$lib" ] || return 0
|
||||
for m in core branding compose vpn managed_files upgrade services ui config_edit; do
|
||||
rm -f "$lib/${m}.sh"
|
||||
done
|
||||
rmdir "$lib" 2>/dev/null || true
|
||||
}
|
||||
|
||||
write_user_cli_wrapper() {
|
||||
local dest="$1"
|
||||
mkdir -p "$(dirname "$dest")"
|
||||
cat >"$dest" <<'EOF'
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
# PATH wrapper — runs the install-tree CLI.
|
||||
|
||||
_read_install_dir() {
|
||||
local f="$1" line
|
||||
[ -f "$f" ] || return 1
|
||||
line=$(grep -E '^INSTALL_DIRECTORY=' "$f" | head -1) || return 1
|
||||
line="${line#INSTALL_DIRECTORY=}"
|
||||
line="${line%$'\r'}"
|
||||
line="${line#\"}"
|
||||
line="${line%\"}"
|
||||
line="${line#\'}"
|
||||
line="${line%\'}"
|
||||
[ -n "$line" ] || return 1
|
||||
printf '%s\n' "$line"
|
||||
}
|
||||
|
||||
dir="${ASSEMBLRR_DIR:-}"
|
||||
if [ -z "$dir" ]; then
|
||||
for f in \
|
||||
/opt/assemblrr/.assemblrr-config \
|
||||
"${HOME}/.assemblrr-config" \
|
||||
"${HOME}/assemblrr/.assemblrr-config"
|
||||
do
|
||||
if dir=$(_read_install_dir "$f"); then
|
||||
break
|
||||
fi
|
||||
dir=""
|
||||
done
|
||||
fi
|
||||
|
||||
if [ -z "$dir" ] || [ ! -f "$dir/cli.sh" ]; then
|
||||
echo "assemblrr: could not find the install. Run setup, or set ASSEMBLRR_DIR." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exec bash "$dir/cli.sh" "$@"
|
||||
EOF
|
||||
chmod +x "$dest"
|
||||
}
|
||||
|
||||
install_user_cli_wrapper() {
|
||||
local dest="$HOME/.local/bin/${APP_CLI_NAME:-assemblrr}"
|
||||
write_user_cli_wrapper "$dest"
|
||||
remove_stale_user_cli_libs
|
||||
ensure_local_bin_on_path
|
||||
}
|
||||
|
||||
# Persist ~/.local/bin on PATH for bash, zsh, and fish.
|
||||
# Does not create ~/.bash_profile (that would hide ~/.profile on login bash).
|
||||
_append_path_line() {
|
||||
|
|
|
|||
|
|
@ -68,18 +68,3 @@ EOF
|
|||
done < <(find "$UPGRADE_SOURCE_ROOT/migrations" -type f -print0 2>/dev/null | sort -z)
|
||||
fi
|
||||
}
|
||||
|
||||
# Lib modules the user-facing CLI copies next to ~/.local/bin/assemblrr.
|
||||
list_cli_lib_modules() {
|
||||
cat <<'EOF'
|
||||
core
|
||||
branding
|
||||
compose
|
||||
vpn
|
||||
managed_files
|
||||
upgrade
|
||||
services
|
||||
ui
|
||||
config_edit
|
||||
EOF
|
||||
}
|
||||
|
|
|
|||
|
|
@ -235,25 +235,10 @@ write_upgrade_version() {
|
|||
|
||||
refresh_user_cli() {
|
||||
local install_dir="$1"
|
||||
mkdir -p "$HOME/.local/bin/lib"
|
||||
local m
|
||||
if ! type list_cli_lib_modules >/dev/null 2>&1; then
|
||||
# shellcheck source=/dev/null
|
||||
[ -f "$install_dir/lib/managed_files.sh" ] && source "$install_dir/lib/managed_files.sh"
|
||||
fi
|
||||
while IFS= read -r m; do
|
||||
[ -z "$m" ] && continue
|
||||
if [ -f "$install_dir/lib/${m}.sh" ]; then
|
||||
cp "$install_dir/lib/${m}.sh" "$HOME/.local/bin/lib/${m}.sh"
|
||||
fi
|
||||
done < <(list_cli_lib_modules)
|
||||
if [ -f "$install_dir/cli.sh" ]; then
|
||||
cp "$install_dir/cli.sh" "$HOME/.local/bin/${APP_CLI_NAME:-assemblrr}"
|
||||
chmod +x "$HOME/.local/bin/${APP_CLI_NAME:-assemblrr}"
|
||||
fi
|
||||
if type ensure_local_bin_on_path >/dev/null 2>&1; then
|
||||
ensure_local_bin_on_path
|
||||
if [ -n "$install_dir" ] && [ ! -f "$HOME/.assemblrr-config" ]; then
|
||||
write_install_pointer "$install_dir" "${MEDIA_DIRECTORY:-}"
|
||||
fi
|
||||
install_user_cli_wrapper
|
||||
}
|
||||
|
||||
# --- Validate compose after apply ---
|
||||
|
|
|
|||
|
|
@ -176,4 +176,35 @@ HOME="$path_home" ensure_local_bin_on_path
|
|||
assert_contains "$(cat "$path_home/.bash_profile")" '.local/bin' "appends existing .bash_profile"
|
||||
assert_contains "$(cat "$path_home/.config/fish/config.fish")" '.local/bin' "writes fish config"
|
||||
|
||||
test_suite "PATH CLI wrapper"
|
||||
wrap_home="$tmp/wrap-home"
|
||||
wrap_inst="$tmp/wrap-install"
|
||||
mkdir -p "$wrap_home/.local/bin/lib" "$wrap_inst"
|
||||
printf '%s\n' '#!/bin/bash' 'echo real-cli' >"$wrap_inst/cli.sh"
|
||||
chmod +x "$wrap_inst/cli.sh"
|
||||
echo stale >"$wrap_home/.local/bin/lib/core.sh"
|
||||
echo leftover >"$wrap_home/.local/bin/lib/config_edit.sh"
|
||||
HOME="$wrap_home" APP_CLI_NAME=assemblrr install_user_cli_wrapper
|
||||
assert_true "wrapper is executable" "[ -x \"$wrap_home/.local/bin/assemblrr\" ]"
|
||||
assert_false "stale core.sh removed" "[ -f \"$wrap_home/.local/bin/lib/core.sh\" ]"
|
||||
assert_false "stale config_edit.sh removed" "[ -f \"$wrap_home/.local/bin/lib/config_edit.sh\" ]"
|
||||
assert_false "empty lib dir removed" "[ -d \"$wrap_home/.local/bin/lib\" ]"
|
||||
assert_not_contains "$(cat "$wrap_home/.local/bin/assemblrr")" "find_install_directory" "wrapper is not the full CLI"
|
||||
out=$(HOME="$wrap_home" ASSEMBLRR_DIR="$wrap_inst" "$wrap_home/.local/bin/assemblrr")
|
||||
assert_eq "real-cli" "$out" "ASSEMBLRR_DIR runs install cli.sh"
|
||||
|
||||
printf 'INSTALL_DIRECTORY="%s"\r\n' "$wrap_inst" >"$wrap_home/.assemblrr-config"
|
||||
out=$(HOME="$wrap_home" env -u ASSEMBLRR_DIR "$wrap_home/.local/bin/assemblrr")
|
||||
assert_eq "real-cli" "$out" "CRLF pointer runs install cli.sh"
|
||||
|
||||
assert_failure "missing install fails" \
|
||||
env HOME="$wrap_home" ASSEMBLRR_DIR="$tmp/no-such-install" "$wrap_home/.local/bin/assemblrr"
|
||||
|
||||
other="$tmp/wrap-other"
|
||||
mkdir -p "$other"
|
||||
printf '%s\n' '#!/bin/bash' 'echo other-cli' >"$other/cli.sh"
|
||||
chmod +x "$other/cli.sh"
|
||||
out=$(HOME="$wrap_home" ASSEMBLRR_DIR="$other" "$wrap_home/.local/bin/assemblrr")
|
||||
assert_eq "other-cli" "$out" "ASSEMBLRR_DIR wins over pointer"
|
||||
|
||||
test_summary
|
||||
|
|
|
|||
|
|
@ -111,8 +111,8 @@ assert_true "upgrade up -d --build --remove-orphans" "grep -q 'up -d --build --r
|
|||
assert_true "upgrade wires with ASSEMBLRR_NONINTERACTIVE" "grep -q 'ASSEMBLRR_NONINTERACTIVE=1' \"$REPO_ROOT/lib/upgrade.sh\""
|
||||
assert_true "upgrade accepts --skip-stack" "grep -q -- '--skip-stack' \"$REPO_ROOT/lib/upgrade.sh\""
|
||||
assert_true "upgrade accepts --skip-wire" "grep -q -- '--skip-wire' \"$REPO_ROOT/lib/upgrade.sh\""
|
||||
mods=$(list_cli_lib_modules)
|
||||
assert_contains "$mods" "config_edit" "CLI modules include config_edit"
|
||||
assert_contains "$mods" "ui" "CLI modules include ui"
|
||||
refresh=$(sed -n '/^refresh_user_cli()/,/^}/p' "$REPO_ROOT/lib/upgrade.sh")
|
||||
assert_contains "$refresh" "install_user_cli_wrapper" "refresh writes PATH wrapper"
|
||||
assert_not_contains "$refresh" "list_cli_lib_modules" "refresh does not copy PATH libs"
|
||||
|
||||
test_summary
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue