I recently found this article online, that explains how to setup a make help target that will automatically parse the Makefile for comments and display a nicely formatted help command.
It parses:
install: ## Install npm dependencies for the api, admin, and frontend apps
@echo "Installing Node dependencies"
@npm install
install-dev: install ## Install dependencies and prepared development configuration
@./node_modules/.bin/selenium-standalone install
@cp -n ./config/development.js-dist ./config/development.js | true
run-frontend-dev: webpack.PID ## Run the frontend and admin apps in dev (using webpack-dev-server)
Into:
install Install npm dependencies for the api, admin, and frontend apps
install-dev Install dependencies and prepared development configuration
run-frontend-dev Run the frontend and admin apps in dev (using webpack-dev-server)
But for some reason I can't get it working (on OSX at least). With this target:
help: ## Show the help prompt.
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
When I run:
make help
I just get:
$ make help
make: Nothing to be done for `help'.
I've tried all of the different solutions from the comments in the article too, but nothing seems to work. What am I doing wrong?
Also, what would a variation on the script be that would allow comments to be placed on a line before the target, instead of after it. Like so:
# Build the source files with Babel.
build: $(shell find lib)
@rm -rf build
@mkdir -p build
@$(babel) lib $(babel_options)
# Seed the database with fake data.
db-fake:
@$(run) node bin/run-sql fake
Here is the full Makefile in question:
# Options.
DEBUG ?=
SOURCEMAPS ?= true
WATCH ?=
# Variables.
bin = ./node_modules/.bin
tests = $(shell find test/routes -depth 1)
shorthand-tests = $(patsubst test/routes/%.js,test-%,$(tests))
# Binaries.
babel = $(bin)/babel
mocha = $(bin)/mocha
node = node
nodemon = $(bin)/nodemon
run = heroku local:run
# Babel options.
babel_options = \
--out-dir build \
--copy-files
# Sourcemaps?
ifneq ($(SOURCEMAPS),false)
babel_options += --source-maps
endif
# Watch?
ifdef WATCH
babel_options += --watch
endif
# Development?
ifneq ($(NODE_ENV),production)
node = $(nodemon)
endif
# Debug?
ifdef DEBUG
node += debug
mocha += debug
endif
# Default.
default: help ## Default.
# Build the source files with Babel.
build: $(shell find lib) ## Build the source files with Babel.
@rm -rf build
@mkdir -p build
@$(babel) lib $(babel_options)
# Seed the database with fake data.
db-fake: ## Seed the database with fake data.
@$(run) node bin/run-sql fake
# Reset the database, dropping everything and the creating again.
db-reset: ## Reset the database, dropping everything and the creating again.
@$(run) node bin/run-sql drop
@$(run) node bin/run-sql create
# Seed the database with test data.
db-seed: ## Seed the database with test data.
@$(run) node bin/run-sql seed
# Show the help prompt.
help: ## Show the help prompt.
@awk '/^#/{c=substr($0,3);next}c&&/^[[:alpha:]][[:alnum:]_-]+:/{print substr($1,1,index($1,":")),c}1{c=0}' mm.mk | column -s: -t
# Open the PSQL interface.
psql: ## Open the PSQL interface.
@psql contentshq
# Run the development server.
server: ## Run the development server.
@$(run) $(node) bin/api
# Start the local postgres server.
start: ## Start the local postgres server.
@pg_ctl -D /usr/local/var/postgres -l /usr/local/var/postgres/server.log start
# Stop the local postgres server.
stop: ## Stop the local postgres server.
@pg_ctl -D /usr/local/var/postgres stop -s -m fast
# Run all of the tests.
test: ## Run all of the tests.
@$(run) $(mocha) $(tests)
# Run specific route tests.
$(shorthand-tests): ## Run specific route tests.
@$(run) $(mocha) test/routes/$(subst test-,,$@).js
# Watch the source files with Babel.
watch: ## Watch the source files with Babel.
@WATCH=true $(MAKE) build
# Phony targets.
.PHONY: help
.PHONY: test
.PHONY: watch
Here's a little awk script which will handle the case where the comment comes before the target name. I used column to put the text into columns, but you could do it in awk using a printf (and, if you wanted, adding the console codes to colorize the output); the advantage of using column is that it works out the column width automatically.
You'd insert it into the Makefile in the same way:
.PHONY: help
# Show this help.
help:
@awk '/^#/{c=substr($$0,3);next}c&&/^[[:alpha:]][[:alnum:]_-]+:/{print substr($$1,1,index($$1,":")),c}1{c=0}' $(MAKEFILE_LIST) | column -s: -t
You need a help rule that will actually extract and print the messages. Assuming the article you're talking about is http://marmelab.com/blog/2016/02/29/auto-documented-makefile.html, this is what you're looking for.
.PHONY: help
help:
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
Your docs before the command approach might be doable but will require some more work. Most UNIX commands work line by line so it's easier to do with the comments as specified in the article.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With