Skip to content

Instantly share code, notes, and snippets.

@plasticine
Last active August 28, 2019 11:30
Show Gist options
  • Save plasticine/a7d269c26128316f83df29216673b2bf to your computer and use it in GitHub Desktop.
Save plasticine/a7d269c26128316f83df29216673b2bf to your computer and use it in GitHub Desktop.
Automatically extract help from your Makefiles using some fully sick awk hacks
# You're looking at it! :)
help:
@makehelp < $(MAKEFILE_LIST)
.PHONY: help
#!/bin/sh
IFS='' read -r -d '' BANNER <<- "BANNER"
__ __
__ _ ___ _/ /_____ __ _____ / /
/ ' \/ _ `/ '_/ -_) / // / _ \/_/
/_/_/_/\_,_/_/\_\\__/ \_,_/ .__(_)
/_/
BANNER
IFS='' read -r -d '' FILTER <<- "FILTER"
BEGIN {
# Ensure that commentBuffer exists as an array
delete commentBuffer[0]
delete targetHelp[0]
format = "%-20s %s \n\n"
}
# Match targets
/^[^.][a-zA-Z\-\_0-9\.]+:/ {
commentBufferLength = length(commentBuffer)
if (commentBufferLength > 0) {
helpText = commentBuffer[0]
for (i = 1; i <= commentBufferLength; i++) {
line = commentBuffer[i]
if (i > 1)
line = sprintf("%-20s%s", "", commentBuffer[i])
helpText = sprintf("%s %s %-20s", helpText, "\n", line)
gsub(/^[ \n]+/, "", helpText)
gsub(/[ \\n]+$/, "", helpText)
}
gsub(/:$/, "", $$1)
targetHelp[$$1] = helpText
}
}
# Empty comment buffer
!NF {
split("", commentBuffer, ":")
}
# Append comment lines to the buffer...
/^#/ {
sub(/^#.?/, "", $0)
commentBuffer[length(commentBuffer)+1] = $$0;
}
END {
print "Usage:"
print " $ make <target>"
print ""
print ""
printf "%-20s %s\n", "Target name", "Description"
printf "%-20s %s\n", "--------------------", "------------------------------------------------------------"
print ""
for (targetName in targetHelp)
printf(format, targetName, targetHelp[targetName])
print ""
}
FILTER
set -euo pipefail
echo "${BANNER}"
awk "$FILTER" $@
@plasticine
Copy link
Author

plasticine commented May 11, 2018

Dumps out your Makefile help in a helpful way. 😗


              __                   __
  __ _  ___ _/ /_____   __ _____  / /
 /  ' \/ _ `/  '_/ -_) / // / _ \/_/
/_/_/_/\_,_/_/\_\__/  \_,_/ .__(_)
                          /_/

Usage:
  $ make <target>


Target name          Description
-------------------- ------------------------------------------------------------

help                 You're looking at it! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment