diff --git a/test/release-path.test.sh b/test/release-path.test.sh index 2ba304a..9f5a30e 100755 --- a/test/release-path.test.sh +++ b/test/release-path.test.sh @@ -97,6 +97,17 @@ path_check() { [ -z "$missing" ] && [ -z "$extra" ] } +path_check_reports_only() { + local tree="$1" expected="$2" output rc + output="$(path_check "$tree" 2>&1)" + rc=$? + if [ "$rc" -ne 1 ] || [ "$output" != "$expected" ]; then + printf 'expected only: %s\ngot (exit %s): %s\n' \ + "$expected" "$rc" "$output" >&2 + return 1 + fi +} + readme_has_no_path_enumeration() { local token found=no for token in \ @@ -119,6 +130,7 @@ fixture() { "\$ROOT/lib/changelog.sh" >"$tree/bin/assemble" printf '#!/usr/bin/env bash\n' >"$tree/lib/changelog.sh" printf '#!/usr/bin/env bash\n' >"$tree/lib/decide.sh" + printf '#!/usr/bin/env bash\n' >"$tree/lib/preflight.sh" # facts.sh sources BOTH on this tree: version.sh, and the forge shim #191 # put on the doors' path so a Forgejo consumer can publish (#198). The # synthetic tree mirrors the real one, or every fixture below reports @@ -134,7 +146,7 @@ fixture() { # Exact output is the record author's copy-paste source. check "manifest prints the specified ordered release path" 0 \ - $'.github/workflows/release.yml\nbin/\nlib/version.sh\nlib/decide.sh\nlib/facts.sh\nlib/changelog.sh\nlib/forge.sh' \ + $'.github/workflows/release.yml\nbin/\nlib/version.sh\nlib/decide.sh\nlib/preflight.sh\nlib/facts.sh\nlib/changelog.sh\nlib/forge.sh' \ bash "$PATH_SCRIPT" check "real workflow and transitive dependencies match the manifest" 0 "" \ path_check "$ROOT" @@ -143,54 +155,56 @@ check "drill doctrine does not duplicate the executable release path" 0 "" \ # A door growing a dependency must name the missing path (#237 D7). tree="$(fixture missing)" -printf 'run: bash "%s"\nrun: bash "%s"\nrun: . "%s"\nrun: . "%s"\nrun: . "%s"\n' \ +printf 'run: bash "%s"\nrun: bash "%s"\nrun: . "%s"\nrun: . "%s"\nrun: . "%s"\nrun: . "%s"\n' \ "\$CEREMONY_DIR/lib/facts.sh" "\$CEREMONY_DIR/lib/decide.sh" \ - "\$CEREMONY_DIR/lib/changelog.sh" "\$CEREMONY_DIR/lib/version.sh" \ - "\$CEREMONY_DIR/lib/ruling.sh" \ + "\$CEREMONY_DIR/lib/preflight.sh" "\$CEREMONY_DIR/lib/changelog.sh" \ + "\$CEREMONY_DIR/lib/version.sh" "\$CEREMONY_DIR/lib/ruling.sh" \ >"$tree/.github/workflows/release.yml" printf '#!/usr/bin/env bash\n' >"$tree/lib/ruling.sh" -check "a new workflow library fails with its missing path" 1 \ - "missing dependency: lib/ruling.sh" path_check "$tree" +check "a new workflow library fails with only its missing path" 0 "" \ + path_check_reports_only "$tree" \ + "release-path: missing dependency: lib/ruling.sh" # A library growing a sibling dependency in the production idiom must also # name the missing path; a literal lib/ marker in a comment is not evidence. tree="$(fixture missing-transitive)" -printf 'run: bash "%s"\nrun: bash "%s"\nrun: . "%s"\n' \ +printf 'run: bash "%s"\nrun: bash "%s"\nrun: . "%s"\nrun: . "%s"\n' \ "\$CEREMONY_DIR/lib/facts.sh" "\$CEREMONY_DIR/lib/decide.sh" \ - "\$CEREMONY_DIR/lib/changelog.sh" \ + "\$CEREMONY_DIR/lib/preflight.sh" "\$CEREMONY_DIR/lib/changelog.sh" \ >"$tree/.github/workflows/release.yml" printf '# shellcheck source=lib/ruling.sh\n. "%s"\n' \ "\$(cd \"\$(dirname \"\${BASH_SOURCE[0]}\")\" && pwd)/ruling.sh" \ >>"$tree/lib/facts.sh" printf '#!/usr/bin/env bash\n' >"$tree/lib/ruling.sh" -check "a new sibling library fails with its missing path" 1 \ - "missing dependency: lib/ruling.sh" path_check "$tree" +check "a new sibling library fails with only its missing path" 0 "" \ + path_check_reports_only "$tree" \ + "release-path: missing dependency: lib/ruling.sh" # A manifest may not rot into a safe-looking superset. tree="$(fixture extra)" -printf 'run: bash "%s"\nrun: bash "%s"\nrun: . "%s"\n' \ +printf 'run: bash "%s"\nrun: bash "%s"\nrun: . "%s"\nrun: . "%s"\n' \ "\$CEREMONY_DIR/lib/facts.sh" "\$CEREMONY_DIR/lib/decide.sh" \ - "\$CEREMONY_DIR/lib/changelog.sh" \ + "\$CEREMONY_DIR/lib/preflight.sh" "\$CEREMONY_DIR/lib/changelog.sh" \ >"$tree/.github/workflows/release.yml" -sed -i 's| lib/forge.sh$| lib/forge.sh \\|' \ +sed -i '$ s|$| \\|' \ "$tree/.github/scripts/release-path.sh" printf ' lib/ruling.sh\n' >>"$tree/.github/scripts/release-path.sh" printf '#!/usr/bin/env bash\n' >"$tree/lib/ruling.sh" -check "a path no door reads fails as stale" 1 "stale path: lib/ruling.sh" \ - path_check "$tree" +check "a path no door reads fails with only its stale path" 0 "" \ + path_check_reports_only "$tree" "release-path: stale path: lib/ruling.sh" # Transitive sourcing is part of the derivation, not decoration. tree="$(fixture transitive)" -printf 'run: bash "%s"\nrun: bash "%s"\nrun: . "%s"\n' \ +printf 'run: bash "%s"\nrun: bash "%s"\nrun: . "%s"\nrun: . "%s"\n' \ "\$CEREMONY_DIR/lib/facts.sh" "\$CEREMONY_DIR/lib/decide.sh" \ - "\$CEREMONY_DIR/lib/changelog.sh" \ + "\$CEREMONY_DIR/lib/preflight.sh" "\$CEREMONY_DIR/lib/changelog.sh" \ >"$tree/.github/workflows/release.yml" # Only the version source is dropped; the forge source #191 added stays, or # the fixture reports two stale paths and proves neither of them (#198). printf '#!/usr/bin/env bash\n# shellcheck source=lib/forge.sh\n. "%s"\n' \ "\$(cd \"\$(dirname \"\${BASH_SOURCE[0]}\")\" && pwd)/forge.sh" \ >"$tree/lib/facts.sh" -check "removing facts' version source fails as a stale path" 1 \ - "stale path: lib/version.sh" path_check "$tree" +check "removing facts' version source fails with only its stale path" 0 "" \ + path_check_reports_only "$tree" "release-path: stale path: lib/version.sh" summary