diff --git a/TODO.md b/TODO.md index da2567f..a153a68 100644 --- a/TODO.md +++ b/TODO.md @@ -160,10 +160,11 @@ Use this as a commit-by-commit work queue. When an item is fixed, update the che - Problem: both files copy the same Base-owned variable snapshot/restore logic with different function prefixes. - Expected fix: create a shared Zsh guard helper and source it from both files. -- [ ] Add BATS coverage for Bash-to-Python setup handoff. +- [x] Add BATS coverage for Bash-to-Python setup handoff. - Files: `cli/bash/commands/basectl/tests/setup.bats`, `cli/bash/commands/basectl/subcommands/setup_common.sh` - Problem: `setup_run_project_artifact_setup` is not covered at the Bash layer. - Expected fix: mock `base-wrapper` or the Python boundary and verify argument passing, manifest/project environment handling, and non-zero exit propagation. + - Done. ## Usability Issues diff --git a/cli/bash/commands/basectl/tests/setup.bats b/cli/bash/commands/basectl/tests/setup.bats index 14e7689..9c9dae7 100644 --- a/cli/bash/commands/basectl/tests/setup.bats +++ b/cli/bash/commands/basectl/tests/setup.bats @@ -321,6 +321,38 @@ EOF chmod +x "$venv_dir/bin/python" } +create_project_setup_venv_stub() { + local exit_code="${2:-0}" + local venv_dir="${1:-$TEST_HOME/.base.d/base/.venv}" + + mkdir -p "$venv_dir/bin" + printf '#!/usr/bin/env bash\n' > "$venv_dir/bin/activate" + cat > "$venv_dir/bin/python" <<'EOF' +#!/usr/bin/env bash +pyyaml_package="${BASE_SETUP_PYYAML_PACKAGE:-PyYAML}" +click_package="${BASE_SETUP_CLICK_PACKAGE:-click}" +if [[ "${1:-}" == "-m" && "${2:-}" == "base_setup" ]]; then + shift 2 + printf '%s\n' "$@" > "${BASE_SETUP_TEST_STATE_DIR:?}/project-setup-args" + printf '%s\n' "${BASE_PROJECT:-}" > "$BASE_SETUP_TEST_STATE_DIR/project-setup-project" + touch "$BASE_SETUP_TEST_STATE_DIR/project-setup-ran" + exit "$(cat "$BASE_SETUP_TEST_STATE_DIR/project-setup-exit-code")" +fi +if [[ "${1:-}" == "-m" && "${2:-}" == "pip" && "${3:-}" == "show" && "${4:-}" == "$pyyaml_package" ]]; then + [[ -f "${BASE_SETUP_TEST_STATE_DIR:?}/pyyaml-installed" ]] + exit $? +fi +if [[ "${1:-}" == "-m" && "${2:-}" == "pip" && "${3:-}" == "show" && "${4:-}" == "$click_package" ]]; then + [[ -f "${BASE_SETUP_TEST_STATE_DIR:?}/click-installed" ]] + exit $? +fi +printf 'unexpected project setup venv python args: %s\n' "$*" >&2 +exit 1 +EOF + chmod +x "$venv_dir/bin/python" + printf '%s\n' "$exit_code" > "$TEST_STATE_DIR/project-setup-exit-code" +} + @test "basectl setup prints usage for help" { run_base_command setup --help @@ -445,6 +477,50 @@ EOF [ -f "$venv_dir/pyvenv.cfg" ] } +@test "basectl setup forwards project setup arguments through base-wrapper" { + local base_venv_dir="$TEST_HOME/.base.d/base/.venv" + local demo_venv_dir="$TEST_HOME/.base.d/demo/.venv" + local manifest_path="$TEST_TMPDIR/demo_manifest.yaml" + + create_brew_stub + create_xcode_stubs + touch "$TEST_STATE_DIR/xcode-installed" + mkdir -p "$TEST_TMPDIR/CommandLineTools" + touch "$TEST_STATE_DIR/python-installed" + touch "$TEST_STATE_DIR/pyyaml-installed" + touch "$TEST_STATE_DIR/click-installed" + create_base_venv_stub "$base_venv_dir" + create_project_setup_venv_stub "$demo_venv_dir" + printf 'project:\n name: demo\nartifacts: []\n' > "$manifest_path" + + run_base_command setup --dry-run --manifest "$manifest_path" demo + + [ "$status" -eq 0 ] + [[ "$output" == *"Running Python project setup layer."* ]] + [ -f "$TEST_STATE_DIR/project-setup-ran" ] + [ "$(cat "$TEST_STATE_DIR/project-setup-project")" = "demo" ] + [ "$(cat "$TEST_STATE_DIR/project-setup-args")" = "$(printf '%s\n' --dry-run --manifest "$manifest_path" demo)" ] +} + +@test "basectl setup propagates Python project setup failure" { + local venv_dir="$TEST_HOME/.base.d/base/.venv" + + create_brew_stub + create_xcode_stubs + touch "$TEST_STATE_DIR/xcode-installed" + mkdir -p "$TEST_TMPDIR/CommandLineTools" + touch "$TEST_STATE_DIR/python-installed" + touch "$TEST_STATE_DIR/pyyaml-installed" + touch "$TEST_STATE_DIR/click-installed" + create_project_setup_venv_stub "$venv_dir" 42 + + run_base_command setup + + [ "$status" -eq 42 ] + [[ "$output" == *"Python project setup layer failed."* ]] + [ -f "$TEST_STATE_DIR/project-setup-ran" ] +} + @test "basectl setup --dev installs BATS with developer dependencies" { local installer