@sebastienrousseau/dotfiles 0.2.520 → 0.2.522
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.
- package/CHANGELOG.md +52 -0
- package/LICENSE-APACHE +190 -0
- package/LICENSE-MIT +21 -0
- package/README.md +43 -37
- package/install.sh +76 -10
- package/package.json +7 -7
- package/tools/README.md +49 -0
- package/tools/ci/install-chezmoi-verified.sh +68 -0
- package/docs/.vitepress/reports/localization-readability-audit.md +0 -73
- package/docs/AI.md +0 -179
- package/docs/ARCHITECTURE.md +0 -117
- package/docs/CNAME +0 -1
- package/docs/CONFIG_STRATEGY.md +0 -124
- package/docs/COPYRIGHT +0 -7
- package/docs/ECOSYSTEM.md +0 -220
- package/docs/GOLD-STANDARD-AUDIT.md +0 -352
- package/docs/GOVERNANCE.md +0 -98
- package/docs/MAINTAINERS.md +0 -41
- package/docs/MINIMUM-TOOLCHAIN.md +0 -100
- package/docs/NAMING_CONVENTIONS.md +0 -102
- package/docs/OPENCODE.md +0 -127
- package/docs/README.md +0 -84
- package/docs/STRUCTURE.md +0 -102
- package/docs/adr/ADR-001-ci-cd-pipeline.md +0 -118
- package/docs/adr/ADR-002-shell-performance.md +0 -130
- package/docs/adr/ADR-003-security-first.md +0 -158
- package/docs/adr/ADR-004-cli-architecture.md +0 -171
- package/docs/adr/ADR-005-chezmoi-choice.md +0 -99
- package/docs/adr/ADR-006-shell-selection.md +0 -124
- package/docs/adr/ADR-007-multi-shell-parity.md +0 -62
- package/docs/adr/ADR-008-alias-system-architecture.md +0 -95
- package/docs/adr/ADR-009-wallpaper-driven-theming.md +0 -131
- package/docs/adr/ADR-010-starship-transient-prompt.md +0 -144
- package/docs/adr/ADR-011-nushell-tier3-keep.md +0 -144
- package/docs/adr/ADR-012-ai-fleet-local-proxy.md +0 -79
- package/docs/adr/README.md +0 -40
- package/docs/architecture/AI_COST_OPTIMIZATION.md +0 -144
- package/docs/architecture/ARCHITECTURE.md +0 -20
- package/docs/architecture/INTEROP.md +0 -44
- package/docs/architecture/REPO_LAYOUT.md +0 -241
- package/docs/architecture/WALKTHROUGH.md +0 -86
- package/docs/architecture/fleet-deployment.md +0 -77
- package/docs/archive/EUXIS_2026_REVIEW.md +0 -127
- package/docs/archive/LEGACY_ROADMAP.md +0 -6
- package/docs/archive/MILESTONE_v0.2.493.md +0 -47
- package/docs/archive/PLAN.md +0 -199
- package/docs/archive/REPO_AUDIT.md +0 -31
- package/docs/articles/.pages +0 -6
- package/docs/articles/2026-07-05-custom-mkdocs-material-dark-theme.md +0 -216
- package/docs/articles/2026-07-05-fish-startup-abbr.md +0 -153
- package/docs/articles/2026-07-05-master-to-main-rename-runbook.md +0 -128
- package/docs/articles/index.md +0 -36
- package/docs/guides/INSTALL.md +0 -144
- package/docs/guides/MACOS_ICLOUD_SYMLINKS.md +0 -121
- package/docs/guides/NEOVIM_IDE_GUIDE.md +0 -61
- package/docs/guides/THEMING.md +0 -230
- package/docs/guides/TROUBLESHOOTING.md +0 -176
- package/docs/guides/WSL2_NIX_TROUBLESHOOTING.md +0 -792
- package/docs/index.md +0 -132
- package/docs/interop/A2A.md +0 -39
- package/docs/interop/POWERSHELL.md +0 -102
- package/docs/manual/00-introduction.md +0 -89
- package/docs/manual/01-concepts/01-architecture.md +0 -138
- package/docs/manual/01-concepts/02-trust-model.md +0 -183
- package/docs/manual/01-concepts/03-theme-engine.md +0 -186
- package/docs/manual/01-concepts/04-fleet.md +0 -148
- package/docs/manual/01-concepts/05-self-healing.md +0 -204
- package/docs/manual/02-tutorials/01-first-install.md +0 -197
- package/docs/manual/02-tutorials/02-add-wallpaper.md +0 -216
- package/docs/manual/02-tutorials/03-create-profile.md +0 -244
- package/docs/manual/02-tutorials/04-encrypt-secret.md +0 -281
- package/docs/manual/02-tutorials/05-deploy-fleet.md +0 -283
- package/docs/manual/03-reference/01-dot-cli.md +0 -475
- package/docs/manual/03-reference/02-config-files.md +0 -265
- package/docs/manual/03-reference/03-environment.md +0 -124
- package/docs/manual/03-reference/04-templates.md +0 -190
- package/docs/manual/03-reference/05-feature-flags.md +0 -187
- package/docs/manual/04-cookbook/01-recipes.md +0 -285
- package/docs/manual/04-cookbook/02-troubleshooting.md +0 -351
- package/docs/manual/04-cookbook/03-faq.md +0 -175
- package/docs/manual/05-appendices/A-platform-matrix.md +0 -101
- package/docs/manual/05-appendices/B-security-checklist.md +0 -85
- package/docs/manual/05-appendices/C-glossary.md +0 -40
- package/docs/manual/05-appendices/D-bibliography.md +0 -58
- package/docs/manual/05-appendices/E-license.md +0 -38
- package/docs/manual/_toc.yml +0 -58
- package/docs/manual/command-index.md +0 -175
- package/docs/manual/concept-index.md +0 -170
- package/docs/manual/index.md +0 -66
- package/docs/migration/README.md +0 -81
- package/docs/migration/from-bare-git-repo.md +0 -156
- package/docs/migration/from-gnu-stow.md +0 -165
- package/docs/migration/from-plain-chezmoi.md +0 -148
- package/docs/migration/from-yadm.md +0 -187
- package/docs/operations/ARCHITECTURE_ROADMAP.md +0 -7
- package/docs/operations/ATTESTATION.md +0 -44
- package/docs/operations/CI_CADENCE.md +0 -107
- package/docs/operations/CI_COMPOSITES.md +0 -156
- package/docs/operations/COMPLETIONS.md +0 -123
- package/docs/operations/COVERAGE.md +0 -204
- package/docs/operations/DRIFT.md +0 -107
- package/docs/operations/HARD_AUDIT_2026.md +0 -631
- package/docs/operations/MAINTENANCE.md +0 -63
- package/docs/operations/MANIFEST.md +0 -127
- package/docs/operations/MIGRATION.md +0 -109
- package/docs/operations/OPERATIONS.md +0 -188
- package/docs/operations/PERFORMANCE.md +0 -133
- package/docs/operations/PERFORMANCE_BUDGETS.md +0 -196
- package/docs/operations/REGISTRY.md +0 -90
- package/docs/operations/RELEASE_PIPELINE.md +0 -128
- package/docs/operations/RELIABILITY.md +0 -122
- package/docs/operations/RFC_v0_2_503_reorganization.md +0 -280
- package/docs/operations/ROADMAP.md +0 -10
- package/docs/operations/ROADMAP_2026.md +0 -7
- package/docs/operations/ROADMAP_V0_2_503.md +0 -10
- package/docs/operations/TESTING.md +0 -216
- package/docs/operations/TRACEABILITY.md +0 -44
- package/docs/operations/TRUSTED_AGENT_WORKSTATION.md +0 -65
- package/docs/operations/VERSION_SYNC.md +0 -393
- package/docs/packaging.md +0 -222
- package/docs/reference/ALIASES.md +0 -131
- package/docs/reference/ALIASES_CHEATSHEET.md +0 -32
- package/docs/reference/ALIASES_DEPRECATIONS.md +0 -13
- package/docs/reference/FEATURE-MATRIX.md +0 -646
- package/docs/reference/FEATURES.md +0 -66
- package/docs/reference/FONTS.md +0 -112
- package/docs/reference/POWERSHELL_PARITY.md +0 -82
- package/docs/reference/PROFILES.md +0 -69
- package/docs/reference/SCREENSHOTS.md +0 -121
- package/docs/reference/SCRIPTS.md +0 -71
- package/docs/reference/SUPPORT_MATRIX.md +0 -80
- package/docs/reference/THEMES.md +0 -117
- package/docs/reference/TOOLS.md +0 -110
- package/docs/reference/UTILS.md +0 -243
- package/docs/registry.json +0 -6
- package/docs/schema/dot-env-v1.json +0 -110
- package/docs/schema/dot-registry-v1.json +0 -33
- package/docs/security/AI_ACT_COMPLIANCE.md +0 -94
- package/docs/security/AUDIT_BYPASS.md +0 -103
- package/docs/security/AUTOMATION_SECRETS.md +0 -26
- package/docs/security/CI_EGRESS_ALLOWLIST.md +0 -127
- package/docs/security/CI_PINNING.md +0 -129
- package/docs/security/COMMIT_SIGNING.md +0 -138
- package/docs/security/COMPLIANCE.md +0 -458
- package/docs/security/DEPS_DEV_EXCEPTIONS.md +0 -86
- package/docs/security/DISCLOSURE.md +0 -130
- package/docs/security/ENCRYPTION.md +0 -57
- package/docs/security/FMEA.md +0 -159
- package/docs/security/FUZZING.md +0 -209
- package/docs/security/HISTORY_FILTERING.md +0 -132
- package/docs/security/INCIDENT_RESPONSE.md +0 -579
- package/docs/security/INSTALL_VERIFICATION.md +0 -122
- package/docs/security/KEYS.md +0 -49
- package/docs/security/KEY_ROTATION.md +0 -303
- package/docs/security/MCP_POLICY.md +0 -78
- package/docs/security/POLICY_RELEASES.md +0 -37
- package/docs/security/README.md +0 -28
- package/docs/security/SCORECARD.md +0 -195
- package/docs/security/SECRETS.md +0 -158
- package/docs/security/SECURITY.md +0 -45
- package/docs/security/SECURITY_CHECKLIST.md +0 -55
- package/docs/security/SHELL_EXEMPTIONS.md +0 -145
- package/docs/security/SOUP_REGISTER.md +0 -36
- package/docs/security/THREAT_MODEL.md +0 -130
- package/docs/security/VERIFICATION_VALIDATION.md +0 -228
- package/docs/security/VERIFY_RELEASE.md +0 -201
- package/docs/security/security-pubkey.asc +0 -15
- package/docs/stylesheets/extra.css +0 -444
- package/docs/themes/README.md +0 -10
- package/docs/themes/VISUAL_INTEGRITY_REPORT.md +0 -30
- package/docs/themes/hero-shot.svg +0 -78
- package/scripts/README.md +0 -123
- package/scripts/ci/check-copyright-headers.sh +0 -8
- package/scripts/ci/check-shell-preamble.sh +0 -8
- package/scripts/ci/guard-gitleaks-checkout.sh +0 -8
- package/scripts/demo/record.sh +0 -43
- package/scripts/diagnostics/a2a-conformance.sh +0 -163
- package/scripts/diagnostics/alias-governance.sh +0 -165
- package/scripts/diagnostics/aliases-cheatsheet.sh +0 -74
- package/scripts/diagnostics/aliases-manifest.sh +0 -77
- package/scripts/diagnostics/attest-verify.sh +0 -147
- package/scripts/diagnostics/benchmark.sh +0 -408
- package/scripts/diagnostics/conflicts.sh +0 -73
- package/scripts/diagnostics/doctor-unified.sh +0 -43
- package/scripts/diagnostics/doctor.sh +0 -797
- package/scripts/diagnostics/drift-dashboard.sh +0 -203
- package/scripts/diagnostics/health.sh +0 -656
- package/scripts/diagnostics/history-analysis.sh +0 -86
- package/scripts/diagnostics/mcp-doctor.sh +0 -582
- package/scripts/diagnostics/perf.sh +0 -453
- package/scripts/diagnostics/scorecard.sh +0 -120
- package/scripts/diagnostics/secret-governance.sh +0 -65
- package/scripts/diagnostics/security-score.sh +0 -467
- package/scripts/diagnostics/smoke-test.sh +0 -88
- package/scripts/diagnostics/snapshot.sh +0 -90
- package/scripts/diagnostics/verify.sh +0 -108
- package/scripts/diagnostics/verify_state.sh +0 -73
- package/scripts/diagnostics/version-locks.sh +0 -94
- package/scripts/diagnostics/workstation-attestation.sh +0 -212
- package/scripts/dot/commands/agent.sh +0 -535
- package/scripts/dot/commands/agents.sh +0 -352
- package/scripts/dot/commands/ai.sh +0 -600
- package/scripts/dot/commands/aliases.sh +0 -277
- package/scripts/dot/commands/appearance.sh +0 -110
- package/scripts/dot/commands/completion.sh +0 -171
- package/scripts/dot/commands/core.sh +0 -217
- package/scripts/dot/commands/diagnostics.sh +0 -265
- package/scripts/dot/commands/env-emit.sh +0 -203
- package/scripts/dot/commands/fleet.sh +0 -711
- package/scripts/dot/commands/init.sh +0 -185
- package/scripts/dot/commands/lint.sh +0 -208
- package/scripts/dot/commands/manual.sh +0 -169
- package/scripts/dot/commands/meta.sh +0 -438
- package/scripts/dot/commands/patterns.sh +0 -55
- package/scripts/dot/commands/registry.sh +0 -455
- package/scripts/dot/commands/restore.sh +0 -232
- package/scripts/dot/commands/secrets.sh +0 -296
- package/scripts/dot/commands/security.sh +0 -102
- package/scripts/dot/commands/tools.sh +0 -570
- package/scripts/dot/data/alias-deprecations.tsv +0 -2
- package/scripts/dot/powershell/Dot.psm1 +0 -319
- package/scripts/fonts/install-nerd-fonts.sh +0 -75
- package/scripts/fonts/patch-fonts.sh +0 -36
- package/scripts/git-hooks/install.sh +0 -12
- package/scripts/git-hooks/pre-commit +0 -12
- package/scripts/git-hooks/pre-commit-audit.sh +0 -146
- package/scripts/git-hooks/pre-push +0 -105
- package/scripts/git-hooks/prepare-commit-msg +0 -29
- package/scripts/lib/secrets_provider.sh +0 -200
- package/scripts/nvim/headless-upgrade.lua +0 -81
- package/scripts/ops/ai-setup.sh +0 -71
- package/scripts/ops/bundle.sh +0 -104
- package/scripts/ops/chaos.sh +0 -50
- package/scripts/ops/chezmoi-apply.sh +0 -333
- package/scripts/ops/chezmoi-diff.sh +0 -16
- package/scripts/ops/chezmoi-remove.sh +0 -46
- package/scripts/ops/chezmoi-update.sh +0 -67
- package/scripts/ops/heal-chezmoi.sh +0 -87
- package/scripts/ops/heal-system.sh +0 -129
- package/scripts/ops/heal-tools.sh +0 -297
- package/scripts/ops/heal.sh +0 -223
- package/scripts/ops/post-apply-repair.sh +0 -107
- package/scripts/ops/prewarm.sh +0 -128
- package/scripts/ops/release.sh +0 -262
- package/scripts/ops/rollback.sh +0 -613
- package/scripts/ops/setup.sh +0 -138
- package/scripts/ops/teleport.sh +0 -34
- package/scripts/qa/check-feature-matrix.sh +0 -296
- package/scripts/qa/check-version-consistency.sh +0 -12
- package/scripts/qa/coverage-baseline.sh +0 -61
- package/scripts/qa/docs-coverage.sh +0 -118
- package/scripts/qa/examples-coverage.sh +0 -94
- package/scripts/qa/powershell-contract.ps1 +0 -95
- package/scripts/qa/reliability-audit.sh +0 -139
- package/scripts/qa/scorecard-snapshot.sh +0 -128
- package/scripts/qa/traceability-coverage.sh +0 -124
- package/scripts/qa/validate-examples.sh +0 -90
- package/scripts/qa/wsl-contract.sh +0 -12
- package/scripts/secrets/age-init.sh +0 -82
- package/scripts/secrets/create-secrets-file.sh +0 -46
- package/scripts/secrets/encrypt-ssh-key.sh +0 -44
- package/scripts/security/backup.sh +0 -58
- package/scripts/security/check-disclosure-key-expiry.sh +0 -111
- package/scripts/security/dns-doh.sh +0 -52
- package/scripts/security/encryption-check.sh +0 -55
- package/scripts/security/enforce-policies.sh +0 -552
- package/scripts/security/firewall.sh +0 -91
- package/scripts/security/lock-configs.sh +0 -67
- package/scripts/security/lock-screen.sh +0 -56
- package/scripts/security/manage-secrets.sh +0 -429
- package/scripts/security/ssh-cert.sh +0 -204
- package/scripts/security/telemetry-kill.sh +0 -51
- package/scripts/security/usb-safety.sh +0 -52
- package/scripts/theme/apply-gnome-theme.sh +0 -333
- package/scripts/theme/extract-heic-frames.sh +0 -115
- package/scripts/theme/extract-theme.py +0 -1020
- package/scripts/theme/install-boot-logo.sh +0 -63
- package/scripts/theme/install-catppuccin-themes.sh +0 -371
- package/scripts/theme/install-cursors.sh +0 -26
- package/scripts/theme/install-file-icons.sh +0 -27
- package/scripts/theme/install-grub-theme.sh +0 -62
- package/scripts/theme/install-lock-icon.sh +0 -31
- package/scripts/theme/merge-wallpaper.sh +0 -146
- package/scripts/theme/rebuild-themes.sh +0 -603
- package/scripts/theme/switch.sh +0 -476
- package/scripts/theme/wallpaper-rotate.sh +0 -137
- package/scripts/theme/wallpaper-sync.sh +0 -690
- package/scripts/tools/cmatrix.sh +0 -22
- package/scripts/tools/detect-collisions.py +0 -103
- package/scripts/tools/emoji-picker.sh +0 -49
- package/scripts/tools/figlet-banner.sh +0 -19
- package/scripts/tools/log-rotate.sh +0 -31
- package/scripts/tools/lolcat-wrap.sh +0 -20
- package/scripts/tools/pipes.sh +0 -49
- package/scripts/tuning/linux.sh +0 -186
- package/scripts/tuning/macos.sh +0 -56
- package/scripts/uninstall.sh +0 -86
- package/scripts/verify-release-versions +0 -156
- package/scripts/version-sync.sh +0 -714
- package/templates/chezmoi-data/geekom-a9.toml.example +0 -21
- package/templates/chezmoi-data/mac-m1.toml.example +0 -16
- package/templates/chezmoi-data/mac-t2-linux.toml.example +0 -21
- package/templates/chezmoi-data/surface-pro-7p.toml.example +0 -21
- package/templates/projects/go/.github/workflows/ci.yml +0 -31
- package/templates/projects/go/README.md +0 -7
- package/templates/projects/go/cmd/__PROJECT_NAME__/main.go +0 -8
- package/templates/projects/go/go.mod +0 -3
- package/templates/projects/go/go.sum +0 -0
- package/templates/projects/molecule/README.md +0 -7
- package/templates/projects/molecule/converge.yml +0 -7
- package/templates/projects/molecule/molecule.yml +0 -16
- package/templates/projects/node/.github/workflows/ci.yml +0 -30
- package/templates/projects/node/README.md +0 -7
- package/templates/projects/node/package-lock.json +0 -12
- package/templates/projects/node/package.json +0 -10
- package/templates/projects/node/src/index.js +0 -3
- package/templates/projects/packer/README.md +0 -15
- package/templates/projects/packer/main.pkr.hcl +0 -15
- package/templates/projects/python/.github/workflows/ci.yml +0 -34
- package/templates/projects/python/README.md +0 -7
- package/templates/projects/python/pyproject.toml +0 -25
- package/templates/projects/python/src/__PROJECT_NAME__/__init__.py +0 -2
- package/templates/projects/python/tests/test_basic.py +0 -3
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
3
|
-
# Copyright (c) 2015-2026 Sebastien Rousseau
|
|
4
|
-
# =============================================================================
|
|
5
|
-
# examples-coverage.sh — enforce that every core feature domain ships a
|
|
6
|
-
# runnable example under examples/. Mirrors scripts/qa/docs-coverage.sh:
|
|
7
|
-
# it is a *coverage contract*, not a linter. Threshold defaults to 100%.
|
|
8
|
-
#
|
|
9
|
-
# A feature domain is "covered" when examples/example-<domain>.sh exists.
|
|
10
|
-
# Keep REQUIRED_AREAS in lockstep with the feature surface — adding a major
|
|
11
|
-
# user-facing capability (a new `dot` subsystem) means adding its example.
|
|
12
|
-
# =============================================================================
|
|
13
|
-
set -euo pipefail
|
|
14
|
-
|
|
15
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
16
|
-
REPO_ROOT="${REPO_ROOT:-$(cd "$SCRIPT_DIR/../.." && pwd)}"
|
|
17
|
-
EXAMPLES_DIR="$REPO_ROOT/examples"
|
|
18
|
-
DOT_CLI="$REPO_ROOT/bin/dot"
|
|
19
|
-
MIN_EXAMPLES_COVERAGE="${MIN_EXAMPLES_COVERAGE:-100}"
|
|
20
|
-
|
|
21
|
-
# Public commands/subcommands, extracted from bin/dot's _dot_help_specs — the
|
|
22
|
-
# same source scripts/qa/docs-coverage.sh uses, so docs and examples stay in
|
|
23
|
-
# lockstep at the command granularity.
|
|
24
|
-
extract_public_commands() {
|
|
25
|
-
awk -F'|' '
|
|
26
|
-
/_dot_help_specs\(\)/ { in_func=1; next }
|
|
27
|
-
in_func && /cat <<'\''EOF'\''/ { in_block=1; next }
|
|
28
|
-
in_block && /^EOF$/ { exit }
|
|
29
|
-
in_block && NF>=2 { print $2 }
|
|
30
|
-
' "$DOT_CLI"
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
# Core feature domains that must each have examples/example-<area>.sh.
|
|
34
|
-
REQUIRED_AREAS=(
|
|
35
|
-
ai-patterns
|
|
36
|
-
cli-utilities
|
|
37
|
-
coverage-gate
|
|
38
|
-
diagnostics
|
|
39
|
-
dot-commands
|
|
40
|
-
functions
|
|
41
|
-
fleet
|
|
42
|
-
git-hooks
|
|
43
|
-
install-uninstall
|
|
44
|
-
ops
|
|
45
|
-
platform-contract
|
|
46
|
-
qa
|
|
47
|
-
secrets
|
|
48
|
-
security
|
|
49
|
-
test-suite
|
|
50
|
-
testing-framework
|
|
51
|
-
theme
|
|
52
|
-
)
|
|
53
|
-
|
|
54
|
-
total=0
|
|
55
|
-
covered=0
|
|
56
|
-
missing=()
|
|
57
|
-
|
|
58
|
-
# --- Check 1: every feature domain has a dedicated example file. ---
|
|
59
|
-
for area in "${REQUIRED_AREAS[@]}"; do
|
|
60
|
-
total=$((total + 1))
|
|
61
|
-
if [ -f "$EXAMPLES_DIR/example-$area.sh" ]; then
|
|
62
|
-
covered=$((covered + 1))
|
|
63
|
-
else
|
|
64
|
-
missing+=("domain:$area")
|
|
65
|
-
fi
|
|
66
|
-
done
|
|
67
|
-
|
|
68
|
-
# --- Check 2: every public command/subcommand is referenced in an example. ---
|
|
69
|
-
while IFS= read -r cmd; do
|
|
70
|
-
[ -n "$cmd" ] || continue
|
|
71
|
-
total=$((total + 1))
|
|
72
|
-
# "dot <cmd>" followed by a non-identifier char (or EOL) — avoids matching
|
|
73
|
-
# `dot ai` against `dot ai-query`, and matches printf '...\n'-terminated refs.
|
|
74
|
-
if grep -rqE "dot ${cmd}([^A-Za-z0-9_-]|\$)" "$EXAMPLES_DIR" 2>/dev/null; then
|
|
75
|
-
covered=$((covered + 1))
|
|
76
|
-
else
|
|
77
|
-
missing+=("cmd:$cmd")
|
|
78
|
-
fi
|
|
79
|
-
done < <(extract_public_commands | sort -u)
|
|
80
|
-
|
|
81
|
-
pct="$(awk -v c="$covered" -v t="$total" \
|
|
82
|
-
'BEGIN{if(t==0){print "0.00"}else{printf "%.2f", (100*c/t)}}')"
|
|
83
|
-
printf 'Examples coverage: %s/%s (%s%%)\n' "$covered" "$total" "$pct"
|
|
84
|
-
printf 'Threshold: %s%%\n' "$MIN_EXAMPLES_COVERAGE"
|
|
85
|
-
if [ "${#missing[@]}" -gt 0 ]; then
|
|
86
|
-
printf 'Missing coverage for: %s\n' "${missing[*]}" >&2
|
|
87
|
-
fi
|
|
88
|
-
|
|
89
|
-
if awk -v p="$pct" -v min="$MIN_EXAMPLES_COVERAGE" 'BEGIN{exit !(p+0 >= min+0)}'; then
|
|
90
|
-
printf 'PASS: every feature domain and every public command has an example.\n'
|
|
91
|
-
exit 0
|
|
92
|
-
fi
|
|
93
|
-
printf 'FAIL: examples coverage %s%% is below the %s%% threshold.\n' "$pct" "$MIN_EXAMPLES_COVERAGE" >&2
|
|
94
|
-
exit 1
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2015-2026 Dotfiles. All rights reserved.
|
|
2
|
-
#
|
|
3
|
-
# PowerShell parity contract — smoke test for the dotfiles PowerShell
|
|
4
|
-
# profile. Run by the windows-latest CI job (#860). Asserts that:
|
|
5
|
-
#
|
|
6
|
-
# 1. The profile parses + loads without throwing.
|
|
7
|
-
# 2. Core function shims (`dot`, `ll`, `la`, `cat`) are defined.
|
|
8
|
-
# 3. PSScriptAnalyzer reports no errors against the profile (warnings
|
|
9
|
-
# surface but don't fail the gate; tighten later).
|
|
10
|
-
#
|
|
11
|
-
# Exit codes:
|
|
12
|
-
# 0 contract intact.
|
|
13
|
-
# 1 any check failed; details printed to host.
|
|
14
|
-
|
|
15
|
-
$ErrorActionPreference = 'Stop'
|
|
16
|
-
$Failures = New-Object System.Collections.Generic.List[string]
|
|
17
|
-
|
|
18
|
-
$RepoRoot = if ($env:GITHUB_WORKSPACE) { $env:GITHUB_WORKSPACE } else { (Get-Location).Path }
|
|
19
|
-
$ProfileSrc = Join-Path $RepoRoot 'defaults/dot_config/powershell/Microsoft.PowerShell_profile.ps1.tmpl'
|
|
20
|
-
|
|
21
|
-
if (-not (Test-Path $ProfileSrc)) {
|
|
22
|
-
Write-Output "FAIL: profile source not found at $ProfileSrc"
|
|
23
|
-
exit 1
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
# Step 1 — chezmoi-render the template into a real .ps1 we can dot-source.
|
|
27
|
-
# In CI, chezmoi is on PATH (installed by setup-chezmoi composite).
|
|
28
|
-
$Rendered = Join-Path $env:TEMP 'Microsoft.PowerShell_profile.ps1'
|
|
29
|
-
if (Get-Command chezmoi -ErrorAction SilentlyContinue) {
|
|
30
|
-
& chezmoi execute-template --init --promptString version=0.2.501 `
|
|
31
|
-
--in $ProfileSrc | Set-Content -Path $Rendered -NoNewline
|
|
32
|
-
} else {
|
|
33
|
-
# Fallback: strip chezmoi template syntax with a simple regex so the
|
|
34
|
-
# contract still runs locally without chezmoi installed.
|
|
35
|
-
(Get-Content $ProfileSrc -Raw) -replace '\{\{[^}]+\}\}', '0.0.0-fallback' |
|
|
36
|
-
Set-Content -Path $Rendered -NoNewline
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if (-not (Test-Path $Rendered)) {
|
|
40
|
-
$Failures.Add("profile template did not render to $Rendered")
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
# Step 2 — dot-source the rendered profile and verify it didn't throw.
|
|
44
|
-
$loadOk = $false
|
|
45
|
-
try {
|
|
46
|
-
. $Rendered
|
|
47
|
-
$loadOk = $true
|
|
48
|
-
Write-Output "OK: profile dot-sourced"
|
|
49
|
-
} catch {
|
|
50
|
-
Write-Output "FAIL: profile threw during load: $_"
|
|
51
|
-
$Failures.Add("profile load: $_")
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
# Step 3 — verify required function shims are defined.
|
|
55
|
-
$RequiredFunctions = @('dot', 'd', 'll', 'la', 'cat')
|
|
56
|
-
foreach ($fn in $RequiredFunctions) {
|
|
57
|
-
if (Get-Command $fn -CommandType Function -ErrorAction SilentlyContinue) {
|
|
58
|
-
Write-Output "OK: function $fn defined"
|
|
59
|
-
} else {
|
|
60
|
-
Write-Output "FAIL: function $fn not defined"
|
|
61
|
-
$Failures.Add("missing function: $fn")
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
# Step 4 — PSScriptAnalyzer (static analysis). Pre-installed on the
|
|
66
|
-
# windows-latest GitHub-hosted runner; install on demand if missing.
|
|
67
|
-
if (-not (Get-Module -ListAvailable -Name PSScriptAnalyzer)) {
|
|
68
|
-
Write-Output "Installing PSScriptAnalyzer..."
|
|
69
|
-
Install-Module -Name PSScriptAnalyzer -Force -Scope CurrentUser -ErrorAction SilentlyContinue | Out-Null
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
if (Get-Module -ListAvailable -Name PSScriptAnalyzer) {
|
|
73
|
-
Import-Module PSScriptAnalyzer -Force
|
|
74
|
-
$Findings = Invoke-ScriptAnalyzer -Path $Rendered -Severity 'Error' -ErrorAction SilentlyContinue
|
|
75
|
-
if ($Findings) {
|
|
76
|
-
foreach ($f in $Findings) {
|
|
77
|
-
Write-Output "FAIL: PSScriptAnalyzer error: $($f.RuleName) at line $($f.Line): $($f.Message)"
|
|
78
|
-
$Failures.Add("PSScriptAnalyzer error: $($f.RuleName)")
|
|
79
|
-
}
|
|
80
|
-
} else {
|
|
81
|
-
Write-Output "OK: PSScriptAnalyzer clean (Error severity)"
|
|
82
|
-
}
|
|
83
|
-
} else {
|
|
84
|
-
Write-Output "WARN: PSScriptAnalyzer not available — static analysis skipped"
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
Write-Output ""
|
|
88
|
-
if ($Failures.Count -eq 0) {
|
|
89
|
-
Write-Output "PowerShell contract: PASS"
|
|
90
|
-
exit 0
|
|
91
|
-
} else {
|
|
92
|
-
Write-Output "PowerShell contract: FAIL ($($Failures.Count) issue(s))"
|
|
93
|
-
foreach ($f in $Failures) { Write-Output " - $f" }
|
|
94
|
-
exit 1
|
|
95
|
-
}
|
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
3
|
-
# Copyright (c) 2015-2026 Sebastien Rousseau
|
|
4
|
-
set -euo pipefail
|
|
5
|
-
|
|
6
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
7
|
-
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
8
|
-
|
|
9
|
-
mode="full"
|
|
10
|
-
run_integration=0
|
|
11
|
-
min_coverage="${MIN_COVERAGE:-100}"
|
|
12
|
-
|
|
13
|
-
platform_name() {
|
|
14
|
-
case "$(uname -s)" in
|
|
15
|
-
Darwin) echo "macOS" ;;
|
|
16
|
-
Linux)
|
|
17
|
-
if grep -qi microsoft /proc/version 2>/dev/null; then
|
|
18
|
-
echo "WSL"
|
|
19
|
-
else
|
|
20
|
-
echo "Linux"
|
|
21
|
-
fi
|
|
22
|
-
;;
|
|
23
|
-
*) echo "Unknown" ;;
|
|
24
|
-
esac
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
usage() {
|
|
28
|
-
cat <<'EOF'
|
|
29
|
-
Reliability Audit
|
|
30
|
-
|
|
31
|
-
Usage:
|
|
32
|
-
reliability-audit.sh [--quick] [--unit-only] [--with-integration]
|
|
33
|
-
|
|
34
|
-
Options:
|
|
35
|
-
--quick Run syntax, unit, coverage, and examples
|
|
36
|
-
--unit-only Run syntax, unit, coverage, and examples
|
|
37
|
-
--with-integration Include integration tests
|
|
38
|
-
EOF
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
run_step() {
|
|
42
|
-
local label="$1"
|
|
43
|
-
shift
|
|
44
|
-
printf '\n[%s] %s\n' "$(date +%H:%M:%S)" "$label"
|
|
45
|
-
"$@"
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
shell_syntax() {
|
|
49
|
-
local failed=0
|
|
50
|
-
local file
|
|
51
|
-
|
|
52
|
-
while IFS= read -r -d '' file; do
|
|
53
|
-
if ! bash -n "$file"; then
|
|
54
|
-
failed=$((failed + 1))
|
|
55
|
-
fi
|
|
56
|
-
done < <(find "$REPO_ROOT" \
|
|
57
|
-
\( -path "$REPO_ROOT/.git" -o -path "$REPO_ROOT/.coverage" \) -prune \
|
|
58
|
-
-o -type f \( -name "*.sh" -o -name "*.bash" \) -print0)
|
|
59
|
-
|
|
60
|
-
if [ "$failed" -ne 0 ]; then
|
|
61
|
-
printf 'Syntax failures: %s\n' "$failed" >&2
|
|
62
|
-
return 1
|
|
63
|
-
fi
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
unit_tests() {
|
|
67
|
-
cd "$REPO_ROOT"
|
|
68
|
-
./tests/framework/test_runner.sh --jobs auto
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
integration_tests() {
|
|
72
|
-
cd "$REPO_ROOT"
|
|
73
|
-
./tests/framework/test_runner.sh --jobs auto --integration-only
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
coverage_gate() {
|
|
77
|
-
cd "$REPO_ROOT"
|
|
78
|
-
MIN_COVERAGE="$min_coverage" ./tests/framework/module_coverage.sh
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
example_gate() {
|
|
82
|
-
cd "$REPO_ROOT"
|
|
83
|
-
bash ./scripts/qa/validate-examples.sh
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
docs_coverage_gate() {
|
|
87
|
-
cd "$REPO_ROOT"
|
|
88
|
-
bash ./scripts/qa/docs-coverage.sh
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
traceability_gate() {
|
|
92
|
-
cd "$REPO_ROOT"
|
|
93
|
-
bash ./scripts/qa/traceability-coverage.sh
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
while [ "$#" -gt 0 ]; do
|
|
97
|
-
case "$1" in
|
|
98
|
-
--quick)
|
|
99
|
-
mode="quick"
|
|
100
|
-
;;
|
|
101
|
-
--unit-only)
|
|
102
|
-
mode="unit"
|
|
103
|
-
;;
|
|
104
|
-
--with-integration)
|
|
105
|
-
run_integration=1
|
|
106
|
-
;;
|
|
107
|
-
-h | --help)
|
|
108
|
-
usage
|
|
109
|
-
exit 0
|
|
110
|
-
;;
|
|
111
|
-
*)
|
|
112
|
-
printf 'Unknown option: %s\n' "$1" >&2
|
|
113
|
-
usage >&2
|
|
114
|
-
exit 1
|
|
115
|
-
;;
|
|
116
|
-
esac
|
|
117
|
-
shift
|
|
118
|
-
done
|
|
119
|
-
|
|
120
|
-
if [ "$mode" = "full" ]; then
|
|
121
|
-
run_integration=1
|
|
122
|
-
fi
|
|
123
|
-
|
|
124
|
-
printf 'Reliability Audit\n'
|
|
125
|
-
printf 'Platform: %s\n' "$(platform_name)"
|
|
126
|
-
printf 'Executable module-mapping floor: %s%%\n' "$min_coverage"
|
|
127
|
-
|
|
128
|
-
run_step "Shell syntax" shell_syntax
|
|
129
|
-
run_step "Unit suite" unit_tests
|
|
130
|
-
run_step "Executable module mapping" coverage_gate
|
|
131
|
-
run_step "Docs coverage" docs_coverage_gate
|
|
132
|
-
run_step "Traceability coverage" traceability_gate
|
|
133
|
-
run_step "Executable examples" example_gate
|
|
134
|
-
|
|
135
|
-
if [ "$run_integration" -eq 1 ]; then
|
|
136
|
-
run_step "Integration suite" integration_tests
|
|
137
|
-
fi
|
|
138
|
-
|
|
139
|
-
printf '\nReliability audit passed.\n'
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
3
|
-
# Copyright (c) 2015-2026 Sebastien Rousseau
|
|
4
|
-
#
|
|
5
|
-
# Fetch the current OpenSSF Scorecard result and refresh the
|
|
6
|
-
# per-check posture table in docs/security/SCORECARD.md.
|
|
7
|
-
#
|
|
8
|
-
# The narrative sections (open findings, exceptions, closed-this-
|
|
9
|
-
# cycle log) are preserved as-is — only the auto-generated
|
|
10
|
-
# baseline block between the BEGIN/END markers is rewritten.
|
|
11
|
-
#
|
|
12
|
-
# Usage:
|
|
13
|
-
# scripts/qa/scorecard-snapshot.sh # refresh
|
|
14
|
-
# scripts/qa/scorecard-snapshot.sh --check # exit 1 if stale
|
|
15
|
-
#
|
|
16
|
-
# Exit codes:
|
|
17
|
-
# 0 snapshot up-to-date / written
|
|
18
|
-
# 1 --check mode and content drifted
|
|
19
|
-
# 2 bad usage / Scorecard API unreachable
|
|
20
|
-
|
|
21
|
-
set -euo pipefail
|
|
22
|
-
|
|
23
|
-
REPO_ROOT="${REPO_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)}"
|
|
24
|
-
cd "$REPO_ROOT"
|
|
25
|
-
|
|
26
|
-
mode="write"
|
|
27
|
-
for arg in "$@"; do
|
|
28
|
-
case "$arg" in
|
|
29
|
-
--check) mode="check" ;;
|
|
30
|
-
-h | --help)
|
|
31
|
-
sed -n '2,16p' "$0"
|
|
32
|
-
exit 0
|
|
33
|
-
;;
|
|
34
|
-
*)
|
|
35
|
-
echo "unknown flag: $arg" >&2
|
|
36
|
-
exit 2
|
|
37
|
-
;;
|
|
38
|
-
esac
|
|
39
|
-
done
|
|
40
|
-
|
|
41
|
-
api='https://api.scorecard.dev/projects/github.com/sebastienrousseau/dotfiles'
|
|
42
|
-
target='docs/security/SCORECARD.md'
|
|
43
|
-
|
|
44
|
-
[[ -f "$target" ]] || {
|
|
45
|
-
echo "target not found: $target" >&2
|
|
46
|
-
exit 2
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
if ! command -v jq >/dev/null 2>&1; then
|
|
50
|
-
echo "jq required" >&2
|
|
51
|
-
exit 2
|
|
52
|
-
fi
|
|
53
|
-
|
|
54
|
-
payload="$(curl --proto '=https' --tlsv1.2 -fsSL --connect-timeout 10 --max-time 30 "$api")" || {
|
|
55
|
-
echo "Scorecard API unreachable: $api" >&2
|
|
56
|
-
exit 2
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
aggregate="$(printf '%s' "$payload" | jq -r '.score')"
|
|
60
|
-
date="$(printf '%s' "$payload" | jq -r '.date')"
|
|
61
|
-
|
|
62
|
-
# Build the auto-block: per-check status + score, one row each.
|
|
63
|
-
block="$(mktemp)"
|
|
64
|
-
trap 'rm -f "$block"' EXIT
|
|
65
|
-
|
|
66
|
-
{
|
|
67
|
-
printf '<!-- BEGIN scorecard-snapshot (auto-generated, do not edit by hand) -->\n'
|
|
68
|
-
printf 'Aggregate score **%s / 10** at %s.\n\n' "$aggregate" "$date"
|
|
69
|
-
printf '| Check | Score | Reason |\n'
|
|
70
|
-
printf '|---|---:|---|\n'
|
|
71
|
-
printf '%s' "$payload" |
|
|
72
|
-
jq -r '.checks
|
|
73
|
-
| sort_by(.name)
|
|
74
|
-
| .[]
|
|
75
|
-
| [.name, (.score|tostring), ((.reason // "") | gsub("\\|"; "\\|") | .[0:100])]
|
|
76
|
-
| "| " + (. | join(" | ")) + " |"'
|
|
77
|
-
# shellcheck disable=SC2016 # backticks here are markdown code-spans, not subshells
|
|
78
|
-
printf '\n_Refresh: `scripts/qa/scorecard-snapshot.sh` · Monitoring: `.github/workflows/scorecard.yml`._\n'
|
|
79
|
-
printf '<!-- END scorecard-snapshot -->\n'
|
|
80
|
-
} >"$block"
|
|
81
|
-
|
|
82
|
-
# Splice the block into the target. Find the BEGIN/END markers; if
|
|
83
|
-
# they're not yet present, append the block after the "## Live
|
|
84
|
-
# score" section header.
|
|
85
|
-
out="$(mktemp)"
|
|
86
|
-
trap 'rm -f "$block" "$out"' EXIT
|
|
87
|
-
|
|
88
|
-
if grep -q '<!-- BEGIN scorecard-snapshot' "$target"; then
|
|
89
|
-
awk -v blockfile="$block" '
|
|
90
|
-
BEGIN { skip = 0 }
|
|
91
|
-
/<!-- BEGIN scorecard-snapshot/ {
|
|
92
|
-
skip = 1
|
|
93
|
-
while ((getline line < blockfile) > 0) print line
|
|
94
|
-
close(blockfile)
|
|
95
|
-
next
|
|
96
|
-
}
|
|
97
|
-
/<!-- END scorecard-snapshot -->/ {
|
|
98
|
-
skip = 0
|
|
99
|
-
next
|
|
100
|
-
}
|
|
101
|
-
skip == 0 { print }
|
|
102
|
-
' "$target" >"$out"
|
|
103
|
-
else
|
|
104
|
-
# First run — inject right after the "## Live score" h2.
|
|
105
|
-
awk -v blockfile="$block" '
|
|
106
|
-
{ print }
|
|
107
|
-
/^## Live score$/ && !inserted {
|
|
108
|
-
print ""
|
|
109
|
-
while ((getline line < blockfile) > 0) print line
|
|
110
|
-
close(blockfile)
|
|
111
|
-
inserted = 1
|
|
112
|
-
}
|
|
113
|
-
' "$target" >"$out"
|
|
114
|
-
fi
|
|
115
|
-
|
|
116
|
-
if [[ "$mode" == "check" ]]; then
|
|
117
|
-
if ! diff -q "$target" "$out" >/dev/null 2>&1; then
|
|
118
|
-
echo "SCORECARD.md snapshot is stale (live score: $aggregate)." >&2
|
|
119
|
-
diff -u "$target" "$out" | head -50 >&2
|
|
120
|
-
exit 1
|
|
121
|
-
fi
|
|
122
|
-
echo "SCORECARD.md snapshot is in sync (aggregate: $aggregate)"
|
|
123
|
-
exit 0
|
|
124
|
-
fi
|
|
125
|
-
|
|
126
|
-
mv "$out" "$target"
|
|
127
|
-
trap - EXIT
|
|
128
|
-
echo "Refreshed $target (aggregate: $aggregate as of $date)"
|
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
3
|
-
# Copyright (c) 2015-2026 Sebastien Rousseau
|
|
4
|
-
set -euo pipefail
|
|
5
|
-
|
|
6
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
7
|
-
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
8
|
-
TRACE_DOC="$REPO_ROOT/docs/operations/TRACEABILITY.md"
|
|
9
|
-
MIN_TRACEABILITY_COVERAGE="${MIN_TRACEABILITY_COVERAGE:-100}"
|
|
10
|
-
|
|
11
|
-
TOTAL_TRACE_CHECKS=0
|
|
12
|
-
COVERED_TRACE_CHECKS=0
|
|
13
|
-
|
|
14
|
-
extract_impl_paths() {
|
|
15
|
-
awk '
|
|
16
|
-
/^\| BT-/ {
|
|
17
|
-
cols = $0
|
|
18
|
-
sub(/^\|[[:space:]]*/, "", cols)
|
|
19
|
-
sub(/[[:space:]]*\|[[:space:]]*$/, "", cols)
|
|
20
|
-
n = split(cols, parts, /\|/)
|
|
21
|
-
gsub(/^[[:space:]]+|[[:space:]]+$/, "", parts[3])
|
|
22
|
-
split(parts[3], impls, /,/)
|
|
23
|
-
for (i in impls) {
|
|
24
|
-
gsub(/^[[:space:]]+|[[:space:]]+$/, "", impls[i])
|
|
25
|
-
gsub(/`/, "", impls[i])
|
|
26
|
-
print impls[i]
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
' "$TRACE_DOC" | sort -u
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
trim() {
|
|
33
|
-
sed 's/^[[:space:]]*//; s/[[:space:]]*$//'
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
record_trace_check() {
|
|
37
|
-
local label="$1"
|
|
38
|
-
local target="$2"
|
|
39
|
-
|
|
40
|
-
TOTAL_TRACE_CHECKS=$((TOTAL_TRACE_CHECKS + 1))
|
|
41
|
-
if [ -e "$target" ]; then
|
|
42
|
-
COVERED_TRACE_CHECKS=$((COVERED_TRACE_CHECKS + 1))
|
|
43
|
-
else
|
|
44
|
-
printf 'Missing traceability target: %s (%s)\n' "$label" "$target" >&2
|
|
45
|
-
fi
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
check_path_list() {
|
|
49
|
-
local kind="$1"
|
|
50
|
-
local value="$2"
|
|
51
|
-
local behavior_id="$3"
|
|
52
|
-
local rel=""
|
|
53
|
-
|
|
54
|
-
while IFS= read -r rel; do
|
|
55
|
-
rel="$(printf '%s' "$rel" | trim)"
|
|
56
|
-
[ -n "$rel" ] || continue
|
|
57
|
-
rel="${rel#\`}"
|
|
58
|
-
rel="${rel%\`}"
|
|
59
|
-
record_trace_check "$behavior_id $kind" "$REPO_ROOT/$rel"
|
|
60
|
-
done < <(printf '%s\n' "$value" | tr ',' '\n')
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
report_traceability() {
|
|
64
|
-
local pct
|
|
65
|
-
pct="$(awk -v c="$COVERED_TRACE_CHECKS" -v t="$TOTAL_TRACE_CHECKS" 'BEGIN{if(t==0){print "0.00"}else{printf "%.2f", (100*c/t)}}')"
|
|
66
|
-
|
|
67
|
-
printf 'Traceability coverage: %s/%s (%s%%)\n' "$COVERED_TRACE_CHECKS" "$TOTAL_TRACE_CHECKS" "$pct"
|
|
68
|
-
printf 'Threshold: %s%%\n' "$MIN_TRACEABILITY_COVERAGE"
|
|
69
|
-
|
|
70
|
-
awk -v p="$pct" -v min="$MIN_TRACEABILITY_COVERAGE" 'BEGIN{exit !(p+0 >= min+0)}'
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
main() {
|
|
74
|
-
local line=""
|
|
75
|
-
local cols=""
|
|
76
|
-
local behavior_id=""
|
|
77
|
-
local impls=""
|
|
78
|
-
local tests=""
|
|
79
|
-
local docs=""
|
|
80
|
-
|
|
81
|
-
while IFS= read -r line; do
|
|
82
|
-
case "$line" in
|
|
83
|
-
\|\ BT-*)
|
|
84
|
-
cols="$(printf '%s\n' "$line" | sed 's/^|//; s/|$//')"
|
|
85
|
-
behavior_id="$(printf '%s\n' "$cols" | cut -d'|' -f1 | trim)"
|
|
86
|
-
impls="$(printf '%s\n' "$cols" | cut -d'|' -f3 | trim)"
|
|
87
|
-
tests="$(printf '%s\n' "$cols" | cut -d'|' -f4 | trim)"
|
|
88
|
-
docs="$(printf '%s\n' "$cols" | cut -d'|' -f5 | trim)"
|
|
89
|
-
|
|
90
|
-
check_path_list "implementation" "$impls" "$behavior_id"
|
|
91
|
-
check_path_list "test" "$tests" "$behavior_id"
|
|
92
|
-
check_path_list "doc" "$docs" "$behavior_id"
|
|
93
|
-
;;
|
|
94
|
-
esac
|
|
95
|
-
done <"$TRACE_DOC"
|
|
96
|
-
|
|
97
|
-
while IFS= read -r required; do
|
|
98
|
-
[ -n "$required" ] || continue
|
|
99
|
-
TOTAL_TRACE_CHECKS=$((TOTAL_TRACE_CHECKS + 1))
|
|
100
|
-
if extract_impl_paths | grep -Fxq "$required"; then
|
|
101
|
-
COVERED_TRACE_CHECKS=$((COVERED_TRACE_CHECKS + 1))
|
|
102
|
-
else
|
|
103
|
-
printf 'Missing traceability row for implementation: %s\n' "$required" >&2
|
|
104
|
-
fi
|
|
105
|
-
done < <(
|
|
106
|
-
{
|
|
107
|
-
find "$REPO_ROOT/scripts/dot/commands" -maxdepth 1 -type f -name '*.sh' | sed "s#^$REPO_ROOT/##"
|
|
108
|
-
find "$REPO_ROOT/scripts/qa" -maxdepth 1 -type f -name '*.sh' | sed "s#^$REPO_ROOT/##"
|
|
109
|
-
} | sort -u
|
|
110
|
-
)
|
|
111
|
-
|
|
112
|
-
# Capture report_traceability's exit — without this the trailing
|
|
113
|
-
# `printf PASS...` returns 0 and overwrites the awk threshold verdict,
|
|
114
|
-
# so a below-threshold run silently exits 0 (same bug as docs-coverage.sh).
|
|
115
|
-
if ! report_traceability; then
|
|
116
|
-
printf 'FAIL: traceability coverage below MIN_TRACEABILITY_COVERAGE=%s%%\n' \
|
|
117
|
-
"$MIN_TRACEABILITY_COVERAGE" >&2
|
|
118
|
-
return 1
|
|
119
|
-
fi
|
|
120
|
-
|
|
121
|
-
printf 'PASS: core internal behaviors have implementation, test, and documentation traceability at or above the required threshold\n'
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
main "$@"
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
3
|
-
# Copyright (c) 2015-2026 Sebastien Rousseau
|
|
4
|
-
set -euo pipefail
|
|
5
|
-
|
|
6
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
7
|
-
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
8
|
-
EXAMPLES_DIR="$REPO_ROOT/examples"
|
|
9
|
-
|
|
10
|
-
# Per-example wall-clock budget. Bounding each example individually means one
|
|
11
|
-
# slow or hanging example is reported by name instead of silently consuming the
|
|
12
|
-
# whole script's budget and surfacing as an opaque rc=124 from the caller.
|
|
13
|
-
EXAMPLE_TIMEOUT="${EXAMPLE_TIMEOUT:-60}"
|
|
14
|
-
|
|
15
|
-
usage() {
|
|
16
|
-
cat <<'USAGE'
|
|
17
|
-
Usage: validate-examples.sh [--help]
|
|
18
|
-
|
|
19
|
-
Runs every executable example in examples/ and fails if any of them fails or
|
|
20
|
-
exceeds the per-example timeout.
|
|
21
|
-
|
|
22
|
-
Environment:
|
|
23
|
-
EXAMPLE_TIMEOUT Per-example timeout in seconds (default: 60). Set to 0 to
|
|
24
|
-
disable the timeout.
|
|
25
|
-
USAGE
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
# Parse arguments before doing any work. Previously this script ignored its
|
|
29
|
-
# arguments entirely, so `--help` silently executed the whole examples suite —
|
|
30
|
-
# which meant asking for help ran a multi-minute job.
|
|
31
|
-
case "${1:-}" in
|
|
32
|
-
-h | --help)
|
|
33
|
-
usage
|
|
34
|
-
exit 0
|
|
35
|
-
;;
|
|
36
|
-
"") ;;
|
|
37
|
-
*)
|
|
38
|
-
printf 'Unknown option: %s\n\n' "$1" >&2
|
|
39
|
-
usage >&2
|
|
40
|
-
exit 2
|
|
41
|
-
;;
|
|
42
|
-
esac
|
|
43
|
-
|
|
44
|
-
if [ ! -d "$EXAMPLES_DIR" ]; then
|
|
45
|
-
echo "No examples directory found: $EXAMPLES_DIR" >&2
|
|
46
|
-
exit 1
|
|
47
|
-
fi
|
|
48
|
-
|
|
49
|
-
# Resolve a timeout binary. GNU coreutils ships `timeout`; on macOS it is
|
|
50
|
-
# `gtimeout` when coreutils is installed. Without either, run unbounded rather
|
|
51
|
-
# than failing outright.
|
|
52
|
-
timeout_cmd=()
|
|
53
|
-
if [ "$EXAMPLE_TIMEOUT" != "0" ]; then
|
|
54
|
-
if command -v timeout >/dev/null 2>&1; then
|
|
55
|
-
timeout_cmd=(timeout --kill-after=5 "$EXAMPLE_TIMEOUT")
|
|
56
|
-
elif command -v gtimeout >/dev/null 2>&1; then
|
|
57
|
-
timeout_cmd=(gtimeout --kill-after=5 "$EXAMPLE_TIMEOUT")
|
|
58
|
-
else
|
|
59
|
-
printf 'warning: no timeout binary found; examples run unbounded\n' >&2
|
|
60
|
-
fi
|
|
61
|
-
fi
|
|
62
|
-
|
|
63
|
-
found=0
|
|
64
|
-
failed=0
|
|
65
|
-
while IFS= read -r -d '' example; do
|
|
66
|
-
found=1
|
|
67
|
-
name="$(basename "$example")"
|
|
68
|
-
printf 'Running example: %s\n' "$name"
|
|
69
|
-
rc=0
|
|
70
|
-
"${timeout_cmd[@]+"${timeout_cmd[@]}"}" bash "$example" </dev/null || rc=$?
|
|
71
|
-
if [ "$rc" -eq 124 ]; then
|
|
72
|
-
printf 'FAIL: %s exceeded the %ss timeout\n' "$name" "$EXAMPLE_TIMEOUT" >&2
|
|
73
|
-
failed=$((failed + 1))
|
|
74
|
-
elif [ "$rc" -ne 0 ]; then
|
|
75
|
-
printf 'FAIL: %s exited %s\n' "$name" "$rc" >&2
|
|
76
|
-
failed=$((failed + 1))
|
|
77
|
-
fi
|
|
78
|
-
done < <(find "$EXAMPLES_DIR" -maxdepth 1 -type f -name "*.sh" -print0 | sort -z)
|
|
79
|
-
|
|
80
|
-
if [ "$found" -eq 0 ]; then
|
|
81
|
-
echo "No executable examples found in $EXAMPLES_DIR" >&2
|
|
82
|
-
exit 1
|
|
83
|
-
fi
|
|
84
|
-
|
|
85
|
-
if [ "$failed" -ne 0 ]; then
|
|
86
|
-
printf '%s example(s) failed.\n' "$failed" >&2
|
|
87
|
-
exit 1
|
|
88
|
-
fi
|
|
89
|
-
|
|
90
|
-
printf 'Examples passed.\n'
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
3
|
-
# Copyright (c) 2015-2026 Sebastien Rousseau
|
|
4
|
-
set -euo pipefail
|
|
5
|
-
|
|
6
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
7
|
-
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
8
|
-
|
|
9
|
-
cd "$REPO_ROOT"
|
|
10
|
-
|
|
11
|
-
bash tests/unit/install/test_os_detection_comprehensive.sh
|
|
12
|
-
bash tests/unit/functions/test_platform_detection_behavior.sh
|