#!/usr/bin/env bash set -euo pipefail repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" work="$(realpath "$(mktemp -d "${HOME}/.pi/agent/shell-check-test.XXXXXX")")" trap 'rm -rf "${work}"' EXIT mkdir -p "${work}/scripts/local" "${work}/fake-bin" cp "${repo_root}/scripts/local/shell-check.sh" "${work}/scripts/local/shell-check" chmod +x "${work}/scripts/local/shell-check" git -C "${work}" init --quiet git -C "${work}" config user.email test@example.invalid git -C "${work}" config user.name test cat >"${work}/.gitignore" <<'EOF' ignored/ target/ generated/ vendor/ EOF mkdir -p "${work}"/{.apk,ignored,target,generated,vendor} printf '#!/usr/bin/env bash\necho apk\n' >"${work}/.apk/bootstrap.sh" printf '#!/usr/bin/env bash\necho tracked\n' >"${work}/tracked shell.sh" printf '#!/usr/bin/env bash\necho untracked\n' >"${work}/untracked shell.sh" printf '#!/usr/bin/env bash\necho ignored\n' >"${work}/ignored/ignored.sh" printf '#!/usr/bin/env bash\necho target\n' >"${work}/target/target.sh" printf '#!/usr/bin/env bash\necho generated\n' >"${work}/generated/generated.sh" printf '#!/usr/bin/env bash\necho vendor\n' >"${work}/vendor/vendor.sh" printf 'plain\n' >"${work}/plain.txt" git -C "${work}" add .gitignore "tracked shell.sh" plain.txt git -C "${work}" commit --quiet -m initial cat >"${work}/fake-bin/shfmt" <<'EOF' #!/usr/bin/env bash printf '%s\0' "$@" >>"${SHELL_CHECK_LOG}" EOF cat >"${work}/fake-bin/shellcheck" <<'EOF' #!/usr/bin/env bash printf '%s\0' "$@" >>"${SHELL_CHECK_LOG}" EOF chmod +x "${work}/fake-bin/"{shfmt,shellcheck} expect_failure() { if "$@" >/dev/null 2>&1; then echo "expected failure: $*" >&2 exit 1 fi } log="${work}/check.log" before="$(sha256sum "${work}/tracked shell.sh")" (cd "${work}" && PATH="${work}/fake-bin:${PATH}" SHELL_CHECK_LOG="${log}" scripts/local/shell-check read) after="$(sha256sum "${work}/tracked shell.sh")" [[ "${before}" == "${after}" ]] || { echo "read modified shell source" >&2 exit 1 } tr '\0' '\n' <"${log}" | grep -Fqx -- '-d' tr '\0' '\n' <"${log}" | grep -Fqx -- "${work}/tracked shell.sh" tr '\0' '\n' <"${log}" | grep -Fqx -- "${work}/untracked shell.sh" for path in .apk/bootstrap.sh ignored/ignored.sh target/target.sh generated/generated.sh vendor/vendor.sh; do if tr '\0' '\n' <"${log}" | grep -Fq -- "${work}/${path}"; then echo "excluded shell path was checked: ${path}" >&2 exit 1 fi done : >"${log}" for path in .apk/bootstrap.sh ignored/ignored.sh target/target.sh generated/generated.sh vendor/vendor.sh; do (cd "${work}" && PATH="${work}/fake-bin:${PATH}" SHELL_CHECK_LOG="${log}" scripts/local/shell-check read "${path}") done [[ ! -s "${log}" ]] || { echo "excluded explicit shell path was checked" >&2 exit 1 } expect_failure bash -c "cd '${work}' && scripts/local/shell-check read plain.txt" expect_failure bash -c "cd '${work}' && scripts/local/shell-check read missing.sh" printf '#!/usr/bin/env bash\necho deleted\n' >"${work}/deleted.sh" git -C "${work}" add deleted.sh git -C "${work}" commit --quiet -m deleted rm "${work}/deleted.sh" expect_failure bash -c "cd '${work}' && scripts/local/shell-check read deleted.sh" empty="$(realpath "$(mktemp -d "${HOME}/.pi/agent/shell-check-empty-test.XXXXXX")")" trap 'rm -rf "${work}" "${empty}"' EXIT mkdir -p "${empty}/scripts/local" cp "${repo_root}/scripts/local/shell-check.sh" "${empty}/scripts/local/shell-check" chmod +x "${empty}/scripts/local/shell-check" git -C "${empty}" init --quiet expect_failure bash -c "cd '${empty}' && scripts/local/shell-check read"