mirror of
https://github.com/daylinmorgan/task.mk.git
synced 2024-12-21 17:40:45 -06:00
docs: update README with explanation
This commit is contained in:
parent
65af033efa
commit
7a23aca580
2 changed files with 304 additions and 13 deletions
189
README.md
189
README.md
|
@ -1,28 +1,191 @@
|
|||
# task.mk
|
||||
<div align="center">
|
||||
<h1 align="center"> task.mk </h1>
|
||||
<img src="./assets/help.svg" alt="help" width=400 >
|
||||
<p align="center">
|
||||
the task runner for GNU Make you've been missing
|
||||
</p>
|
||||
</div>
|
||||
</br>
|
||||
|
||||
GNU make is the task runner we love to hate, but can't escape. So let's improve the UX for users.
|
||||
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.
|
||||
|
||||
So I give you `task.mk`, a standalone makefile you can deploy alongside your own
|
||||
`Makefile`'s to add some QOL improvements for your users and fellow maintainers.
|
||||
`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 Color Support
|
||||
- Formatted Help Screen
|
||||
- Custom print function
|
||||
- ANSI escape code support (including NO_COLOR)
|
||||
- formatted help output
|
||||
- custom print function
|
||||
|
||||
Depends on `GNU Make`, obviously and `Python >=3.7`.
|
||||
|
||||
Wait python?!, I'm not `pip` installing some package just to parse my makefile.
|
||||
Wait python?!?!, I'm not `pip` installing some package just to parse my makefile.
|
||||
I agree, so I've hacked together a file containing the bits of python we need with some tricks to run it.
|
||||
|
||||
## Usage
|
||||
## Setup
|
||||
|
||||
You can include this as an optional dependency on your project by adding the below lines the end of your make file.
|
||||
When your users first your `make help` it will download `task.mk`.
|
||||
If you intend to use any of the other features like `tprint` (see below),
|
||||
I'd recommend committing `.task.mk` into version control so behavior is consistent.
|
||||
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.
|
||||
|
||||
```make
|
||||
-include .task.mk
|
||||
$(if $(filter help,$(MAKECMDGOALS)),.task.mk: ; curl -fsSL https://raw.githubusercontent.com/daylinmorgan/task.mk/22.9.5/task.mk -o .task.mk)
|
||||
```
|
||||
|
||||
If you intend to use any of the other features like `tprint` (see below),
|
||||
I'd recommend committing `.task.mk` into version control so behavior is consistent.
|
||||
|
||||
```bash
|
||||
curl -fsSL https://raw.githubusercontent.com/daylinmorgan/task.mk/22.9.5/task.mk -o .task.mk
|
||||
```
|
||||
|
||||
## 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 `## <recipe> | <msg>`
|
||||
|
||||
```make
|
||||
## build | build the project
|
||||
.PHONY: build
|
||||
build:
|
||||
...
|
||||
```
|
||||
|
||||
Now when you invoke `task.mk` 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.
|
||||
|
||||
```make
|
||||
## 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`.
|
||||
|
||||
## Configuration
|
||||
|
||||
You can quickly customize some of the default behavior of `task.mk` by overriding the below variables prior to the `-include .task.mk`.
|
||||
|
||||
```make
|
||||
# ---- CONFIG ---- #
|
||||
HEADER_COLOR ?= b_cyan
|
||||
PARAMS_COLOR ?= b_magenta
|
||||
ACCENT_COLOR ?= b_yellow
|
||||
GOAL_COLOR ?= $(ACCENT_COLOR)
|
||||
MSG_COLOR ?= faint
|
||||
HELP_SEP ?= |
|
||||
HELP_SORT ?= # sort goals alphabetically
|
||||
|
||||
# python f-string literals
|
||||
EPILOG ?=
|
||||
define USAGE ?=
|
||||
{ansi.$(HEADER_COLOR)}usage{ansi.end}:
|
||||
make <recipe>
|
||||
|
||||
endef
|
||||
```
|
||||
|
||||
**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.
|
||||
`$(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`.
|
||||
|
||||
```make
|
||||
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 '\'.
|
||||
|
||||
```make
|
||||
define bash_script
|
||||
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)
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 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.
|
||||
|
||||
```zsh
|
||||
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 native features of [`just`](https://github.com/casey/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`](https://github.com/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.
|
||||
|
||||
|
||||
```make
|
||||
## h, help | show this help
|
||||
.PHONY: help h
|
||||
help h: Makefile params
|
||||
@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];}' $<
|
||||
```
|
128
assets/help.svg
Normal file
128
assets/help.svg
Normal file
|
@ -0,0 +1,128 @@
|
|||
<svg class="rich-terminal shadow" viewBox="0 0 646.3333333333334 497.13333333333327" xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- Generated with Rich https://www.textualize.io -->
|
||||
<style>
|
||||
@font-face {
|
||||
font-family: "Fira Code";
|
||||
src: local("FiraCode-Regular"),
|
||||
url("https://cdn.jsdelivr.net/gh/ryanoasis/nerd-fonts@2.1.0/patched-fonts/FiraCode/Regular/complete/Fira%20Code%20Regular%20Nerd%20Font%20Complete.ttf") format("truetype");
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Fira Code";
|
||||
src: local("FiraCode-Bold"),
|
||||
url("https://cdn.jsdelivr.net/gh/ryanoasis/nerd-fonts@2.1.0/patched-fonts/FiraCode/Bold/complete/Fira%20Code%20Bold%20Nerd%20Font%20Complete.ttf") format("truetype");
|
||||
font-style: bold;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.terminal-649569392-matrix {
|
||||
font-family: Fira Code, monospace;
|
||||
font-size: 20px;
|
||||
line-height: 24.4px;
|
||||
font-variant-east-asian: full-width;
|
||||
}
|
||||
|
||||
.terminal-649569392-title {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
font-family: arial;
|
||||
}
|
||||
|
||||
.shadow {
|
||||
-webkit-filter: drop-shadow( 2px 5px 2px rgba(0, 0, 0, .7));
|
||||
filter: drop-shadow( 2px 5px 2px rgba(0, 0, 0, .7));
|
||||
}
|
||||
.terminal-649569392-r1 { fill: #94e2d5;font-weight: bold }
|
||||
.terminal-649569392-r2 { fill: #c6d0f5 }
|
||||
.terminal-649569392-r3 { fill: #f5c2e7;font-weight: bold }
|
||||
.terminal-649569392-r4 { fill: #c6d0f5;font-style: italic;;text-decoration: underline; }
|
||||
.terminal-649569392-r5 { fill: #f9e2af;font-weight: bold }
|
||||
.terminal-649569392-r6 { fill: #8288a5 }
|
||||
</style>
|
||||
|
||||
<defs>
|
||||
<clipPath id="terminal-649569392-clip-terminal">
|
||||
<rect x="0" y="0" width="609.0" height="413.79999999999995" />
|
||||
</clipPath>
|
||||
<clipPath id="terminal-649569392-line-0">
|
||||
<rect x="0" y="1.5" width="610" height="24.65"/>
|
||||
</clipPath>
|
||||
<clipPath id="terminal-649569392-line-1">
|
||||
<rect x="0" y="25.9" width="610" height="24.65"/>
|
||||
</clipPath>
|
||||
<clipPath id="terminal-649569392-line-2">
|
||||
<rect x="0" y="50.3" width="610" height="24.65"/>
|
||||
</clipPath>
|
||||
<clipPath id="terminal-649569392-line-3">
|
||||
<rect x="0" y="74.7" width="610" height="24.65"/>
|
||||
</clipPath>
|
||||
<clipPath id="terminal-649569392-line-4">
|
||||
<rect x="0" y="99.1" width="610" height="24.65"/>
|
||||
</clipPath>
|
||||
<clipPath id="terminal-649569392-line-5">
|
||||
<rect x="0" y="123.5" width="610" height="24.65"/>
|
||||
</clipPath>
|
||||
<clipPath id="terminal-649569392-line-6">
|
||||
<rect x="0" y="147.9" width="610" height="24.65"/>
|
||||
</clipPath>
|
||||
<clipPath id="terminal-649569392-line-7">
|
||||
<rect x="0" y="172.3" width="610" height="24.65"/>
|
||||
</clipPath>
|
||||
<clipPath id="terminal-649569392-line-8">
|
||||
<rect x="0" y="196.7" width="610" height="24.65"/>
|
||||
</clipPath>
|
||||
<clipPath id="terminal-649569392-line-9">
|
||||
<rect x="0" y="221.1" width="610" height="24.65"/>
|
||||
</clipPath>
|
||||
<clipPath id="terminal-649569392-line-10">
|
||||
<rect x="0" y="245.5" width="610" height="24.65"/>
|
||||
</clipPath>
|
||||
<clipPath id="terminal-649569392-line-11">
|
||||
<rect x="0" y="269.9" width="610" height="24.65"/>
|
||||
</clipPath>
|
||||
<clipPath id="terminal-649569392-line-12">
|
||||
<rect x="0" y="294.3" width="610" height="24.65"/>
|
||||
</clipPath>
|
||||
<clipPath id="terminal-649569392-line-13">
|
||||
<rect x="0" y="318.7" width="610" height="24.65"/>
|
||||
</clipPath>
|
||||
<clipPath id="terminal-649569392-line-14">
|
||||
<rect x="0" y="343.1" width="610" height="24.65"/>
|
||||
</clipPath>
|
||||
<clipPath id="terminal-649569392-line-15">
|
||||
<rect x="0" y="367.5" width="610" height="24.65"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
|
||||
<rect fill="#1e1e2e" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="10.1667" y="1" width="626" height="462.8" rx="8"/><text class="terminal-649569392-title" fill="#c6d0f5" text-anchor="middle" x="313" y="27">make help</text>
|
||||
<g transform="translate(32,22)">
|
||||
<circle cx="0" cy="0" r="7" fill="#ff5f57"/>
|
||||
<circle cx="22" cy="0" r="7" fill="#febc2e"/>
|
||||
<circle cx="44" cy="0" r="7" fill="#28c840"/>
|
||||
</g>
|
||||
|
||||
<g transform="translate(18.166666666666664, 41) scale(.95)" clip-path="url(#terminal-649569392-clip-terminal)">
|
||||
|
||||
<g class="terminal-649569392-matrix">
|
||||
<text class="terminal-649569392-r1" x="0" y="20" textLength="73.2" clip-path="url(#terminal-649569392-line-0)">usage:</text><text class="terminal-649569392-r2" x="610" y="20" textLength="12.2" clip-path="url(#terminal-649569392-line-0)">
|
||||
</text><text class="terminal-649569392-r2" x="97.6" y="44.4" textLength="158.6" clip-path="url(#terminal-649569392-line-1)">make <recipe></text><text class="terminal-649569392-r2" x="610" y="44.4" textLength="12.2" clip-path="url(#terminal-649569392-line-1)">
|
||||
</text><text class="terminal-649569392-r2" x="610" y="68.8" textLength="12.2" clip-path="url(#terminal-649569392-line-2)">
|
||||
</text><text class="terminal-649569392-r2" x="0" y="93.2" textLength="146.4" clip-path="url(#terminal-649569392-line-3)">  Turn your </text><text class="terminal-649569392-r3" x="146.4" y="93.2" textLength="122" clip-path="url(#terminal-649569392-line-3)">`Makefile`</text><text class="terminal-649569392-r2" x="268.4" y="93.2" textLength="61" clip-path="url(#terminal-649569392-line-3)"> into</text><text class="terminal-649569392-r2" x="610" y="93.2" textLength="12.2" clip-path="url(#terminal-649569392-line-3)">
|
||||
</text><text class="terminal-649569392-r2" x="0" y="117.6" textLength="73.2" clip-path="url(#terminal-649569392-line-4)">  the </text><text class="terminal-649569392-r4" x="73.2" y="117.6" textLength="134.2" clip-path="url(#terminal-649569392-line-4)">task runner</text><text class="terminal-649569392-r2" x="207.4" y="117.6" textLength="231.8" clip-path="url(#terminal-649569392-line-4)"> you always needed.</text><text class="terminal-649569392-r2" x="610" y="117.6" textLength="12.2" clip-path="url(#terminal-649569392-line-4)">
|
||||
</text><text class="terminal-649569392-r2" x="0" y="142" textLength="378.2" clip-path="url(#terminal-649569392-line-5)">  See the example output below.</text><text class="terminal-649569392-r2" x="610" y="142" textLength="12.2" clip-path="url(#terminal-649569392-line-5)">
|
||||
</text><text class="terminal-649569392-r2" x="610" y="166.4" textLength="12.2" clip-path="url(#terminal-649569392-line-6)">
|
||||
</text><text class="terminal-649569392-r5" x="0" y="190.8" textLength="109.8" clip-path="url(#terminal-649569392-line-7)">bootstrap</text><text class="terminal-649569392-r2" x="109.8" y="190.8" textLength="36.6" clip-path="url(#terminal-649569392-line-7)"> | </text><text class="terminal-649569392-r6" x="146.4" y="190.8" textLength="366" clip-path="url(#terminal-649569392-line-7)">generate local dev environment</text><text class="terminal-649569392-r2" x="610" y="190.8" textLength="12.2" clip-path="url(#terminal-649569392-line-7)">
|
||||
</text><text class="terminal-649569392-r5" x="0" y="215.2" textLength="109.8" clip-path="url(#terminal-649569392-line-8)">     lint</text><text class="terminal-649569392-r2" x="109.8" y="215.2" textLength="36.6" clip-path="url(#terminal-649569392-line-8)"> | </text><text class="terminal-649569392-r6" x="146.4" y="215.2" textLength="183" clip-path="url(#terminal-649569392-line-8)">lint the python</text><text class="terminal-649569392-r2" x="610" y="215.2" textLength="12.2" clip-path="url(#terminal-649569392-line-8)">
|
||||
</text><text class="terminal-649569392-r5" x="0" y="239.6" textLength="109.8" clip-path="url(#terminal-649569392-line-9)">   assets</text><text class="terminal-649569392-r2" x="109.8" y="239.6" textLength="36.6" clip-path="url(#terminal-649569392-line-9)"> | </text><text class="terminal-649569392-r6" x="146.4" y="239.6" textLength="183" clip-path="url(#terminal-649569392-line-9)">generate assets</text><text class="terminal-649569392-r2" x="610" y="239.6" textLength="12.2" clip-path="url(#terminal-649569392-line-9)">
|
||||
</text><text class="terminal-649569392-r5" x="0" y="264" textLength="109.8" clip-path="url(#terminal-649569392-line-10)">   list-%</text><text class="terminal-649569392-r2" x="109.8" y="264" textLength="36.6" clip-path="url(#terminal-649569392-line-10)"> | </text><text class="terminal-649569392-r6" x="146.4" y="264" textLength="366" clip-path="url(#terminal-649569392-line-10)">use pathlib.Path to list files</text><text class="terminal-649569392-r2" x="610" y="264" textLength="12.2" clip-path="url(#terminal-649569392-line-10)">
|
||||
</text><text class="terminal-649569392-r5" x="0" y="288.4" textLength="109.8" clip-path="url(#terminal-649569392-line-11)">  release</text><text class="terminal-649569392-r2" x="109.8" y="288.4" textLength="36.6" clip-path="url(#terminal-649569392-line-11)"> | </text><text class="terminal-649569392-r6" x="146.4" y="288.4" textLength="366" clip-path="url(#terminal-649569392-line-11)">release new version of task.mk</text><text class="terminal-649569392-r2" x="610" y="288.4" textLength="12.2" clip-path="url(#terminal-649569392-line-11)">
|
||||
</text><text class="terminal-649569392-r5" x="0" y="312.8" textLength="109.8" clip-path="url(#terminal-649569392-line-12)"> c, clean</text><text class="terminal-649569392-r2" x="109.8" y="312.8" textLength="36.6" clip-path="url(#terminal-649569392-line-12)"> | </text><text class="terminal-649569392-r6" x="146.4" y="312.8" textLength="317.2" clip-path="url(#terminal-649569392-line-12)">remove the generated files</text><text class="terminal-649569392-r2" x="610" y="312.8" textLength="12.2" clip-path="url(#terminal-649569392-line-12)">
|
||||
</text><text class="terminal-649569392-r5" x="0" y="337.2" textLength="109.8" clip-path="url(#terminal-649569392-line-13)">     info</text><text class="terminal-649569392-r2" x="109.8" y="337.2" textLength="36.6" clip-path="url(#terminal-649569392-line-13)"> | </text><text class="terminal-649569392-r6" x="146.4" y="337.2" textLength="329.4" clip-path="url(#terminal-649569392-line-13)">demonsrtate usage of tprint</text><text class="terminal-649569392-r2" x="610" y="337.2" textLength="12.2" clip-path="url(#terminal-649569392-line-13)">
|
||||
</text><text class="terminal-649569392-r5" x="0" y="361.6" textLength="109.8" clip-path="url(#terminal-649569392-line-14)">  h, help</text><text class="terminal-649569392-r2" x="109.8" y="361.6" textLength="36.6" clip-path="url(#terminal-649569392-line-14)"> | </text><text class="terminal-649569392-r6" x="146.4" y="361.6" textLength="170.8" clip-path="url(#terminal-649569392-line-14)">show this help</text><text class="terminal-649569392-r2" x="610" y="361.6" textLength="12.2" clip-path="url(#terminal-649569392-line-14)">
|
||||
</text><text class="terminal-649569392-r2" x="610" y="386" textLength="12.2" clip-path="url(#terminal-649569392-line-15)">
|
||||
</text><text class="terminal-649569392-r2" x="0" y="410.4" textLength="610" clip-path="url(#terminal-649569392-line-16)">for more info: see github.com/daylinmorgan/task.mk</text><text class="terminal-649569392-r2" x="610" y="410.4" textLength="12.2" clip-path="url(#terminal-649569392-line-16)">
|
||||
</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 11 KiB |
Loading…
Reference in a new issue