@hybridlabor-api/aos 4.8.0 → 4.10.0

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 (186) hide show
  1. package/.agents/{agents.md → AGENTS.md} +3 -1
  2. package/.agents/nodes.json +3 -1
  3. package/.agents/vendor-manifest.json +23 -1
  4. package/.claude/agents/godmode-media-eventtech.md +1 -1
  5. package/.claude/hooks/conventional-commits.mjs +125 -0
  6. package/.claude/hooks/env-file-protection.mjs +105 -0
  7. package/.claude/hooks/go-gate.mjs +101 -81
  8. package/.claude/hooks/memb-inject.mjs +29 -1
  9. package/.claude/settings.json +13 -0
  10. package/.claude/workflows/startcycle-dispatch.mjs +23 -1
  11. package/.opencode/agents/godmode-media-eventtech.md +1 -1
  12. package/.opencode/plugins/bdb-aos.js +31 -4
  13. package/CLAUDE.md +0 -571
  14. package/README.de.md +1 -1
  15. package/README.md +1 -1
  16. package/README.pt.md +1 -1
  17. package/THIRD_PARTY_NOTICES.md +126 -0
  18. package/bin/aos-doctor.mjs +1 -1
  19. package/docs/skills_table.md +1 -1
  20. package/installer.js +187 -55
  21. package/package.json +7 -3
  22. package/packages/aos-cli/README.md +80 -0
  23. package/packages/aos-cli/bin/aos-cli.mjs +134 -0
  24. package/packages/aos-cli/core-skills.json +12 -0
  25. package/packages/aos-cli/extensions/aos.ts +321 -0
  26. package/packages/aos-cli/package-lock.json +1923 -0
  27. package/packages/aos-cli/package.json +29 -0
  28. package/packages/aos-cli/scripts/check-theme.mjs +63 -0
  29. package/packages/aos-cli/themes/aos.json +97 -0
  30. package/scripts/build-plugin-manifest.mjs +131 -0
  31. package/scripts/validate-skills.mjs +81 -6
  32. package/skills/basic/ao-orchestrator/SKILL.md +116 -0
  33. package/skills/basic/bdb-eventagency-skill/SKILL.md +252 -0
  34. package/skills/basic/bdb-shipping-skill/SKILL.md +161 -0
  35. package/skills/basic/godmode-eventtech/SKILL.md +4 -1
  36. package/skills/global_config/agenttrail/SKILL.md +6 -1
  37. package/skills/global_config/aos-project-init/SKILL.md +2 -0
  38. package/skills/global_config/aos-project-init/assets/AGENTS.template.md +1 -1
  39. package/skills/global_config/aos-project-init/scripts/aos-project-doctor.mjs +1 -1
  40. package/skills/global_config/aos-setup/SKILL.md +1 -1
  41. package/skills/global_config/aos-setup/scripts/aos-doctor.mjs +1 -1
  42. package/skills/global_config/ask-tim/SKILL.md +7 -7
  43. package/skills/global_config/bash-script-generator/SKILL.md +201 -0
  44. package/skills/global_config/bash-script-generator/assets/templates/standard-template.sh +96 -0
  45. package/skills/global_config/bash-script-generator/docs/bash-scripting-guide.md +729 -0
  46. package/skills/global_config/bash-script-generator/docs/generation-best-practices.md +193 -0
  47. package/skills/global_config/bash-script-generator/docs/script-patterns.md +566 -0
  48. package/skills/global_config/bash-script-generator/docs/text-processing-guide.md +437 -0
  49. package/skills/global_config/bash-script-generator/examples/log-analyzer.sh +92 -0
  50. package/skills/global_config/bash-script-generator/scripts/generate_script_template.sh +123 -0
  51. package/skills/global_config/bash-script-generator/scripts/run_ci_checks.sh +172 -0
  52. package/skills/global_config/bash-script-generator/scripts/test_generator.sh +413 -0
  53. package/skills/global_config/bash-script-validator/SKILL.md +249 -0
  54. package/skills/global_config/bash-script-validator/docs/awk-reference.md +449 -0
  55. package/skills/global_config/bash-script-validator/docs/bash-reference.md +468 -0
  56. package/skills/global_config/bash-script-validator/docs/common-mistakes.md +623 -0
  57. package/skills/global_config/bash-script-validator/docs/grep-reference.md +395 -0
  58. package/skills/global_config/bash-script-validator/docs/regex-reference.md +391 -0
  59. package/skills/global_config/bash-script-validator/docs/sed-reference.md +454 -0
  60. package/skills/global_config/bash-script-validator/docs/shell-reference.md +463 -0
  61. package/skills/global_config/bash-script-validator/docs/shellcheck-reference.md +399 -0
  62. package/skills/global_config/bash-script-validator/examples/bad-bash.sh +55 -0
  63. package/skills/global_config/bash-script-validator/examples/bad-shell.sh +54 -0
  64. package/skills/global_config/bash-script-validator/examples/good-bash.sh +71 -0
  65. package/skills/global_config/bash-script-validator/examples/good-shell.sh +69 -0
  66. package/skills/global_config/bash-script-validator/scripts/run_ci_checks.sh +23 -0
  67. package/skills/global_config/bash-script-validator/scripts/shellcheck_wrapper.sh +174 -0
  68. package/skills/global_config/bash-script-validator/scripts/test_validate.sh +446 -0
  69. package/skills/global_config/bash-script-validator/scripts/validate.sh +512 -0
  70. package/skills/global_config/ci-pipeline/SKILL.md +135 -0
  71. package/skills/global_config/deja-memory/SKILL.md +3 -1
  72. package/skills/global_config/dispatching-parallel-agents/SKILL.md +170 -0
  73. package/skills/global_config/dockerfile-generator/SKILL.md +1038 -0
  74. package/skills/global_config/dockerfile-generator/examples/example.dockerignore +95 -0
  75. package/skills/global_config/dockerfile-generator/examples/golang-distroless.Dockerfile +34 -0
  76. package/skills/global_config/dockerfile-generator/examples/java-springboot.Dockerfile +45 -0
  77. package/skills/global_config/dockerfile-generator/examples/nextjs-production.Dockerfile +49 -0
  78. package/skills/global_config/dockerfile-generator/examples/nodejs-multistage.Dockerfile +55 -0
  79. package/skills/global_config/dockerfile-generator/examples/python-fastapi.Dockerfile +48 -0
  80. package/skills/global_config/dockerfile-generator/references/language_specific_guides.md +510 -0
  81. package/skills/global_config/dockerfile-generator/references/multistage_builds.md +570 -0
  82. package/skills/global_config/dockerfile-generator/references/optimization_patterns.md +492 -0
  83. package/skills/global_config/dockerfile-generator/references/security_best_practices.md +375 -0
  84. package/skills/global_config/dockerfile-generator/scripts/generate_dockerignore.sh +199 -0
  85. package/skills/global_config/dockerfile-generator/scripts/generate_golang.sh +172 -0
  86. package/skills/global_config/dockerfile-generator/scripts/generate_java.sh +185 -0
  87. package/skills/global_config/dockerfile-generator/scripts/generate_nodejs.sh +279 -0
  88. package/skills/global_config/dockerfile-generator/scripts/generate_python.sh +218 -0
  89. package/skills/global_config/dockerfile-generator/scripts/test_generator.sh +210 -0
  90. package/skills/global_config/dockerfile-validator/SKILL.md +300 -0
  91. package/skills/global_config/dockerfile-validator/examples/.dockerignore.example +34 -0
  92. package/skills/global_config/dockerfile-validator/examples/bad-example.Dockerfile +37 -0
  93. package/skills/global_config/dockerfile-validator/examples/golang-distroless.Dockerfile +50 -0
  94. package/skills/global_config/dockerfile-validator/examples/good-example.Dockerfile +52 -0
  95. package/skills/global_config/dockerfile-validator/examples/python-optimized.Dockerfile +53 -0
  96. package/skills/global_config/dockerfile-validator/examples/security-issues.Dockerfile +42 -0
  97. package/skills/global_config/dockerfile-validator/references/docker_best_practices.md +348 -0
  98. package/skills/global_config/dockerfile-validator/references/optimization_guide.md +473 -0
  99. package/skills/global_config/dockerfile-validator/references/security_checklist.md +208 -0
  100. package/skills/global_config/dockerfile-validator/scripts/dockerfile-validate.sh +699 -0
  101. package/skills/global_config/dockerfile-validator/scripts/test_validate.sh +35 -0
  102. package/skills/global_config/dockerfile-validator/tests/fixtures/copy-before-yarn-lock-read.Dockerfile +6 -0
  103. package/skills/global_config/dockerfile-validator/tests/fixtures/copy-before-yarn.Dockerfile +6 -0
  104. package/skills/global_config/dockerfile-validator/tests/fixtures/from-platform-nonroot.Dockerfile +7 -0
  105. package/skills/global_config/dockerfile-validator/tests/test_regression.sh +164 -0
  106. package/skills/global_config/finishing-a-development-branch/SKILL.md +228 -0
  107. package/skills/global_config/github-actions-generator/SKILL.md +353 -0
  108. package/skills/global_config/github-actions-generator/assets/templates/action/composite/action.yml +82 -0
  109. package/skills/global_config/github-actions-generator/assets/templates/action/docker/Dockerfile +25 -0
  110. package/skills/global_config/github-actions-generator/assets/templates/action/docker/action.yml +42 -0
  111. package/skills/global_config/github-actions-generator/assets/templates/action/docker/entrypoint.sh +27 -0
  112. package/skills/global_config/github-actions-generator/assets/templates/action/javascript/action.yml +33 -0
  113. package/skills/global_config/github-actions-generator/assets/templates/action/javascript/index.js +50 -0
  114. package/skills/global_config/github-actions-generator/assets/templates/action/javascript/package.json +27 -0
  115. package/skills/global_config/github-actions-generator/assets/templates/workflow/basic_workflow.yml +242 -0
  116. package/skills/global_config/github-actions-generator/assets/templates/workflow/reusable_workflow.yml +106 -0
  117. package/skills/global_config/github-actions-generator/examples/README.md +147 -0
  118. package/skills/global_config/github-actions-generator/examples/actions/setup-node-cached/action.yml +93 -0
  119. package/skills/global_config/github-actions-generator/examples/caching/docker-buildkit.yml +256 -0
  120. package/skills/global_config/github-actions-generator/examples/security/dependency-review.yml +62 -0
  121. package/skills/global_config/github-actions-generator/examples/security/sbom-attestation.yml +119 -0
  122. package/skills/global_config/github-actions-generator/examples/triggers/chatops-commands.yml +475 -0
  123. package/skills/global_config/github-actions-generator/examples/triggers/repository-dispatch.yml +418 -0
  124. package/skills/global_config/github-actions-generator/examples/triggers/workflow-orchestration.yml +404 -0
  125. package/skills/global_config/github-actions-generator/examples/workflows/docker-build-push.yml +68 -0
  126. package/skills/global_config/github-actions-generator/examples/workflows/go-ci.yml +161 -0
  127. package/skills/global_config/github-actions-generator/examples/workflows/monorepo-ci.yml +340 -0
  128. package/skills/global_config/github-actions-generator/examples/workflows/multi-environment-deploy.yml +406 -0
  129. package/skills/global_config/github-actions-generator/examples/workflows/nodejs-ci.yml +122 -0
  130. package/skills/global_config/github-actions-generator/examples/workflows/python-ci.yml +157 -0
  131. package/skills/global_config/github-actions-generator/examples/workflows/scheduled-tasks.yml +376 -0
  132. package/skills/global_config/github-actions-generator/references/advanced-triggers.md +917 -0
  133. package/skills/global_config/github-actions-generator/references/best-practices.md +755 -0
  134. package/skills/global_config/github-actions-generator/references/common-actions.md +715 -0
  135. package/skills/global_config/github-actions-generator/references/custom-actions.md +320 -0
  136. package/skills/global_config/github-actions-generator/references/expressions-and-contexts.md +688 -0
  137. package/skills/global_config/github-actions-generator/references/modern-features.md +421 -0
  138. package/skills/global_config/github-actions-generator/scripts/test_generator.sh +344 -0
  139. package/skills/global_config/github-actions-templates/SKILL.md +7 -0
  140. package/skills/global_config/github-actions-validator/SKILL.md +576 -0
  141. package/skills/global_config/github-actions-validator/examples/README.md +88 -0
  142. package/skills/global_config/github-actions-validator/examples/outdated-versions.yml +76 -0
  143. package/skills/global_config/github-actions-validator/examples/valid-ci.yml +79 -0
  144. package/skills/global_config/github-actions-validator/examples/with-errors.yml +47 -0
  145. package/skills/global_config/github-actions-validator/references/act_usage.md +233 -0
  146. package/skills/global_config/github-actions-validator/references/action_versions.md +122 -0
  147. package/skills/global_config/github-actions-validator/references/actionlint_usage.md +343 -0
  148. package/skills/global_config/github-actions-validator/references/common_errors.md +512 -0
  149. package/skills/global_config/github-actions-validator/references/modern_features.md +384 -0
  150. package/skills/global_config/github-actions-validator/references/runners.md +317 -0
  151. package/skills/global_config/github-actions-validator/scripts/install_tools.sh +113 -0
  152. package/skills/global_config/github-actions-validator/scripts/validate_workflow.sh +910 -0
  153. package/skills/global_config/github-actions-validator/tests/test_validate_workflow.sh +237 -0
  154. package/skills/global_config/makefile-generator/SKILL.md +614 -0
  155. package/skills/global_config/makefile-generator/assets/templates/.gitkeep +1 -0
  156. package/skills/global_config/makefile-generator/docs/makefile-structure.md +530 -0
  157. package/skills/global_config/makefile-generator/docs/optimization-guide.md +784 -0
  158. package/skills/global_config/makefile-generator/docs/patterns-guide.md +642 -0
  159. package/skills/global_config/makefile-generator/docs/security-guide.md +361 -0
  160. package/skills/global_config/makefile-generator/docs/targets-guide.md +642 -0
  161. package/skills/global_config/makefile-generator/docs/variables-guide.md +596 -0
  162. package/skills/global_config/makefile-generator/scripts/add_standard_targets.sh +539 -0
  163. package/skills/global_config/makefile-generator/scripts/generate_makefile_template.sh +690 -0
  164. package/skills/global_config/makefile-generator/test/test_helper_scripts.sh +190 -0
  165. package/skills/global_config/makefile-validator/SKILL.md +244 -0
  166. package/skills/global_config/makefile-validator/docs/bake-tool.md +1000 -0
  167. package/skills/global_config/makefile-validator/docs/best-practices.md +858 -0
  168. package/skills/global_config/makefile-validator/docs/common-mistakes.md +944 -0
  169. package/skills/global_config/makefile-validator/examples/bad-makefile.mk +77 -0
  170. package/skills/global_config/makefile-validator/examples/good-makefile.mk +103 -0
  171. package/skills/global_config/makefile-validator/scripts/test_validate.sh +382 -0
  172. package/skills/global_config/makefile-validator/scripts/validate_makefile.sh +712 -0
  173. package/skills/global_config/{MCP_Manage → mcp-manage}/SKILL.md +3 -3
  174. package/skills/global_config/plan-canvas/SKILL.md +9 -2
  175. package/skills/global_config/plan-canvas/scripts/lib/plan-canvas/ui.js +10 -2
  176. package/skills/global_config/plan-canvas/scripts/plan-canvas.js +1 -1
  177. package/skills/global_config/read-the-damn-docs/SKILL.md +175 -0
  178. package/skills/global_config/requesting-code-review/SKILL.md +98 -0
  179. package/skills/global_config/requesting-code-review/code-reviewer.md +198 -0
  180. package/skills/global_config/using-git-worktrees/SKILL.md +170 -0
  181. package/skills/global_config/verification-before-completion/SKILL.md +123 -0
  182. package/skills/global_config/writing-plans/SKILL.md +126 -46
  183. package/skills/global_config/writing-plans-legacy/SKILL.md +152 -0
  184. package/.claude/CLAUDE.md +0 -12
  185. package/mcps/RhinoMCP/docs/content/docs/getting-started/gemini.md +0 -61
  186. /package/{GEMINI.md → RULES.md} +0 -0
