@biffo/cli 0.273.1 → 0.273.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/scripts/verify.sh +156 -68
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@biffo/cli",
3
- "version": "0.273.1",
3
+ "version": "0.273.2",
4
4
  "description": "Biffo project scaffolding CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/scripts/verify.sh CHANGED
@@ -614,7 +614,18 @@ if [ -n "$PY_DIRS" ]; then
614
614
  # shellcheck disable=SC2086
615
615
  [ -n "$bandit_paths" ] && ci_has "bandit" && run_check "bandit$suffix" uv run bandit -r $bandit_paths -ll -q
616
616
  if [ "$PYTEST" = "0" ]; then
617
- skip "pytest$suffix" "excluded by BIFFO_VERIFY_PYTEST=0"
617
+ # #1464: applicable, not "not applicable" -- CI still runs pytest here;
618
+ # this repo's copy was explicitly told not to. See the cost-skip
619
+ # branch below for the rest of the reasoning; both read from the same
620
+ # bucket now.
621
+ if ci_has "pytest"; then
622
+ if [ -z "$LIST" ]; then
623
+ NOT_RUN="$NOT_RUN pytest$suffix"
624
+ printf ' \033[33mWARN\033[0m %-16s NOT RUN - excluded by BIFFO_VERIFY_PYTEST=0\n' "pytest$suffix"
625
+ fi
626
+ else
627
+ skip "pytest$suffix" "excluded by BIFFO_VERIFY_PYTEST=0"
628
+ fi
618
629
  elif [ -n "$PYTEST" ] || pytest_is_fast "."; then
619
630
  if ci_has "pytest"; then
620
631
  run_check "pytest$suffix" uv run pytest -q
@@ -625,7 +636,23 @@ if [ -n "$PY_DIRS" ]; then
625
636
  pytest_record "." "$LAST_CHECK_SECONDS"
626
637
  fi
627
638
  else
628
- skip "pytest$suffix" "suite is slower than ${PYTEST_BUDGET_SECONDS}s - CI keeps it"
639
+ # #1464: a cost decision, not an absence. pytest IS the single largest
640
+ # thing CI checks about this directory -- filing it as "not applicable
641
+ # here" (the SKIPPED bucket) reads as "nothing to do here", identical
642
+ # to `build` in a Python-only repo. It belongs beside pg-test and
643
+ # terraform-fmt: applicable, and the gate did not run it, because
644
+ # running it here would cost more than the push gate should spend.
645
+ if ci_has "pytest"; then
646
+ if [ -z "$LIST" ]; then
647
+ NOT_RUN="$NOT_RUN pytest$suffix"
648
+ printf ' \033[33mWARN\033[0m %-16s NOT RUN - suite is slower than %ss - CI keeps it\n' \
649
+ "pytest$suffix" "$PYTEST_BUDGET_SECONDS"
650
+ printf ' \033[33m%s\033[0m\n' \
651
+ "CI runs pytest here as a required check; run \`uv run pytest\` before pushing."
652
+ fi
653
+ else
654
+ skip "pytest$suffix" "suite is slower than ${PYTEST_BUDGET_SECONDS}s and CI does not run it either"
655
+ fi
629
656
  fi
630
657
  else
631
658
  ci_has "ruff check" && run_check "ruff-check$suffix" uv run --directory "$d" ruff check .
@@ -633,19 +660,47 @@ if [ -n "$PY_DIRS" ]; then
633
660
  ci_has "pyright" && run_check "pyright$suffix" uv run --directory "$d" pyright
634
661
  ci_has "bandit" && run_check "bandit$suffix" uv run --directory "$d" bandit -r src -ll -q
635
662
  if [ "$PYTEST" = "0" ]; then
636
- skip "pytest$suffix" "excluded by BIFFO_VERIFY_PYTEST=0"
663
+ # #1464: same reclassification as the "." case above.
664
+ if ci_has "pytest"; then
665
+ if [ -z "$LIST" ]; then
666
+ NOT_RUN="$NOT_RUN pytest$suffix"
667
+ printf ' \033[33mWARN\033[0m %-16s NOT RUN - excluded by BIFFO_VERIFY_PYTEST=0\n' "pytest$suffix"
668
+ fi
669
+ else
670
+ skip "pytest$suffix" "excluded by BIFFO_VERIFY_PYTEST=0"
671
+ fi
637
672
  elif [ -n "$PYTEST" ] || pytest_is_fast "$d"; then
