Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 20 additions & 3 deletions .github/workflows/ci-pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,16 @@ jobs:
# proof scripts and Verilog sources, so globbing `*.v` would install
# a V toolchain to lint a Coq development.
N_V=$(count 'v.mod' '*/v.mod')
N_HASKELL=$(count '*.cabal' 'stack.yaml' '*/stack.yaml' '*.hs')
# Haskell is counted ONLY where its consuming job can run: the `haskell`
# job runs `cabal build all` at the REPOSITORY ROOT, which needs a root
# `cabal.project` or a root `*.cabal`. `:(glob)` stops `*` crossing `/`.
# The old marker set (`*.cabal`, `*.hs`, `stack.yaml` at any depth)
# went true on a nested satellite (standards: sanctify-php,
# palimpsest-license/TOOLS/validation/haskell) and then failed with
# Cabal-7136 "There is no <pkgname>.cabal package file or cabal.project" —
# a guard counting a different set than its consumer checks
# (standards#1161). Nested Haskell is reported below as unsupported.
N_HASKELL=$(count 'cabal.project' ':(glob)*.cabal')
# ⚠ DO NOT REMOVE THE DENO PROBE. It does not exist to lint Deno —
# it is the trigger for the REFUSAL job `deno` below, i.e. the teeth
# of the estate's standing no-Deno ruling, with slugs still live in
Expand Down Expand Up @@ -220,6 +229,14 @@ jobs:
# which repositories get linted.
probe 'Bun' 'bun.lock' '*/bun.lock' 'bun.lockb' '*/bun.lockb' 'bunfig.toml' '*/bunfig.toml' 'package.json' '*/package.json'

# Haskell the `haskell` job cannot build (no root cabal.project or
# `*.cabal`): nested projects, stack-only projects, loose `*.hs`.
# Probed only when N_HASKELL is 0 — under a root project, nested
# sources belong to it and ARE built.
if [ "$N_HASKELL" -eq 0 ]; then
probe 'Haskell (no root cabal.project/*.cabal)' '*.cabal' 'cabal.project' '*/cabal.project' 'stack.yaml' '*/stack.yaml' '*.hs'
fi

bool() { [ "$1" -gt 0 ] && echo true || echo false; }

