From 21f6b79e268dae4fdb93cf5d14bc2b723cb2d3ff Mon Sep 17 00:00:00 2001 From: noctuum <25441068+noctuum@users.noreply.github.com> Date: Fri, 30 Oct 2026 22:21:13 +0500 Subject: [PATCH 1/5] feat(lib): add AURTOMATOR_DATA_DIR --- scripts/lib/common.sh | 23 ++++++++++++++++++++--- tests/helpers/setup.sh | 4 +++- tests/scripts.bats | 39 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 61 insertions(+), 5 deletions(-) diff --git a/scripts/lib/common.sh b/scripts/lib/common.sh index 2ff19e4..6804d8d 100644 --- a/scripts/lib/common.sh +++ b/scripts/lib/common.sh @@ -5,12 +5,29 @@ # # Usage: source "${SCRIPT_DIR}/../scripts/lib/common.sh" # Requires: yq (https://github.com/mikefarah/yq) +# +# AURTOMATOR_DIR is the root of the checkout that holds this file. +# AURTOMATOR_DATA_DIR is the directory with the packages and .aurtomator.conf. +# It comes from the environment and defaults to the working directory. set -euo pipefail -# Resolve project root +# Resolve project root. The scripts and lib/version.sh read it. +# shellcheck disable=SC2034 AURTOMATOR_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +# Resolve the data root. The variable is set last, so the message names the +# value as the caller gave it. +resolve_data_dir() { + local dir + if ! dir="$(cd -- "${AURTOMATOR_DATA_DIR:-.}" 2>/dev/null && pwd)"; then + echo "AURTOMATOR_DATA_DIR is not a directory: ${AURTOMATOR_DATA_DIR}" >&2 + exit 1 + fi + AURTOMATOR_DATA_DIR="$dir" +} +resolve_data_dir + # ============================================================================= # DEPENDENCY CHECK # ============================================================================= @@ -103,7 +120,7 @@ pkg_asset_var() { # ============================================================================= load_config() { - local config="${AURTOMATOR_DIR}/.aurtomator.conf" + local config="${AURTOMATOR_DATA_DIR}/.aurtomator.conf" if [[ -f "$config" ]]; then # shellcheck source=/dev/null source "$config" @@ -118,7 +135,7 @@ load_config() { # Usage: pkg_file my-package pkg_file() { local name="$1" - local file="${AURTOMATOR_DIR}/packages/${name}.yml" + local file="${AURTOMATOR_DATA_DIR}/packages/${name}.yml" if [[ ! -f "$file" ]]; then log_err "Package not found: $file" return 1 diff --git a/tests/helpers/setup.sh b/tests/helpers/setup.sh index a8ff628..849c530 100644 --- a/tests/helpers/setup.sh +++ b/tests/helpers/setup.sh @@ -28,8 +28,10 @@ setup_test_env() { chmod +x "$MOCK_DIR/curl" export PATH="$MOCK_DIR:$PATH" - # Override AURTOMATOR_DIR so all scripts use our temp workspace + # Override AURTOMATOR_DIR and AURTOMATOR_DATA_DIR so all scripts use our + # temp workspace export AURTOMATOR_DIR="$TEST_TMPDIR" + export AURTOMATOR_DATA_DIR="$TEST_TMPDIR" # No pause before an AUR clone, between attempts or before a second check export AURTOMATOR_CLONE_DELAY=0 AURTOMATOR_RETRY_DELAY=0 AURTOMATOR_RECHECK_DELAY=0 diff --git a/tests/scripts.bats b/tests/scripts.bats index d07b6a5..4e62bab 100644 --- a/tests/scripts.bats +++ b/tests/scripts.bats @@ -38,6 +38,43 @@ teardown() { [[ "$output" == *"Package not found: "*"/packages/nonexistent.yml"* ]] } +# setup_test_env exports AURTOMATOR_DATA_DIR, so env -u removes it +@test "lib.sh: AURTOMATOR_DATA_DIR defaults to the working directory" { + mkdir -p "$BATS_TEST_TMPDIR/data/packages" + touch "$BATS_TEST_TMPDIR/data/packages/foo.yml" + + run env -u AURTOMATOR_DATA_DIR bash -c 'cd "$1" && source "$0/scripts/lib.sh" && pkg_file foo' "$TEST_TMPDIR" "$BATS_TEST_TMPDIR/data" + [ "$status" -eq 0 ] + [ "$output" = "$BATS_TEST_TMPDIR/data/packages/foo.yml" ] +} + +@test "lib.sh: pkg_file and load_config read AURTOMATOR_DATA_DIR" { + mkdir -p "$BATS_TEST_TMPDIR/data/packages" + touch "$BATS_TEST_TMPDIR/data/packages/foo.yml" + echo "GIT_AUTHOR_NAME='x'" >"$BATS_TEST_TMPDIR/data/.aurtomator.conf" + + AURTOMATOR_DATA_DIR="$BATS_TEST_TMPDIR/data" run bash -c 'source "$0/scripts/lib.sh" && load_config && pkg_file foo && echo "$GIT_AUTHOR_NAME"' "$TEST_TMPDIR" + [ "$status" -eq 0 ] + [ "${lines[0]}" = "$BATS_TEST_TMPDIR/data/packages/foo.yml" ] + [ "${lines[1]}" = x ] +} + +@test "lib.sh: a wrong AURTOMATOR_DATA_DIR stops the script" { + AURTOMATOR_DATA_DIR="$BATS_TEST_TMPDIR/none" run bash -c 'source "$0/scripts/lib.sh"; echo reached' "$TEST_TMPDIR" + [ "$status" -eq 1 ] + [ "$output" = "AURTOMATOR_DATA_DIR is not a directory: $BATS_TEST_TMPDIR/none" ] +} + +# Without -- cd takes -P as its option and goes to $HOME +@test "lib.sh: AURTOMATOR_DATA_DIR may start with a dash" { + mkdir -p "$BATS_TEST_TMPDIR/-P/packages" + touch "$BATS_TEST_TMPDIR/-P/packages/foo.yml" + + run env AURTOMATOR_DATA_DIR=-P bash -c 'cd "$1" && source "$0/scripts/lib.sh" && pkg_file foo' "$TEST_TMPDIR" "$BATS_TEST_TMPDIR" + [ "$status" -eq 0 ] + [ "$output" = "$BATS_TEST_TMPDIR/-P/packages/foo.yml" ] +} + @test "lib.sh: pkg_get reads YAML field" { create_test_package "mypkg" "github-release" "upstream: type: github @@ -1550,7 +1587,7 @@ make_spaced_project() { @test "check-all: finds the packages of a project whose path has a space" { make_spaced_project - run "$SPACED/scripts/check-all.sh" + AURTOMATOR_DATA_DIR="$SPACED" run "$SPACED/scripts/check-all.sh" [ "$status" -eq 0 ] [[ "$output" == *"Checked: 1, Updated: 0, Errors: 0"* ]] [ "$(cat "$SPACED/.status/pkg")" = "up_to_date" ] From 0f9fe71df72c4b733f35f109cac6331ff627b46d Mon Sep 17 00:00:00 2001 From: noctuum <25441068+noctuum@users.noreply.github.com> Date: Fri, 30 Oct 2026 22:33:16 +0500 Subject: [PATCH 2/5] feat(scripts): check-all reads the data root --- scripts/check-all.sh | 10 +++++----- scripts/lib/common.sh | 5 +++-- tests/publish.bats | 9 +++++++++ tests/scripts.bats | 19 +++++++++++++++++++ 4 files changed, 36 insertions(+), 7 deletions(-) diff --git a/scripts/check-all.sh b/scripts/check-all.sh index 316b815..ed999ee 100755 --- a/scripts/check-all.sh +++ b/scripts/check-all.sh @@ -16,8 +16,8 @@ # version that run found and without running the strategies # With --dry-run: runs update-pkg.sh or publish-pkg.sh in dry-run mode # -# Writes per-package status to .status/ directory for README generation -# and auto-issue creation. +# Writes per-package status to .status/ of the data root (AURTOMATOR_DATA_DIR) +# for README generation and auto-issue creation. set -euo pipefail # shellcheck source=lib.sh @@ -99,7 +99,7 @@ done # path. if [[ "$MODE" == "verify" ]]; then failed=0 - for pkg_file in "${AURTOMATOR_DIR}"/packages/*.yml; do + for pkg_file in "${AURTOMATOR_DATA_DIR}"/packages/*.yml; do [[ -f "$pkg_file" ]] || continue pkg_name=$(pkg_get "$pkg_file" .name) prepared="${WORK_DIR}/prepared/${pkg_name}" @@ -141,7 +141,7 @@ if [[ "$MODE" == "verify" ]]; then fi # Status directory for per-package results -STATUS_DIR="${AURTOMATOR_DIR}/.status" +STATUS_DIR="${AURTOMATOR_DATA_DIR}/.status" # --prepare and --publish take the statuses of the check run before them, # read here before anything else runs, and run no strategy: --prepare runs @@ -481,7 +481,7 @@ run_package() { } RECHECK=() -for pkg_file in "${AURTOMATOR_DIR}"/packages/*.yml; do +for pkg_file in "${AURTOMATOR_DATA_DIR}"/packages/*.yml; do [[ -f "$pkg_file" ]] || continue run_package "$pkg_file" 1 done diff --git a/scripts/lib/common.sh b/scripts/lib/common.sh index 6804d8d..7e64515 100644 --- a/scripts/lib/common.sh +++ b/scripts/lib/common.sh @@ -7,8 +7,9 @@ # Requires: yq (https://github.com/mikefarah/yq) # # AURTOMATOR_DIR is the root of the checkout that holds this file. -# AURTOMATOR_DATA_DIR is the directory with the packages and .aurtomator.conf. -# It comes from the environment and defaults to the working directory. +# AURTOMATOR_DATA_DIR is the directory with the packages, .status/ and +# .aurtomator.conf. It comes from the environment and defaults to the working +# directory. set -euo pipefail diff --git a/tests/publish.bats b/tests/publish.bats index f7afbee..d8d9daf 100644 --- a/tests/publish.bats +++ b/tests/publish.bats @@ -1983,6 +1983,15 @@ current: '1.0.0'" [ "$(cat "$TEST_TMPDIR/verify-pkg.sh.args")" = "pkg $TEST_TMPDIR/out/prepared/pkg" ] } +@test "check-all --verify: verifies the packages of AURTOMATOR_DATA_DIR" { + mkdir -p "$BATS_TEST_TMPDIR/data/packages" "$TEST_TMPDIR/out/prepared/pkg" + printf '%s\n' 'name: pkg' 'strategy: github-release' 'upstream:' ' project: owner/repo' "current: '1.0.0'" >"$BATS_TEST_TMPDIR/data/packages/pkg.yml" + stub_script verify-pkg.sh 0 + AURTOMATOR_DATA_DIR="$BATS_TEST_TMPDIR/data" run "$TEST_TMPDIR/scripts/check-all.sh" --verify "$TEST_TMPDIR/out" + [ "$status" -eq 0 ] + [ "$(cat "$TEST_TMPDIR/verify-pkg.sh.args")" = "pkg $TEST_TMPDIR/out/prepared/pkg" ] +} + # === alert_issue_body === @test "alert_issue_body: lists every note of a held update" { diff --git a/tests/scripts.bats b/tests/scripts.bats index 4e62bab..e691bd3 100644 --- a/tests/scripts.bats +++ b/tests/scripts.bats @@ -1572,6 +1572,25 @@ EOF [[ "$output" == *"Checked: 0"* ]] } +# A skipped downgrade is logged with the name of its package +@test "check-all: reads the packages of AURTOMATOR_DATA_DIR and runs the strategies of the checkout" { + mkdir -p "$BATS_TEST_TMPDIR/data/packages" + cat >"$BATS_TEST_TMPDIR/data/packages/foo.yml" < Date: Fri, 30 Oct 2026 22:43:14 +0500 Subject: [PATCH 3/5] feat(scripts): validate-pkg reads the data root --- scripts/validate-pkg.sh | 2 +- tests/validate-pkg.bats | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/scripts/validate-pkg.sh b/scripts/validate-pkg.sh index fd25ea6..ebe27fa 100755 --- a/scripts/validate-pkg.sh +++ b/scripts/validate-pkg.sh @@ -667,7 +667,7 @@ validate_pkg() { if [[ "${1:-}" == "--all" ]]; then total=0 failed=0 - for pkg_file in "${AURTOMATOR_DIR}"/packages/*.yml; do + for pkg_file in "${AURTOMATOR_DATA_DIR}"/packages/*.yml; do [[ -f "$pkg_file" ]] || continue ((total++)) || true if ! validate_pkg "$pkg_file"; then diff --git a/tests/validate-pkg.bats b/tests/validate-pkg.bats index 5805fa9..922253e 100644 --- a/tests/validate-pkg.bats +++ b/tests/validate-pkg.bats @@ -906,6 +906,18 @@ pkgver_dashes: _" [[ "$output" == *"No packages found"* ]] } +# The data root holds the packages and no strategies/, so the strategy names +# have to come from the checkout +@test "validate-pkg: --all validates the packages of AURTOMATOR_DATA_DIR" { + mkdir -p "$BATS_TEST_TMPDIR/data/packages" + printf '%s\n' 'name: pkg-a' 'strategy: github-release' 'upstream:' ' project: owner/repo' >"$BATS_TEST_TMPDIR/data/packages/pkg-a.yml" + printf '%s\n' 'name: pkg-b' 'strategy: pypi' 'upstream:' ' registry: requests' >"$BATS_TEST_TMPDIR/data/packages/pkg-b.yml" + + AURTOMATOR_DATA_DIR="$BATS_TEST_TMPDIR/data" run "$TEST_TMPDIR/scripts/validate-pkg.sh" --all + [ "$status" -eq 0 ] + [[ "$output" == *"All 2 packages valid"* ]] +} + @test "validate: fails on nonexistent package" { run "$TEST_TMPDIR/scripts/validate-pkg.sh" "nonexistent" [ "$status" -ne 0 ] From 5c74890657e059aa15d14379b7ceb4da1058feed Mon Sep 17 00:00:00 2001 From: noctuum <25441068+noctuum@users.noreply.github.com> Date: Fri, 30 Oct 2026 22:54:18 +0500 Subject: [PATCH 4/5] feat(scripts): update-readme reads the data root --- scripts/lib/common.sh | 6 +++--- scripts/update-readme.sh | 8 ++++---- tests/scripts.bats | 27 ++++++++++++++++++++++++++- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/scripts/lib/common.sh b/scripts/lib/common.sh index 7e64515..3025401 100644 --- a/scripts/lib/common.sh +++ b/scripts/lib/common.sh @@ -7,9 +7,9 @@ # Requires: yq (https://github.com/mikefarah/yq) # # AURTOMATOR_DIR is the root of the checkout that holds this file. -# AURTOMATOR_DATA_DIR is the directory with the packages, .status/ and -# .aurtomator.conf. It comes from the environment and defaults to the working -# directory. +# AURTOMATOR_DATA_DIR is the directory with the packages, .status/, +# .aurtomator.conf, README.md and the origin remote the badges read. It comes +# from the environment and defaults to the working directory. set -euo pipefail diff --git a/scripts/update-readme.sh b/scripts/update-readme.sh index 3cb5300..925047c 100755 --- a/scripts/update-readme.sh +++ b/scripts/update-readme.sh @@ -19,8 +19,8 @@ set -euo pipefail source "$(dirname "${BASH_SOURCE[0]}")/lib.sh" require_cmd yq -readonly README="${AURTOMATOR_DIR}/README.md" -readonly STATUS_DIR="${AURTOMATOR_DIR}/.status" +readonly README="${AURTOMATOR_DATA_DIR}/README.md" +readonly STATUS_DIR="${AURTOMATOR_DATA_DIR}/.status" if [[ ! -f "$README" ]]; then log_err "README.md not found" @@ -67,7 +67,7 @@ fi # Only a GitHub origin names the repo, so the URL of another remote, or a # local path, never reaches the README repo_url="" -origin_url=$(git -C "$AURTOMATOR_DIR" remote get-url origin 2>/dev/null || true) +origin_url=$(git -C "$AURTOMATOR_DATA_DIR" remote get-url origin 2>/dev/null || true) if [[ "$origin_url" =~ [/@]github\.com[:/]([A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+) ]]; then repo_url="${BASH_REMATCH[1]%.git}" fi @@ -136,7 +136,7 @@ table_header=$'\n' "$data/README.md" + [ ! -e "$TEST_TMPDIR/README.md" ] +} + # === lib.sh: warn_maintainer_line === @test "lib.sh: warn_maintainer_line warns when missing" { From 93f0dcb3f980ddfb7a928e155b959ff7bcf54577 Mon Sep 17 00:00:00 2001 From: noctuum <25441068+noctuum@users.noreply.github.com> Date: Fri, 30 Oct 2026 23:09:02 +0500 Subject: [PATCH 5/5] feat(setup): run from the packages repository --- scripts/setup.sh | 46 +++++++++++++------- tests/setup.bats | 106 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 134 insertions(+), 18 deletions(-) diff --git a/scripts/setup.sh b/scripts/setup.sh index 91dae44..aa8b8f8 100755 --- a/scripts/setup.sh +++ b/scripts/setup.sh @@ -2,13 +2,13 @@ # # setup.sh - First-time aurtomator configuration # -# Usage: -# ./scripts/setup.sh # full setup (all steps) -# ./scripts/setup.sh identity # git author name/email only -# ./scripts/setup.sh ssh # SSH key for AUR only -# ./scripts/setup.sh gpg # GPG signing key only -# ./scripts/setup.sh secrets # GitHub Secrets only -# ./scripts/setup.sh verify # verify everything works +# Usage, from inside your packages repository: +# cd && /scripts/setup.sh # full setup (all steps) +# setup.sh identity # git author name/email only +# setup.sh ssh # SSH key for AUR only +# setup.sh gpg # GPG signing key only +# setup.sh secrets # GitHub Secrets only +# setup.sh verify # verify everything works # # Options: # --git-name Git author name for AUR commits @@ -21,7 +21,20 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" AURTOMATOR_DIR="${AURTOMATOR_DIR:-$(cd "$SCRIPT_DIR/.." && pwd)}" -CONFIG_FILE="${AURTOMATOR_DIR}/.aurtomator.conf" + +# The data root, resolved as in lib/common.sh, which this script does not +# source. The variable is set last, so the message names the value as the +# caller gave it. +resolve_data_dir() { + local dir + if ! dir="$(cd -- "${AURTOMATOR_DATA_DIR:-.}" 2>/dev/null && pwd)"; then + echo "AURTOMATOR_DATA_DIR is not a directory: ${AURTOMATOR_DATA_DIR}" >&2 + exit 1 + fi + AURTOMATOR_DATA_DIR="$dir" +} +resolve_data_dir +CONFIG_FILE="${AURTOMATOR_DATA_DIR}/.aurtomator.conf" # Defaults GIT_AUTHOR_NAME="" @@ -101,6 +114,7 @@ save_config() { setup_identity() { header "identity" "Who you are on AUR" + printf " Data directory: %s\n" "$AURTOMATOR_DATA_DIR" # Detect defaults from git config local default_name default_email @@ -151,7 +165,7 @@ check_ssh_key() { printf "\n CI uses the key without a prompt. Remove the passphrase from a copy:\n" printf " cp %s %s-ci\n" "$AUR_SSH_KEY" "$AUR_SSH_KEY" printf " ssh-keygen -p -N '' -f %s-ci\n" "$AUR_SSH_KEY" - printf " ./scripts/setup.sh ssh --ssh-key %s-ci\n\n" "$AUR_SSH_KEY" + printf " %s ssh --ssh-key %s-ci\n\n" "$0" "$AUR_SSH_KEY" return 1 else fail "Not a valid private key: $AUR_SSH_KEY" @@ -362,7 +376,7 @@ setup_secrets() { gpg_source="copy" elif gpg_key_has_passphrase "$GPG_KEY_ID"; then warn "GPG key $GPG_KEY_ID has a passphrase, GPG_SIGNING_KEY not set" - warn "Run ./scripts/setup.sh gpg secrets to make a passphrase-free copy" + warn "Run $0 gpg secrets to make a passphrase-free copy" else gpg_source="key" fi @@ -371,7 +385,7 @@ setup_secrets() { if [[ "$has_gh" == "true" ]]; then # Detect repo from origin remote (not upstream) local gh_repo - gh_repo=$(git -C "$AURTOMATOR_DIR" remote get-url origin 2>/dev/null | sed 's|.*github.com[:/]||; s|\.git$||' || true) + gh_repo=$(git -C "$AURTOMATOR_DATA_DIR" remote get-url origin 2>/dev/null | sed 's|.*github.com[:/]||; s|\.git$||' || true) if [[ -z "$gh_repo" ]]; then gh_repo=$(ask "GitHub repo (owner/name)") fi @@ -479,7 +493,7 @@ verify_all() { # Secrets if command -v gh &>/dev/null && gh auth status &>/dev/null 2>&1; then local gh_repo - gh_repo=$(git -C "$AURTOMATOR_DIR" remote get-url origin 2>/dev/null | sed 's|.*github.com[:/]||; s|\.git$||' || true) + gh_repo=$(git -C "$AURTOMATOR_DATA_DIR" remote get-url origin 2>/dev/null | sed 's|.*github.com[:/]||; s|\.git$||' || true) local secret_list secret_list=$(gh secret list -R "$gh_repo" 2>/dev/null || true) local secret_count=0 @@ -503,10 +517,10 @@ verify_all() { if [[ "$errors" -eq 0 ]]; then printf "\n %s%sReady.%s Add your first package:\n" "$GREEN" "$BOLD" "$RESET" - printf " cp packages/example.yml.sample packages/.yml\n\n" + printf " cp %s/packages/example.yml.sample %s/packages/.yml\n\n" "$AURTOMATOR_DIR" "$AURTOMATOR_DATA_DIR" else printf "\n %s%s%d issue(s) found.%s Fix and re-run:\n" "$YELLOW" "$BOLD" "$errors" "$RESET" - printf " ./scripts/setup.sh verify\n\n" + printf " %s verify\n\n" "$0" return 1 fi } @@ -549,7 +563,7 @@ while [[ $# -gt 0 ]]; do exit 0 ;; *) - echo "Unknown option: $1 (see ./scripts/setup.sh --help)" >&2 + echo "Unknown option: $1 (see $0 --help)" >&2 exit 1 ;; esac @@ -580,5 +594,5 @@ for step in "${STEPS[@]}"; do esac save_config done -ok "Config saved to .aurtomator.conf" +ok "Config saved to .aurtomator.conf in $AURTOMATOR_DATA_DIR" exit "$EXIT_STATUS" diff --git a/tests/setup.bats b/tests/setup.bats index bb84843..e015703 100644 --- a/tests/setup.bats +++ b/tests/setup.bats @@ -240,6 +240,12 @@ EOF [[ "$output" == *"setup.sh"* ]] } +@test "setup: --help shows how to run it from the packages repository" { + run "$TEST_TMPDIR/scripts/setup.sh" --help + [ "$status" -eq 0 ] + [[ "$output" == *"cd && /scripts/setup.sh"* ]] +} + @test "setup: unknown flag exits 1" { run "$TEST_TMPDIR/scripts/setup.sh" --bogus-flag [ "$status" -eq 1 ] @@ -488,6 +494,17 @@ EOF [[ "$output" == *"✓ GPG: signing works with VALIDKEY123"* ]] [[ "$output" == *"✓ Secrets: 4/4 configured"* ]] [[ "$output" == *"1 issue(s) found."* ]] + [[ "$output" == *"$TEST_TMPDIR/scripts/setup.sh verify"* ]] +} + +@test "setup verify: names the sample of the clone and the packages of AURTOMATOR_DATA_DIR" { + write_full_config "" + mkdir -p "$BATS_TEST_TMPDIR/data" + cp "$TEST_TMPDIR/.aurtomator.conf" "$BATS_TEST_TMPDIR/data/" + + AURTOMATOR_DATA_DIR="$BATS_TEST_TMPDIR/data" run "$TEST_TMPDIR/scripts/setup.sh" verify --non-interactive + [ "$status" -eq 0 ] + [[ "$output" == *"cp $TEST_TMPDIR/packages/example.yml.sample $BATS_TEST_TMPDIR/data/packages/.yml"* ]] } @test "setup verify: counts every failed check" { @@ -570,7 +587,7 @@ EOF run "$TEST_TMPDIR/scripts/setup.sh" secrets --non-interactive [ "$status" -eq 0 ] [[ "$output" == *"has a passphrase"* ]] - [[ "$output" == *"./scripts/setup.sh gpg secrets"* ]] + [[ "$output" == *"Run $TEST_TMPDIR/scripts/setup.sh gpg secrets"* ]] [[ "$output" != *"Set Actions secret GPG_SIGNING_KEY"* ]] } @@ -785,7 +802,7 @@ EOF @test "setup: unknown option suggests --help" { run "$TEST_TMPDIR/scripts/setup.sh" --bogus-flag [ "$status" -eq 1 ] - [[ "$output" == *"--help"* ]] + [[ "$output" == *"(see $TEST_TMPDIR/scripts/setup.sh --help)"* ]] } # === Verify secret counts === @@ -829,6 +846,7 @@ EOF [[ "$output" == *"✗ SSH key has a passphrase: $TEST_TMPDIR/ssh-pass/key"* ]] [[ "$output" == *"cp $TEST_TMPDIR/ssh-pass/key $TEST_TMPDIR/ssh-pass/key-ci"* ]] [[ "$output" == *"ssh-keygen -p -N '' -f $TEST_TMPDIR/ssh-pass/key-ci"* ]] + [[ "$output" == *"$TEST_TMPDIR/scripts/setup.sh ssh --ssh-key $TEST_TMPDIR/ssh-pass/key-ci"* ]] [ ! -e "$TEST_TMPDIR/.aurtomator.conf" ] } @@ -1077,3 +1095,87 @@ EOF [[ "$output" == *"! Secrets: cannot verify (gh not available)"* ]] [[ "$output" == *"Ready."* ]] } + +# === Data directory === + +@test "setup: saves .aurtomator.conf in AURTOMATOR_DATA_DIR" { + local data="$BATS_TEST_TMPDIR/data" + mkdir -p "$data" + + AURTOMATOR_DATA_DIR="$data" run "$TEST_TMPDIR/scripts/setup.sh" identity \ + --git-name "Jane Doe" --git-email "jane@example.com" \ + --non-interactive + [ "$status" -eq 0 ] + grep -qx "GIT_AUTHOR_NAME='Jane Doe'" "$data/.aurtomator.conf" + [ ! -e "$TEST_TMPDIR/.aurtomator.conf" ] + [[ "$output" == *"Who you are on AUR"$'\n\n'" Data directory: $data"$'\n'* ]] + [[ "$output" == *"Config saved to .aurtomator.conf in $data"* ]] +} + +@test "setup: reads the repository from the origin of AURTOMATOR_DATA_DIR" { + local data="$BATS_TEST_TMPDIR/data" + mkdir -p "$data" + git -C "$data" init -q + git -C "$data" remote add origin "git@github.com:owner/data.git" + log_gh_calls + + AURTOMATOR_DATA_DIR="$data" run "$TEST_TMPDIR/scripts/setup.sh" secrets \ + --git-name "Jane Doe" --git-email "jane@example.com" \ + --ssh-key "$TEST_TMPDIR/ssh/aur.pem" --non-interactive + [ "$status" -eq 0 ] + [[ "$output" == *"Target repo: owner/data"* ]] + grep -qx 'secret set AUR_SSH_KEY -R owner/data' "$TEST_TMPDIR/gh.args" + [[ "$(<"$TEST_TMPDIR/gh.args")" != *"test/repo"* ]] +} + +@test "setup verify: reads the secrets of the repository of AURTOMATOR_DATA_DIR" { + local data="$BATS_TEST_TMPDIR/data" + mkdir -p "$data" + git -C "$data" init -q + git -C "$data" remote add origin "git@github.com:owner/data.git" + # Lists the three secrets of owner/data and none of any other repository + cat >"$TEST_TMPDIR/mock-bin/gh" <<'EOF' +#!/usr/bin/env bash +if [[ "$*" == "secret list -R owner/data" ]]; then + printf '%s\n' "AUR_SSH_KEY Updated 2026-03-26" "AUR_GIT_NAME Updated 2026-03-26" "AUR_GIT_EMAIL Updated 2026-03-26" +fi +exit 0 +EOF + + AURTOMATOR_DATA_DIR="$data" run "$TEST_TMPDIR/scripts/setup.sh" verify \ + --git-name "Jane Doe" --git-email "jane@example.com" \ + --ssh-key "$TEST_TMPDIR/ssh/aur.pem" --non-interactive + [ "$status" -eq 0 ] + [[ "$output" == *"Secrets: 3/3 configured"* ]] +} + +# setup_test_env exports AURTOMATOR_DATA_DIR, so env -u removes it +@test "setup: AURTOMATOR_DATA_DIR defaults to the working directory" { + local data="$BATS_TEST_TMPDIR/data" + mkdir -p "$data" + + run env -u AURTOMATOR_DATA_DIR bash -c 'cd "$1" && "$0/scripts/setup.sh" identity --git-name "Jane Doe" --git-email "jane@example.com" --non-interactive' "$TEST_TMPDIR" "$data" + [ "$status" -eq 0 ] + [ -f "$data/.aurtomator.conf" ] + [ ! -e "$TEST_TMPDIR/.aurtomator.conf" ] + [[ "$output" == *" Data directory: $data"$'\n'* ]] +} + +@test "setup: a wrong AURTOMATOR_DATA_DIR stops the script" { + AURTOMATOR_DATA_DIR="$BATS_TEST_TMPDIR/none" run --separate-stderr "$TEST_TMPDIR/scripts/setup.sh" identity \ + --git-name "Jane Doe" --git-email "jane@example.com" \ + --non-interactive + [ "$status" -eq 1 ] + [ "$stderr" = "AURTOMATOR_DATA_DIR is not a directory: $BATS_TEST_TMPDIR/none" ] + [ -z "$output" ] +} + +# Without -- cd takes -P as its option and goes to $HOME, a scratch directory here +@test "setup: AURTOMATOR_DATA_DIR may start with a dash" { + mkdir -p "$BATS_TEST_TMPDIR/-P" "$BATS_TEST_TMPDIR/home" + + run env AURTOMATOR_DATA_DIR=-P HOME="$BATS_TEST_TMPDIR/home" bash -c 'cd "$1" && "$0/scripts/setup.sh" identity --git-name "Jane Doe" --git-email "jane@example.com" --non-interactive' "$TEST_TMPDIR" "$BATS_TEST_TMPDIR" + [ "$status" -eq 0 ] + [ -f "$BATS_TEST_TMPDIR/-P/.aurtomator.conf" ] + [[ "$output" == *" Data directory: $BATS_TEST_TMPDIR/-P"$'\n'* ]] +}
PackageVersionStrategy' '' >"$SPACED/README.md" git -C "$SPACED" init -q - run "$SPACED/scripts/update-readme.sh" + AURTOMATOR_DATA_DIR="$SPACED" run "$SPACED/scripts/update-readme.sh" [ "$status" -eq 0 ] grep -qF '>pkg' "$SPACED/README.md" } @@ -1700,6 +1700,31 @@ EOF grep -q "failed" "$TEST_TMPDIR/README.md" } +@test "update-readme: writes the README of AURTOMATOR_DATA_DIR from its packages and origin" { + local data="$BATS_TEST_TMPDIR/data" + mkdir -p "$data/packages" "$data/.status" + git -C "$data" init -q + git -C "$data" remote add origin "https://github.com/owner/data.git" + cat >"$data/packages/foo.yml" <"$data/.status/foo" + printf '%s\n' '# test' '' '' \ + '' '' >"$data/README.md" + + AURTOMATOR_DATA_DIR="$data" run "$TEST_TMPDIR/scripts/update-readme.sh" + [ "$status" -eq 0 ] + [[ "$output" == *"Badges updated (repo: owner/data)"* ]] + grep -qF 'https://github.com/owner/data/actions/workflows/ci.yml/badge.svg' "$data/README.md" + grep -q '>foo1.0.0github-release-.* 3.0.0 available