@sebastienrousseau/dotfiles 0.2.518 → 0.2.520
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 +191 -0
- package/README.md +1164 -164
- package/docs/ARCHITECTURE.md +117 -0
- package/docs/COPYRIGHT +1 -1
- package/docs/ECOSYSTEM.md +220 -0
- package/docs/GOLD-STANDARD-AUDIT.md +352 -0
- package/docs/GOVERNANCE.md +1 -1
- package/docs/MAINTAINERS.md +1 -1
- package/docs/MINIMUM-TOOLCHAIN.md +100 -0
- package/docs/README.md +1 -1
- package/docs/STRUCTURE.md +1 -1
- package/docs/architecture/ARCHITECTURE.md +11 -108
- package/docs/architecture/REPO_LAYOUT.md +4 -4
- package/docs/guides/MACOS_ICLOUD_SYMLINKS.md +121 -0
- package/docs/index.md +3 -3
- package/docs/manual/00-introduction.md +1 -1
- package/docs/manual/03-reference/01-dot-cli.md +28 -3
- package/docs/manual/command-index.md +24 -4
- package/docs/manual/concept-index.md +2 -0
- package/docs/migration/README.md +81 -0
- package/docs/migration/from-bare-git-repo.md +156 -0
- package/docs/migration/from-gnu-stow.md +165 -0
- package/docs/migration/from-plain-chezmoi.md +148 -0
- package/docs/migration/from-yadm.md +187 -0
- package/docs/operations/PERFORMANCE_BUDGETS.md +196 -0
- package/docs/operations/REGISTRY.md +1 -1
- package/docs/operations/RELEASE_PIPELINE.md +4 -4
- package/docs/operations/TESTING.md +3 -3
- package/docs/operations/TRACEABILITY.md +1 -0
- package/docs/packaging.md +222 -0
- package/docs/reference/FEATURE-MATRIX.md +646 -0
- package/docs/reference/TOOLS.md +1 -1
- package/docs/reference/UTILS.md +1 -0
- package/docs/security/COMPLIANCE.md +1 -1
- package/docs/security/DISCLOSURE.md +4 -4
- package/docs/security/FUZZING.md +113 -18
- package/docs/security/KEY_ROTATION.md +1 -1
- package/docs/security/SCORECARD.md +3 -3
- package/docs/security/VERIFY_RELEASE.md +2 -2
- package/install.sh +6 -6
- package/package.json +2 -2
- package/scripts/ci/check-copyright-headers.sh +1 -1
- package/scripts/ci/check-shell-preamble.sh +1 -1
- package/scripts/ci/guard-gitleaks-checkout.sh +1 -1
- package/scripts/demo/record.sh +1 -1
- package/scripts/diagnostics/a2a-conformance.sh +1 -1
- package/scripts/diagnostics/alias-governance.sh +30 -3
- package/scripts/diagnostics/aliases-cheatsheet.sh +1 -1
- package/scripts/diagnostics/aliases-manifest.sh +1 -1
- package/scripts/diagnostics/attest-verify.sh +147 -0
- package/scripts/diagnostics/benchmark.sh +1 -1
- package/scripts/diagnostics/conflicts.sh +1 -1
- package/scripts/diagnostics/doctor-unified.sh +6 -2
- package/scripts/diagnostics/doctor.sh +56 -10
- package/scripts/diagnostics/drift-dashboard.sh +3 -2
- package/scripts/diagnostics/health.sh +43 -10
- package/scripts/diagnostics/history-analysis.sh +1 -1
- package/scripts/diagnostics/mcp-doctor.sh +2 -2
- package/scripts/diagnostics/perf.sh +1 -1
- package/scripts/diagnostics/scorecard.sh +3 -2
- package/scripts/diagnostics/secret-governance.sh +1 -1
- package/scripts/diagnostics/security-score.sh +1 -1
- package/scripts/diagnostics/smoke-test.sh +1 -1
- package/scripts/diagnostics/snapshot.sh +1 -1
- package/scripts/diagnostics/verify.sh +1 -1
- package/scripts/diagnostics/verify_state.sh +1 -1
- package/scripts/diagnostics/version-locks.sh +1 -1
- package/scripts/diagnostics/workstation-attestation.sh +26 -1
- package/scripts/dot/commands/agent.sh +64 -14
- package/scripts/dot/commands/agents.sh +24 -8
- package/scripts/dot/commands/ai.sh +20 -7
- package/scripts/dot/commands/aliases.sh +1 -1
- package/scripts/dot/commands/appearance.sh +1 -1
- package/scripts/dot/commands/completion.sh +42 -5
- package/scripts/dot/commands/core.sh +1 -1
- package/scripts/dot/commands/diagnostics.sh +1 -1
- package/scripts/dot/commands/env-emit.sh +1 -1
- package/scripts/dot/commands/fleet.sh +41 -18
- package/scripts/dot/commands/init.sh +1 -1
- package/scripts/dot/commands/lint.sh +1 -1
- package/scripts/dot/commands/manual.sh +1 -1
- package/scripts/dot/commands/meta.sh +115 -10
- package/scripts/dot/commands/patterns.sh +1 -1
- package/scripts/dot/commands/registry.sh +43 -7
- package/scripts/dot/commands/restore.sh +1 -1
- package/scripts/dot/commands/secrets.sh +1 -1
- package/scripts/dot/commands/security.sh +1 -1
- package/scripts/dot/commands/tools.sh +21 -7
- package/scripts/fonts/install-nerd-fonts.sh +1 -1
- package/scripts/fonts/patch-fonts.sh +1 -1
- package/scripts/git-hooks/install.sh +1 -1
- package/scripts/git-hooks/pre-commit-audit.sh +2 -2
- package/scripts/lib/secrets_provider.sh +19 -4
- package/scripts/nvim/headless-upgrade.lua +81 -0
- package/scripts/ops/ai-setup.sh +1 -1
- package/scripts/ops/bundle.sh +1 -1
- package/scripts/ops/chaos.sh +1 -1
- package/scripts/ops/chezmoi-apply.sh +1 -1
- package/scripts/ops/chezmoi-diff.sh +1 -1
- package/scripts/ops/chezmoi-remove.sh +3 -3
- package/scripts/ops/chezmoi-update.sh +6 -2
- package/scripts/ops/heal-chezmoi.sh +1 -1
- package/scripts/ops/heal-system.sh +1 -1
- package/scripts/ops/heal-tools.sh +1 -1
- package/scripts/ops/heal.sh +1 -1
- package/scripts/ops/post-apply-repair.sh +1 -1
- package/scripts/ops/prewarm.sh +1 -1
- package/scripts/ops/release.sh +1 -1
- package/scripts/ops/rollback.sh +11 -2
- package/scripts/ops/setup.sh +1 -1
- package/scripts/ops/teleport.sh +1 -1
- package/scripts/qa/check-feature-matrix.sh +296 -0
- package/scripts/qa/check-version-consistency.sh +7 -119
- package/scripts/qa/coverage-baseline.sh +1 -1
- package/scripts/qa/docs-coverage.sh +9 -3
- package/scripts/qa/examples-coverage.sh +1 -1
- package/scripts/qa/reliability-audit.sh +1 -1
- package/scripts/qa/scorecard-snapshot.sh +1 -1
- package/scripts/qa/traceability-coverage.sh +9 -2
- package/scripts/qa/validate-examples.sh +66 -3
- package/scripts/qa/wsl-contract.sh +1 -1
- package/scripts/secrets/age-init.sh +1 -1
- package/scripts/secrets/create-secrets-file.sh +1 -1
- package/scripts/secrets/encrypt-ssh-key.sh +1 -1
- package/scripts/security/backup.sh +1 -1
- package/scripts/security/check-disclosure-key-expiry.sh +1 -1
- package/scripts/security/dns-doh.sh +1 -1
- package/scripts/security/encryption-check.sh +1 -1
- package/scripts/security/enforce-policies.sh +315 -98
- package/scripts/security/firewall.sh +1 -1
- package/scripts/security/lock-configs.sh +1 -1
- package/scripts/security/lock-screen.sh +1 -1
- package/scripts/security/manage-secrets.sh +1 -1
- package/scripts/security/ssh-cert.sh +1 -1
- package/scripts/security/telemetry-kill.sh +1 -1
- package/scripts/security/usb-safety.sh +1 -1
- package/scripts/theme/apply-gnome-theme.sh +1 -1
- package/scripts/theme/extract-heic-frames.sh +1 -1
- package/scripts/theme/extract-theme.py +284 -6
- package/scripts/theme/install-boot-logo.sh +1 -1
- package/scripts/theme/install-catppuccin-themes.sh +1 -1
- package/scripts/theme/install-cursors.sh +1 -1
- package/scripts/theme/install-file-icons.sh +1 -1
- package/scripts/theme/install-grub-theme.sh +1 -1
- package/scripts/theme/install-lock-icon.sh +1 -1
- package/scripts/theme/merge-wallpaper.sh +1 -1
- package/scripts/theme/rebuild-themes.sh +64 -5
- package/scripts/theme/switch.sh +46 -19
- package/scripts/theme/wallpaper-rotate.sh +1 -1
- package/scripts/theme/wallpaper-sync.sh +1 -1
- package/scripts/tools/cmatrix.sh +1 -1
- package/scripts/tools/detect-collisions.py +1 -1
- package/scripts/tools/emoji-picker.sh +1 -1
- package/scripts/tools/figlet-banner.sh +1 -1
- package/scripts/tools/log-rotate.sh +1 -1
- package/scripts/tools/lolcat-wrap.sh +1 -1
- package/scripts/tools/pipes.sh +1 -1
- package/scripts/tuning/linux.sh +1 -1
- package/scripts/tuning/macos.sh +1 -1
- package/scripts/uninstall.sh +1 -1
- package/scripts/verify-release-versions +156 -0
- package/scripts/version-sync.sh +63 -3
- package/LICENSE +0 -21
|
@@ -1,124 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# SPDX-License-Identifier: MIT
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
3
3
|
# Copyright (c) 2015-2026 Sebastien Rousseau
|
|
4
4
|
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
#
|
|
5
|
+
# Compatibility wrapper. The canonical name for this gate is
|
|
6
|
+
# `scripts/verify-release-versions` (the name the repository standard
|
|
7
|
+
# uses); this path is kept so existing callers — the `version-consistency`
|
|
8
|
+
# pre-commit hook, older docs, muscle memory — keep working.
|
|
9
9
|
#
|
|
10
|
-
#
|
|
11
|
-
# tables, roadmap docs that mention previous versions) are NOT
|
|
12
|
-
# checked — they are intentionally pinned to the version they
|
|
13
|
-
# describe.
|
|
14
|
-
#
|
|
15
|
-
# Usage:
|
|
16
|
-
# scripts/qa/check-version-consistency.sh # verify
|
|
17
|
-
# scripts/qa/check-version-consistency.sh --fix # auto-fix
|
|
18
|
-
# scripts/qa/check-version-consistency.sh --quiet # rc-only
|
|
19
|
-
#
|
|
20
|
-
# Exit codes:
|
|
21
|
-
# 0 every live reference matches
|
|
22
|
-
# 1 drift detected (with diff printed unless --quiet)
|
|
23
|
-
# 2 bad usage / missing canonical version
|
|
24
|
-
|
|
10
|
+
# Do not add logic here. Edit scripts/verify-release-versions.
|
|
25
11
|
set -euo pipefail
|
|
26
|
-
|
|
27
|
-
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
28
|
-
cd "$REPO_ROOT"
|
|
29
|
-
|
|
30
|
-
# ── Parse flags ─────────────────────────────────────────────────────────
|
|
31
|
-
fix=0
|
|
32
|
-
quiet=0
|
|
33
|
-
for arg in "$@"; do
|
|
34
|
-
case "$arg" in
|
|
35
|
-
--fix) fix=1 ;;
|
|
36
|
-
--quiet | -q) quiet=1 ;;
|
|
37
|
-
-h | --help)
|
|
38
|
-
sed -n '2,21p' "$0"
|
|
39
|
-
exit 0
|
|
40
|
-
;;
|
|
41
|
-
*)
|
|
42
|
-
echo "unknown flag: $arg" >&2
|
|
43
|
-
exit 2
|
|
44
|
-
;;
|
|
45
|
-
esac
|
|
46
|
-
done
|
|
47
|
-
|
|
48
|
-
_log() { ((quiet)) || printf '%s\n' "$*"; }
|
|
49
|
-
_err() { printf 'check-version-consistency: %s\n' "$*" >&2; }
|
|
50
|
-
|
|
51
|
-
# ── Canonical version ──────────────────────────────────────────────────
|
|
52
|
-
canonical="$(grep -E '^dotfiles_version[[:space:]]*=' defaults/.chezmoidata.toml |
|
|
53
|
-
head -1 | sed -E 's/.*"([^"]+)".*/\1/')"
|
|
54
|
-
|
|
55
|
-
if [[ -z "$canonical" ]]; then
|
|
56
|
-
_err 'failed to read dotfiles_version from defaults/.chezmoidata.toml'
|
|
57
|
-
exit 2
|
|
58
|
-
fi
|
|
59
|
-
_log "canonical: $canonical (defaults/.chezmoidata.toml)"
|
|
60
|
-
|
|
61
|
-
# ── Per-file expected-substring map ────────────────────────────────────
|
|
62
|
-
# Each entry: PATH|MATCH_PATTERN|EXPECTED_STRING
|
|
63
|
-
# MATCH_PATTERN is a fixed substring to grep for on the file to
|
|
64
|
-
# locate the version-bearing line; we then verify it contains the
|
|
65
|
-
# expected substring rendered with $canonical. version-sync.sh
|
|
66
|
-
# already handles many files (it reads package.json as source);
|
|
67
|
-
# this list captures the surfaces version-sync.sh historically
|
|
68
|
-
# missed — bento.sh banner, man-page header, dispatcher header.
|
|
69
|
-
specs=(
|
|
70
|
-
"package.json|\"version\"|\"version\": \"${canonical}\""
|
|
71
|
-
"bin/dot|^VERSION=|VERSION=\"${canonical}\""
|
|
72
|
-
"bin/dot|^# Dotfiles CLI Entry Point - v|# Dotfiles CLI Entry Point - v${canonical}"
|
|
73
|
-
"share/man/man1/dot.1|^.TH DOT 1|dotfiles v${canonical}"
|
|
74
|
-
"lib/dot/bento.sh|D O T F I L E S|[v${canonical}]"
|
|
75
|
-
"README.md|img.shields.io/badge/Version|Version-v${canonical}-blue"
|
|
76
|
-
"CLAUDE.md|^Chezmoi-managed dotfiles|Version \`${canonical}\`"
|
|
77
|
-
"AGENTS.md|^Chezmoi-managed dotfiles|Version \`${canonical}\`"
|
|
78
|
-
)
|
|
79
|
-
|
|
80
|
-
drift=0
|
|
81
|
-
for spec in "${specs[@]}"; do
|
|
82
|
-
IFS='|' read -r path pattern expected <<<"$spec"
|
|
83
|
-
if [[ ! -f "$path" ]]; then
|
|
84
|
-
_err "MISSING: $path (declared in spec list)"
|
|
85
|
-
drift=$((drift + 1))
|
|
86
|
-
continue
|
|
87
|
-
fi
|
|
88
|
-
line="$(grep -E "$pattern" "$path" | head -1 || true)"
|
|
89
|
-
if [[ -z "$line" ]]; then
|
|
90
|
-
_err "PATTERN NOT FOUND: '$pattern' in $path"
|
|
91
|
-
drift=$((drift + 1))
|
|
92
|
-
continue
|
|
93
|
-
fi
|
|
94
|
-
if [[ "$line" != *"$expected"* ]]; then
|
|
95
|
-
_err "DRIFT in $path"
|
|
96
|
-
_err " found: $line"
|
|
97
|
-
_err " expected: contains '$expected'"
|
|
98
|
-
drift=$((drift + 1))
|
|
99
|
-
if ((fix)); then
|
|
100
|
-
# Auto-fix: only safe when the file contains a previous v0.X.YYY
|
|
101
|
-
# we can sed-replace. Skip otherwise.
|
|
102
|
-
old="$(printf '%s' "$line" | grep -oE 'v[0-9]+\.[0-9]+\.[0-9]+' | head -1)"
|
|
103
|
-
if [[ -n "$old" ]] && [[ "$old" != "v${canonical}" ]]; then
|
|
104
|
-
sed -i.bak "s|${old}|v${canonical}|g" "$path" && rm -f "$path.bak"
|
|
105
|
-
_log " fixed: $path ($old → v${canonical})"
|
|
106
|
-
fi
|
|
107
|
-
fi
|
|
108
|
-
fi
|
|
109
|
-
done
|
|
110
|
-
|
|
111
|
-
if ((drift > 0)); then
|
|
112
|
-
if ((fix)); then
|
|
113
|
-
_log ""
|
|
114
|
-
_log "Auto-fixed where safe. Re-run without --fix to verify."
|
|
115
|
-
else
|
|
116
|
-
_log ""
|
|
117
|
-
_log "Tip: rerun with --fix to auto-correct (only safe substitutions)."
|
|
118
|
-
_log " For non-trivial drift, edit the file manually then re-run."
|
|
119
|
-
fi
|
|
120
|
-
exit 1
|
|
121
|
-
fi
|
|
122
|
-
|
|
123
|
-
_log "all $((${#specs[@]})) live version surfaces match $canonical"
|
|
124
|
-
exit 0
|
|
12
|
+
exec bash "$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)/scripts/verify-release-versions" "$@"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# SPDX-License-Identifier: MIT
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
3
3
|
# Copyright (c) 2015-2026 Sebastien Rousseau
|
|
4
4
|
set -euo pipefail
|
|
5
5
|
|
|
@@ -10,7 +10,7 @@ DOT_CLI="$REPO_ROOT/bin/dot"
|
|
|
10
10
|
UTILS_DOC="$REPO_ROOT/docs/reference/UTILS.md"
|
|
11
11
|
AI_DOC="$REPO_ROOT/docs/AI.md"
|
|
12
12
|
SCRIPTS_DOC="$REPO_ROOT/docs/reference/SCRIPTS.md"
|
|
13
|
-
ARCH_DOC="$REPO_ROOT/docs/
|
|
13
|
+
ARCH_DOC="$REPO_ROOT/docs/ARCHITECTURE.md"
|
|
14
14
|
FUNCTION_GROUPS_JSON="$REPO_ROOT/defaults/.chezmoitemplates/functions/groups.json"
|
|
15
15
|
MIN_DOCS_COVERAGE="${MIN_DOCS_COVERAGE:-100}"
|
|
16
16
|
|
|
@@ -104,7 +104,13 @@ main() {
|
|
|
104
104
|
check_ai_provider_docs
|
|
105
105
|
check_utility_docs
|
|
106
106
|
check_function_group_docs
|
|
107
|
-
|
|
107
|
+
# Capture the coverage threshold verdict — without this the final
|
|
108
|
+
# `printf PASS...` overwrites report_coverage's exit code and CI
|
|
109
|
+
# never sees a coverage regression.
|
|
110
|
+
if ! report_coverage; then
|
|
111
|
+
printf 'FAIL: docs coverage below MIN_DOCS_COVERAGE=%s%%\n' "$MIN_DOCS_COVERAGE" >&2
|
|
112
|
+
return 1
|
|
113
|
+
fi
|
|
108
114
|
|
|
109
115
|
printf 'PASS: public dot commands, utility entrypoints, AI providers, and function groups are documented at or above the required threshold\n'
|
|
110
116
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# SPDX-License-Identifier: MIT
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
3
3
|
# Copyright (c) 2015-2026 Sebastien Rousseau
|
|
4
4
|
# =============================================================================
|
|
5
5
|
# examples-coverage.sh — enforce that every core feature domain ships a
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# SPDX-License-Identifier: MIT
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
3
3
|
# Copyright (c) 2015-2026 Sebastien Rousseau
|
|
4
4
|
set -euo pipefail
|
|
5
5
|
|
|
@@ -109,7 +109,14 @@ main() {
|
|
|
109
109
|
} | sort -u
|
|
110
110
|
)
|
|
111
111
|
|
|
112
|
-
report_traceability
|
|
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
|
|
113
120
|
|
|
114
121
|
printf 'PASS: core internal behaviors have implementation, test, and documentation traceability at or above the required threshold\n'
|
|
115
122
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# SPDX-License-Identifier: MIT
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
3
3
|
# Copyright (c) 2015-2026 Sebastien Rousseau
|
|
4
4
|
set -euo pipefail
|
|
5
5
|
|
|
@@ -7,16 +7,74 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
7
7
|
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
8
8
|
EXAMPLES_DIR="$REPO_ROOT/examples"
|
|
9
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
|
+
|
|
10
44
|
if [ ! -d "$EXAMPLES_DIR" ]; then
|
|
11
45
|
echo "No examples directory found: $EXAMPLES_DIR" >&2
|
|
12
46
|
exit 1
|
|
13
47
|
fi
|
|
14
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
|
+
|
|
15
63
|
found=0
|
|
64
|
+
failed=0
|
|
16
65
|
while IFS= read -r -d '' example; do
|
|
17
66
|
found=1
|
|
18
|
-
|
|
19
|
-
|
|
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
|
|
20
78
|
done < <(find "$EXAMPLES_DIR" -maxdepth 1 -type f -name "*.sh" -print0 | sort -z)
|
|
21
79
|
|
|
22
80
|
if [ "$found" -eq 0 ]; then
|
|
@@ -24,4 +82,9 @@ if [ "$found" -eq 0 ]; then
|
|
|
24
82
|
exit 1
|
|
25
83
|
fi
|
|
26
84
|
|
|
85
|
+
if [ "$failed" -ne 0 ]; then
|
|
86
|
+
printf '%s example(s) failed.\n' "$failed" >&2
|
|
87
|
+
exit 1
|
|
88
|
+
fi
|
|
89
|
+
|
|
27
90
|
printf 'Examples passed.\n'
|