{
Expand All @@ -246,7 +263,7 @@ jobs:
echo "| Nickel | \`*.ncl\` excluding \`*.k9.ncl\` | ${N_NICKEL} |"
echo "| ReScript | \`rescript.json\`, \`bsconfig.json\`, \`*.res\` | ${N_RESCRIPT} |"
echo "| V | \`v.mod\` only | ${N_V} |"
echo "| Haskell | \`*.cabal\`, \`stack.yaml\`, \`*.hs\` | ${N_HASKELL} |"
echo "| Haskell | root \`cabal.project\` or root \`*.cabal\` | ${N_HASKELL} |"
echo "| Deno | \`deno.json(c)\` | ${N_DENO} |"
echo "| **Total checkable** | | **${TOTAL}** |"
echo ""
Expand Down Expand Up @@ -983,7 +1000,7 @@ jobs:
row "Deno" "$R_DENO" "BANNED — refusal gate; skipped means no deno.json(c) tracked (has_deno=${H_DENO})"
row "ReScript" "$R_RESCRIPT" "no rescript.json/bsconfig.json/*.res tracked (has_rescript=${H_RESCRIPT})"
row "V" "$R_V" "no v.mod tracked (has_v=${H_V})"
row "Haskell" "$R_HASKELL" "no *.cabal/stack.yaml/*.hs tracked (has_haskell=${H_HASKELL})"
row "Haskell" "$R_HASKELL" "no root cabal.project/*.cabal tracked (has_haskell=${H_HASKELL})"
echo ""
echo "_A skipped gate examined nothing. It is not a pass._"
echo ""
Expand Down
16 changes: 16 additions & 0 deletions .hypatia-baseline.json
Original file line number Diff line number Diff line change
Expand Up @@ -1663,5 +1663,21 @@
"note": "TRIAGED (round-2 fix-forward 2026-09-22; collapsed 2026-09-22 per #966): Hypatia emits invalid_actions_lock from TWO rule modules for ONE defect -- workflow_audit/parse_actions_lock (file `actions.lock`) and WH004 standalone (workflow_hardening, full path `.github/workflows/actions.lock`). Both verified by running the real scanner locally. The defect: asana/push-signed-commits@d615 (immutable pin, ref v1.3) declares transitive actions/setup-python@v2, which floats upstream and can never be a lock key. gh-actions-lock v0.1.6 verify says valid:true on the same file; Hypatia is stricter than the authoritative tool. Exposure is upstream float only. Exit: Asana pins setup-python, we replace the action, or Hypatia downgrades float-transitives. #947 deleted the metadata to silence the scanner; round 2 restored it verbatim and acked honestly. Tracking moved from #951 to #963 on 2026-09-22: #951 was closed COMPLETED with zero comments while the defect is demonstrably live (actions.lock:210 still declares the floating transitive under the asana pin, and setup-python is never a top-level lock key), because #963 superseded it. An acknowledgement expiring 2026-12-22 against a CLOSED issue has nobody owning its exit criteria -- the ack keeps working and the cure stops being anyone job. This was two entries until list-valued rule_module landed (#971) -- two entries meant two expiry dates for one decision, which is how a half-expired acknowledgement silently reopens a gate. DELIBERATE SCOPE CHANGE, recorded because it is a widening and not a refactor: the workflow_hardening half previously matched the exact path `.github/workflows/actions.lock`, and one entry carries one matcher, so it now matches `**actions.lock` -- the breadth the workflow_audit half already had at the same severity and type. Measured consequence: a workflow_hardening invalid_actions_lock at e.g. `vendor/actions.lock` was KEPT before and is SUPPRESSED now. Accepted because both halves are the same defect with the same exit criteria; if a second actions.lock is ever vendored, narrow this entry rather than trusting it.",
"expires_at": "2026-12-22",
"tracking_issue": "hyperpolymath/standards#963"
},
{
"severity": "warn",
"rule_module": "research_extensions",
"type": "RE001",
"file": ".github/workflows/k9-contractile.yml",
"note": "ESTATE DECISION PENDING (hypatia triage 2026-09-22): adopt step-security/harden-runner or record a principled WONTFIX; the estate uses it nowhere today. Same decision as the other RE001 entries; this workflow's 'Publish the K9 verdict' job (GITHUB_TOKEN only) joined the set on 2026-10-06.",
"expires_at": "2026-12-22",
"tracking_issue": "hyperpolymath/standards#941"
},
{
"severity": "high",
"rule_module": "code_safety",
"type": "ncl_k9_missing_pedigree",
"file": "1-formats/k9/tools/fixtures/invalid/L1-K9-S001-no-pedigree.k9.ncl",
"note": "FALSE POSITIVE BY DESIGN: this is the NEGATIVE CONTROL for K9-S001 (no pedigree). k9-validate.sh --fixtures requires it to be rejected at L1 for exactly this reason; adding a pedigree would destroy the control. Exact path, not a pattern, so a real component that loses its pedigree is still reported."
}
]
8 changes: 4 additions & 4 deletions .machine_readable/REGISTRY.a2ml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ name = "K9 Self-Validating Components"
stream = "foundation"
home = "1-formats/k9/"
canonical_doc = "1-formats/k9/README.adoc"
source_hash = "sha256:d10e71f64586a5c6faac5833d6a52225d22042170e63df0ad2076ee610be8831"
source_hash = "sha256:dbf336e383f49c098a9cc7a3126fe817b824f41c054a7d2977ff47150db59281"
route = "the K9 specification, security analysis and adoption guidance (implementations live in hyperpolymath/k9-ecosystem)"