@@ -0,0 +1,77 @@
1
+ # Bad Makefile Example
2
+ # Demonstrates common mistakes and anti-patterns
3
+ # DO NOT USE THIS IN PRODUCTION!
4
+
5
+ # Variables with recursive expansion (inefficient)
6
+ BUILD_TIME = $(shell date +%Y%m%d-%H%M%S)
7
+ SOURCES = $(wildcard src/*.c)
8
+
9
+ # Hardcoded credentials (SECURITY ISSUE!)
10
+ API_KEY = sk-1234567890abcdef
11
+ DB_PASSWORD = super_secret_password
12
+
13
+ # No .PHONY declarations (major issue!)
14
+ all: build test
15
+
16
+ build:
17
+ echo "Building..."
18
+ gcc -o app $(SOURCES)
19
+
20
+ # Missing .PHONY - won't run if file 'test' exists
21
+ test:
22
+ go test ./...
23
+
24
+ # Missing .PHONY - dangerous!
25
+ clean:
26
+ rm -rf $(BUILD_DIR)/*
27
+
28
+ # Unsafe variable expansion
29
+ deploy:
30
+ ssh user@$(SERVER) "cd /app && git pull origin $(BRANCH)"
31
+
32
+ # Missing error handling
33
+ install:
34
+ cp app /usr/local/bin/
35
+ cp docs/app.1 /usr/share/man/man1/
36
+
37
+ # Spaces instead of tabs in some recipes (syntax error!)
38
+ broken-target:
39
+ echo "This uses spaces!"
40
+ echo "This will fail!"
41
+
42
+ # Mixed tabs and spaces (syntax error!)
43
+ mixed:
44
+ echo "This uses a tab"
45
+ echo "This uses spaces - ERROR!"
46
+
47
+ # No dependency specification
48
+ app.o:
49
+ gcc -c app.c
50
+
51
+ # Hardcoded paths (not portable)
52
+ backup:
53
+ cp app $(HOME)/backups/
54
+
55
+ # No validation of dangerous operations
56
+ dangerous-clean:
57
+ rm -rf $(USER_INPUT)/*
58
+
59
+ # Incorrect variable expansion in loop
60
+ loop-bug:
61
+ for file in *.c; do \
62
+ echo "Compiling $file"; \
63
+ gcc -c $file; \
64
+ done
65
+
66
+ # Missing := causing repeated shell calls
67
+ debug:
68
+ echo $(BUILD_TIME)
69
+ echo $(BUILD_TIME)
70
+
71
+ # Unquoted variable in dangerous context
72
+ unsafe-rm:
73
+ rm -rf $(BUILD_DIR)
74
+
75
+ # No default values for critical variables
76
+ install-unsafe:
77
+ cp app $(PREFIX)/bin/
@@ -0,0 +1,103 @@
1
+ # Good Makefile Example
2
+ # Demonstrates best practices for Makefile creation
3
+ # Project: Example Application
4
+ # Version: 1.0.0
5
+
6
+ # Modern Makefile Header (GNU Make 4.0+)
7
+ # See: https://tech.davis-hansson.com/p/make/
8
+ SHELL := bash
9
+
10
+ # Delete target on recipe failure (GNU Make best practice)
11
+ .DELETE_ON_ERROR:
12
+
13
+ # Disable built-in suffix rules for faster builds
14
+ .SUFFIXES:
15
+
16
+ # Variables with immediate expansion (recommended)
17
+ PROJECT := example-app
18
+ VERSION := 1.0.0
19
+ BUILD_DIR := build
20
+ SRC_DIR := src
21
+ TEST_DIR := tests
22
+
23
+ # Compiler and flags
24
+ CC ?= gcc
25
+ CFLAGS := -Wall -Wextra -O2
26
+ LDFLAGS :=
27
+
28
+ # Find source files
29
+ SOURCES := $(wildcard $(SRC_DIR)/*.c)
30
+ OBJECTS := $(patsubst $(SRC_DIR)/%.c,$(BUILD_DIR)/%.o,$(SOURCES))
31
+
32
+ # Phony targets properly declared
33
+ .PHONY: all build clean test install uninstall help
34
+
35
+ # Default target (first in file)
36
+ all: build test
37
+
38
+ # Help target for user guidance
39
+ help:
40
+ @echo "Available targets:"
41
+ @echo " make build - Build the application"
42
+ @echo " make test - Run tests"
43
+ @echo " make clean - Remove build artifacts"
44
+ @echo " make install - Install to PREFIX (default: /usr/local)"
45
+ @echo " make uninstall - Remove installed files"
46
+ @echo " make help - Show this help message"
47
+
48
+ # Build the main application
49
+ build: $(BUILD_DIR)/$(PROJECT)
50
+ @echo "Build complete: $(BUILD_DIR)/$(PROJECT)"
51
+
52
+ # Link object files into executable
53
+ $(BUILD_DIR)/$(PROJECT): $(OBJECTS) | $(BUILD_DIR)
54
+ @echo "Linking $@..."
55
+ $(CC) $(OBJECTS) $(LDFLAGS) -o $@
56
+
57
+ # Compile source files to object files
58
+ $(BUILD_DIR)/%.o: $(SRC_DIR)/%.c | $(BUILD_DIR)
59
+ @echo "Compiling $<..."
60
+ @mkdir -p $(dir $@)
61
+ $(CC) $(CFLAGS) -c $< -o $@
62
+
63
+ # Create build directory (order-only prerequisite)
64
+ $(BUILD_DIR):
65
+ @mkdir -p $(BUILD_DIR)
66
+
67
+ # Run tests
68
+ test: build
69
+ @echo "Running tests..."
70
+ @set -e; \
71
+ for test in $(TEST_DIR)/*.sh; do \
72
+ echo " Running $$test..."; \
73
+ bash $$test; \
74
+ done
75
+ @echo "All tests passed!"
76
+
77
+ # Clean build artifacts
78
+ clean:
79
+ @echo "Cleaning build artifacts..."
80
+ @if [ -d "$(BUILD_DIR)" ]; then \
81
+ rm -rf $(BUILD_DIR); \
82
+ echo " Removed $(BUILD_DIR)"; \
83
+ fi
84
+ @echo "Clean complete"
85
+
86
+ # Installation with proper defaults
87
+ PREFIX ?= /usr/local
88
+ BINDIR ?= $(PREFIX)/bin
89
+
90
+ install: build
91
+ @echo "Installing $(PROJECT) to $(DESTDIR)$(BINDIR)..."
92
+ @install -d $(DESTDIR)$(BINDIR)
93
+ @install -m 755 $(BUILD_DIR)/$(PROJECT) $(DESTDIR)$(BINDIR)/
94
+ @echo "Installation complete"
95
+
96
+ # Uninstall
97
+ uninstall:
98
+ @echo "Uninstalling $(PROJECT) from $(DESTDIR)$(BINDIR)..."
99
+ @if [ -f "$(DESTDIR)$(BINDIR)/$(PROJECT)" ]; then \
100
+ rm -f $(DESTDIR)$(BINDIR)/$(PROJECT); \
101
+ echo " Removed $(DESTDIR)$(BINDIR)/$(PROJECT)"; \
102
+ fi
103
+ @echo "Uninstall complete"
@@ -0,0 +1,382 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # Regression test suite for validate_makefile.sh
4
+ #
5
+ # Runs the validator against fixture files and asserts expected exit codes and
6
+ # output patterns. Each fixture file is validated once; all assertions on it
7
+ # share that single run so mbake is only installed once per fixture.
8
+ #
9
+ # Exit 0 when all assertions pass; exit 1 on the first failure.
10
+ #
11
+ # Usage:
12
+ # bash scripts/test_validate.sh # from makefile-validator/ directory
13
+ # bash devops-skills-plugin/skills/makefile-validator/scripts/test_validate.sh
14
+ #
15
+ # Suites:
16
+ # MAKEFILE_VALIDATOR_TEST_SUITE=offline # deterministic default (MBAKE_SKIP_INSTALL=1)
17
+ # MAKEFILE_VALIDATOR_TEST_SUITE=integration # mbake install path checks
18
+ # MAKEFILE_VALIDATOR_TEST_SUITE=all # run both suites
19
+
20
+ set -euo pipefail
21
+
22
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
23
+ readonly SCRIPT_DIR
24
+ VALIDATOR="$SCRIPT_DIR/validate_makefile.sh"
25
+ EXAMPLES_DIR="$SCRIPT_DIR/../examples"
26
+ TEST_SUITE="${MAKEFILE_VALIDATOR_TEST_SUITE:-${TEST_SUITE:-offline}}"
27
+
28
+ PASS=0
29
+ FAIL=0
30
+ TMPFILES=()
31
+ RUN_OFFLINE=0
32
+ RUN_INTEGRATION=0
33
+
34
+ case "$TEST_SUITE" in
35
+ offline)
36
+ RUN_OFFLINE=1
37
+ ;;
38
+ integration)
39
+ RUN_INTEGRATION=1
40
+ ;;
41
+ all)
42
+ RUN_OFFLINE=1
43
+ RUN_INTEGRATION=1
44
+ ;;
45
+ *)
46
+ echo "[ERROR] Unsupported test suite: $TEST_SUITE" >&2
47
+ echo " Use one of: offline, integration, all" >&2
48
+ exit 2
49
+ ;;
50
+ esac
51
+
52
+ # ─── cleanup ────────────────────────────────────────────────────────────────
53
+
54
+ cleanup() {
55
+ local f
56
+ for f in "${TMPFILES[@]:-}"; do
57
+ if [[ -d "$f" ]]; then
58
+ rm -rf "$f" 2>/dev/null || true
59
+ else
60
+ rm -f "$f" 2>/dev/null || true
61
+ fi
62
+ done
63
+ TMPFILES=()
64
+ }
65
+ trap cleanup EXIT INT TERM
66
+
67
+ # ─── helpers ────────────────────────────────────────────────────────────────
68
+
69
+ pass() { printf " PASS %s\n" "$1"; PASS=$((PASS + 1)); }
70
+ fail() { printf " FAIL %s\n" "$1"; FAIL=$((FAIL + 1)); }
71
+
72
+ # Run the validator once; populate OUTPUT and EXIT_CODE globals.
73
+ # The || true prevents set -e from aborting on a non-zero validator exit.
74
+ _run() {
75
+ local file="$1"
76
+ local mbake_skip_install="${2:-1}"
77
+ EXIT_CODE=0
78
+ OUTPUT=$(NO_COLOR=1 MBAKE_SKIP_INSTALL="$mbake_skip_install" bash "$VALIDATOR" "$file" 2>&1) || EXIT_CODE=$?
79
+ }
80
+
81
+ # Assert the exit code stored in EXIT_CODE equals $1.
82
+ assert_exit() {
83
+ local label="$1" expected="$2"
84
+ if [[ "$EXIT_CODE" -eq "$expected" ]]; then
85
+ pass "$label (exit $EXIT_CODE)"
86
+ else
87
+ fail "$label — expected exit $expected, got $EXIT_CODE"
88
+ printf '%s\n' "$OUTPUT" | sed 's/^/ /'
89
+ fi
90
+ }
91
+
92
+ # Assert that OUTPUT matches an ERE pattern.
93
+ assert_contains() {
94
+ local label="$1" pattern="$2"
95
+ if printf '%s\n' "$OUTPUT" | grep -qE "$pattern"; then
96
+ pass "$label"
97
+ else
98
+ fail "$label — pattern not found: $pattern"
99
+ printf '%s\n' "$OUTPUT" | sed 's/^/ /'
100
+ fi
101
+ }
102
+
103
+ # Assert that OUTPUT does NOT match an ERE pattern.
104
+ assert_not_contains() {
105
+ local label="$1" pattern="$2"
106
+ if printf '%s\n' "$OUTPUT" | grep -qE "$pattern"; then
107
+ fail "$label — unexpected pattern found: $pattern"
108
+ printf '%s\n' "$OUTPUT" | grep -E "$pattern" | sed 's/^/ /'
109
+ else
110
+ pass "$label"
111
+ fi
112
+ }
113
+
114
+ # Assert a path does not exist.
115
+ assert_path_absent() {
116
+ local label="$1" path="$2"
117
+ if [[ ! -e "$path" ]]; then
118
+ pass "$label"
119
+ else
120
+ fail "$label — path still exists: $path"
121
+ fi
122
+ }
123
+
124
+ # Create a named temp fixture (.mk extension) and register it for cleanup.
125
+ # macOS mktemp requires Xs to be at the very end of the template, so we create
126
+ # a plain temp file and rename it with a .mk suffix.
127
+ mktemp_mk() {
128
+ local base f
129
+ base=$(mktemp "${TMPDIR:-/tmp}/test-mk-XXXXXX")
130
+ f="${base}.mk"
131
+ mv "$base" "$f"
132
+ TMPFILES+=("$f")
133
+ echo "$f"
134
+ }
135
+
136
+ # ─── Test Groups ────────────────────────────────────────────────────────────
137
+
138
+ echo ""
139
+ echo "Running validate_makefile.sh regression tests (suite: $TEST_SUITE)..."
140
+
141
+ if [[ "$RUN_OFFLINE" -eq 1 ]]; then
142
+ # ── Harness: cleanup removes both files and directories ───────────────────
143
+ echo ""
144
+ echo "── harness: cleanup removes files and directories ───────────────────"
145
+ cleanup_file=$(mktemp "${TMPDIR:-/tmp}/test-clean-file-XXXXXX")
146
+ cleanup_dir=$(mktemp -d "${TMPDIR:-/tmp}/test-clean-dir-XXXXXX")
147
+ TMPFILES+=("$cleanup_file" "$cleanup_dir")
148
+ cleanup
149
+ assert_path_absent "cleanup removes temp file" "$cleanup_file"
150
+ assert_path_absent "cleanup removes temp directory" "$cleanup_dir"
151
+
152
+ # ── Offline mode: deterministic mbake skip ────────────────────────────────
153
+ echo ""
154
+ echo "── offline: deterministic mbake skip mode ───────────────────────────"
155
+ FAKEOFFLINEBIN=$(mktemp -d "${TMPDIR:-/tmp}/test-offlinebin-XXXXXX")
156
+ TMPFILES+=("$FAKEOFFLINEBIN")
157
+ printf '#!/usr/bin/env bash\necho "python3: blocked" >&2; exit 127\n' > "$FAKEOFFLINEBIN/python3"
158
+ printf '#!/usr/bin/env bash\necho "pip3: blocked" >&2; exit 127\n' > "$FAKEOFFLINEBIN/pip3"
159
+ chmod +x "$FAKEOFFLINEBIN/python3" "$FAKEOFFLINEBIN/pip3"
160
+
161
+ PATH="$FAKEOFFLINEBIN:$PATH" _run "$EXAMPLES_DIR/good-makefile.mk" 1
162
+ assert_exit "offline mode exits cleanly" 0
163
+ assert_contains "offline mode banner printed" "MBAKE_SKIP_INSTALL=1 enabled"
164
+ assert_contains "mbake stages skipped by deterministic mode" "Skipped.*MBAKE_SKIP_INSTALL=1"
165
+ assert_not_contains "python3 warning suppressed in offline mode" "python3 not found"
166
+ assert_not_contains "pip3 warning suppressed in offline mode" "pip3 not found"
167
+ assert_not_contains "venv setup skipped in offline mode" "Creating temporary venv|Installing mbake"
168
+
169
+ # ── good-makefile.mk ─────────────────────────────────────────────────────
170
+ echo ""
171
+ echo "── good-makefile.mk ─────────────────────────────────────────────────"
172
+ _run "$EXAMPLES_DIR/good-makefile.mk"
173
+ assert_exit "exits cleanly" 0
174
+ assert_not_contains "no credential false positive" "hardcoded credentials"
175
+ assert_not_contains "no tab false positive" "spaces instead of tabs"
176
+ assert_not_contains "no validation-failed summary" "Validation FAILED"
177
+ assert_contains "passes summary printed" "Validation PASSED"
178
+
179
+ # ── bad-makefile.mk ──────────────────────────────────────────────────────
180
+ echo ""
181
+ echo "── bad-makefile.mk ──────────────────────────────────────────────────"
182
+ _run "$EXAMPLES_DIR/bad-makefile.mk"
183
+ assert_exit "exits with error code" 2
184
+ assert_contains "catches spaces-as-tabs" "spaces instead of tabs"
185
+ assert_contains "catches hardcoded credentials" "hardcoded credentials"
186
+ assert_contains "catches missing .DELETE_ON_ERROR" "Missing .DELETE_ON_ERROR"
187
+ assert_contains "catches missing .PHONY" "No .PHONY declarations"
188
+ assert_contains "catches unsafe variable expansion" "without defaults"
189
+ assert_contains "catches recursive = with shell" "Shell commands with recursive expansion"
190
+ assert_contains "failed summary printed" "Validation FAILED"
191
+
192
+ # ── Edge: commented-out credentials must NOT be flagged ──────────────────
193
+ echo ""
194
+ echo "── edge: commented credentials ──────────────────────────────────────"
195
+ F=$(mktemp_mk)
196
+ cat > "$F" << 'MKEOF'
197
+ SHELL := bash
198
+ .DELETE_ON_ERROR:
199
+ .PHONY: deploy
200
+
201
+ # Documentation example (not a real secret):
202
+ # API_KEY = sk-example-1234567890abcdef
203
+ # DB_PASSWORD = super_secret_password
204
+ # github_token = ghp_example_token
205
+
206
+ deploy:
207
+ @echo "Deploying..."
208
+ MKEOF
209
+ _run "$F"
210
+ assert_not_contains "commented creds not flagged" "hardcoded credentials"
211
+
212
+ # ── Edge: actual credentials after comment lines must still be caught ────
213
+ echo ""
214
+ echo "── edge: real credentials are still caught ──────────────────────────"
215
+ F=$(mktemp_mk)
216
+ cat > "$F" << 'MKEOF'
217
+ SHELL := bash
218
+ .DELETE_ON_ERROR:
219
+ .PHONY: deploy
220
+
221
+ # This is a comment about the key below
222
+ API_KEY = sk-1234567890abcdef
223
+
224
+ deploy:
225
+ @echo "Deploying..."
226
+ MKEOF
227
+ _run "$F"
228
+ assert_contains "real creds after comments still caught" "hardcoded credentials"
229
+
230
+ # ── Edge: lowercase variable in dangerous command ─────────────────────────
231
+ echo ""
232
+ echo "── edge: lowercase variable in rm -rf ───────────────────────────────"
233
+ F=$(mktemp_mk)
234
+ cat > "$F" << 'MKEOF'
235
+ SHELL := bash
236
+ .DELETE_ON_ERROR:
237
+ .PHONY: clean
238
+
239
+ clean:
240
+ rm -rf $(build_dir)
241
+ MKEOF
242
+ _run "$F"
243
+ assert_contains "lowercase unsafe var detected" "without defaults"
244
+
245
+ # ── Edge: bare make call at end of line (no args) ─────────────────────────
246
+ echo ""
247
+ echo "── edge: bare make call (no args at end of line) ────────────────────"
248
+ F=$(mktemp_mk)
249
+ cat > "$F" << 'MKEOF'
250
+ SHELL := bash
251
+ .DELETE_ON_ERROR:
252
+ .PHONY: recurse
253
+
254
+ recurse:
255
+ make
256
+ MKEOF
257
+ _run "$F"
258
+ assert_contains "bare make call detected" "Direct.*call"
259
+
260
+ # ── Edge: make with args is also caught ───────────────────────────────────
261
+ echo ""
262
+ echo "── edge: make with args ─────────────────────────────────────────────"
263
+ F=$(mktemp_mk)
264
+ cat > "$F" << 'MKEOF'
265
+ SHELL := bash
266
+ .DELETE_ON_ERROR:
267
+ .PHONY: recurse
268
+
269
+ recurse:
270
+ make build
271
+ MKEOF
272
+ _run "$F"
273
+ assert_contains "make-with-args detected" "Direct.*call"
274
+
275
+ # ── Edge: $(MAKE) must NOT be flagged as a bare make call ─────────────────
276
+ echo ""
277
+ echo "── edge: \$(MAKE) is not flagged ────────────────────────────────────"
278
+ F=$(mktemp_mk)
279
+ cat > "$F" << 'MKEOF'
280
+ SHELL := bash
281
+ .DELETE_ON_ERROR:
282
+ MAKEFLAGS += --warn-undefined-variables
283
+ MAKEFLAGS += --no-builtin-rules
284
+ .PHONY: recurse
285
+
286
+ ## Default target
287
+ recurse:
288
+ $(MAKE) build
289
+ MKEOF
290
+ _run "$F"
291
+ assert_not_contains "MAKE macro not flagged" "Direct.*call"
292
+
293
+ # ── Edge: syntax_check single make invocation (output present on error) ───
294
+ echo ""
295
+ echo "── edge: syntax error output is shown ───────────────────────────────"
296
+ F=$(mktemp_mk)
297
+ # Write a Makefile with a deliberate syntax error (spaces instead of tabs)
298
+ printf 'build:\n echo broken\n' > "$F"
299
+ _run "$F"
300
+ assert_contains "syntax error output shown" "missing separator|Syntax errors detected"
301
+
302
+ # ── Edge: graceful degradation when python3 is absent ─────────────────────
303
+ # Shadow python3 with a stub that exits 127 so the validator cannot set up mbake.
304
+ # The script should warn, skip mbake stages, still run custom/syntax checks,
305
+ # and exit with warnings (1) rather than a hard error.
306
+ echo ""
307
+ echo "── edge: graceful degradation (no python3) ───────────────────────────"
308
+ FAKEBINDIR=$(mktemp -d "${TMPDIR:-/tmp}/test-fakebin-XXXXXX")
309
+ TMPFILES+=("$FAKEBINDIR")
310
+ printf '#!/usr/bin/env bash\necho "python3: not found" >&2; exit 127\n' > "$FAKEBINDIR/python3"
311
+ chmod +x "$FAKEBINDIR/python3"
312
+
313
+ F=$(mktemp_mk)
314
+ cat > "$F" << 'MKEOF'
315
+ SHELL := bash
316
+ .DELETE_ON_ERROR:
317
+ MAKEFLAGS += --warn-undefined-variables
318
+ MAKEFLAGS += --no-builtin-rules
319
+ .PHONY: build
320
+
321
+ ## Default target
322
+ build:
323
+ @echo "ok"
324
+ MKEOF
325
+
326
+ PATH="$FAKEBINDIR:$PATH" _run "$F" 0
327
+ assert_exit "degraded run exits with warnings" 1
328
+ assert_not_contains "no hard exit on missing python3" "ERROR.*python3"
329
+ assert_contains "warns about missing python3" "python3 not found|mbake.*skipped"
330
+ assert_contains "mbake stages shown as skipped" "Skipped.*mbake"
331
+ assert_contains "custom checks section printed" "\\[CUSTOM CHECKS\\]"
332
+ assert_contains "custom checks executed" "No additional issues found|No \\.PHONY declarations found|Missing \\.DELETE_ON_ERROR declaration"
333
+ assert_contains "degraded summary is warning mode" "Validation PASSED with warnings|Validation PASSED"
334
+ else
335
+ echo ""
336
+ echo "── offline suite skipped (set MAKEFILE_VALIDATOR_TEST_SUITE=offline|all) ──"
337
+ fi
338
+
339
+ if [[ "$RUN_INTEGRATION" -eq 1 ]]; then
340
+ # ── Integration: ensure mbake path executes when skip mode is disabled ────
341
+ echo ""
342
+ echo "── integration: mbake path is exercised ──────────────────────────────"
343
+ _run "$EXAMPLES_DIR/good-makefile.mk" 0
344
+ assert_not_contains "integration run does not use skip mode" "MBAKE_SKIP_INSTALL=1"
345
+ assert_not_contains "mbake stages are not skipped" "Skipped.*mbake not available|Skipped.*MBAKE_SKIP_INSTALL=1"
346
+ assert_contains "venv setup is attempted" "ENVIRONMENT SETUP|Creating temporary venv|Installing mbake"
347
+ assert_contains "mbake validation stage is present" "Running mbake validate|mbake validation passed|mbake validation failed"
348
+
349
+ # ── Edge: .PRECIOUS (non-list special target) not flagged by format check ─
350
+ # When mbake reports "Unknown special target '.PRECIOUS'", it should be
351
+ # treated as a known mbake false-positive (not a real error or warning).
352
+ echo ""
353
+ echo "── integration: .PRECIOUS not flagged as mbake error ─────────────────"
354
+ F=$(mktemp_mk)
355
+ cat > "$F" << 'MKEOF'
356
+ SHELL := bash
357
+ .DELETE_ON_ERROR:
358
+ .PRECIOUS: %.tar.gz
359
+ MAKEFLAGS += --warn-undefined-variables
360
+ MAKEFLAGS += --no-builtin-rules
361
+ .PHONY: build
362
+
363
+ ## Default target
364
+ build:
365
+ @echo "ok"
366
+ MKEOF
367
+ _run "$F" 0
368
+ # .PRECIOUS is valid GNU Make but mbake may not know it; should be info, not warning/error
369
+ assert_not_contains ".PRECIOUS not counted as error" "Errors:[[:space:]]+[1-9]"
370
+ else
371
+ echo ""
372
+ echo "── integration suite skipped (set MAKEFILE_VALIDATOR_TEST_SUITE=integration|all) ──"
373
+ fi
374
+
375
+ # ─── Summary ────────────────────────────────────────────────────────────────
376
+ echo ""
377
+ echo "══════════════════════════════════════════════════════════════════════"
378
+ printf " Results: %d passed, %d failed\n" "$PASS" "$FAIL"
379
+ echo "══════════════════════════════════════════════════════════════════════"
380
+ echo ""
381
+
382
+ [[ "$FAIL" -eq 0 ]]