From cb60d05584ee52625e070259a48ba49a0701ad48 Mon Sep 17 00:00:00 2001 From: daylinmorgan Date: Wed, 28 Sep 2022 15:04:26 +0000 Subject: [PATCH] deploy: 4e57dfe0e30d54fdbc10436c2335c339aaf3f586 --- 404.html | 2 +- examples/check/index.html | 2 +- examples/embedded/index.html | 2 +- examples/index.html | 2 +- examples/recipe-help/index.html | 2 +- index.html | 10 +++++----- search/search_index.json | 2 +- sitemap.xml | 12 ++++++------ sitemap.xml.gz | Bin 250 -> 249 bytes usage/index.html | 2 +- 10 files changed, 18 insertions(+), 18 deletions(-) diff --git a/404.html b/404.html index 0fd6e56..851895b 100644 --- a/404.html +++ b/404.html @@ -9,7 +9,7 @@ - + diff --git a/examples/check/index.html b/examples/check/index.html index 8a7694c..69b2270 100644 --- a/examples/check/index.html +++ b/examples/check/index.html @@ -11,7 +11,7 @@ - + diff --git a/examples/embedded/index.html b/examples/embedded/index.html index aa57574..0f7cde3 100644 --- a/examples/embedded/index.html +++ b/examples/embedded/index.html @@ -11,7 +11,7 @@ - + diff --git a/examples/index.html b/examples/index.html index 543a6e7..57681eb 100644 --- a/examples/index.html +++ b/examples/index.html @@ -11,7 +11,7 @@ - + diff --git a/examples/recipe-help/index.html b/examples/recipe-help/index.html index 7c4e517..88a2059 100644 --- a/examples/recipe-help/index.html +++ b/examples/recipe-help/index.html @@ -11,7 +11,7 @@ - + diff --git a/index.html b/index.html index f8c5dbd..cefc70a 100644 --- a/index.html +++ b/index.html @@ -11,7 +11,7 @@ - + @@ -580,17 +580,17 @@ to add some QOL improvements for your users and fellow maintainers.

Depends on GNU Make, obviously and Python >=3.7, and bash (or zsh).

Wait python?!?!, I'm not pip installing some package just to parse my makefile. -I agree, all you need is one file .task.mk. +I agree, all you need is one file .task.mk. You can automagically include it with just two additional lines to your Makefile (and probably one to your .gitignore) and your good to go.

Setup

You can include this as an optional dependency on your project by adding the below lines to the end of your Makefile. If someone tries to invoke make help it will download .task.mk for them.