[[spec]]
Expand Down Expand Up @@ -153,7 +153,7 @@ name = "AXEL Protocol"
stream = "protocol"
home = "2-protocols/axel/"
canonical_doc = "2-protocols/axel/README.adoc"
source_hash = "sha256:c67b62c6dcbb730664318eb235b25c687493bf74cabbc20af5a71c0d7849acea"
source_hash = "sha256:dbfe6d40af030e4dd23575d7f01dc86d1557b1d395534af73aa1ab0ac133c59c"
route = "age-gating + explicit-content enforcement"

[[spec]]
Expand Down Expand Up @@ -207,7 +207,7 @@ name = "RSR — Rhodium Standard Repositories"
stream = "governance"
home = "rhodium-standard-repositories/"
canonical_doc = "rhodium-standard-repositories/README.adoc"
source_hash = "sha256:8bcf1e52445efa2c7f9c83850ca98f7a92190230b76f897d8442c5a377e74c39"
source_hash = "sha256:daeb002c345125c6a5132a71ae07a120691840ca0048b49674a7aab02e40acad"
route = "the repository-compliance standard every repo is graded against"

[[spec]]
Expand All @@ -216,7 +216,7 @@ name = "Session Management Standards"
stream = "governance"
home = "3-practice/session-management-standards/"
canonical_doc = "3-practice/session-management-standards/README.adoc"
source_hash = "sha256:beea95b19ff9565abf30d34b758bfb669c5140fc5eef5046a494eafe20a7a91f"
source_hash = "sha256:9e3e5f7bc1469e0736359e3e85cba5311b8ed87056d137d86a98e81c4e3c4b5a"
route = "continuity / verify / handover protocols"