638
673
  if ci_has "pytest"; then
639
674
  run_check "pytest$suffix" uv run --directory "$d" pytest -q
640
675
  pytest_record "$d" "$LAST_CHECK_SECONDS"
641
676
  fi
642
677
  else
643
- skip "pytest$suffix" "suite is slower than ${PYTEST_BUDGET_SECONDS}s - CI keeps it"
678
+ # #1464: same reclassification as the "." case above -- a cost
679
+ # decision, not an absence.
680
+ if ci_has "pytest"; then
681
+ if [ -z "$LIST" ]; then
682
+ NOT_RUN="$NOT_RUN pytest$suffix"
683
+ printf ' \033[33mWARN\033[0m %-16s NOT RUN - suite is slower than %ss - CI keeps it\n' \
684
+ "pytest$suffix" "$PYTEST_BUDGET_SECONDS"
685
+ printf ' \033[33m%s\033[0m\n' \
686
+ "CI runs pytest here as a required check; run \`uv run --directory $d pytest\` before pushing."
687
+ fi
688
+ else
689
+ skip "pytest$suffix" "suite is slower than ${PYTEST_BUDGET_SECONDS}s and CI does not run it either"
690
+ fi
644
691
  fi
645
692
  fi
646
693
  done
647
694
  else
648
- skip python "uv not installed"
695
+ # #1464: this repo HAS Python (PY_DIRS is non-empty) and CI checks it --
696
+ # the gate simply cannot, because uv is missing here. Same shape as
697
+ # terraform-fmt/gitleaks below: applicable, not run, not "not applicable".
698
+ if [ -z "$LIST" ]; then
699
+ NOT_RUN="$NOT_RUN python"
700
+ printf ' \033[33mWARN\033[0m %-16s NOT RUN - uv not installed\n' "python"
701
+ printf ' \033[33m%s\033[0m\n' \
702
+ "CI runs ruff/pyright/pytest here; nothing local is checking them."
703
+ fi
649
704
  fi
650
705
  else
651
706
  skip python "no pyproject.toml anywhere in this repo"
@@ -934,7 +989,16 @@ elif [ -z "$PG_TEST_DSN" ]; then
934
989
  fi
935
990
  fi
936
991
  elif ! command -v uv >/dev/null 2>&1; then
937
- skip pg-test "uv not installed"
992
+ # #1464: reached only when _pg_modules is non-empty AND a DSN is set -- this
993
+ # repo has Postgres-dependent tests and a database to run them against; uv
994
+ # missing is the only thing stopping the lane, same as pg-test's DSN-unset
995
+ # WARN above. Applicable, not run, not "not applicable".
996
+ if [ -z "$LIST" ]; then
997
+ NOT_RUN="$NOT_RUN pg-test"
998
+ printf ' \033[33mWARN\033[0m %-16s NOT RUN - uv not installed\n' "pg-test"
999
+ printf ' \033[33m%s\033[0m\n' \
1000
+ "CI runs these as a required check; nothing local is checking them."
1001
+ fi
938
1002
  else
939
1003
  # Run from the uv project that owns the modules, with paths relative to it, so
940
1004
  # this works wherever a repo keeps its API (root here, services/api in every
@@ -945,7 +1009,15 @@ else
945
1009
  [ -f "$_pg_dir/pyproject.toml" ] && break
946
1010
  done
947
1011
  if [ ! -f "$_pg_dir/pyproject.toml" ]; then
948
- skip pg-test "no pyproject.toml above the Postgres modules"
1012
+ # #1464: same shape as the two branches above -- the Postgres-dependent
1013
+ # tests and the DSN both exist, the gate just cannot find a project root
1014
+ # to run them from. Applicable, not run.
1015
+ if [ -z "$LIST" ]; then
1016
+ NOT_RUN="$NOT_RUN pg-test"
1017
+ printf ' \033[33mWARN\033[0m %-16s NOT RUN - no pyproject.toml above the Postgres modules\n' "pg-test"
1018
+ printf ' \033[33m%s\033[0m\n' \
1019
+ "CI runs these as a required check; nothing local is checking them."
1020
+ fi
949
1021
  else
