Loading...
Loading...
Best practices for creating self-documenting Makefiles with auto-generated help. Use when creating or modifying Makefiles to ensure they follow conventions for discoverability and maintainability.
npx skill4agent add plinde/claude-plugins makefile-best-practiceshelphelp.DEFAULT_GOAL := helpmakehelp##target-name: ## Description of what this target does
@command here
help: ## Show this help
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)target: ## Description####@ Sectionawk.DEFAULT_GOAL := helphelphelp## Description##.PHONYhelp$(MAKEFILE_LIST)Makefile Audit: <path>
PASS: .DEFAULT_GOAL set to help
PASS: help target exists
FAIL: 3 targets missing ## descriptions: build, test, deploy
WARN: Missing .PHONY for: build, test, clean
Summary: 2 passed, 1 failed, 1 warning~/binSCRIPT_NAME := my-script.sh
INSTALL_DIR := $(HOME)/bin
INSTALL_PATH := $(INSTALL_DIR)/$(SCRIPT_NAME)
SOURCE_PATH := $(CURDIR)/$(SCRIPT_NAME)install: ## Install symlink to ~/bin
@mkdir -p $(INSTALL_DIR)
@if [ -L "$(INSTALL_PATH)" ]; then \
echo "Removing existing symlink..."; \
rm -f "$(INSTALL_PATH)"; \
elif [ -e "$(INSTALL_PATH)" ]; then \
echo "Error: $(INSTALL_PATH) exists and is not a symlink"; \
exit 1; \
fi
@ln -s "$(SOURCE_PATH)" "$(INSTALL_PATH)"
@echo "Installed: $(INSTALL_PATH) -> $(SOURCE_PATH)"uninstall: ## Remove symlink from ~/bin
@if [ -L "$(INSTALL_PATH)" ]; then \
rm -f "$(INSTALL_PATH)"; \
echo "Removed: $(INSTALL_PATH)"; \
elif [ -e "$(INSTALL_PATH)" ]; then \
echo "Error: $(INSTALL_PATH) exists but is not a symlink (not removing)"; \
exit 1; \
else \
echo "Nothing to remove: $(INSTALL_PATH) does not exist"; \
ficheck: ## Check installation status
@echo "Source: $(SOURCE_PATH)"
@if [ -L "$(INSTALL_PATH)" ]; then \
echo "Status: Installed (symlink)"; \
echo "Target: $$(readlink "$(INSTALL_PATH)")"; \
elif [ -e "$(INSTALL_PATH)" ]; then \
echo "Status: Exists but NOT a symlink"; \
else \
echo "Status: Not installed"; \
fimkdir -pinstall: ## Install symlink to ~/bin
@mkdir -p $(INSTALL_DIR)
# ... symlink creation ...
@echo ""
@echo "Add to your shell config:"
@echo " source ~/bin/$(SCRIPT_NAME)"# my-tool Makefile
SCRIPT_NAME := my-tool.sh
INSTALL_DIR := $(HOME)/bin
INSTALL_PATH := $(INSTALL_DIR)/$(SCRIPT_NAME)
SOURCE_PATH := $(CURDIR)/$(SCRIPT_NAME)
.PHONY: help install uninstall check lint test all clean
.DEFAULT_GOAL := help
##@ General
help: ## Show this help message
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
##@ Installation
install: ## Install symlink to ~/bin
@mkdir -p $(INSTALL_DIR)
@if [ -L "$(INSTALL_PATH)" ]; then \
echo "Removing existing symlink..."; \
rm -f "$(INSTALL_PATH)"; \
elif [ -e "$(INSTALL_PATH)" ]; then \
echo "Error: $(INSTALL_PATH) exists and is not a symlink"; \
exit 1; \
fi
@ln -s "$(SOURCE_PATH)" "$(INSTALL_PATH)"
@echo "Installed: $(INSTALL_PATH) -> $(SOURCE_PATH)"
uninstall: ## Remove symlink from ~/bin
@if [ -L "$(INSTALL_PATH)" ]; then \
rm -f "$(INSTALL_PATH)"; \
echo "Removed: $(INSTALL_PATH)"; \
elif [ -e "$(INSTALL_PATH)" ]; then \
echo "Error: $(INSTALL_PATH) exists but is not a symlink (not removing)"; \
exit 1; \
else \
echo "Nothing to remove: $(INSTALL_PATH) does not exist"; \
fi
check: ## Check installation status
@echo "Source: $(SOURCE_PATH)"
@if [ -L "$(INSTALL_PATH)" ]; then \
echo "Status: Installed (symlink)"; \
echo "Target: $$(readlink "$(INSTALL_PATH)")"; \
elif [ -e "$(INSTALL_PATH)" ]; then \
echo "Status: Exists but NOT a symlink"; \
else \
echo "Status: Not installed"; \
fi
##@ Development
lint: ## Run shellcheck on scripts
shellcheck $(SCRIPT_NAME)
test: ## Run tests
./test.sh
# Stubs to satisfy checkmake minphony rule
all: help
clean: uninstall