[[spec]]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
"SonarSource/sonarqube-scan-action@*",
"step-security/harden-runner@*",
"Swatinem/rust-cache@*",
"swatinem/rust-cache@*",
"taiki-e/install-action@*",
"trufflesecurity/trufflehog@*",
"webfactory/ssh-agent@*"
Expand Down
4 changes: 3 additions & 1 deletion scripts/apply-baseline.sh
Original file line number Diff line number Diff line change
Expand Up @@ -293,9 +293,11 @@ rank() {

THRESHOLD_RANK="$(rank "$BLOCKING_THRESHOLD")"
MAX_KEPT_RANK=0
BLOCKING_COUNT=0 # kept findings at or above the threshold (the gate message names these, not all kept)
while IFS= read -r sev; do
r="$(rank "$sev")"
if (( r > MAX_KEPT_RANK )); then MAX_KEPT_RANK=$r; fi
if (( r >= THRESHOLD_RANK )); then BLOCKING_COUNT=$((BLOCKING_COUNT + 1)); fi
done < <(jq -r '.[].severity' <<<"$KEPT")

KEPT_COUNT="$(jq 'length' <<<"$KEPT")"
Expand Down Expand Up @@ -334,7 +336,7 @@ if [[ "$MODE" == "advisory" ]]; then
fi

if (( MAX_KEPT_RANK >= THRESHOLD_RANK )); then
echo "::error::Gate failed: $KEPT_COUNT unfiltered finding(s) at or above '$BLOCKING_THRESHOLD'." >&2
echo "::error::Gate failed: $BLOCKING_COUNT unfiltered finding(s) at or above '$BLOCKING_THRESHOLD' ($KEPT_COUNT kept in total)." >&2
exit 1
fi

Expand Down
181 changes: 94 additions & 87 deletions scripts/kyaml-format.sh
Original file line number Diff line number Diff line change
@@ -1,105 +1,112 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: CC-BY-SA-4.0
# KYAML formatter/linter for arbitrary YAML files
# Part of standards#1022: formatter/linter for arbitrary YAML
# SPDX-License-Identifier: MPL-2.0
# SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
#
# Usage:
# kyaml-format.sh [--check] FILE...
# kyaml-format.sh — format arbitrary YAML as KYAML, or check that it already is
# (YAML-POLICY Y-3; KYAML adoption step 3, standards#1022).
#
# Flags:
# --check Check only, exit 2 if file would be changed
# The rewriter is `yq -p yaml -o kyaml '.'`, verbatim — the one rewriter the
# step-2 comment-preservation proof (tools/yaml-comment-proof, standards#1021)
# covers. That proof does not generalise to any other rewriter, so this script
# deliberately adds none: no post-processing, no re-indenting, no sed.
#
# Exit codes:
# 0 All files OK (no changes needed in --check mode, or all formatted successfully)
# 1 Error (parse failure, missing file, etc.)
# 2 File would be changed (--check mode only)
#
# Preconditions (per YAML-POLICY.adoc §3.3):
# - GitHub Actions must parse KYAML workflows (proven in standards#1020)
# - Comment preservation must be proven (standards#1021)
# Usage:
# kyaml-format.sh [--check] FILE...
#
# This script runs `yq -o kyaml` verbatim and:
# - Refuses (exit 1) a file that does not parse
# - Refuses (exit 1) a file that has no final newline
# - Refuses (exit 2 in --check mode) a file that would change its data
# - Is idempotent: yq -o kyaml round-trips cleanly
# (default) rewrite each FILE in place as KYAML when it is not already.
# --check rewrite nothing; exit 1 if any FILE is not already KYAML.
#
# KYAML definition (KEP-5295):
# - {} for every map and [] for every list (flow style)
# - every string value double-quoted; keys unquoted where unambiguous
# - trailing commas permitted
# - two-space indentation
# - --- document header
# Exit contract:
# 0 = every FILE is KYAML (after the rewrite, in format mode)
# 1 = --check: at least one FILE is not KYAML (each one is named)
# 2 = refused: no FILE given, a FILE is missing or unparseable, a FILE has no
# final newline, or the rewrite would change the parsed data. A refusal
# never rewrites that FILE and never counts as clean.
#
# Note: KYAML is a subset of YAML, not a new format. Every existing YAML
# parser already handles KYAML syntax.

set -euo pipefail

CHECK_MODE=false
FILES=()
# Why the final-newline refusal: a `|` block scalar that ends at EOF with no
# line break is read differently by go-yaml (yq) and eemeli/yaml — measured on
# k9-contractile.yml, the trailing "\n" of its last run: body exists for one
# parser and not the other. Formatting such a file would silently pick one
# reading, so the script refuses it and names the fix instead.
set -uo pipefail

# Parse arguments
while [[ $# -gt 0 ]]; do
case "$1" in
--check)
CHECK_MODE=true
shift
;;
*)
FILES+=("$1")
shift
;;
esac
done
MODE=format
if [ "${1:-}" = "--check" ]; then

Check failure on line 34 in scripts/kyaml-format.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaETBPAUKt3XiyvGCRgR&open=AaETBPAUKt3XiyvGCRgR&pullRequest=1184
MODE=check
shift
fi

if [[ ${#FILES[@]} -eq 0 ]]; then
echo "Error: No files specified" >&2
echo "Usage: $0 [--check] FILE..." >&2
exit 1
if [ "$#" -eq 0 ]; then

Check failure on line 39 in scripts/kyaml-format.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaETBPAUKt3XiyvGCRgS&open=AaETBPAUKt3XiyvGCRgS&pullRequest=1184
echo "kyaml-format: no files given (usage: kyaml-format.sh [--check] FILE...)" >&2
exit 2
fi

RETCODE=0
CHANGED=false
command -v yq >/dev/null 2>&1 || { echo "kyaml-format: yq is not on PATH" >&2; exit 2; }

TMP="$(mktemp -d)"
trap 'rm -rf "$TMP"' EXIT

for file in "${FILES[@]}"; do
if [[ ! -f "$file" ]]; then
echo "Error: File not found: $file" >&2
exit 1
fi
# canonical_data <file> — prints the file's parsed value as key-sorted JSON;
# fails when the file does not parse.
canonical_data() {

Check warning on line 51 in scripts/kyaml-format.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Add an explicit return statement at the end of the function.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaETBPAUKt3XiyvGCRgU&open=AaETBPAUKt3XiyvGCRgU&pullRequest=1184
yq -p yaml -o json -I 0 'sort_keys(..)' "$1"

Check warning on line 52 in scripts/kyaml-format.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Assign this positional parameter to a local variable.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaETBPAUKt3XiyvGCRgT&open=AaETBPAUKt3XiyvGCRgT&pullRequest=1184
}

# Check for final newline
if [[ -n "$(tail -c 1 "$file" 2>/dev/null)" ]]; then
echo "Error: File has no final newline: $file" >&2
exit 1
fi
# kyaml_of <file> <out> — writes the KYAML rendering of <file> to <out>;
# fails when <file> does not parse.
kyaml_of() {

Check warning on line 57 in scripts/kyaml-format.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Add an explicit return statement at the end of the function.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaETBPAUKt3XiyvGCRgX&open=AaETBPAUKt3XiyvGCRgX&pullRequest=1184
yq -p yaml -o kyaml '.' "$1" > "$2"

Check warning on line 58 in scripts/kyaml-format.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Assign this positional parameter to a local variable.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaETBPAUKt3XiyvGCRgV&open=AaETBPAUKt3XiyvGCRgV&pullRequest=1184

Check warning on line 58 in scripts/kyaml-format.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Assign this positional parameter to a local variable.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaETBPAUKt3XiyvGCRgW&open=AaETBPAUKt3XiyvGCRgW&pullRequest=1184
}

# Try to parse with yq (dry run first)
if ! yq -o kyaml "$file" >/dev/null 2>&1; then
echo "Error: File does not parse as YAML: $file" >&2
exit 1
fi
# refuse <file> <reason> — reports a file this script will not judge.
refuse() {

Check warning on line 62 in scripts/kyaml-format.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Add an explicit return statement at the end of the function.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaETBPAUKt3XiyvGCRgY&open=AaETBPAUKt3XiyvGCRgY&pullRequest=1184
echo "::error file=$1::kyaml-format: REFUSED $1 — $2" >&2
refused=$((refused + 1))
}

if $CHECK_MODE; then
# Check if formatting would change the file
yq -o kyaml "$file" > /tmp/kyaml_check_$$
if ! cmp -s "$file" /tmp/kyaml_check_$$; then
echo "File would be changed: $file" >&2
CHANGED=true
fi
rm -f /tmp/kyaml_check_$$
else
# Format the file in place
yq -i -o kyaml "$file"
if [[ $? -ne 0 ]]; then
echo "Error: Failed to format: $file" >&2
exit 1
fi
fi
refused=0 drift=0 clean=0 rewritten=0
i=0
for f in "$@"; do
i=$((i + 1))
out="$TMP/$i.kyaml"
if [ ! -f "$f" ]; then

Check failure on line 72 in scripts/kyaml-format.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaETBPAUKt3XiyvGCRgZ&open=AaETBPAUKt3XiyvGCRgZ&pullRequest=1184
refuse "$f" "no such file"; continue
fi
if [ -s "$f" ] && [ -n "$(tail -c1 "$f")" ]; then

Check failure on line 75 in scripts/kyaml-format.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaETBPAUKt3XiyvGCRga&open=AaETBPAUKt3XiyvGCRga&pullRequest=1184

Check failure on line 75 in scripts/kyaml-format.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaETBPAUKt3XiyvGCRgb&open=AaETBPAUKt3XiyvGCRgb&pullRequest=1184
refuse "$f" "no final newline; add one first (a trailing block scalar is ambiguous without it)"; continue
fi
if ! kyaml_of "$f" "$out" 2>"$TMP/err"; then
refuse "$f" "does not parse: $(head -1 "$TMP/err")"; continue
fi
if cmp -s "$f" "$out"; then
clean=$((clean + 1)); continue
fi
# The rewrite is only acceptable when it preserves the data exactly.
if ! before=$(canonical_data "$f") || ! after=$(canonical_data "$out") || [ "$before" != "$after" ]; then

Check failure on line 85 in scripts/kyaml-format.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaETBPAUKt3XiyvGCRgc&open=AaETBPAUKt3XiyvGCRgc&pullRequest=1184
refuse "$f" "the KYAML rendering does not parse to the same data"; continue
fi
if [ "$MODE" = check ]; then

Check failure on line 88 in scripts/kyaml-format.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaETBPAUKt3XiyvGCRgd&open=AaETBPAUKt3XiyvGCRgd&pullRequest=1184
echo "::error file=$f::kyaml-format: $f is not KYAML — run scripts/kyaml-format.sh $f" >&2
drift=$((drift + 1))
else
cat "$out" > "$f"
echo "kyaml-format: rewrote $f"
rewritten=$((rewritten + 1))
fi
done

if $CHANGED; then
exit 2
total=$#
if [ "$refused" -gt 0 ]; then

Check failure on line 99 in scripts/kyaml-format.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaETBPAUKt3XiyvGCRge&open=AaETBPAUKt3XiyvGCRge&pullRequest=1184
echo "kyaml-format: $refused of $total file(s) REFUSED — not judged, not clean" >&2
exit 2
fi

exit $RETCODE
if [ "$drift" -gt 0 ]; then

Check failure on line 103 in scripts/kyaml-format.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaETBPAUKt3XiyvGCRgf&open=AaETBPAUKt3XiyvGCRgf&pullRequest=1184
echo "kyaml-format: $drift of $total file(s) are not KYAML" >&2
exit 1
fi
if [ "$MODE" = check ]; then

Check failure on line 107 in scripts/kyaml-format.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaETBPAUKt3XiyvGCRgg&open=AaETBPAUKt3XiyvGCRgg&pullRequest=1184
echo "kyaml-format: all $total file(s) are KYAML"
else
echo "kyaml-format: $total file(s) KYAML ($rewritten rewritten, $clean already clean)"
fi
exit 0
17 changes: 11 additions & 6 deletions scripts/kyaml-migrate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ if $DRY_RUN; then
exit 0
fi

# Scratch file for each candidate rewrite: private (mktemp), never a fixed
# /tmp name, and removed on every exit path.
NEW_FILE="$(mktemp)"
trap 'rm -f "$NEW_FILE"' EXIT

CHANGED=false
ERRORS=0
CONVERTED=0
Expand All @@ -85,24 +90,24 @@ for file in "${YAML_FILES[@]}"; do
fi

# Try to parse with yq
if ! yq -o kyaml "$file" > /tmp/kyaml_new_$$ 2>&1; then
if ! yq -o kyaml "$file" > "$NEW_FILE" 2>&1; then
echo "ERROR (parse failed)"
ERRORS=$((ERRORS + 1))
rm -f /tmp/kyaml_new_$$
: > "$NEW_FILE"
continue
fi

# Check if conversion would change the file
if cmp -s "$file" /tmp/kyaml_new_$$; then
if cmp -s "$file" "$NEW_FILE"; then
echo "OK (already KYAML)"
rm -f /tmp/kyaml_new_$$
: > "$NEW_FILE"
continue
fi

if $CHECK_MODE; then
echo "WOULD CHANGE"
CHANGED=true
rm -f /tmp/kyaml_new_$$
: > "$NEW_FILE"
continue
fi

Expand All @@ -111,7 +116,7 @@ for file in "${YAML_FILES[@]}"; do
echo "WOULD CONVERT"
CHANGED=true
else
mv /tmp/kyaml_new_$$ "$file"
cat "$NEW_FILE" > "$file" # keep the target mode; mktemp is 0600
echo "CONVERTED"
CONVERTED=$((CONVERTED + 1))
fi
Expand Down
4 changes: 3 additions & 1 deletion scripts/test_kyaml_comment_preservation.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ log() {
}

# Create a test file with various comment types
TEST_FILE="/tmp/kyaml_test_$$"
TEST_DIR="$(mktemp -d)"
trap 'rm -rf "$TEST_DIR"' EXIT
TEST_FILE="$TEST_DIR/kyaml_test"
cat > "$TEST_FILE" << 'EOF'
# Header comment
# Another header line
Expand Down
Loading