950
1022
  _pg_rel=$(echo "$_pg_modules" | sed "s|^$_pg_dir/||" | tr '\n' ' ')
951
1023
  # Not a plain `run_check` call: `pg_test_run` returns THREE states (0 pass,
@@ -995,59 +1067,73 @@ fi
995
1067
 
996
1068
  # Terraform, wherever this repo keeps it: modules/ in the template and
997
1069
  # instances, infra/ and modules/ in siblings, terraform/ in the runner fleets.
998
- if [ -n "$LIST" ] || command -v terraform >/dev/null 2>&1; then
999
- # Scope must match this repo's CI, not exceed it. The template and instances
1000
- # deliberately fmt-check modules/ ONLY: infra/environments/ is user-owned, and
1001
- # a template-shipped check asserting over paths the template does not own is
1002
- # the #325 trap -- it reds an instance on content it neither wrote nor can
1003
- # repair. Siblings own their whole infra/ and their CI checks it, so they get
1004
- # both. biffo.sibling.json is what tells them apart.
1005
- tf_dirs=""
1006
- [ -d modules ] && tf_dirs="$tf_dirs modules/"
1007
- [ -f biffo.sibling.json ] && [ -d infra ] && tf_dirs="$tf_dirs infra/"
1008
- # terraform/ is the whole of a runner fleet (#1239). Both fleets kept every
1009
- # .tf file there, which is neither of the two directories above, so `tf_dirs`
1010
- # came out empty and this gate printed `no terraform in this repo` -- in the
1011
- # two repos that are nothing BUT terraform. Their CI does check it
1012
- # (`terraform fmt -check -recursive terraform/`), so the gap was local only:
1013
- # the gate that exists to catch this before the push was the one thing not
1014
- # catching it. No repo in the estate holds both terraform/ and modules/, so
1015
- # adding it cannot widen scope anywhere that was already covered.
1016
- [ -d terraform ] && tf_dirs="$tf_dirs terraform/"
1017
- if [ -n "$tf_dirs" ]; then
1070
+ #
1071
+ # Applicability (does this repo have terraform this gate should check) is
1072
+ # decided BEFORE tool availability, not after (#1464 audit). The old shape
1073
+ # gated the whole block on `command -v terraform`, so a repo with real .tf
1074
+ # files under modules/ or infra/ but no local `terraform` binary printed
1075
+ # "terraform not installed" -- worded like the same considered skip as a repo
1076
+ # with no terraform at all, when it is actually the fail-open shape: CI checks
1077
+ # this, and the gate did not, because a tool was missing, not because there
1078
+ # was nothing to check.
1079
+ #
1080
+ # Scope must match this repo's CI, not exceed it. The template and instances
1081
+ # deliberately fmt-check modules/ ONLY: infra/environments/ is user-owned, and
1082
+ # a template-shipped check asserting over paths the template does not own is
1083
+ # the #325 trap -- it reds an instance on content it neither wrote nor can
1084
+ # repair. Siblings own their whole infra/ and their CI checks it, so they get
1085
+ # both. biffo.sibling.json is what tells them apart.
1086
+ tf_dirs=""
1087
+ [ -d modules ] && tf_dirs="$tf_dirs modules/"
1088
+ [ -f biffo.sibling.json ] && [ -d infra ] && tf_dirs="$tf_dirs infra/"
1089
+ # terraform/ is the whole of a runner fleet (#1239). Both fleets kept every
1090
+ # .tf file there, which is neither of the two directories above, so `tf_dirs`
1091
+ # came out empty and this gate printed `no terraform in this repo` -- in the
1092
+ # two repos that are nothing BUT terraform. Their CI does check it
1093
+ # (`terraform fmt -check -recursive terraform/`), so the gap was local only:
1094
+ # the gate that exists to catch this before the push was the one thing not
1095
+ # catching it. No repo in the estate holds both terraform/ and modules/, so
1096
+ # adding it cannot widen scope anywhere that was already covered.
1097
+ [ -d terraform ] && tf_dirs="$tf_dirs terraform/"
1098
+ if [ -n "$tf_dirs" ]; then
1099
+ if [ -n "$LIST" ] || command -v terraform >/dev/null 2>&1; then
1018
1100
  # shellcheck disable=SC2086
1019
1101
  ci_has "terraform fmt" && run_check terraform-fmt terraform fmt -check -recursive $tf_dirs
1020
1102
  else
1021
- # Distinguish "this repo has no terraform" from "this repo has terraform
1022
- # somewhere I do not look". The old message asserted the first and was
1023
- # printed for the second, which is the difference between a considered skip
1024
- # and a blind spot wearing its clothes -- the same shape as a branch audit
1025
- # dropping the repos it could not read (#1145) and reporting the remainder
1026
- # as the whole.
1027
- # Pruned rather than filtered, and NOT capped: `| head -20 | wc -l` would
1028
- # silently report 20 for a repo with 200, and a count that stops counting is
1029
- # the denominator defect this estate keeps re-learning.
1030
- _tf_stray=$(find . \
1031
- \( -name .git -o -name .worktrees -o -name .terraform -o -name node_modules \) -prune \
1032
- -o -name '*.tf' -print 2>/dev/null | wc -l | tr -d ' ')
1033
- if [ "${_tf_stray:-0}" -gt 0 ] && [ -z "$LIST" ]; then
1034
- # A WARN, not a skip and not a failure -- exactly the posture pg-test
1035
- # takes above for "the repo HAS the thing and the gate is blind to it".
1036
- # Not a failure because the right scope depends on what this repo's CI
1037
- # covers, which this gate cannot decide for a layout nobody has declared.
1038
- NOT_RUN="$NOT_RUN terraform-fmt"
1039
- printf ' \033[33mWARN\033[0m %-16s NOT RUN - %s .tf file(s) present, none in a directory this gate checks\n' \
1040
- "terraform-fmt" "$_tf_stray"
1041
- printf ' \033[33m%s\033[0m\n' \
1042
- "it looks in modules/, infra/ (siblings) and terraform/ - this repo uses none of them"
1043
- printf ' \033[90m%s\033[0m\n' \
1044
- "add the directory to the tf_dirs block in scripts/verify.sh (biffo-template#1239)"
1045
- else
1046
- skip terraform-fmt "no .tf files in modules/, infra/ or terraform/"
1047
- fi
1103
+ NOT_RUN="$NOT_RUN terraform-fmt"
1104
+ printf ' \033[33mWARN\033[0m %-16s NOT RUN - terraform not installed, %s present\n' \
1105
+ "terraform-fmt" "$tf_dirs"
1106
+ printf ' \033[33m%s\033[0m\n' \
1107
+ "CI runs terraform fmt -check here; nothing local is checking it."
1048
1108
  fi
1049
1109
  else
1050
- skip terraform-fmt "terraform not installed"
1110
+ # Distinguish "this repo has no terraform" from "this repo has terraform
1111
+ # somewhere I do not look". The old message asserted the first and was
1112
+ # printed for the second, which is the difference between a considered skip
1113
+ # and a blind spot wearing its clothes -- the same shape as a branch audit
1114
+ # dropping the repos it could not read (#1145) and reporting the remainder
1115
+ # as the whole.
1116
+ # Pruned rather than filtered, and NOT capped: `| head -20 | wc -l` would
1117
+ # silently report 20 for a repo with 200, and a count that stops counting is
1118
+ # the denominator defect this estate keeps re-learning.
1119
+ _tf_stray=$(find . \
1120
+ \( -name .git -o -name .worktrees -o -name .terraform -o -name node_modules \) -prune \
1121
+ -o -name '*.tf' -print 2>/dev/null | wc -l | tr -d ' ')
1122
+ if [ "${_tf_stray:-0}" -gt 0 ] && [ -z "$LIST" ]; then
1123
+ # A WARN, not a skip and not a failure -- exactly the posture pg-test
1124
+ # takes above for "the repo HAS the thing and the gate is blind to it".
1125
+ # Not a failure because the right scope depends on what this repo's CI
1126
+ # covers, which this gate cannot decide for a layout nobody has declared.
1127
+ NOT_RUN="$NOT_RUN terraform-fmt"
1128
+ printf ' \033[33mWARN\033[0m %-16s NOT RUN - %s .tf file(s) present, none in a directory this gate checks\n' \
1129
+ "terraform-fmt" "$_tf_stray"
1130
+ printf ' \033[33m%s\033[0m\n' \
1131
+ "it looks in modules/, infra/ (siblings) and terraform/ - this repo uses none of them"
1132
+ printf ' \033[90m%s\033[0m\n' \
1133
+ "add the directory to the tf_dirs block in scripts/verify.sh (biffo-template#1239)"
1134
+ else
1135
+ skip terraform-fmt "no .tf files in modules/, infra/ or terraform/"
1136
+ fi
1051
1137
  fi
