最近蠻常用 Makefile 的,想說寫一個 help 選項,這樣就不用要使用時都要打開 Makefile 看怎麼用,意外查到可以使用小技巧來印出 help。達到註解及文件的效果。
原本可能在寫完所有 rule 後要再加一個 help
來寫準備印出來給使用者的內容。如下:
action1: ## Do action 1.
@printf "Doing action 1..."
action2: ## Do action 2.
@printf "Doing action 2..."
help: ## Show help message.
@printf "Usage:\n"
@printf " make <target>\n\n"
@printf "Targets:\n"
@printf " action1\tDo action 1.\n"
@printf " action2\tDo action 2.\n"
@printf " help\t\tShow help message.\n"
這種方式在數量一多下會很麻煩,尤其是要不斷確認上面是否有被更動。所以找到許多人針對每個 target 的註解去產生 help 資訊。這裡使用 perl 跟 awk 幫忙。
下方印出的結果同上就不貼圖片了。
action1: ## Do action 1.
@printf "Doing action 1..."
action2: ## Do action 2.
@printf "Doing action 2..."
help: ## Show help message.
@printf "Usage:\n"
@printf " make <target>\n\n"
@printf "Targets:\n"
@perl -nle'print $& if m{^[a-zA-Z0-9_-]+:.*?## .*$$}' $(MAKEFILE_LIST) | \
sort | \
awk 'BEGIN {FS = ":.*?## "}; \
{printf " %-18s %s\n", $$1, $$2}'
稍微解釋一下 perl 那一行
首先就是先使用 regexp 去 match 符合的表達式,^[a-zA-Z0-9_-]+:.*?## .*$$
表示由一個單字(可能含數字)開頭 :
後方是相依的部份,最後是用 ##
註解的描述。
接著利用 pipe (|
) 給 awk,它可以針對欄 (column) 去操作文字,BEGIN
區塊表示初始化宣告,也就是輸入的字串是用 ##
當作分割符號,最後利用 printf()
去把第一欄及第二欄印出來。
最後最後,加上點顏色頗不錯 OuO
# color
BLUE = \033[34m
NC = \033[0m
action1: ## Do action 1.
@printf "Doing action 1..."
action2: ## Do action 2.
@printf "Doing action 2..."
help: ## Show help message.
@printf "Usage:\n"
@printf " make $(BLUE)<target>$(NC)\n\n"
@printf "Targets:\n"
@perl -nle'print $& if m{^[a-zA-Z0-9_-]+:.*?## .*$$}' $(MAKEFILE_LIST) | \
sort | \
awk 'BEGIN {FS = ":.*?## "}; \
{printf "$(BLUE) %-18s$(NC) %s\n", $$1, $$2}'