-include .task.mk
-$(if $(filter help,$(MAKECMDGOALS)),$(if $(wildcard .task.mk),,.task.mk: ; curl -fsSL https://raw.githubusercontent.com/daylinmorgan/task.mk/v22.9.19/task.mk -o .task.mk))
+$(if $(filter help,$(MAKECMDGOALS)),$(if $(wildcard .task.mk),,.task.mk: ; curl -fsSL https://raw.githubusercontent.com/daylinmorgan/task.mk/v22.9.28/task.mk -o .task.mk))
 

You might also consider making it a consistently downloaded dependency if you plan to use any of it's advanced feature set, by dropping the $(MAKECMDGOALS) check.

-include .task.mk
-$(if $(wildcard .task.mk),,.task.mk: ; curl -fsSL https://raw.githubusercontent.com/daylinmorgan/task.mk/v22.9.19/task.mk -o .task.mk)
+$(if $(wildcard .task.mk),,.task.mk: ; curl -fsSL https://raw.githubusercontent.com/daylinmorgan/task.mk/v22.9.28/task.mk -o .task.mk)
 

Alternatively, you can use the builtin rule _update-task.mk to update to the latest development version.

See Usage to get started running all your tasks. @@ -627,7 +627,7 @@ But like just it's a tool people don't usually already have and it' Last update: - September 21, 2022 + September 28, 2022
Created: diff --git a/search/search_index.json b/search/search_index.json index 3076e0c..5278992 100644 --- a/search/search_index.json +++ b/search/search_index.json @@ -1 +1 @@ -{"config":{"indexing":"full","lang":["en"],"min_search_length":3,"prebuild_index":false,"separator":"[\\s\\-]+"},"docs":[{"location":"","text":"task.mk the task runner for GNU Make you've been missing GNU make is an excellent build tool and the task runner we love to hate, but can't escape. So let's improve the UX to make it the best task runner it can be. Task.mk , is a standalone Makefile you can deploy alongside your own to add some QOL improvements for your users and fellow maintainers. Current Features: ANSI escape code support (including NO_COLOR) formatted help output custom print function confirmation prompt Depends on GNU Make , obviously and Python >=3.7 , and bash (or zsh ). Wait python?!?!, I'm not pip installing some package just to parse my makefile. I agree, all you need is one file .task.mk . You can automagically include it with just two additional lines to your Makefile (and probably one to your .gitignore ) and your good to go. Setup You can include this as an optional dependency on your project by adding the below lines to the end of your Makefile . If someone tries to invoke make help it will download .task.mk for them. -include .task.mk $(if $(filter help,$(MAKECMDGOALS)),$(if $(wildcard .task.mk),,.task.mk : ; curl - fsSL https :// raw . githubusercontent . com / daylinmorgan / task . mk / v 22.9.19/ task . mk - o . task . mk )) You might also consider making it a consistently downloaded dependency if you plan to use any of it's advanced feature set, by dropping the $(MAKECMDGOALS) check. -include .task.mk $(if $(wildcard .task.mk),,.task.mk : ; curl - fsSL https :// raw . githubusercontent . com / daylinmorgan / task . mk / v 22.9.19/ task . mk - o . task . mk ) Alternatively, you can use the builtin rule _update-task.mk to update to the latest development version. See Usage to get started running all your tasks. See Examples for more use cases. Zsh Completions for GNU Make If you use GNU Make with zsh you may want to add the following line to your rc file to allow make to handle the autocomplete. zstyle ':completion::complete:make:*:targets' call-command true Why Make? There are lot of GNU Make alternatives but none have near the same level of ubiquity. This project attaches to make some of the native features of just , a command runner. Just is a great task runner, but it suffers two problems, users probably don't have it installed already, and there is no way to define file specific recipes. Most of my Makefile 's are comprised primarily of handy .PHONY recipes, but I always end up with a few file specific recipes. Another interesting project I've evaluated for these purposes is go-task/task . Task has many of the features of GNU Make and some novel features of it's own. But like just it's a tool people don't usually already have and it's configured using a yaml file. Yaml files can be finicky to work with and and it uses a golang based shell runtime, not your native shell, which might lead to unexpected behavior. Simpler Alternative But I just want a basic help output, surely I don't need python for this... you would be right. Task.mk replaces my old make help recipe boilerplate which may better serve you (so long as you have sed / awk ). ## h, help | show this help .PHONY : help h help h : Makefile @awk -v fill = $( shell sed -n 's/^## \\(.*\\) | .*/\\1/p' $< | wc -L ) \\ 'match($$0,/^## (.*) \\|/,name) && match($$0,/\\| (.*)$$/,help)\\ {printf \"\\033[1;93m%*s\\033[0m | \\033[30m%s\\033[0m\\n\",\\ fill,name[1],help[1];} match($$0,/^### (.*)/,str) \\ {printf \"%*s \\033[30m%s\\033[0m\\n\",fill,\" \",str[1];}' $<","title":"Home"},{"location":"#setup","text":"You can include this as an optional dependency on your project by adding the below lines to the end of your Makefile . If someone tries to invoke make help it will download .task.mk for them. -include .task.mk $(if $(filter help,$(MAKECMDGOALS)),$(if $(wildcard .task.mk),,.task.mk : ; curl - fsSL https :// raw . githubusercontent . com / daylinmorgan / task . mk / v 22.9.19/ task . mk - o . task . mk )) You might also consider making it a consistently downloaded dependency if you plan to use any of it's advanced feature set, by dropping the $(MAKECMDGOALS) check. -include .task.mk $(if $(wildcard .task.mk),,.task.mk : ; curl - fsSL https :// raw . githubusercontent . com / daylinmorgan / task . mk / v 22.9.19/ task . mk - o . task . mk ) Alternatively, you can use the builtin rule _update-task.mk to update to the latest development version. See Usage to get started running all your tasks. See Examples for more use cases.","title":"Setup"},{"location":"#zsh-completions-for-gnu-make","text":"If you use GNU Make with zsh you may want to add the following line to your rc file to allow make to handle the autocomplete. zstyle ':completion::complete:make:*:targets' call-command true","title":"Zsh Completions for GNU Make"},{"location":"#why-make","text":"There are lot of GNU Make alternatives but none have near the same level of ubiquity. This project attaches to make some of the native features of just , a command runner. Just is a great task runner, but it suffers two problems, users probably don't have it installed already, and there is no way to define file specific recipes. Most of my Makefile 's are comprised primarily of handy .PHONY recipes, but I always end up with a few file specific recipes. Another interesting project I've evaluated for these purposes is go-task/task . Task has many of the features of GNU Make and some novel features of it's own. But like just it's a tool people don't usually already have and it's configured using a yaml file. Yaml files can be finicky to work with and and it uses a golang based shell runtime, not your native shell, which might lead to unexpected behavior.","title":"Why Make?"},{"location":"#simpler-alternative","text":"But I just want a basic help output, surely I don't need python for this... you would be right. Task.mk replaces my old make help recipe boilerplate which may better serve you (so long as you have sed / awk ). ## h, help | show this help .PHONY : help h help h : Makefile @awk -v fill = $( shell sed -n 's/^## \\(.*\\) | .*/\\1/p' $< | wc -L ) \\ 'match($$0,/^## (.*) \\|/,name) && match($$0,/\\| (.*)$$/,help)\\ {printf \"\\033[1;93m%*s\\033[0m | \\033[30m%s\\033[0m\\n\",\\ fill,name[1],help[1];} match($$0,/^### (.*)/,str) \\ {printf \"%*s \\033[30m%s\\033[0m\\n\",fill,\" \",str[1];}' $<","title":"Simpler Alternative"},{"location":"usage/","text":"Usage Task.mk will add access to a recipe help (also aliased to h ). In order to use make help to you will need to add some custom comments to your Makefile . Deliberately, I don't get names from recipes themselves. This not only greatly simplifies the parsing but add's some opportunity to customize the output. Such as to document wildcard or redundant recipes. You can place these anywhere, but I recommend adding these notes directly above their relevant recipes. The format is ## | ## build | build the project .PHONY : build build : ... Now when you invoke make help it will parse these and generate your help output. In addition to a generic help output you can expose some configuration settings with make vars . To do so define the variables you'd like to print with PRINT_VARS := VAR1 VAR2 VAR3 . In addition to the help and vars recipes you can use a custom make function to format your text for fancier output. For this there are two options depending on your needs tprint or tprint-sh . ( tprint-sh is for use within a multiline sub-shell that has already been silenced, see the version-check rule of this project's Makefile for an example.) To use tprint you call it with the builtin make call function. It accepts only one argument: an unquoted f-string literal. All strings passed to tprint have access to an object ansi or a for simplicity. This stores ANSI escape codes which can be used to style your text. ## build | compile the source .PHONY : build build : $( call tprint, { a.cyan } Build Starting { a.end } ) ... $( call tprint, { a.green } Build Finished { a.end } ) See this projects make info for more examples of tprint . To see the available colors and formatting(bold,italic,etc.) use the hidden recipe make _print-ansi . Note : Any help commands starting with an underscore will be ignored. To view hidden tasks (or recipes in GNU Make land) you can use make _help . In addition, you can use custom colors using the builtin ansi.custom or ( a.custom ) method. It has two optional arguments fg and bg . Which can be used to specify either an 8-bit color from the 256 colors . Or a tuple/list to define an RBG 24-bit color, for instance a.custom(fg=(5,10,255)) . See this project's make info for an example. Configuration You can quickly customize some of the default behavior of task.mk by overriding the below variables prior to the -include .task.mk . # ---- [config] ---- # HEADER_STYLE ?= b_cyan ACCENT_STYLE ?= b_yellow PARAMS_STYLE ?= $( ACCENT_STYLE ) GOAL_STYLE ?= $( ACCENT_STYLE ) MSG_STYLE ?= faint DIVIDER_STYLE ?= default DIVIDER ?= \u2500 HELP_SEP ?= \u2502 # python f-string literals EPILOG ?= USAGE ?={ ansi. $( HEADER_STYLE ) } usage { ansi.end } : \\n make \\n INHERIT_SHELL ?= To use a custom color for one of the predefined configuration variables specify only the custom method. HEADER_STYLE = custom ( fg = 171 ,bg = 227 ) NOTE : HELP_SEP does not change the argument definitions syntax only the format of make help . Advanced Usage: Embedded Python Scripts You can take advantage of the builtin python script runner and write multi-line python scripts of your own. This is a simple example but a few lines of python in your Makefile may be easier than balancing sub-shells and strung together awk commands. When make expands the function it will take the parameters passed to py and expand them. $(1) is the variable name and $(2) in this case is the implicit pattern from the rule. Pay attention to quotes. If you need to debug your python script, use DEBUG=1 when you run make and it will first print the script that will be piped to python . define list_files_py from pathlib import Path print( \"files in $(2)\" ) print([f.name for f in (Path( \"$(2)\" ).iterdir())]) endef ## list-% | use pathlib.Path to list files list-% : $( call py,list_files_py, $* ) For what it's worth there is also a predefined function for bash (named tbash ) as well should you need to accomplish something similar of more easily embedding your bash script rather than having to escape every line with a backslash. define bash_script figlet task.mk 2>/dev/null || echo 'no figlet : (' echo \"This is from bash\" cat /etc/hostname printf \"%s\\n\" \"$(2)\" endef .PHONY : test - bash test-bash : $( call tbash,bash_script,test bash multiline )","title":"Usage"},{"location":"usage/#usage","text":"Task.mk will add access to a recipe help (also aliased to h ). In order to use make help to you will need to add some custom comments to your Makefile . Deliberately, I don't get names from recipes themselves. This not only greatly simplifies the parsing but add's some opportunity to customize the output. Such as to document wildcard or redundant recipes. You can place these anywhere, but I recommend adding these notes directly above their relevant recipes. The format is ## | ## build | build the project .PHONY : build build : ... Now when you invoke make help it will parse these and generate your help output. In addition to a generic help output you can expose some configuration settings with make vars . To do so define the variables you'd like to print with PRINT_VARS := VAR1 VAR2 VAR3 . In addition to the help and vars recipes you can use a custom make function to format your text for fancier output. For this there are two options depending on your needs tprint or tprint-sh . ( tprint-sh is for use within a multiline sub-shell that has already been silenced, see the version-check rule of this project's Makefile for an example.) To use tprint you call it with the builtin make call function. It accepts only one argument: an unquoted f-string literal. All strings passed to tprint have access to an object ansi or a for simplicity. This stores ANSI escape codes which can be used to style your text. ## build | compile the source .PHONY : build build : $( call tprint, { a.cyan } Build Starting { a.end } ) ... $( call tprint, { a.green } Build Finished { a.end } ) See this projects make info for more examples of tprint . To see the available colors and formatting(bold,italic,etc.) use the hidden recipe make _print-ansi . Note : Any help commands starting with an underscore will be ignored. To view hidden tasks (or recipes in GNU Make land) you can use make _help . In addition, you can use custom colors using the builtin ansi.custom or ( a.custom ) method. It has two optional arguments fg and bg . Which can be used to specify either an 8-bit color from the 256 colors . Or a tuple/list to define an RBG 24-bit color, for instance a.custom(fg=(5,10,255)) . See this project's make info for an example.","title":"Usage"},{"location":"usage/#configuration","text":"You can quickly customize some of the default behavior of task.mk by overriding the below variables prior to the -include .task.mk . # ---- [config] ---- # HEADER_STYLE ?= b_cyan ACCENT_STYLE ?= b_yellow PARAMS_STYLE ?= $( ACCENT_STYLE ) GOAL_STYLE ?= $( ACCENT_STYLE ) MSG_STYLE ?= faint DIVIDER_STYLE ?= default DIVIDER ?= \u2500 HELP_SEP ?= \u2502 # python f-string literals EPILOG ?= USAGE ?={ ansi. $( HEADER_STYLE ) } usage { ansi.end } : \\n make \\n INHERIT_SHELL ?= To use a custom color for one of the predefined configuration variables specify only the custom method. HEADER_STYLE = custom ( fg = 171 ,bg = 227 ) NOTE : HELP_SEP does not change the argument definitions syntax only the format of make help .","title":"Configuration"},{"location":"usage/#advanced-usage-embedded-python-scripts","text":"You can take advantage of the builtin python script runner and write multi-line python scripts of your own. This is a simple example but a few lines of python in your Makefile may be easier than balancing sub-shells and strung together awk commands. When make expands the function it will take the parameters passed to py and expand them. $(1) is the variable name and $(2) in this case is the implicit pattern from the rule. Pay attention to quotes. If you need to debug your python script, use DEBUG=1 when you run make and it will first print the script that will be piped to python . define list_files_py from pathlib import Path print( \"files in $(2)\" ) print([f.name for f in (Path( \"$(2)\" ).iterdir())]) endef ## list-% | use pathlib.Path to list files list-% : $( call py,list_files_py, $* ) For what it's worth there is also a predefined function for bash (named tbash ) as well should you need to accomplish something similar of more easily embedding your bash script rather than having to escape every line with a backslash. define bash_script figlet task.mk 2>/dev/null || echo 'no figlet : (' echo \"This is from bash\" cat /etc/hostname printf \"%s\\n\" \"$(2)\" endef .PHONY : test - bash test-bash : $( call tbash,bash_script,test bash multiline )","title":"Advanced Usage: Embedded Python Scripts"},{"location":"examples/","text":"Examples Confirm Perform a basic confirmation test with the user and exit with error code 1 if input is N/n. Embedded Scripts Use the builtin functions to write multi-line python/bash scripts directly in your Makefile Recipe Help Display the target, docstring and recipe for a given target then exit.","title":"Examples"},{"location":"examples/#examples","text":"Confirm Perform a basic confirmation test with the user and exit with error code 1 if input is N/n. Embedded Scripts Use the builtin functions to write multi-line python/bash scripts directly in your Makefile Recipe Help Display the target, docstring and recipe for a given target then exit.","title":"Examples"},{"location":"examples/check/","text":"Check check.mk ## check | get user confirmation or exit .PHONY : check check : $( call tconfirm,Would you like to proceed? ) @echo \"you said yes!\" define USAGE {a.$(HEADER_STYLE)}usage : { a . end } make interactivity w/ task.mk \\n endef .DEFAULT_GOAL = help include $(shell git rev-parse --show-toplevel)/task.mk","title":"Check"},{"location":"examples/check/#check","text":"check.mk ## check | get user confirmation or exit .PHONY : check check : $( call tconfirm,Would you like to proceed? ) @echo \"you said yes!\" define USAGE {a.$(HEADER_STYLE)}usage : { a . end } make interactivity w/ task.mk \\n endef .DEFAULT_GOAL = help include $(shell git rev-parse --show-toplevel)/task.mk","title":"Check"},{"location":"examples/embedded/","text":"Embedded embedded.mk ### examples of task.mk features | args: --divider --align center --msg-style b_red define list_files_py from pathlib import Path print( \"files in $(2)\" ) print([f.name for f in (Path( \"$(2)\" ).iterdir())]) endef ## list-% | use pathlib.Path to list files ### name the directory in rule (make list-src) | args: --align sep list-% : $( call py,list_files_py, $* ) # dollar signs will always be a problem define bash_script echo \"Is the process running bash? We can check with ps\" ps -o args = -p $$$$ | grep -E -m 1 -o '\\w{0,5}sh' if [ -x \"$(command -v figlet)\" ]; then echo 'no figlet :(' else echo \"What text to figlet? \" read name figlet $$ name fi echo \"the argument below as given in the makefile itself\" echo \"it's expanded before the script is passed to bash\" printf \"%s\\n\" \"$(2)\" endef ## embedded-bash | bash script with pipes and make input .PHONY : embedded - bash embedded-bash : $( call tbash,bash_script,bash multiline is probably working ) define USAGE {a.$(HEADER_STYLE)}usage : { a . end } make examples of embedded scripts in ` { a.magenta } Makefile { a.end } ` endef .DEFAULT_GOAL = help include $(shell git rev-parse --show-toplevel)/task.mk","title":"Embedded"},{"location":"examples/embedded/#embedded","text":"embedded.mk ### examples of task.mk features | args: --divider --align center --msg-style b_red define list_files_py from pathlib import Path print( \"files in $(2)\" ) print([f.name for f in (Path( \"$(2)\" ).iterdir())]) endef ## list-% | use pathlib.Path to list files ### name the directory in rule (make list-src) | args: --align sep list-% : $( call py,list_files_py, $* ) # dollar signs will always be a problem define bash_script echo \"Is the process running bash? We can check with ps\" ps -o args = -p $$$$ | grep -E -m 1 -o '\\w{0,5}sh' if [ -x \"$(command -v figlet)\" ]; then echo 'no figlet :(' else echo \"What text to figlet? \" read name figlet $$ name fi echo \"the argument below as given in the makefile itself\" echo \"it's expanded before the script is passed to bash\" printf \"%s\\n\" \"$(2)\" endef ## embedded-bash | bash script with pipes and make input .PHONY : embedded - bash embedded-bash : $( call tbash,bash_script,bash multiline is probably working ) define USAGE {a.$(HEADER_STYLE)}usage : { a . end } make examples of embedded scripts in ` { a.magenta } Makefile { a.end } ` endef .DEFAULT_GOAL = help include $(shell git rev-parse --show-toplevel)/task.mk","title":"Embedded"},{"location":"examples/recipe-help/","text":"Recipe Help recipe-help.mk ## deps-only | a task/target with dependencies .PHONY : deps - only deps-only : foo ## foo | a dummy rule that depends on the local files .PHONY : foo foo : $( wildcard * ) @echo 'this is a dummy rule' # bar but no docstring .PHONY : bar bar : @echo 'some rule with no help string' define USAGE {a.header}usage : { a . end } make make help endef .DEFAULT_GOAL = help include $(shell git rev-parse --show-toplevel)/task.mk","title":"Recipe Help"},{"location":"examples/recipe-help/#recipe-help","text":"recipe-help.mk ## deps-only | a task/target with dependencies .PHONY : deps - only deps-only : foo ## foo | a dummy rule that depends on the local files .PHONY : foo foo : $( wildcard * ) @echo 'this is a dummy rule' # bar but no docstring .PHONY : bar bar : @echo 'some rule with no help string' define USAGE {a.header}usage : { a . end } make make help endef .DEFAULT_GOAL = help include $(shell git rev-parse --show-toplevel)/task.mk","title":"Recipe Help"}]} \ No newline at end of file +{"config":{"indexing":"full","lang":["en"],"min_search_length":3,"prebuild_index":false,"separator":"[\\s\\-]+"},"docs":[{"location":"","text":"task.mk the task runner for GNU Make you've been missing GNU make is an excellent build tool and the task runner we love to hate, but can't escape. So let's improve the UX to make it the best task runner it can be. Task.mk , is a standalone Makefile you can deploy alongside your own to add some QOL improvements for your users and fellow maintainers. Current Features: ANSI escape code support (including NO_COLOR) formatted help output custom print function confirmation prompt Depends on GNU Make , obviously and Python >=3.7 , and bash (or zsh ). Wait python?!?!, I'm not pip installing some package just to parse my makefile. I agree, all you need is one file .task.mk . You can automagically include it with just two additional lines to your Makefile (and probably one to your .gitignore ) and your good to go. Setup You can include this as an optional dependency on your project by adding the below lines to the end of your Makefile . If someone tries to invoke make help it will download .task.mk for them. -include .task.mk $(if $(filter help,$(MAKECMDGOALS)),$(if $(wildcard .task.mk),,.task.mk : ; curl - fsSL https :// raw . githubusercontent . com / daylinmorgan / task . mk / v 22.9.28/ task . mk - o . task . mk )) You might also consider making it a consistently downloaded dependency if you plan to use any of it's advanced feature set, by dropping the $(MAKECMDGOALS) check. -include .task.mk $(if $(wildcard .task.mk),,.task.mk : ; curl - fsSL https :// raw . githubusercontent . com / daylinmorgan / task . mk / v 22.9.28/ task . mk - o . task . mk ) Alternatively, you can use the builtin rule _update-task.mk to update to the latest development version. See Usage to get started running all your tasks. See Examples for more use cases. Zsh Completions for GNU Make If you use GNU Make with zsh you may want to add the following line to your rc file to allow make to handle the autocomplete. zstyle ':completion::complete:make:*:targets' call-command true Why Make? There are lot of GNU Make alternatives but none have near the same level of ubiquity. This project attaches to make some of the native features of just , a command runner. Just is a great task runner, but it suffers two problems, users probably don't have it installed already, and there is no way to define file specific recipes. Most of my Makefile 's are comprised primarily of handy .PHONY recipes, but I always end up with a few file specific recipes. Another interesting project I've evaluated for these purposes is go-task/task . Task has many of the features of GNU Make and some novel features of it's own. But like just it's a tool people don't usually already have and it's configured using a yaml file. Yaml files can be finicky to work with and and it uses a golang based shell runtime, not your native shell, which might lead to unexpected behavior. Simpler Alternative But I just want a basic help output, surely I don't need python for this... you would be right. Task.mk replaces my old make help recipe boilerplate which may better serve you (so long as you have sed / awk ). ## h, help | show this help .PHONY : help h help h : Makefile @awk -v fill = $( shell sed -n 's/^## \\(.*\\) | .*/\\1/p' $< | wc -L ) \\ 'match($$0,/^## (.*) \\|/,name) && match($$0,/\\| (.*)$$/,help)\\ {printf \"\\033[1;93m%*s\\033[0m | \\033[30m%s\\033[0m\\n\",\\ fill,name[1],help[1];} match($$0,/^### (.*)/,str) \\ {printf \"%*s \\033[30m%s\\033[0m\\n\",fill,\" \",str[1];}' $<","title":"Home"},{"location":"#setup","text":"You can include this as an optional dependency on your project by adding the below lines to the end of your Makefile . If someone tries to invoke make help it will download .task.mk for them. -include .task.mk $(if $(filter help,$(MAKECMDGOALS)),$(if $(wildcard .task.mk),,.task.mk : ; curl - fsSL https :// raw . githubusercontent . com / daylinmorgan / task . mk / v 22.9.28/ task . mk - o . task . mk )) You might also consider making it a consistently downloaded dependency if you plan to use any of it's advanced feature set, by dropping the $(MAKECMDGOALS) check. -include .task.mk $(if $(wildcard .task.mk),,.task.mk : ; curl - fsSL https :// raw . githubusercontent . com / daylinmorgan / task . mk / v 22.9.28/ task . mk - o . task . mk ) Alternatively, you can use the builtin rule _update-task.mk to update to the latest development version. See Usage to get started running all your tasks. See Examples for more use cases.","title":"Setup"},{"location":"#zsh-completions-for-gnu-make","text":"If you use GNU Make with zsh you may want to add the following line to your rc file to allow make to handle the autocomplete. zstyle ':completion::complete:make:*:targets' call-command true","title":"Zsh Completions for GNU Make"},{"location":"#why-make","text":"There are lot of GNU Make alternatives but none have near the same level of ubiquity. This project attaches to make some of the native features of just , a command runner. Just is a great task runner, but it suffers two problems, users probably don't have it installed already, and there is no way to define file specific recipes. Most of my Makefile 's are comprised primarily of handy .PHONY recipes, but I always end up with a few file specific recipes. Another interesting project I've evaluated for these purposes is go-task/task . Task has many of the features of GNU Make and some novel features of it's own. But like just it's a tool people don't usually already have and it's configured using a yaml file. Yaml files can be finicky to work with and and it uses a golang based shell runtime, not your native shell, which might lead to unexpected behavior.","title":"Why Make?"},{"location":"#simpler-alternative","text":"But I just want a basic help output, surely I don't need python for this... you would be right. Task.mk replaces my old make help recipe boilerplate which may better serve you (so long as you have sed / awk ). ## h, help | show this help .PHONY : help h help h : Makefile @awk -v fill = $( shell sed -n 's/^## \\(.*\\) | .*/\\1/p' $< | wc -L ) \\ 'match($$0,/^## (.*) \\|/,name) && match($$0,/\\| (.*)$$/,help)\\ {printf \"\\033[1;93m%*s\\033[0m | \\033[30m%s\\033[0m\\n\",\\ fill,name[1],help[1];} match($$0,/^### (.*)/,str) \\ {printf \"%*s \\033[30m%s\\033[0m\\n\",fill,\" \",str[1];}' $<","title":"Simpler Alternative"},{"location":"usage/","text":"Usage Task.mk will add access to a recipe help (also aliased to h ). In order to use make help to you will need to add some custom comments to your Makefile . Deliberately, I don't get names from recipes themselves. This not only greatly simplifies the parsing but add's some opportunity to customize the output. Such as to document wildcard or redundant recipes. You can place these anywhere, but I recommend adding these notes directly above their relevant recipes. The format is ## | ## build | build the project .PHONY : build build : ... Now when you invoke make help it will parse these and generate your help output. In addition to a generic help output you can expose some configuration settings with make vars . To do so define the variables you'd like to print with PRINT_VARS := VAR1 VAR2 VAR3 . In addition to the help and vars recipes you can use a custom make function to format your text for fancier output. For this there are two options depending on your needs tprint or tprint-sh . ( tprint-sh is for use within a multiline sub-shell that has already been silenced, see the version-check rule of this project's Makefile for an example.) To use tprint you call it with the builtin make call function. It accepts only one argument: an unquoted f-string literal. All strings passed to tprint have access to an object ansi or a for simplicity. This stores ANSI escape codes which can be used to style your text. ## build | compile the source .PHONY : build build : $( call tprint, { a.cyan } Build Starting { a.end } ) ... $( call tprint, { a.green } Build Finished { a.end } ) See this projects make info for more examples of tprint . To see the available colors and formatting(bold,italic,etc.) use the hidden recipe make _print-ansi . Note : Any help commands starting with an underscore will be ignored. To view hidden tasks (or recipes in GNU Make land) you can use make _help . In addition, you can use custom colors using the builtin ansi.custom or ( a.custom ) method. It has two optional arguments fg and bg . Which can be used to specify either an 8-bit color from the 256 colors . Or a tuple/list to define an RBG 24-bit color, for instance a.custom(fg=(5,10,255)) . See this project's make info for an example. Configuration You can quickly customize some of the default behavior of task.mk by overriding the below variables prior to the -include .task.mk . # ---- [config] ---- # HEADER_STYLE ?= b_cyan ACCENT_STYLE ?= b_yellow PARAMS_STYLE ?= $( ACCENT_STYLE ) GOAL_STYLE ?= $( ACCENT_STYLE ) MSG_STYLE ?= faint DIVIDER_STYLE ?= default DIVIDER ?= \u2500 HELP_SEP ?= \u2502 # python f-string literals EPILOG ?= USAGE ?={ ansi. $( HEADER_STYLE ) } usage { ansi.end } : \\n make \\n INHERIT_SHELL ?= To use a custom color for one of the predefined configuration variables specify only the custom method. HEADER_STYLE = custom ( fg = 171 ,bg = 227 ) NOTE : HELP_SEP does not change the argument definitions syntax only the format of make help . Advanced Usage: Embedded Python Scripts You can take advantage of the builtin python script runner and write multi-line python scripts of your own. This is a simple example but a few lines of python in your Makefile may be easier than balancing sub-shells and strung together awk commands. When make expands the function it will take the parameters passed to py and expand them. $(1) is the variable name and $(2) in this case is the implicit pattern from the rule. Pay attention to quotes. If you need to debug your python script, use DEBUG=1 when you run make and it will first print the script that will be piped to python . define list_files_py from pathlib import Path print( \"files in $(2)\" ) print([f.name for f in (Path( \"$(2)\" ).iterdir())]) endef ## list-% | use pathlib.Path to list files list-% : $( call py,list_files_py, $* ) For what it's worth there is also a predefined function for bash (named tbash ) as well should you need to accomplish something similar of more easily embedding your bash script rather than having to escape every line with a backslash. define bash_script figlet task.mk 2>/dev/null || echo 'no figlet : (' echo \"This is from bash\" cat /etc/hostname printf \"%s\\n\" \"$(2)\" endef .PHONY : test - bash test-bash : $( call tbash,bash_script,test bash multiline )","title":"Usage"},{"location":"usage/#usage","text":"Task.mk will add access to a recipe help (also aliased to h ). In order to use make help to you will need to add some custom comments to your Makefile . Deliberately, I don't get names from recipes themselves. This not only greatly simplifies the parsing but add's some opportunity to customize the output. Such as to document wildcard or redundant recipes. You can place these anywhere, but I recommend adding these notes directly above their relevant recipes. The format is ## | ## build | build the project .PHONY : build build : ... Now when you invoke make help it will parse these and generate your help output. In addition to a generic help output you can expose some configuration settings with make vars . To do so define the variables you'd like to print with PRINT_VARS := VAR1 VAR2 VAR3 . In addition to the help and vars recipes you can use a custom make function to format your text for fancier output. For this there are two options depending on your needs tprint or tprint-sh . ( tprint-sh is for use within a multiline sub-shell that has already been silenced, see the version-check rule of this project's Makefile for an example.) To use tprint you call it with the builtin make call function. It accepts only one argument: an unquoted f-string literal. All strings passed to tprint have access to an object ansi or a for simplicity. This stores ANSI escape codes which can be used to style your text. ## build | compile the source .PHONY : build build : $( call tprint, { a.cyan } Build Starting { a.end } ) ... $( call tprint, { a.green } Build Finished { a.end } ) See this projects make info for more examples of tprint . To see the available colors and formatting(bold,italic,etc.) use the hidden recipe make _print-ansi . Note : Any help commands starting with an underscore will be ignored. To view hidden tasks (or recipes in GNU Make land) you can use make _help . In addition, you can use custom colors using the builtin ansi.custom or ( a.custom ) method. It has two optional arguments fg and bg . Which can be used to specify either an 8-bit color from the 256 colors . Or a tuple/list to define an RBG 24-bit color, for instance a.custom(fg=(5,10,255)) . See this project's make info for an example.","title":"Usage"},{"location":"usage/#configuration","text":"You can quickly customize some of the default behavior of task.mk by overriding the below variables prior to the -include .task.mk . # ---- [config] ---- # HEADER_STYLE ?= b_cyan ACCENT_STYLE ?= b_yellow PARAMS_STYLE ?= $( ACCENT_STYLE ) GOAL_STYLE ?= $( ACCENT_STYLE ) MSG_STYLE ?= faint DIVIDER_STYLE ?= default DIVIDER ?= \u2500 HELP_SEP ?= \u2502 # python f-string literals EPILOG ?= USAGE ?={ ansi. $( HEADER_STYLE ) } usage { ansi.end } : \\n make \\n INHERIT_SHELL ?= To use a custom color for one of the predefined configuration variables specify only the custom method. HEADER_STYLE = custom ( fg = 171 ,bg = 227 ) NOTE : HELP_SEP does not change the argument definitions syntax only the format of make help .","title":"Configuration"},{"location":"usage/#advanced-usage-embedded-python-scripts","text":"You can take advantage of the builtin python script runner and write multi-line python scripts of your own. This is a simple example but a few lines of python in your Makefile may be easier than balancing sub-shells and strung together awk commands. When make expands the function it will take the parameters passed to py and expand them. $(1) is the variable name and $(2) in this case is the implicit pattern from the rule. Pay attention to quotes. If you need to debug your python script, use DEBUG=1 when you run make and it will first print the script that will be piped to python . define list_files_py from pathlib import Path print( \"files in $(2)\" ) print([f.name for f in (Path( \"$(2)\" ).iterdir())]) endef ## list-% | use pathlib.Path to list files list-% : $( call py,list_files_py, $* ) For what it's worth there is also a predefined function for bash (named tbash ) as well should you need to accomplish something similar of more easily embedding your bash script rather than having to escape every line with a backslash. define bash_script figlet task.mk 2>/dev/null || echo 'no figlet : (' echo \"This is from bash\" cat /etc/hostname printf \"%s\\n\" \"$(2)\" endef .PHONY : test - bash test-bash : $( call tbash,bash_script,test bash multiline )","title":"Advanced Usage: Embedded Python Scripts"},{"location":"examples/","text":"Examples Confirm Perform a basic confirmation test with the user and exit with error code 1 if input is N/n. Embedded Scripts Use the builtin functions to write multi-line python/bash scripts directly in your Makefile Recipe Help Display the target, docstring and recipe for a given target then exit.","title":"Examples"},{"location":"examples/#examples","text":"Confirm Perform a basic confirmation test with the user and exit with error code 1 if input is N/n. Embedded Scripts Use the builtin functions to write multi-line python/bash scripts directly in your Makefile Recipe Help Display the target, docstring and recipe for a given target then exit.","title":"Examples"},{"location":"examples/check/","text":"Check check.mk ## check | get user confirmation or exit .PHONY : check check : $( call tconfirm,Would you like to proceed? ) @echo \"you said yes!\" define USAGE {a.$(HEADER_STYLE)}usage : { a . end } make interactivity w/ task.mk \\n endef .DEFAULT_GOAL = help include $(shell git rev-parse --show-toplevel)/task.mk","title":"Check"},{"location":"examples/check/#check","text":"check.mk ## check | get user confirmation or exit .PHONY : check check : $( call tconfirm,Would you like to proceed? ) @echo \"you said yes!\" define USAGE {a.$(HEADER_STYLE)}usage : { a . end } make interactivity w/ task.mk \\n endef .DEFAULT_GOAL = help include $(shell git rev-parse --show-toplevel)/task.mk","title":"Check"},{"location":"examples/embedded/","text":"Embedded embedded.mk ### examples of task.mk features | args: --divider --align center --msg-style b_red define list_files_py from pathlib import Path print( \"files in $(2)\" ) print([f.name for f in (Path( \"$(2)\" ).iterdir())]) endef ## list-% | use pathlib.Path to list files ### name the directory in rule (make list-src) | args: --align sep list-% : $( call py,list_files_py, $* ) # dollar signs will always be a problem define bash_script echo \"Is the process running bash? We can check with ps\" ps -o args = -p $$$$ | grep -E -m 1 -o '\\w{0,5}sh' if [ -x \"$(command -v figlet)\" ]; then echo 'no figlet :(' else echo \"What text to figlet? \" read name figlet $$ name fi echo \"the argument below as given in the makefile itself\" echo \"it's expanded before the script is passed to bash\" printf \"%s\\n\" \"$(2)\" endef ## embedded-bash | bash script with pipes and make input .PHONY : embedded - bash embedded-bash : $( call tbash,bash_script,bash multiline is probably working ) define USAGE {a.$(HEADER_STYLE)}usage : { a . end } make examples of embedded scripts in ` { a.magenta } Makefile { a.end } ` endef .DEFAULT_GOAL = help include $(shell git rev-parse --show-toplevel)/task.mk","title":"Embedded"},{"location":"examples/embedded/#embedded","text":"embedded.mk ### examples of task.mk features | args: --divider --align center --msg-style b_red define list_files_py from pathlib import Path print( \"files in $(2)\" ) print([f.name for f in (Path( \"$(2)\" ).iterdir())]) endef ## list-% | use pathlib.Path to list files ### name the directory in rule (make list-src) | args: --align sep list-% : $( call py,list_files_py, $* ) # dollar signs will always be a problem define bash_script echo \"Is the process running bash? We can check with ps\" ps -o args = -p $$$$ | grep -E -m 1 -o '\\w{0,5}sh' if [ -x \"$(command -v figlet)\" ]; then echo 'no figlet :(' else echo \"What text to figlet? \" read name figlet $$ name fi echo \"the argument below as given in the makefile itself\" echo \"it's expanded before the script is passed to bash\" printf \"%s\\n\" \"$(2)\" endef ## embedded-bash | bash script with pipes and make input .PHONY : embedded - bash embedded-bash : $( call tbash,bash_script,bash multiline is probably working ) define USAGE {a.$(HEADER_STYLE)}usage : { a . end } make examples of embedded scripts in ` { a.magenta } Makefile { a.end } ` endef .DEFAULT_GOAL = help include $(shell git rev-parse --show-toplevel)/task.mk","title":"Embedded"},{"location":"examples/recipe-help/","text":"Recipe Help recipe-help.mk ## deps-only | a task/target with dependencies .PHONY : deps - only deps-only : foo ## foo | a dummy rule that depends on the local files .PHONY : foo foo : $( wildcard * ) @echo 'this is a dummy rule' # bar but no docstring .PHONY : bar bar : @echo 'some rule with no help string' define USAGE {a.header}usage : { a . end } make make help endef .DEFAULT_GOAL = help include $(shell git rev-parse --show-toplevel)/task.mk","title":"Recipe Help"},{"location":"examples/recipe-help/#recipe-help","text":"recipe-help.mk ## deps-only | a task/target with dependencies .PHONY : deps - only deps-only : foo ## foo | a dummy rule that depends on the local files .PHONY : foo foo : $( wildcard * ) @echo 'this is a dummy rule' # bar but no docstring .PHONY : bar bar : @echo 'some rule with no help string' define USAGE {a.header}usage : { a . end } make make help endef .DEFAULT_GOAL = help include $(shell git rev-parse --show-toplevel)/task.mk","title":"Recipe Help"}]} \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml index 6f8a916..ab92e30 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -2,32 +2,32 @@ https://gh.dayl.in/task.mk/ - 2022-09-25 + 2022-09-28 daily https://gh.dayl.in/task.mk/usage/ - 2022-09-25 + 2022-09-28 daily https://gh.dayl.in/task.mk/examples/ - 2022-09-25 + 2022-09-28 daily https://gh.dayl.in/task.mk/examples/check/ - 2022-09-25 + 2022-09-28 daily https://gh.dayl.in/task.mk/examples/embedded/ - 2022-09-25 + 2022-09-28 daily https://gh.dayl.in/task.mk/examples/recipe-help/ - 2022-09-25 + 2022-09-28 daily \ No newline at end of file diff --git a/sitemap.xml.gz b/sitemap.xml.gz index 54f61c119ae85ee4d59641e6c010058a227bacbb..1a7ecd8c01b6dc380ebf148731504b795b59d85e 100644 GIT binary patch literal 249 zcmVdfWiarS;UcuO?#|gNd5W-KlRr9L zQ5x8!8Qi2#4shFYbvM+sZAI{(pf%`iTV_x;K|6v=|1bJD>em-PjF5mkDg*!kK~;D4 literal 250 zcmVnY11z7VEOPI9iyS{I`L)*VpHLkeRq_yFzb1cl zI-@kONi(?0kUZeF - +