1052
1138
 
1053
1139
  # The Biffo guards, where the dispatcher exists. Cheap, and two of them
@@ -1191,22 +1277,24 @@ if ci_has "gitleaks"; then
1191
1277
  # machine without gitleaks the parity test then reported the gate as missing a
1192
1278
  # check it does declare. The parity test caught it.
1193
1279
  #
1194
- # `terraform-fmt` above has the same shape and is only unexposed because
1195
- # terraform happens to be installed here. Recorded, not fixed in this change.
1280
+ # `terraform-fmt` above used to have the same shape, unexposed only because
1281
+ # terraform happened to be installed here -- fixed alongside this (#1464).
1282
+ # Reached only when `ci_has "gitleaks"` is true, i.e. CI does run this: not
1283
+ # installed locally is applicable-but-not-run, not "not applicable".
1196
1284
  if [ -n "$LIST" ] || command -v gitleaks >/dev/null 2>&1; then
1197
1285
  run_check gitleaks gitleaks_tracked_only
1198
1286
  else
1199
- # Say how to close it, pinned to the version ci.yml installs. A skip that
1200
- # only reports its own absence stays skipped: this one sat `n/a` long
1201
- # enough for the `\b\d{12}\b` account-id rule to reach CI three times,
1202
- # most recently on two test UUIDs whose last segment happened to be
1203
- # twelve digits (tabsii-platform#446). Thirty seconds of install would
1204
- # have caught it before the push, and version parity matters — an older
1205
- # gitleaks disagreeing with CI reintroduces exactly the local/CI
1206
- # divergence this gate exists to remove.
1207
- skip gitleaks "not installed - CI still runs both passes. Install the version ci.yml pins:
1208
- curl -sSfL -o /tmp/gl.tgz https://github.com/gitleaks/gitleaks/releases/download/v8.30.1/gitleaks_8.30.1_linux_x64.tar.gz \\
1209
- && tar -xzf /tmp/gl.tgz -C \"\$HOME/.local/bin\" gitleaks"
1287
+ # Say how to close it, pinned to the version ci.yml installs. This sat
1288
+ # filed as a skip long enough for the `\b\d{12}\b` account-id rule to
1289
+ # reach CI three times, most recently on two test UUIDs whose last segment
1290
+ # happened to be twelve digits (tabsii-platform#446). Thirty seconds of
1291
+ # install would have caught it before the push, and version parity
1292
+ # matters an older gitleaks disagreeing with CI reintroduces exactly the
1293
+ # local/CI divergence this gate exists to remove.
1294
+ NOT_RUN="$NOT_RUN gitleaks"
1295
+ printf ' \033[33mWARN\033[0m %-16s NOT RUN - not installed. CI still runs both passes. Install the version ci.yml pins:\n' "gitleaks"
1296
+ printf ' \033[33m%s\033[0m\n' \
1297
+ "curl -sSfL -o /tmp/gl.tgz https://github.com/gitleaks/gitleaks/releases/download/v8.30.1/gitleaks_8.30.1_linux_x64.tar.gz && tar -xzf /tmp/gl.tgz -C \"\$HOME/.local/bin\" gitleaks"
1210
1298
  fi
1211
1299
  fi
1212
1300