@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.
- package/.agents/{agents.md → AGENTS.md} +3 -1
- package/.agents/nodes.json +3 -1
- package/.agents/vendor-manifest.json +23 -1
- package/.claude/agents/godmode-media-eventtech.md +1 -1
- package/.claude/hooks/conventional-commits.mjs +125 -0
- package/.claude/hooks/env-file-protection.mjs +105 -0
- package/.claude/hooks/go-gate.mjs +101 -81
- package/.claude/hooks/memb-inject.mjs +29 -1
- package/.claude/settings.json +13 -0
- package/.claude/workflows/startcycle-dispatch.mjs +23 -1
- package/.opencode/agents/godmode-media-eventtech.md +1 -1
- package/.opencode/plugins/bdb-aos.js +31 -4
- package/CLAUDE.md +0 -571
- package/README.de.md +1 -1
- package/README.md +1 -1
- package/README.pt.md +1 -1
- package/THIRD_PARTY_NOTICES.md +126 -0
- package/bin/aos-doctor.mjs +1 -1
- package/docs/skills_table.md +1 -1
- package/installer.js +187 -55
- package/package.json +7 -3
- package/packages/aos-cli/README.md +80 -0
- package/packages/aos-cli/bin/aos-cli.mjs +134 -0
- package/packages/aos-cli/core-skills.json +12 -0
- package/packages/aos-cli/extensions/aos.ts +321 -0
- package/packages/aos-cli/package-lock.json +1923 -0
- package/packages/aos-cli/package.json +29 -0
- package/packages/aos-cli/scripts/check-theme.mjs +63 -0
- package/packages/aos-cli/themes/aos.json +97 -0
- package/scripts/build-plugin-manifest.mjs +131 -0
- package/scripts/validate-skills.mjs +81 -6
- package/skills/basic/ao-orchestrator/SKILL.md +116 -0
- package/skills/basic/bdb-eventagency-skill/SKILL.md +252 -0
- package/skills/basic/bdb-shipping-skill/SKILL.md +161 -0
- package/skills/basic/godmode-eventtech/SKILL.md +4 -1
- package/skills/global_config/agenttrail/SKILL.md +6 -1
- package/skills/global_config/aos-project-init/SKILL.md +2 -0
- package/skills/global_config/aos-project-init/assets/AGENTS.template.md +1 -1
- package/skills/global_config/aos-project-init/scripts/aos-project-doctor.mjs +1 -1
- package/skills/global_config/aos-setup/SKILL.md +1 -1
- package/skills/global_config/aos-setup/scripts/aos-doctor.mjs +1 -1
- package/skills/global_config/ask-tim/SKILL.md +7 -7
- package/skills/global_config/bash-script-generator/SKILL.md +201 -0
- package/skills/global_config/bash-script-generator/assets/templates/standard-template.sh +96 -0
- package/skills/global_config/bash-script-generator/docs/bash-scripting-guide.md +729 -0
- package/skills/global_config/bash-script-generator/docs/generation-best-practices.md +193 -0
- package/skills/global_config/bash-script-generator/docs/script-patterns.md +566 -0
- package/skills/global_config/bash-script-generator/docs/text-processing-guide.md +437 -0
- package/skills/global_config/bash-script-generator/examples/log-analyzer.sh +92 -0
- package/skills/global_config/bash-script-generator/scripts/generate_script_template.sh +123 -0
- package/skills/global_config/bash-script-generator/scripts/run_ci_checks.sh +172 -0
- package/skills/global_config/bash-script-generator/scripts/test_generator.sh +413 -0
- package/skills/global_config/bash-script-validator/SKILL.md +249 -0
- package/skills/global_config/bash-script-validator/docs/awk-reference.md +449 -0
- package/skills/global_config/bash-script-validator/docs/bash-reference.md +468 -0
- package/skills/global_config/bash-script-validator/docs/common-mistakes.md +623 -0
- package/skills/global_config/bash-script-validator/docs/grep-reference.md +395 -0
- package/skills/global_config/bash-script-validator/docs/regex-reference.md +391 -0
- package/skills/global_config/bash-script-validator/docs/sed-reference.md +454 -0
- package/skills/global_config/bash-script-validator/docs/shell-reference.md +463 -0
- package/skills/global_config/bash-script-validator/docs/shellcheck-reference.md +399 -0
- package/skills/global_config/bash-script-validator/examples/bad-bash.sh +55 -0
- package/skills/global_config/bash-script-validator/examples/bad-shell.sh +54 -0
- package/skills/global_config/bash-script-validator/examples/good-bash.sh +71 -0
- package/skills/global_config/bash-script-validator/examples/good-shell.sh +69 -0
- package/skills/global_config/bash-script-validator/scripts/run_ci_checks.sh +23 -0
- package/skills/global_config/bash-script-validator/scripts/shellcheck_wrapper.sh +174 -0
- package/skills/global_config/bash-script-validator/scripts/test_validate.sh +446 -0
- package/skills/global_config/bash-script-validator/scripts/validate.sh +512 -0
- package/skills/global_config/ci-pipeline/SKILL.md +135 -0
- package/skills/global_config/deja-memory/SKILL.md +3 -1
- package/skills/global_config/dispatching-parallel-agents/SKILL.md +170 -0
- package/skills/global_config/dockerfile-generator/SKILL.md +1038 -0
- package/skills/global_config/dockerfile-generator/examples/example.dockerignore +95 -0
- package/skills/global_config/dockerfile-generator/examples/golang-distroless.Dockerfile +34 -0
- package/skills/global_config/dockerfile-generator/examples/java-springboot.Dockerfile +45 -0
- package/skills/global_config/dockerfile-generator/examples/nextjs-production.Dockerfile +49 -0
- package/skills/global_config/dockerfile-generator/examples/nodejs-multistage.Dockerfile +55 -0
- package/skills/global_config/dockerfile-generator/examples/python-fastapi.Dockerfile +48 -0
- package/skills/global_config/dockerfile-generator/references/language_specific_guides.md +510 -0
- package/skills/global_config/dockerfile-generator/references/multistage_builds.md +570 -0
- package/skills/global_config/dockerfile-generator/references/optimization_patterns.md +492 -0
- package/skills/global_config/dockerfile-generator/references/security_best_practices.md +375 -0
- package/skills/global_config/dockerfile-generator/scripts/generate_dockerignore.sh +199 -0
- package/skills/global_config/dockerfile-generator/scripts/generate_golang.sh +172 -0
- package/skills/global_config/dockerfile-generator/scripts/generate_java.sh +185 -0
- package/skills/global_config/dockerfile-generator/scripts/generate_nodejs.sh +279 -0
- package/skills/global_config/dockerfile-generator/scripts/generate_python.sh +218 -0
- package/skills/global_config/dockerfile-generator/scripts/test_generator.sh +210 -0
- package/skills/global_config/dockerfile-validator/SKILL.md +300 -0
- package/skills/global_config/dockerfile-validator/examples/.dockerignore.example +34 -0
- package/skills/global_config/dockerfile-validator/examples/bad-example.Dockerfile +37 -0
- package/skills/global_config/dockerfile-validator/examples/golang-distroless.Dockerfile +50 -0
- package/skills/global_config/dockerfile-validator/examples/good-example.Dockerfile +52 -0
- package/skills/global_config/dockerfile-validator/examples/python-optimized.Dockerfile +53 -0
- package/skills/global_config/dockerfile-validator/examples/security-issues.Dockerfile +42 -0
- package/skills/global_config/dockerfile-validator/references/docker_best_practices.md +348 -0
- package/skills/global_config/dockerfile-validator/references/optimization_guide.md +473 -0
- package/skills/global_config/dockerfile-validator/references/security_checklist.md +208 -0
- package/skills/global_config/dockerfile-validator/scripts/dockerfile-validate.sh +699 -0
- package/skills/global_config/dockerfile-validator/scripts/test_validate.sh +35 -0
- package/skills/global_config/dockerfile-validator/tests/fixtures/copy-before-yarn-lock-read.Dockerfile +6 -0
- package/skills/global_config/dockerfile-validator/tests/fixtures/copy-before-yarn.Dockerfile +6 -0
- package/skills/global_config/dockerfile-validator/tests/fixtures/from-platform-nonroot.Dockerfile +7 -0
- package/skills/global_config/dockerfile-validator/tests/test_regression.sh +164 -0
- package/skills/global_config/finishing-a-development-branch/SKILL.md +228 -0
- package/skills/global_config/github-actions-generator/SKILL.md +353 -0
- package/skills/global_config/github-actions-generator/assets/templates/action/composite/action.yml +82 -0
- package/skills/global_config/github-actions-generator/assets/templates/action/docker/Dockerfile +25 -0
- package/skills/global_config/github-actions-generator/assets/templates/action/docker/action.yml +42 -0
- package/skills/global_config/github-actions-generator/assets/templates/action/docker/entrypoint.sh +27 -0
- package/skills/global_config/github-actions-generator/assets/templates/action/javascript/action.yml +33 -0
- package/skills/global_config/github-actions-generator/assets/templates/action/javascript/index.js +50 -0
- package/skills/global_config/github-actions-generator/assets/templates/action/javascript/package.json +27 -0
- package/skills/global_config/github-actions-generator/assets/templates/workflow/basic_workflow.yml +242 -0
- package/skills/global_config/github-actions-generator/assets/templates/workflow/reusable_workflow.yml +106 -0
- package/skills/global_config/github-actions-generator/examples/README.md +147 -0
- package/skills/global_config/github-actions-generator/examples/actions/setup-node-cached/action.yml +93 -0
- package/skills/global_config/github-actions-generator/examples/caching/docker-buildkit.yml +256 -0
- package/skills/global_config/github-actions-generator/examples/security/dependency-review.yml +62 -0
- package/skills/global_config/github-actions-generator/examples/security/sbom-attestation.yml +119 -0
- package/skills/global_config/github-actions-generator/examples/triggers/chatops-commands.yml +475 -0
- package/skills/global_config/github-actions-generator/examples/triggers/repository-dispatch.yml +418 -0
- package/skills/global_config/github-actions-generator/examples/triggers/workflow-orchestration.yml +404 -0
- package/skills/global_config/github-actions-generator/examples/workflows/docker-build-push.yml +68 -0
- package/skills/global_config/github-actions-generator/examples/workflows/go-ci.yml +161 -0
- package/skills/global_config/github-actions-generator/examples/workflows/monorepo-ci.yml +340 -0
- package/skills/global_config/github-actions-generator/examples/workflows/multi-environment-deploy.yml +406 -0
- package/skills/global_config/github-actions-generator/examples/workflows/nodejs-ci.yml +122 -0
- package/skills/global_config/github-actions-generator/examples/workflows/python-ci.yml +157 -0
- package/skills/global_config/github-actions-generator/examples/workflows/scheduled-tasks.yml +376 -0
- package/skills/global_config/github-actions-generator/references/advanced-triggers.md +917 -0
- package/skills/global_config/github-actions-generator/references/best-practices.md +755 -0
- package/skills/global_config/github-actions-generator/references/common-actions.md +715 -0
- package/skills/global_config/github-actions-generator/references/custom-actions.md +320 -0
- package/skills/global_config/github-actions-generator/references/expressions-and-contexts.md +688 -0
- package/skills/global_config/github-actions-generator/references/modern-features.md +421 -0
- package/skills/global_config/github-actions-generator/scripts/test_generator.sh +344 -0
- package/skills/global_config/github-actions-templates/SKILL.md +7 -0
- package/skills/global_config/github-actions-validator/SKILL.md +576 -0
- package/skills/global_config/github-actions-validator/examples/README.md +88 -0
- package/skills/global_config/github-actions-validator/examples/outdated-versions.yml +76 -0
- package/skills/global_config/github-actions-validator/examples/valid-ci.yml +79 -0
- package/skills/global_config/github-actions-validator/examples/with-errors.yml +47 -0
- package/skills/global_config/github-actions-validator/references/act_usage.md +233 -0
- package/skills/global_config/github-actions-validator/references/action_versions.md +122 -0
- package/skills/global_config/github-actions-validator/references/actionlint_usage.md +343 -0
- package/skills/global_config/github-actions-validator/references/common_errors.md +512 -0
- package/skills/global_config/github-actions-validator/references/modern_features.md +384 -0
- package/skills/global_config/github-actions-validator/references/runners.md +317 -0
- package/skills/global_config/github-actions-validator/scripts/install_tools.sh +113 -0
- package/skills/global_config/github-actions-validator/scripts/validate_workflow.sh +910 -0
- package/skills/global_config/github-actions-validator/tests/test_validate_workflow.sh +237 -0
- package/skills/global_config/makefile-generator/SKILL.md +614 -0
- package/skills/global_config/makefile-generator/assets/templates/.gitkeep +1 -0
- package/skills/global_config/makefile-generator/docs/makefile-structure.md +530 -0
- package/skills/global_config/makefile-generator/docs/optimization-guide.md +784 -0
- package/skills/global_config/makefile-generator/docs/patterns-guide.md +642 -0
- package/skills/global_config/makefile-generator/docs/security-guide.md +361 -0
- package/skills/global_config/makefile-generator/docs/targets-guide.md +642 -0
- package/skills/global_config/makefile-generator/docs/variables-guide.md +596 -0
- package/skills/global_config/makefile-generator/scripts/add_standard_targets.sh +539 -0
- package/skills/global_config/makefile-generator/scripts/generate_makefile_template.sh +690 -0
- package/skills/global_config/makefile-generator/test/test_helper_scripts.sh +190 -0
- package/skills/global_config/makefile-validator/SKILL.md +244 -0
- package/skills/global_config/makefile-validator/docs/bake-tool.md +1000 -0
- package/skills/global_config/makefile-validator/docs/best-practices.md +858 -0
- package/skills/global_config/makefile-validator/docs/common-mistakes.md +944 -0
- package/skills/global_config/makefile-validator/examples/bad-makefile.mk +77 -0
- package/skills/global_config/makefile-validator/examples/good-makefile.mk +103 -0
- package/skills/global_config/makefile-validator/scripts/test_validate.sh +382 -0
- package/skills/global_config/makefile-validator/scripts/validate_makefile.sh +712 -0
- package/skills/global_config/{MCP_Manage → mcp-manage}/SKILL.md +3 -3
- package/skills/global_config/plan-canvas/SKILL.md +9 -2
- package/skills/global_config/plan-canvas/scripts/lib/plan-canvas/ui.js +10 -2
- package/skills/global_config/plan-canvas/scripts/plan-canvas.js +1 -1
- package/skills/global_config/read-the-damn-docs/SKILL.md +175 -0
- package/skills/global_config/requesting-code-review/SKILL.md +98 -0
- package/skills/global_config/requesting-code-review/code-reviewer.md +198 -0
- package/skills/global_config/using-git-worktrees/SKILL.md +170 -0
- package/skills/global_config/verification-before-completion/SKILL.md +123 -0
- package/skills/global_config/writing-plans/SKILL.md +126 -46
- package/skills/global_config/writing-plans-legacy/SKILL.md +152 -0
- package/.claude/CLAUDE.md +0 -12
- package/mcps/RhinoMCP/docs/content/docs/getting-started/gemini.md +0 -61
- /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 ]]
|