mirror of
https://github.com/daylinmorgan/task.mk.git
synced 2024-12-22 10:00:43 -06:00
Compare commits
12 commits
234e3cee35
...
b19ddbae68
Author | SHA1 | Date | |
---|---|---|---|
b19ddbae68 | |||
3cd8b28a58 | |||
43aba3fbee | |||
d6bd8a0247 | |||
401eb1088b | |||
3defee72dc | |||
b75a3c2c98 | |||
63eb8ac754 | |||
bc4c95aab9 | |||
cc81782069 | |||
b1449d8991 | |||
bcb07718fd |
21 changed files with 592 additions and 381 deletions
16
Makefile
16
Makefile
|
@ -1,20 +1,22 @@
|
||||||
VERSION ?= $(shell git describe --tags --always --dirty | sed s'/dirty/dev/')
|
VERSION ?= $(shell git describe --tags --always --dirty | sed s'/dirty/dev/')
|
||||||
TEMPLATES := $(shell find src/ -type f)
|
TEMPLATES := $(shell find src/ -type f)
|
||||||
.DEFAULT_GOAL := help
|
.DEFAULT_GOAL := help
|
||||||
SHELL := /bin/zsh
|
|
||||||
INHERIT_SHELL = true
|
|
||||||
msg = $(if $(tprint),$(call tprint,{a.bold}==> {a.magenta}$(1){a.end}),@echo '==> $(1)')
|
msg = $(if $(tprint),$(call tprint,{a.bold}==> {a.magenta}$(1){a.end}),@echo '==> $(1)')
|
||||||
|
|
||||||
|
|
||||||
### task.mk development | args: -d -ms b_green --align center
|
### task.mk development | args: -d -ms b_green --align center
|
||||||
## bootstrap | generate local dev environment
|
## bootstrap | generate local dev environment
|
||||||
.PHONY: bootstrap
|
.PHONY: bootstrap env hooks
|
||||||
bootstrap:
|
bootstrap: env hooks
|
||||||
$(call msg,Bootstrap Environment)
|
env:
|
||||||
|
$(call msg,Bootstrapping Environment)
|
||||||
@mamba create -p ./env python jinja2 black -y
|
@mamba create -p ./env python jinja2 black -y
|
||||||
@mamba run -p ./env pip install yartsu
|
@mamba run -p ./env pip install yartsu
|
||||||
|
hooks:
|
||||||
@git config core.hooksPath .githooks
|
@git config core.hooksPath .githooks
|
||||||
|
docs-env:
|
||||||
|
@mamba run -p ./env pip install mkdocs-material mkdocs-git-revision-date-localized-plugin
|
||||||
## l, lint | lint the python
|
## l, lint | lint the python
|
||||||
.PHONY: l lint
|
.PHONY: l lint
|
||||||
l lint:
|
l lint:
|
||||||
|
@ -67,7 +69,7 @@ task.mk: $(TEMPLATES) generate.py
|
||||||
./generate.py $(VERSION) > task.mk
|
./generate.py $(VERSION) > task.mk
|
||||||
|
|
||||||
define USAGE
|
define USAGE
|
||||||
{a.$(HEADER_STYLE)}usage:{a.end}\n make <recipe>\n
|
{a.style('usage','header')}:\n make <recipe>\n
|
||||||
Turn your {a.style('`Makefile`','b_magenta')} into
|
Turn your {a.style('`Makefile`','b_magenta')} into
|
||||||
the {a.italic}{a.underline}task runner{a.end} you always needed.
|
the {a.italic}{a.underline}task runner{a.end} you always needed.
|
||||||
See the example output below.\n
|
See the example output below.\n
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
MAKEFLAGS += --no-print-directory
|
MAKEFLAGS += --no-print-directory
|
||||||
COLS ?= 60
|
COLS ?= 60
|
||||||
ROWS ?= 20
|
ROWS ?= 20
|
||||||
EXAMPLES := check embedded
|
EXAMPLES := check embedded recipe-help
|
||||||
CASTS := $(addsuffix /demo.cast, $(EXAMPLES))
|
CASTS := $(addsuffix /demo.cast, $(EXAMPLES))
|
||||||
|
|
||||||
all: $(CASTS)
|
all: $(CASTS)
|
||||||
|
|
|
@ -1,129 +1,84 @@
|
||||||
{"version": 2, "width": 48, "height": 12, "timestamp": 1663712361, "env": {"SHELL": "/usr/bin/zsh", "TERM": "xterm-256color"}}
|
{"version": 2, "width": 48, "height": 12, "timestamp": 1664060067, "env": {"SHELL": "/usr/bin/zsh", "TERM": "xterm-256color"}}
|
||||||
[0.008114, "o", "\u001b[H\u001b[2J\u001b[3J"]
|
[0.008028, "o", "\u001b[H\u001b[2J\u001b[3J"]
|
||||||
[0.00852, "o", "bash >> "]
|
[0.008412, "o", "bash >> "]
|
||||||
[0.008755, "o", "m"]
|
[0.008649, "o", "ma"]
|
||||||
[0.189398, "o", "a"]
|
[0.189116, "o", "ke"]
|
||||||
[0.279744, "o", "k"]
|
[0.279092, "o", " -"]
|
||||||
[0.369775, "o", "e"]
|
[0.369181, "o", "f "]
|
||||||
[0.459919, "o", " -"]
|
[0.459296, "o", "ch"]
|
||||||
[0.549908, "o", "f"]
|
[0.549434, "o", "ec"]
|
||||||
[0.639982, "o", " "]
|
[0.639704, "o", "k/"]
|
||||||
[0.730339, "o", "c"]
|
[0.729786, "o", "ch"]
|
||||||
[0.820338, "o", "h"]
|
[0.81994, "o", "ec"]
|
||||||
[0.910414, "o", "ec"]
|
[0.910178, "o", "k."]
|
||||||
[1.090651, "o", "k"]
|
[1.090415, "o", "mk"]
|
||||||
[1.18077, "o", "/"]
|
[1.180666, "o", " h"]
|
||||||
[1.271098, "o", "c"]
|
[1.270767, "o", "el"]
|
||||||
[1.361098, "o", "h"]
|
[1.360807, "o", "p\r\n"]
|
||||||
[1.451216, "o", "ec"]
|
[2.392643, "o", "\u001b[1;36musage:\u001b[0m\r\n\tmake <recipe>\r\n\t\r\n\tinteractivity w/ task.mk\r\n\r\n\u001b[1;33m check\u001b[0m │ \u001b[2mget user confirmation or exit\u001b[0m\r\n\u001b[1;33m h, help\u001b[0m │ \u001b[2mshow this help\u001b[0m\r\n\r\n"]
|
||||||
[1.541276, "o", "k"]
|
[4.398843, "o", "\u001b[H\u001b[2J\u001b[3J"]
|
||||||
[1.631388, "o", "."]
|
[4.398948, "o", "bash >> "]
|
||||||
[1.721603, "o", "m"]
|
[4.399576, "o", "ma"]
|
||||||
[1.811718, "o", "k"]
|
[4.580421, "o", "ke"]
|
||||||
[1.992079, "o", " h"]
|
[4.670533, "o", " -"]
|
||||||
[2.082138, "o", "e"]
|
[4.760674, "o", "f "]
|
||||||
[2.172379, "o", "l"]
|
[4.850908, "o", "ch"]
|
||||||
[2.262403, "o", "p"]
|
[4.940859, "o", "ec"]
|
||||||
[2.352473, "o", "\r\n"]
|
[5.031095, "o", "k/"]
|
||||||
[3.381969, "o", "\u001b[1;36musage:\u001b[0m\r\n\tmake <recipe>\r\n\t\r\n\tinteractivity w/ task.mk\r\n\r\n\u001b[1;33m check\u001b[0m │ \u001b[2mget user confirmation or exit\u001b[0m\r\n\u001b[1;33m h, help\u001b[0m │ \u001b[2mshow this help\u001b[0m\r\n\r\n"]
|
[5.121228, "o", "ch"]
|
||||||
[5.387545, "o", "\u001b[H\u001b[2J\u001b[3J"]
|
[5.211271, "o", "ec"]
|
||||||
[5.387892, "o", "bash >> "]
|
[5.301383, "o", "k."]
|
||||||
[5.390047, "o", "m"]
|
[5.481587, "o", "mk"]
|
||||||
[5.570645, "o", "a"]
|
[5.571714, "o", " c"]
|
||||||
[5.660579, "o", "k"]
|
[5.662002, "o", "he"]
|
||||||
[5.750852, "o", "e"]
|
[5.752104, "o", "ck"]
|
||||||
[5.841071, "o", " -"]
|
[5.842305, "o", "\r\n"]
|
||||||
[5.931225, "o", "f"]
|
[6.864798, "o", "Would you like to proceed? \u001b[1;31m[Y/n]\u001b[0m "]
|
||||||
[6.021286, "o", " "]
|
[7.488194, "o", "y"]
|
||||||
[6.111373, "o", "c"]
|
[7.830894, "o", "\r\n"]
|
||||||
[6.201586, "o", "h"]
|
[7.836313, "o", "you said yes!\r\n"]
|
||||||
[6.291778, "o", "ec"]
|
[9.840217, "o", "# "]
|
||||||
[6.472054, "o", "k"]
|
[10.020704, "o", "Le"]
|
||||||
[6.562124, "o", "/"]
|
[10.110897, "o", "t'"]
|
||||||
[6.652262, "o", "c"]
|
[10.201077, "o", "s "]
|
||||||
[6.74248, "o", "h"]
|
[10.291171, "o", "tr"]
|
||||||
[6.832675, "o", "ec"]
|
[10.381382, "o", "y "]
|
||||||
[6.922668, "o", "k"]
|
[10.471532, "o", "ag"]
|
||||||
[7.012809, "o", "."]
|
[10.5617, "o", "ai"]
|
||||||
[7.102973, "o", "m"]
|
[10.651984, "o", "n "]
|
||||||
[7.193151, "o", "k"]
|
[10.742177, "o", "bu"]
|
||||||
[7.373458, "o", " c"]
|
[10.922348, "o", "t "]
|
||||||
[7.463783, "o", "h"]
|
[11.012569, "o", "in"]
|
||||||
[7.553761, "o", "e"]
|
[11.102605, "o", "st"]
|
||||||
[7.643931, "o", "c"]
|
[11.192785, "o", "ea"]
|
||||||
[7.734197, "o", "k"]
|
[11.282913, "o", "d "]
|
||||||
[7.824356, "o", "\r\n"]
|
[11.373109, "o", "sa"]
|
||||||
[8.857505, "o", "Would you like to proceed? \u001b[1;31m[Y/n]\u001b[0m "]
|
[11.463146, "o", "y "]
|
||||||
[9.54018, "o", "y"]
|
[11.553266, "o", "no"]
|
||||||
[9.595198, "o", "\r\n"]
|
[11.6436, "o", " t"]
|
||||||
[9.598684, "o", "you said yes!\r\n"]
|
[11.823731, "o", "hi"]
|
||||||
[11.602689, "o", "#"]
|
[11.913841, "o", "s "]
|
||||||
[11.783071, "o", " "]
|
[12.003886, "o", "ti"]
|
||||||
[11.873235, "o", "L"]
|
[12.094101, "o", "me"]
|
||||||
[11.963465, "o", "e"]
|
[12.184197, "o", "\r\n"]
|
||||||
[12.053444, "o", "t'"]
|
[13.185929, "o", "\u001b[H\u001b[2J\u001b[3J"]
|
||||||
[12.143548, "o", "s"]
|
[13.185977, "o", "bash >> "]
|
||||||
[12.233881, "o", " "]
|
[13.186676, "o", "ma"]
|
||||||
[12.323915, "o", "t"]
|
[13.367108, "o", "ke"]
|
||||||
[12.41414, "o", "r"]
|
[13.457234, "o", " -"]
|
||||||
[12.50428, "o", "y "]
|
[13.547276, "o", "f "]
|
||||||
[12.684471, "o", "a"]
|
[13.637696, "o", "ch"]
|
||||||
[12.774773, "o", "g"]
|
[13.727919, "o", "ec"]
|
||||||
[12.864864, "o", "a"]
|
[13.817921, "o", "k/"]
|
||||||
[12.954989, "o", "i"]
|
[13.908217, "o", "ch"]
|
||||||
[13.045011, "o", "n "]
|
[13.998375, "o", "ec"]
|
||||||
[13.135204, "o", "b"]
|
[14.08855, "o", "k."]
|
||||||
[13.225451, "o", "u"]
|
[14.268802, "o", "mk"]
|
||||||
[13.315649, "o", "t"]
|
[14.359106, "o", " c"]
|
||||||
[13.405687, "o", " "]
|
[14.449085, "o", "he"]
|
||||||
[13.585943, "o", "in"]
|
[14.539194, "o", "ck"]
|
||||||
[13.676051, "o", "s"]
|
[14.629387, "o", "\r\n"]
|
||||||
[13.766346, "o", "t"]
|
[15.652945, "o", "Would you like to proceed? \u001b[1;31m[Y/n]\u001b[0m "]
|
||||||
[13.856324, "o", "e"]
|
[16.544875, "o", "n"]
|
||||||
[13.946542, "o", "a"]
|
[17.098374, "o", "\r\n"]
|
||||||
[14.036697, "o", "d "]
|
[17.103306, "o", "make[1]: *** [check/check.mk:4: check] Error 1\r\n"]
|
||||||
[14.126782, "o", "s"]
|
|
||||||
[14.216944, "o", "a"]
|
|
||||||
[14.307128, "o", "y"]
|
|
||||||
[14.487468, "o", " "]
|
|
||||||
[14.577551, "o", "no"]
|
|
||||||
[14.667739, "o", " "]
|
|
||||||
[14.757899, "o", "t"]
|
|
||||||
[14.848007, "o", "h"]
|
|
||||||
[14.93806, "o", "i"]
|
|
||||||
[15.0283, "o", "s "]
|
|
||||||
[15.118379, "o", "t"]
|
|
||||||
[15.208471, "o", "i"]
|
|
||||||
[15.388757, "o", "m"]
|
|
||||||
[15.47897, "o", "e"]
|
|
||||||
[15.569031, "o", "\r\n"]
|
|
||||||
[16.571969, "o", "\u001b[H\u001b[2J\u001b[3J"]
|
|
||||||
[16.572047, "o", "bash >> "]
|
|
||||||
[16.574017, "o", "m"]
|
|
||||||
[16.754499, "o", "a"]
|
|
||||||
[16.844612, "o", "k"]
|
|
||||||
[16.93468, "o", "e"]
|
|
||||||
[17.024972, "o", " -"]
|
|
||||||
[17.115137, "o", "f"]
|
|
||||||
[17.205244, "o", " "]
|
|
||||||
[17.295415, "o", "c"]
|
|
||||||
[17.385554, "o", "h"]
|
|
||||||
[17.475882, "o", "ec"]
|
|
||||||
[17.655989, "o", "k"]
|
|
||||||
[17.746279, "o", "/"]
|
|
||||||
[17.83643, "o", "c"]
|
|
||||||
[17.926644, "o", "h"]
|
|
||||||
[18.016673, "o", "ec"]
|
|
||||||
[18.106718, "o", "k"]
|
|
||||||
[18.197045, "o", "."]
|
|
||||||
[18.287031, "o", "m"]
|
|
||||||
[18.377151, "o", "k"]
|
|
||||||
[18.55735, "o", " c"]
|
|
||||||
[18.647478, "o", "h"]
|
|
||||||
[18.737616, "o", "e"]
|
|
||||||
[18.827879, "o", "c"]
|
|
||||||
[18.917992, "o", "k"]
|
|
||||||
[19.008133, "o", "\r\n"]
|
|
||||||
[20.034923, "o", "Would you like to proceed? \u001b[1;31m[Y/n]\u001b[0m "]
|
|
||||||
[22.08808, "o", "n"]
|
|
||||||
[22.227223, "o", "\r\n"]
|
|
||||||
|
|
|
@ -1,126 +1,83 @@
|
||||||
{"version": 2, "width": 60, "height": 20, "timestamp": 1663712193, "env": {"SHELL": "/usr/bin/zsh", "TERM": "xterm-256color"}}
|
{"version": 2, "width": 60, "height": 20, "timestamp": 1664060088, "env": {"SHELL": "/usr/bin/zsh", "TERM": "xterm-256color"}}
|
||||||
[0.008386, "o", "\u001b[H\u001b[2J\u001b[3J"]
|
[0.008131, "o", "\u001b[H\u001b[2J\u001b[3J"]
|
||||||
[0.008986, "o", "bash >> "]
|
[0.008522, "o", "bash >> "]
|
||||||
[0.009151, "o", "m"]
|
[0.008683, "o", "ma"]
|
||||||
[0.189701, "o", "a"]
|
[0.189166, "o", "ke"]
|
||||||
[0.280162, "o", "k"]
|
[0.279481, "o", " -"]
|
||||||
[0.37038, "o", "e"]
|
[0.369776, "o", "f "]
|
||||||
[0.460683, "o", " -"]
|
[0.460021, "o", "em"]
|
||||||
[0.551001, "o", "f"]
|
[0.550229, "o", "be"]
|
||||||
[0.641267, "o", " "]
|
[0.640359, "o", "dd"]
|
||||||
[0.731609, "o", "e"]
|
[0.730591, "o", "ed"]
|
||||||
[0.821777, "o", "m"]
|
[0.820572, "o", "/e"]
|
||||||
[0.912103, "o", "be"]
|
[0.910745, "o", "mb"]
|
||||||
[1.092658, "o", "d"]
|
[1.091087, "o", "ed"]
|
||||||
[1.182705, "o", "d"]
|
[1.181312, "o", "de"]
|
||||||
[1.273152, "o", "e"]
|
[1.271441, "o", "d."]
|
||||||
[1.363457, "o", "d"]
|
[1.361501, "o", "mk"]
|
||||||
[1.453758, "o", "/e"]
|
[1.451615, "o", " h"]
|
||||||
[1.544059, "o", "m"]
|
[1.541783, "o", "el"]
|
||||||
[1.634282, "o", "b"]
|
[1.63204, "o", "p\r\n"]
|
||||||
[1.724452, "o", "e"]
|
[2.664242, "o", "\u001b[1;36musage:\u001b[0m\r\n\tmake <recipe>\r\n\t\r\n\texamples of embedded scripts in `\u001b[35mMakefile\u001b[0m`\r\n\r\n \u001b[1;31m examples of task.mk features \u001b[0m\r\n\u001b[38m ─────────────────────────────────────────────────────\u001b[0m\r\n\u001b[1;33m list-%\u001b[0m │ \u001b[2muse pathlib.Path to list files\u001b[0m\r\n \u001b[2mname the directory in rule (make list-src)\u001b[0m\r\n\u001b[1;33m embedded-bash\u001b[0m │ \u001b[2mbash script with pipes and make input\u001b[0m\r\n\u001b[1;33m h, help\u001b[0m │ \u001b[2mshow this help\u001b[0m\r\n\r\n"]
|
||||||
[1.814601, "o", "d"]
|
[4.671801, "o", "\u001b[H\u001b[2J\u001b[3Jbash >> "]
|
||||||
[1.995155, "o", "de"]
|
[4.67392, "o", "ma"]
|
||||||
[2.085437, "o", "d"]
|
[4.854455, "o", "ke"]
|
||||||
[2.175546, "o", "."]
|
[4.944728, "o", " -"]
|
||||||
[2.265856, "o", "m"]
|
[5.034921, "o", "f "]
|
||||||
[2.356192, "o", "k"]
|
[5.124982, "o", "em"]
|
||||||
[2.446468, "o", " h"]
|
[5.215103, "o", "be"]
|
||||||
[2.536781, "o", "e"]
|
[5.305188, "o", "dd"]
|
||||||
[2.627101, "o", "l"]
|
[5.395353, "o", "ed"]
|
||||||
[2.717423, "o", "p"]
|
[5.485457, "o", "/e"]
|
||||||
[2.897934, "o", "\r\n"]
|
[5.576246, "o", "mb"]
|
||||||
[3.931131, "o", "\u001b[1;36musage:\u001b[0m\r\n\tmake <recipe>\r\n\t\r\n\texamples of embedded scripts in `\u001b[35mMakefile\u001b[0m`\r\n\r\n \u001b[1;31m examples of task.mk features \u001b[0m\r\n\u001b[38m ─────────────────────────────────────────────────────\u001b[0m\r\n\u001b[1;33m list-%\u001b[0m │ \u001b[2muse pathlib.Path to list files\u001b[0m\r\n \u001b[2mname the directory in rule (make list-src)\u001b[0m\r\n\u001b[1;33m embedded-bash\u001b[0m │ \u001b[2mbash script with pipes and make input\u001b[0m\r\n\u001b[1;33m h, help\u001b[0m │ \u001b[2mshow this help\u001b[0m\r\n\r\n"]
|
[5.75589, "o", "ed"]
|
||||||
[5.936874, "o", "\u001b[H\u001b[2J\u001b[3J"]
|
[5.846014, "o", "de"]
|
||||||
[5.937167, "o", "bash >> "]
|
[5.93612, "o", "d."]
|
||||||
[5.939502, "o", "m"]
|
[6.026298, "o", "mk"]
|
||||||
[6.120169, "o", "a"]
|
[6.11644, "o", " l"]
|
||||||
[6.210505, "o", "k"]
|
[6.206464, "o", "is"]
|
||||||
[6.300671, "o", "e"]
|
[6.296631, "o", "t-"]
|
||||||
[6.390788, "o", " -"]
|
[6.386781, "o", "em"]
|
||||||
[6.480981, "o", "f"]
|
[6.477052, "o", "be"]
|
||||||
[6.571285, "o", " "]
|
[6.657201, "o", "dd"]
|
||||||
[6.661457, "o", "e"]
|
[6.747412, "o", "ed"]
|
||||||
[6.751758, "o", "m"]
|
[6.837566, "o", "\r\n"]
|
||||||
[6.842048, "o", "be"]
|
[7.867599, "o", "files in embedded\r\n['embedded.mk', 'demo.cast', 'record.sh', 'index.md']\r\n"]
|
||||||
[7.022576, "o", "d"]
|
[9.872436, "o", "\u001b[H\u001b[2J\u001b[3J"]
|
||||||
[7.112852, "o", "d"]
|
[9.872754, "o", "bash >> "]
|
||||||
[7.203064, "o", "e"]
|
[9.874651, "o", "ma"]
|
||||||
[7.293421, "o", "d"]
|
[10.055031, "o", "ke"]
|
||||||
[7.383397, "o", "/e"]
|
[10.145171, "o", " -"]
|
||||||
[7.473873, "o", "m"]
|
[10.235256, "o", "f "]
|
||||||
[7.564152, "o", "b"]
|
[10.325347, "o", "em"]
|
||||||
[7.65431, "o", "e"]
|
[10.415525, "o", "be"]
|
||||||
[7.744607, "o", "d"]
|
[10.505721, "o", "dd"]
|
||||||
[7.925168, "o", "de"]
|
[10.595814, "o", "ed"]
|
||||||
[8.015472, "o", "d"]
|
[10.685931, "o", "/e"]
|
||||||
[8.105767, "o", "."]
|
[10.776068, "o", "mb"]
|
||||||
[8.195936, "o", "m"]
|
[10.956362, "o", "ed"]
|
||||||
[8.286184, "o", "k"]
|
[11.046547, "o", "de"]
|
||||||
[8.376537, "o", " l"]
|
[11.136692, "o", "d."]
|
||||||
[8.466624, "o", "i"]
|
[11.226851, "o", "mk"]
|
||||||
[8.557058, "o", "s"]
|
[11.316894, "o", " e"]
|
||||||
[8.64739, "o", "t"]
|
[11.406996, "o", "mb"]
|
||||||
[8.827942, "o", "-"]
|
[11.497205, "o", "ed"]
|
||||||
[8.91803, "o", "em"]
|
[11.58725, "o", "de"]
|
||||||
[9.008446, "o", "b"]
|
[11.677471, "o", "d-"]
|
||||||
[9.098742, "o", "e"]
|
[11.85761, "o", "ba"]
|
||||||
[9.189059, "o", "d"]
|
[11.947917, "o", "sh"]
|
||||||
[9.279328, "o", "d"]
|
[12.038071, "o", "\r\n"]
|
||||||
[9.36965, "o", "ed"]
|
[13.045213, "o", "Is the process running bash? We can check with ps\r\n"]
|
||||||
[9.459574, "o", "\r\n"]
|
[13.051057, "o", "bash\r\n"]
|
||||||
[10.492826, "o", "files in embedded\r\n"]
|
[13.051385, "o", "What text to figlet? \r\n"]
|
||||||
[10.492943, "o", "['embedded.mk', 'demo.cast', 'record.sh', 'index.md']\r\n"]
|
[14.434504, "o", "t"]
|
||||||
[12.498865, "o", "\u001b[H\u001b[2J\u001b[3J"]
|
[14.503239, "o", "a"]
|
||||||
[12.498984, "o", "bash >> "]
|
[14.605384, "o", "s"]
|
||||||
[12.501382, "o", "m"]
|
[14.745978, "o", "k"]
|
||||||
[12.681906, "o", "a"]
|
[14.946139, "o", "."]
|
||||||
[12.7722, "o", "k"]
|
[15.080651, "o", "m"]
|
||||||
[12.862501, "o", "e"]
|
[15.228545, "o", "k"]
|
||||||
[12.952783, "o", " -"]
|
[15.617669, "o", "\r\n"]
|
||||||
[13.043086, "o", "f"]
|
[15.618495, "o", " _ _ _ \r\n| |_ __ _ ___| | __ _ __ ___ | | __\r\n| __/ _` / __| |/ / | '_ ` _ \\| |/ /\r\n| || (_| \\__ \\ < _| | | | | | < \r\n \\__\\__,_|___/_|\\_(_)_| |_| |_|_|\\_\\\r\n \r\n"]
|
||||||
[13.13339, "o", " "]
|
[15.618636, "o", "the argument below as given in the makefile itself\r\n"]
|
||||||
[13.223546, "o", "e"]
|
[15.618695, "o", "it's expanded before the script is passed to bash\r\nbash multiline is probably working\r\n"]
|
||||||
[13.313887, "o", "m"]
|
|
||||||
[13.40413, "o", "be"]
|
|
||||||
[13.584464, "o", "d"]
|
|
||||||
[13.674721, "o", "d"]
|
|
||||||
[13.764931, "o", "e"]
|
|
||||||
[13.855143, "o", "d"]
|
|
||||||
[13.945476, "o", "/e"]
|
|
||||||
[14.035801, "o", "m"]
|
|
||||||
[14.126086, "o", "b"]
|
|
||||||
[14.216402, "o", "e"]
|
|
||||||
[14.306688, "o", "d"]
|
|
||||||
[14.487263, "o", "de"]
|
|
||||||
[14.577566, "o", "d"]
|
|
||||||
[14.667572, "o", "."]
|
|
||||||
[14.757974, "o", "m"]
|
|
||||||
[14.848201, "o", "k"]
|
|
||||||
[14.938383, "o", " e"]
|
|
||||||
[15.02867, "o", "m"]
|
|
||||||
[15.118961, "o", "b"]
|
|
||||||
[15.2091, "o", "e"]
|
|
||||||
[15.38968, "o", "d"]
|
|
||||||
[15.479924, "o", "de"]
|
|
||||||
[15.570276, "o", "d"]
|
|
||||||
[15.66027, "o", "-"]
|
|
||||||
[15.750729, "o", "b"]
|
|
||||||
[15.84091, "o", "a"]
|
|
||||||
[15.931277, "o", "sh"]
|
|
||||||
[16.021429, "o", "\r\n"]
|
|
||||||
[17.044626, "o", "Is the process running bash? We can check with ps\r\n"]
|
|
||||||
[17.063304, "o", "bash\r\n"]
|
|
||||||
[17.063756, "o", "What text to figlet? \r\n"]
|
|
||||||
[20.107984, "o", "t"]
|
|
||||||
[20.125262, "o", "a"]
|
|
||||||
[20.276406, "o", "s"]
|
|
||||||
[20.454083, "o", "k"]
|
|
||||||
[20.705234, "o", "."]
|
|
||||||
[20.931947, "o", "m"]
|
|
||||||
[21.010096, "o", "k"]
|
|
||||||
[21.288327, "o", "\r\n"]
|
|
||||||
[21.292384, "o", " _ _ _ \r\n| |_ __ _ ___| | __ _ __ ___ | | __\r\n| __/ _` / __| |/ / | '_ ` _ \\| |/ /\r\n| || (_| \\__ \\ < _| | | | | | < \r\n \\__\\__,_|___/_|\\_(_)_| |_| |_|_|\\_\\\r\n \r\n"]
|
|
||||||
[21.292754, "o", "the argument below as given in the makefile itself\r\n"]
|
|
||||||
[21.292898, "o", "it's expanded before the script is passed to bash\r\n"]
|
|
||||||
[21.292925, "o", "bash multiline is probably working\r\n"]
|
|
||||||
|
|
|
@ -5,4 +5,5 @@ source "$(dirname "${BASH_SOURCE[0]}")/../functions.sh"
|
||||||
cmd 'make -f embedded/embedded.mk help'
|
cmd 'make -f embedded/embedded.mk help'
|
||||||
cmd 'make -f embedded/embedded.mk list-embedded'
|
cmd 'make -f embedded/embedded.mk list-embedded'
|
||||||
cmd 'make -f embedded/embedded.mk embedded-bash'
|
cmd 'make -f embedded/embedded.mk embedded-bash'
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
msg() {
|
msg() {
|
||||||
printf '%s\n' "$1" | pv -qL 12
|
printf '%s\n' "$1" | pv -qL 20
|
||||||
sleep 1
|
sleep 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
# Examples
|
# Examples
|
||||||
|
|
||||||
|
|
||||||
[`Check`](./check)
|
[Confirm](./check)
|
||||||
|
|
||||||
: Perform a basic confirmation test with the user and exit with error code 1 if input is N/n.
|
: Perform a basic confirmation test with the user and exit with error code 1 if input is N/n.
|
||||||
|
|
||||||
[`Embedded`](./embedded)
|
[Embedded Scripts](./embedded)
|
||||||
|
|
||||||
: Use the builtin functions to write multi-line python/bash scripts directly in your `Makefile`
|
: Use the builtin functions to write multi-line python/bash scripts directly in your `Makefile`
|
||||||
|
|
||||||
|
[Recipe Help](./recipe-help)
|
||||||
|
|
||||||
|
: Display the target, docstring and recipe for a given target then exit.
|
||||||
|
|
138
docs/examples/recipe-help/demo.cast
Normal file
138
docs/examples/recipe-help/demo.cast
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
{"version": 2, "width": 60, "height": 20, "timestamp": 1664060106, "env": {"SHELL": "/usr/bin/zsh", "TERM": "xterm-256color"}}
|
||||||
|
[0.007806, "o", "\u001b[H\u001b[2J\u001b[3J"]
|
||||||
|
[0.008354, "o", "bash >> "]
|
||||||
|
[0.008532, "o", "ma"]
|
||||||
|
[0.189207, "o", "ke"]
|
||||||
|
[0.279458, "o", " -"]
|
||||||
|
[0.369697, "o", "f "]
|
||||||
|
[0.459892, "o", "re"]
|
||||||
|
[0.550111, "o", "ci"]
|
||||||
|
[0.640099, "o", "pe"]
|
||||||
|
[0.730309, "o", "-h"]
|
||||||
|
[0.820408, "o", "el"]
|
||||||
|
[0.910572, "o", "p/"]
|
||||||
|
[1.090837, "o", "re"]
|
||||||
|
[1.180944, "o", "ci"]
|
||||||
|
[1.271024, "o", "pe"]
|
||||||
|
[1.36131, "o", "-h"]
|
||||||
|
[1.451464, "o", "el"]
|
||||||
|
[1.541712, "o", "p."]
|
||||||
|
[1.631676, "o", "mk"]
|
||||||
|
[1.721815, "o", " h"]
|
||||||
|
[1.812133, "o", "el"]
|
||||||
|
[1.99248, "o", "p\r\n"]
|
||||||
|
[3.025715, "o", "\u001b[1;36musage:\u001b[0m\r\n\tmake <recipe>\r\n\tmake help <recipe>\r\n\r\n\u001b[1;33m deps-only\u001b[0m │ \u001b[2ma task/target with dependencies\u001b[0m\r\n\u001b[1;33m foo\u001b[0m │ \u001b[2ma dummy rule that depends on the local files\u001b[0m\r\n\u001b[1;33m h, help\u001b[0m │ \u001b[2mshow this help\u001b[0m\r\n\r\n"]
|
||||||
|
[5.032814, "o", "\u001b[H\u001b[2J\u001b[3Jbash >> "]
|
||||||
|
[5.034705, "o", "ma"]
|
||||||
|
[5.215256, "o", "ke"]
|
||||||
|
[5.305482, "o", " -"]
|
||||||
|
[5.395504, "o", "f "]
|
||||||
|
[5.485805, "o", "re"]
|
||||||
|
[5.576036, "o", "ci"]
|
||||||
|
[5.666095, "o", "pe"]
|
||||||
|
[5.756177, "o", "-h"]
|
||||||
|
[5.846563, "o", "el"]
|
||||||
|
[5.93671, "o", "p/"]
|
||||||
|
[6.11689, "o", "re"]
|
||||||
|
[6.206935, "o", "ci"]
|
||||||
|
[6.297128, "o", "pe"]
|
||||||
|
[6.387205, "o", "-h"]
|
||||||
|
[6.477454, "o", "el"]
|
||||||
|
[6.567496, "o", "p."]
|
||||||
|
[6.657713, "o", "mk"]
|
||||||
|
[6.747729, "o", " h"]
|
||||||
|
[6.838006, "o", "el"]
|
||||||
|
[7.018242, "o", "p "]
|
||||||
|
[7.108261, "o", "he"]
|
||||||
|
[7.198405, "o", "lp"]
|
||||||
|
[7.288809, "o", "\r\n"]
|
||||||
|
[8.318829, "o", "\u001b[1;36mtask.mk recipe help\u001b[0m\r\n\r\n"]
|
||||||
|
[8.325694, "o", " \u001b[1;33mh help\u001b[0m\r\n\u001b[38m ────────────────────────────────────────────────────────\u001b[0m\r\n $(call py,help_py) || { echo \"exiting early!\"; exit 1; }\r\n\r\n"]
|
||||||
|
[8.329695, "o", "exiting early!\r\nmake[1]: *** [/home/daylin/dev/github/mine/task.mk/task.mk:30: help] Error 1\r\n"]
|
||||||
|
[10.332715, "o", "\u001b[H\u001b[2J\u001b[3J"]
|
||||||
|
[10.333056, "o", "bash >> "]
|
||||||
|
[10.335005, "o", "ma"]
|
||||||
|
[10.515605, "o", "ke"]
|
||||||
|
[10.605896, "o", " -"]
|
||||||
|
[10.696226, "o", "f "]
|
||||||
|
[10.78629, "o", "re"]
|
||||||
|
[10.876669, "o", "ci"]
|
||||||
|
[10.966704, "o", "pe"]
|
||||||
|
[11.056858, "o", "-h"]
|
||||||
|
[11.146831, "o", "el"]
|
||||||
|
[11.236969, "o", "p/"]
|
||||||
|
[11.417281, "o", "re"]
|
||||||
|
[11.507468, "o", "ci"]
|
||||||
|
[11.597442, "o", "pe"]
|
||||||
|
[11.687589, "o", "-h"]
|
||||||
|
[11.777832, "o", "el"]
|
||||||
|
[11.867969, "o", "p."]
|
||||||
|
[11.958105, "o", "mk"]
|
||||||
|
[12.048177, "o", " h"]
|
||||||
|
[12.138291, "o", "el"]
|
||||||
|
[12.318676, "o", "p "]
|
||||||
|
[12.408796, "o", "de"]
|
||||||
|
[12.498823, "o", "ps"]
|
||||||
|
[12.588985, "o", "-o"]
|
||||||
|
[12.679133, "o", "nl"]
|
||||||
|
[12.769237, "o", "y\r\n"]
|
||||||
|
[13.807661, "o", "\u001b[1;36mtask.mk recipe help\u001b[0m\r\n\r\n"]
|
||||||
|
[13.816448, "o", "\u001b[1;33m deps-only\u001b[0m │ \u001b[2ma task/target with dependencies\u001b[0m\r\n \u001b[38mdeps\u001b[0m: \u001b[2mfoo\u001b[0m\r\n\r\n"]
|
||||||
|
[13.820255, "o", "exiting early!\r\n"]
|
||||||
|
[13.820461, "o", "make[1]: *** [/home/daylin/dev/github/mine/task.mk/task.mk:30: help] Error 1\r\n"]
|
||||||
|
[15.823763, "o", "\u001b[H\u001b[2J\u001b[3J"]
|
||||||
|
[15.824036, "o", "bash >> "]
|
||||||
|
[15.826016, "o", "ma"]
|
||||||
|
[16.006673, "o", "ke"]
|
||||||
|
[16.09685, "o", " -"]
|
||||||
|
[16.186936, "o", "f "]
|
||||||
|
[16.277228, "o", "re"]
|
||||||
|
[16.367339, "o", "ci"]
|
||||||
|
[16.45744, "o", "pe"]
|
||||||
|
[16.547483, "o", "-h"]
|
||||||
|
[16.637622, "o", "el"]
|
||||||
|
[16.727742, "o", "p/"]
|
||||||
|
[16.907989, "o", "re"]
|
||||||
|
[16.99817, "o", "ci"]
|
||||||
|
[17.088391, "o", "pe"]
|
||||||
|
[17.178352, "o", "-h"]
|
||||||
|
[17.268476, "o", "el"]
|
||||||
|
[17.358766, "o", "p."]
|
||||||
|
[17.448842, "o", "mk"]
|
||||||
|
[17.539039, "o", " h"]
|
||||||
|
[17.629197, "o", "el"]
|
||||||
|
[17.809354, "o", "p "]
|
||||||
|
[17.899578, "o", "fo"]
|
||||||
|
[17.989694, "o", "o\r\n"]
|
||||||
|
[19.020047, "o", "\u001b[1;36mtask.mk recipe help\u001b[0m\r\n\r\n"]
|
||||||
|
[19.03039, "o", "\u001b[1;33m foo\u001b[0m │ \u001b[2ma dummy rule that depends on the local files\u001b[0m\r\n \u001b[38mdeps\u001b[0m: \u001b[2mcheck embedded functions.sh index.md Makefile recipe-help\u001b[0m\r\n\u001b[38m ────────────────────────────\u001b[0m\r\n @echo 'this is a dummy rule'\r\n\r\n"]
|
||||||
|
[19.035496, "o", "exiting early!\r\n"]
|
||||||
|
[19.035706, "o", "make[1]: *** [/home/daylin/dev/github/mine/task.mk/task.mk:30: help] Error 1\r\n"]
|
||||||
|
[21.039168, "o", "\u001b[H\u001b[2J\u001b[3J"]
|
||||||
|
[21.03927, "o", "bash >> "]
|
||||||
|
[21.041378, "o", "ma"]
|
||||||
|
[21.221916, "o", "ke"]
|
||||||
|
[21.31205, "o", " -"]
|
||||||
|
[21.402214, "o", "f "]
|
||||||
|
[21.492482, "o", "re"]
|
||||||
|
[21.582638, "o", "ci"]
|
||||||
|
[21.672609, "o", "pe"]
|
||||||
|
[21.762748, "o", "-h"]
|
||||||
|
[21.853045, "o", "el"]
|
||||||
|
[21.943154, "o", "p/"]
|
||||||
|
[22.123286, "o", "re"]
|
||||||
|
[22.2134, "o", "ci"]
|
||||||
|
[22.303509, "o", "pe"]
|
||||||
|
[22.393685, "o", "-h"]
|
||||||
|
[22.483815, "o", "el"]
|
||||||
|
[22.574005, "o", "p."]
|
||||||
|
[22.664056, "o", "mk"]
|
||||||
|
[22.754229, "o", " h"]
|
||||||
|
[22.844432, "o", "el"]
|
||||||
|
[23.02464, "o", "p "]
|
||||||
|
[23.114692, "o", "ba"]
|
||||||
|
[23.205123, "o", "r\r\n"]
|
||||||
|
[24.260098, "o", "\u001b[1;36mtask.mk recipe help\u001b[0m\r\n\r\n"]
|
||||||
|
[24.267129, "o", " \u001b[1;33mbar\u001b[0m\r\n\u001b[38m ─────────────────────────────────────\u001b[0m\r\n @echo 'some rule with no help string'\r\n\r\n"]
|
||||||
|
[24.271004, "o", "exiting early!\r\n"]
|
||||||
|
[24.271137, "o", "make[1]: *** [/home/daylin/dev/github/mine/task.mk/task.mk:30: help] Error 1\r\n"]
|
12
docs/examples/recipe-help/index.md
Normal file
12
docs/examples/recipe-help/index.md
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
---
|
||||||
|
asciinema: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# Recipe Help
|
||||||
|
|
||||||
|
<div id="demo-cast"></div>
|
||||||
|
|
||||||
|
```make title="recipe-help.mk"
|
||||||
|
--8<-- "docs/examples/recipe-help/recipe-help.mk"
|
||||||
|
```
|
||||||
|
|
24
docs/examples/recipe-help/recipe-help.mk
Normal file
24
docs/examples/recipe-help/recipe-help.mk
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
## 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 <recipe>
|
||||||
|
make help <recipe>
|
||||||
|
|
||||||
|
endef
|
||||||
|
|
||||||
|
.DEFAULT_GOAL = help
|
||||||
|
include $(shell git rev-parse --show-toplevel)/task.mk
|
||||||
|
|
11
docs/examples/recipe-help/record.sh
Executable file
11
docs/examples/recipe-help/record.sh
Executable file
|
@ -0,0 +1,11 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
source "$(dirname "${BASH_SOURCE[0]}")/../functions.sh"
|
||||||
|
|
||||||
|
cmd 'make -f recipe-help/recipe-help.mk help'
|
||||||
|
cmd 'make -f recipe-help/recipe-help.mk help help'
|
||||||
|
cmd 'make -f recipe-help/recipe-help.mk help deps-only'
|
||||||
|
cmd 'make -f recipe-help/recipe-help.mk help foo'
|
||||||
|
cmd 'make -f recipe-help/recipe-help.mk help bar'
|
||||||
|
|
||||||
|
sleep 1
|
|
@ -4,7 +4,14 @@ import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import jinja2
|
import jinja2
|
||||||
|
|
||||||
py_script_names = ["help", "ansi", "info", "print-ansi", "vars", "confirm"]
|
py_script_names = [
|
||||||
|
"help",
|
||||||
|
"info",
|
||||||
|
"print-ansi",
|
||||||
|
"vars",
|
||||||
|
"confirm",
|
||||||
|
"utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def get_jinja_env():
|
def get_jinja_env():
|
||||||
|
|
|
@ -4,17 +4,8 @@ ifeq (help,$(firstword $(MAKECMDGOALS)))
|
||||||
export HELP_ARGS
|
export HELP_ARGS
|
||||||
endif
|
endif
|
||||||
## h, help | show this help
|
## h, help | show this help
|
||||||
ifdef HELP_ARGS
|
|
||||||
help: help-args
|
|
||||||
$(error exiting early)
|
|
||||||
.PHONY: help-args
|
|
||||||
help-args:
|
|
||||||
$(call py,help_py)
|
|
||||||
else
|
|
||||||
.PHONY: help h
|
|
||||||
h help:
|
h help:
|
||||||
$(call py,help_py)
|
$(call py,help_py) || { echo "exiting early!"; exit 1; }
|
||||||
endif
|
|
||||||
.PHONY: _help
|
.PHONY: _help
|
||||||
_help: export SHOW_HIDDEN=true
|
_help: export SHOW_HIDDEN=true
|
||||||
_help: help
|
_help: help
|
||||||
|
@ -38,7 +29,8 @@ tconfirm = $(call py,confirm_py,$(1))
|
||||||
_update-task.mk:
|
_update-task.mk:
|
||||||
$(call tprint,{a.b_cyan}Updating task.mk{a.end})
|
$(call tprint,{a.b_cyan}Updating task.mk{a.end})
|
||||||
curl https://raw.githubusercontent.com/daylinmorgan/task.mk/main/task.mk -o .task.mk
|
curl https://raw.githubusercontent.com/daylinmorgan/task.mk/main/task.mk -o .task.mk
|
||||||
export MAKEFILE_LIST
|
TASK_MAKEFILE_LIST := $(filter-out $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)),$(MAKEFILE_LIST))
|
||||||
|
export MAKEFILE_LIST MAKE TASK_MAKEFILE_LIST
|
||||||
ifndef INHERIT_SHELL
|
ifndef INHERIT_SHELL
|
||||||
SHELL := $(shell which bash)
|
SHELL := $(shell which bash)
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -4,10 +4,11 @@ ACCENT_STYLE ?= b_yellow
|
||||||
PARAMS_STYLE ?= $(ACCENT_STYLE)
|
PARAMS_STYLE ?= $(ACCENT_STYLE)
|
||||||
GOAL_STYLE ?= $(ACCENT_STYLE)
|
GOAL_STYLE ?= $(ACCENT_STYLE)
|
||||||
MSG_STYLE ?= faint
|
MSG_STYLE ?= faint
|
||||||
DIVIDER_STYLE ?= default
|
|
||||||
DIVIDER ?= ─
|
DIVIDER ?= ─
|
||||||
|
DIVIDER_STYLE ?= default
|
||||||
HELP_SEP ?= │
|
HELP_SEP ?= │
|
||||||
|
WRAP ?= 100
|
||||||
# python f-string literals
|
# python f-string literals
|
||||||
EPILOG ?=
|
EPILOG ?=
|
||||||
USAGE ?={ansi.$(HEADER_STYLE)}usage{ansi.end}:\n make <recipe>\n
|
USAGE ?={ansi.header}usage{ansi.end}:\n make <recipe>\n
|
||||||
INHERIT_SHELL ?=
|
INHERIT_SHELL ?=
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
##- '$(ansi_py)' -##
|
##- '$(utils_py)' -##
|
||||||
|
|
||||||
|
|
||||||
def confirm():
|
def confirm():
|
||||||
|
|
78
src/help.py
78
src/help.py
|
@ -5,8 +5,16 @@ import argparse
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
from textwrap import wrap
|
||||||
|
|
||||||
|
##- '$(utils_py)' -##
|
||||||
|
###-
|
||||||
|
# this is just to trick the LSP during development
|
||||||
|
from utils import ansi, cfg
|
||||||
|
# -###
|
||||||
|
|
||||||
##- '$(ansi_py)' -##
|
|
||||||
|
|
||||||
MaxLens = namedtuple("MaxLens", "goal msg")
|
MaxLens = namedtuple("MaxLens", "goal msg")
|
||||||
|
|
||||||
|
@ -28,9 +36,13 @@ def parseargs(argstring):
|
||||||
return parser.parse_args(argstring.split())
|
return parser.parse_args(argstring.split())
|
||||||
|
|
||||||
|
|
||||||
|
def divider(len):
|
||||||
|
return ansi.style(f" {cfg.div*len}", "div_style")
|
||||||
|
|
||||||
|
|
||||||
def gen_makefile():
|
def gen_makefile():
|
||||||
makefile = ""
|
makefile = ""
|
||||||
for file in os.getenv("MAKEFILE_LIST").split():
|
for file in os.getenv("MAKEFILE_LIST", "").split():
|
||||||
with open(file, "r") as f:
|
with open(file, "r") as f:
|
||||||
makefile += f.read() + "\n\n"
|
makefile += f.read() + "\n\n"
|
||||||
return makefile
|
return makefile
|
||||||
|
@ -64,35 +76,61 @@ def recipe_help_header(goal):
|
||||||
item[0].get("msgargs", ""),
|
item[0].get("msgargs", ""),
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
return f" {ansi.style(goal,'$(GOAL_STYLE)')}:"
|
return f" {ansi.style(goal,'goal')}"
|
||||||
|
|
||||||
|
|
||||||
|
def get_goal_deps(goal="task.mk"):
|
||||||
|
make = os.getenv("MAKE", "make")
|
||||||
|
cmd = [make, "-p", "-n", "-i"]
|
||||||
|
for file in os.getenv("TASK_MAKEFILE_LIST", "").split():
|
||||||
|
cmd.extend(["-f", file])
|
||||||
|
database = subprocess.check_output(cmd, universal_newlines=True)
|
||||||
|
dep_pattern = re.compile(r"^" + goal + ":(.*)?")
|
||||||
|
for line in database.splitlines():
|
||||||
|
match = dep_pattern.search(line)
|
||||||
|
if match and match.groups()[0]:
|
||||||
|
return wrap(
|
||||||
|
f"{ansi.style('deps','default')}: {ansi.style(match.groups()[0].strip(),'msg')}",
|
||||||
|
width=cfg.wrap,
|
||||||
|
initial_indent=" ",
|
||||||
|
subsequent_indent=" ",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def parse_goal(file, goal):
|
def parse_goal(file, goal):
|
||||||
goals = goal_pattern.findall(file)
|
goals = goal_pattern.findall(file)
|
||||||
matched_goal = [i for i in goals if goal in i.split()]
|
matched_goal = [i for i in goals if goal in i.split()]
|
||||||
output = []
|
output = []
|
||||||
|
|
||||||
if matched_goal:
|
if matched_goal:
|
||||||
output.append(recipe_help_header(matched_goal[0]))
|
output.append(recipe_help_header(matched_goal[0]))
|
||||||
|
deps = get_goal_deps(matched_goal[0])
|
||||||
|
if deps:
|
||||||
|
output.extend(deps)
|
||||||
lines = file.splitlines()
|
lines = file.splitlines()
|
||||||
loc = [n for n, l in enumerate(lines) if l.startswith(f"{matched_goal[0]}:")][0]
|
loc = [n for n, l in enumerate(lines) if l.startswith(f"{matched_goal[0]}:")][0]
|
||||||
recipe = []
|
recipe = []
|
||||||
|
|
||||||
for line in lines[loc + 1 :]:
|
for line in lines[loc + 1 :]:
|
||||||
if not line.startswith("\t"):
|
if not line.startswith("\t"):
|
||||||
break
|
break
|
||||||
recipe.append(line)
|
recipe.append(f" {line.strip()}")
|
||||||
output.append(divider(max((len(l) for l in recipe)) + 5))
|
output.append(divider(max((len(l.strip()) for l in recipe))))
|
||||||
output.append("\n".join(recipe) + "\n")
|
output.append("\n".join(recipe))
|
||||||
else:
|
else:
|
||||||
output.append(f"{ansi.b_red}ERROR{ansi.end} Failed to find goal: {goal}")
|
deps = get_goal_deps(goal)
|
||||||
|
if deps:
|
||||||
|
output.append(recipe_help_header(goal))
|
||||||
|
output.extend(deps)
|
||||||
|
|
||||||
|
if not output:
|
||||||
|
output.append(f"{ansi.style('ERROR','b_red')}: Failed to find goal: {goal}")
|
||||||
return output
|
return output
|
||||||
|
|
||||||
|
|
||||||
def fmt_goal(goal, msg, max_goal_len, argstr):
|
def fmt_goal(goal, msg, max_goal_len, argstr):
|
||||||
args = parseargs(argstr)
|
args = parseargs(argstr)
|
||||||
goal_style = args.goal_style.strip() if args.goal_style else "$(GOAL_STYLE)"
|
goal_style = args.goal_style.strip() if args.goal_style else "goal"
|
||||||
msg_style = args.msg_style.strip() if args.msg_style else "$(MSG_STYLE)"
|
msg_style = args.msg_style.strip() if args.msg_style else "msg"
|
||||||
return (
|
return (
|
||||||
ansi.style(f" {goal:>{max_goal_len}}", goal_style)
|
ansi.style(f" {goal:>{max_goal_len}}", goal_style)
|
||||||
+ f" $(HELP_SEP) "
|
+ f" $(HELP_SEP) "
|
||||||
|
@ -100,27 +138,23 @@ def fmt_goal(goal, msg, max_goal_len, argstr):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def divider(len):
|
|
||||||
return ansi.style(f" {'$(DIVIDER)'*len}", "$(DIVIDER_STYLE)")
|
|
||||||
|
|
||||||
|
|
||||||
def fmt_rawmsg(msg, argstr, maxlens):
|
def fmt_rawmsg(msg, argstr, maxlens):
|
||||||
args = parseargs(argstr)
|
args = parseargs(argstr)
|
||||||
lines = []
|
lines = []
|
||||||
msg_style = args.msg_style.strip() if args.msg_style else "$(MSG_STYLE)"
|
msg_style = args.msg_style.strip() if args.msg_style else "msg"
|
||||||
if not os.getenv("SHOW_HIDDEN") and args.hidden:
|
if not os.getenv("SHOW_HIDDEN") and args.hidden:
|
||||||
return []
|
return []
|
||||||
if msg:
|
if msg:
|
||||||
if args.align == "sep":
|
if args.align == "sep":
|
||||||
lines.append(
|
lines.append(
|
||||||
f"{' '*(maxlens.goal+len('$(HELP_SEP)')+4)}{ansi.style(msg,msg_style)}"
|
f"{' '*(maxlens.goal+len(cfg.sep)+4)}{ansi.style(msg,msg_style)}"
|
||||||
)
|
)
|
||||||
elif args.align == "center":
|
elif args.align == "center":
|
||||||
lines.append(f" {ansi.style(msg.center(sum(maxlens)),msg_style)}")
|
lines.append(f" {ansi.style(msg.center(sum(maxlens)),msg_style)}")
|
||||||
else:
|
else:
|
||||||
lines.append(f" {ansi.style(msg,msg_style)}")
|
lines.append(f" {ansi.style(msg,msg_style)}")
|
||||||
if args.divider:
|
if args.divider:
|
||||||
lines.append(divider(len("$(HELP_SEP)") + sum(maxlens) + 2))
|
lines.append(divider(len(cfg.sep) + sum(maxlens) + 2))
|
||||||
if args.whitespace:
|
if args.whitespace:
|
||||||
lines.append("\n")
|
lines.append("\n")
|
||||||
|
|
||||||
|
@ -128,7 +162,7 @@ def fmt_rawmsg(msg, argstr, maxlens):
|
||||||
|
|
||||||
|
|
||||||
def print_help():
|
def print_help():
|
||||||
lines = [f"""$(USAGE)"""]
|
lines = [cfg.usage]
|
||||||
|
|
||||||
items = list(parse_help(gen_makefile()))
|
items = list(parse_help(gen_makefile()))
|
||||||
maxlens = MaxLens(
|
maxlens = MaxLens(
|
||||||
|
@ -143,25 +177,27 @@ def print_help():
|
||||||
)
|
)
|
||||||
if "rawmsg" in item:
|
if "rawmsg" in item:
|
||||||
lines.extend(fmt_rawmsg(item["rawmsg"], item.get("rawargs", ""), maxlens))
|
lines.extend(fmt_rawmsg(item["rawmsg"], item.get("rawargs", ""), maxlens))
|
||||||
lines.append(f"""$(EPILOG)""")
|
lines.append(cfg.epilog)
|
||||||
print("\n".join(lines))
|
print("\n".join(lines))
|
||||||
|
|
||||||
|
|
||||||
def print_arg_help(help_args):
|
def print_arg_help(help_args):
|
||||||
|
print(f"{ansi.style('task.mk recipe help','header')}\n")
|
||||||
for arg in help_args.split():
|
for arg in help_args.split():
|
||||||
print(f"{ansi.style('task.mk recipe help','$(HEADER_STYLE)')}\n")
|
|
||||||
print("\n".join(parse_goal(gen_makefile(), arg)))
|
print("\n".join(parse_goal(gen_makefile(), arg)))
|
||||||
|
print()
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
help_args = os.getenv("HELP_ARGS")
|
help_args = os.getenv("HELP_ARGS")
|
||||||
if help_args:
|
if help_args:
|
||||||
print_arg_help(help_args)
|
print_arg_help(help_args)
|
||||||
print(a.faint)
|
sys.exit(1)
|
||||||
else:
|
else:
|
||||||
print_help()
|
print_help()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
||||||
#% endblock %#
|
#% endblock %#
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#% extends "py-script.mk" %#
|
#% extends "py-script.mk" %#
|
||||||
#% block name %#info#% endblock %#
|
#% block name %#info#% endblock %#
|
||||||
#% block script %#
|
#% block script %#
|
||||||
##- '$(ansi_py)' -##
|
##- '$(utils_py)' -##
|
||||||
|
|
||||||
print(f"""$(2)""")
|
print(f"""$(2)""")
|
||||||
#% endblock %#
|
#% endblock %#
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#% extends "py-script.mk" %#
|
#% extends "py-script.mk" %#
|
||||||
#% block name %#print_ansi#% endblock %#
|
#% block name %#print_ansi#% endblock %#
|
||||||
#% block script %#
|
#% block script %#
|
||||||
##- '$(ansi_py)' -##
|
##- '$(utils_py)' -##
|
||||||
sep = f"$(HELP_SEP)"
|
sep = f"$(HELP_SEP)"
|
||||||
codes_names = {getattr(ansi, attr): attr for attr in ansi.__dict__}
|
codes_names = {getattr(ansi, attr): attr for attr in ansi.__dict__}
|
||||||
for code in sorted(codes_names.keys(), key=lambda item: (len(item), item)):
|
for code in sorted(codes_names.keys(), key=lambda item: (len(item), item)):
|
||||||
|
|
|
@ -1,8 +1,19 @@
|
||||||
#% extends "py-script.mk" %#
|
#% extends "py-script.mk" %#
|
||||||
#% block name %#ansi#% endblock %#
|
#% block name %#utils#% endblock %#
|
||||||
#% block script %#
|
#% block script %#
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Config:
|
||||||
|
div: str
|
||||||
|
sep: str
|
||||||
|
epilog: str
|
||||||
|
usage: str
|
||||||
|
wrap: int
|
||||||
|
|
||||||
|
|
||||||
color2byte = dict(
|
color2byte = dict(
|
||||||
black=0,
|
black=0,
|
||||||
|
@ -40,6 +51,7 @@ class Ansi:
|
||||||
)
|
)
|
||||||
for name, byte in state2byte.items():
|
for name, byte in state2byte.items():
|
||||||
self.setcode(name, f"\033[{byte}m")
|
self.setcode(name, f"\033[{byte}m")
|
||||||
|
self.add_cfg()
|
||||||
|
|
||||||
def setcode(self, name, escape_code):
|
def setcode(self, name, escape_code):
|
||||||
"""create attr for style and escape code"""
|
"""create attr for style and escape code"""
|
||||||
|
@ -77,6 +89,18 @@ class Ansi:
|
||||||
|
|
||||||
return code + end
|
return code + end
|
||||||
|
|
||||||
|
def add_cfg(self):
|
||||||
|
cfg_styles = {
|
||||||
|
"header": "$(HEADER_STYLE)",
|
||||||
|
"accent": "$(ACCENT_STYLE)",
|
||||||
|
"params": "$(PARAMS_STYLE)",
|
||||||
|
"goal": "$(GOAL_STYLE)",
|
||||||
|
"msg": "$(MSG_STYLE)",
|
||||||
|
"div_style": "$(DIVIDER_STYLE)",
|
||||||
|
}
|
||||||
|
for name, style in cfg_styles.items():
|
||||||
|
self.setcode(name, getattr(self, style))
|
||||||
|
|
||||||
def style(self, text, style):
|
def style(self, text, style):
|
||||||
if style not in self.__dict__:
|
if style not in self.__dict__:
|
||||||
print(f"unknown style: {style}")
|
print(f"unknown style: {style}")
|
||||||
|
@ -86,4 +110,7 @@ class Ansi:
|
||||||
|
|
||||||
|
|
||||||
a = ansi = Ansi()
|
a = ansi = Ansi()
|
||||||
|
|
||||||
|
cfg = Config(
|
||||||
|
"$(DIVIDER)", "$(HELP_SEP)", f"""$(EPILOG)""", f"""$(USAGE)""",int('$(WRAP)'))
|
||||||
#% endblock %#
|
#% endblock %#
|
|
@ -3,15 +3,15 @@
|
||||||
#% block script %#
|
#% block script %#
|
||||||
import os
|
import os
|
||||||
|
|
||||||
##- '$(ansi_py)' -##
|
##- '$(utils_py)' -##
|
||||||
|
|
||||||
vars = "$2".split()
|
vars = "$2".split()
|
||||||
length = max((len(v) for v in vars))
|
length = max((len(v) for v in vars))
|
||||||
|
|
||||||
print(f"{ansi.$(HEADER_STYLE)}vars:{ansi.end}\n")
|
print(f"{ansi.header}vars{ansi.end}:\n")
|
||||||
|
|
||||||
for v in vars:
|
for v in vars:
|
||||||
print(f" {ansi.b_magenta}{v:<{length}}{ansi.end} = {os.getenv(v)}")
|
print(f" {ansi.params}{v:<{length}}{ansi.end} = {os.getenv(v)}")
|
||||||
|
|
||||||
print()
|
print()
|
||||||
#% endblock %#
|
#% endblock %#
|
||||||
|
|
190
task.mk
190
task.mk
|
@ -1,7 +1,7 @@
|
||||||
# }> [github.com/daylinmorgan/task.mk] <{ #
|
# }> [github.com/daylinmorgan/task.mk] <{ #
|
||||||
# Copyright (c) 2022 Daylin Morgan
|
# Copyright (c) 2022 Daylin Morgan
|
||||||
# MIT License
|
# MIT License
|
||||||
# version: v22.9.19-5-g5f593e3-dev
|
# version: v22.9.19-20-g32110dd
|
||||||
#
|
#
|
||||||
# task.mk should be included at the bottom of your Makefile with `-include .task.mk`
|
# task.mk should be included at the bottom of your Makefile with `-include .task.mk`
|
||||||
# See below for the standard configuration options that should be set prior to including this file.
|
# See below for the standard configuration options that should be set prior to including this file.
|
||||||
|
@ -12,12 +12,13 @@ ACCENT_STYLE ?= b_yellow
|
||||||
PARAMS_STYLE ?= $(ACCENT_STYLE)
|
PARAMS_STYLE ?= $(ACCENT_STYLE)
|
||||||
GOAL_STYLE ?= $(ACCENT_STYLE)
|
GOAL_STYLE ?= $(ACCENT_STYLE)
|
||||||
MSG_STYLE ?= faint
|
MSG_STYLE ?= faint
|
||||||
DIVIDER_STYLE ?= default
|
|
||||||
DIVIDER ?= ─
|
DIVIDER ?= ─
|
||||||
|
DIVIDER_STYLE ?= default
|
||||||
HELP_SEP ?= │
|
HELP_SEP ?= │
|
||||||
|
WRAP ?= 100
|
||||||
# python f-string literals
|
# python f-string literals
|
||||||
EPILOG ?=
|
EPILOG ?=
|
||||||
USAGE ?={ansi.$(HEADER_STYLE)}usage{ansi.end}:\n make <recipe>\n
|
USAGE ?={ansi.header}usage{ansi.end}:\n make <recipe>\n
|
||||||
INHERIT_SHELL ?=
|
INHERIT_SHELL ?=
|
||||||
# ---- [builtin recipes] ---- #
|
# ---- [builtin recipes] ---- #
|
||||||
ifeq (help,$(firstword $(MAKECMDGOALS)))
|
ifeq (help,$(firstword $(MAKECMDGOALS)))
|
||||||
|
@ -25,9 +26,8 @@ ifeq (help,$(firstword $(MAKECMDGOALS)))
|
||||||
export HELP_ARGS
|
export HELP_ARGS
|
||||||
endif
|
endif
|
||||||
## h, help | show this help
|
## h, help | show this help
|
||||||
.PHONY: help h
|
h help:
|
||||||
help h:
|
$(call py,help_py) || { echo "exiting early!"; exit 1; }
|
||||||
$(call py,help_py)
|
|
||||||
.PHONY: _help
|
.PHONY: _help
|
||||||
_help: export SHOW_HIDDEN=true
|
_help: export SHOW_HIDDEN=true
|
||||||
_help: help
|
_help: help
|
||||||
|
@ -51,9 +51,10 @@ tconfirm = $(call py,confirm_py,$(1))
|
||||||
_update-task.mk:
|
_update-task.mk:
|
||||||
$(call tprint,{a.b_cyan}Updating task.mk{a.end})
|
$(call tprint,{a.b_cyan}Updating task.mk{a.end})
|
||||||
curl https://raw.githubusercontent.com/daylinmorgan/task.mk/main/task.mk -o .task.mk
|
curl https://raw.githubusercontent.com/daylinmorgan/task.mk/main/task.mk -o .task.mk
|
||||||
export MAKEFILE_LIST
|
TASK_MAKEFILE_LIST := $(filter-out $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)),$(MAKEFILE_LIST))
|
||||||
|
export MAKEFILE_LIST MAKE TASK_MAKEFILE_LIST
|
||||||
ifndef INHERIT_SHELL
|
ifndef INHERIT_SHELL
|
||||||
SHELL := /bin/bash
|
SHELL := $(shell which bash)
|
||||||
endif
|
endif
|
||||||
# ---- [python/bash script runner] ---- #
|
# ---- [python/bash script runner] ---- #
|
||||||
define _newline
|
define _newline
|
||||||
|
@ -84,8 +85,10 @@ import argparse
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
$(ansi_py)
|
import subprocess
|
||||||
$(quit_make_py)
|
import sys
|
||||||
|
from textwrap import wrap
|
||||||
|
$(utils_py)
|
||||||
MaxLens = namedtuple("MaxLens", "goal msg")
|
MaxLens = namedtuple("MaxLens", "goal msg")
|
||||||
pattern = re.compile(
|
pattern = re.compile(
|
||||||
r"^## (?P<goal>.*?) \| (?P<msg>.*?)(?:\s?\| args: (?P<msgargs>.*?))?$$|^### (?P<rawmsg>.*?)?(?:\s?\| args: (?P<rawargs>.*?))?$$"
|
r"^## (?P<goal>.*?) \| (?P<msg>.*?)(?:\s?\| args: (?P<msgargs>.*?))?$$|^### (?P<rawmsg>.*?)?(?:\s?\| args: (?P<rawargs>.*?))?$$"
|
||||||
|
@ -100,9 +103,11 @@ def parseargs(argstring):
|
||||||
parser.add_argument("-gs", "--goal-style", type=str)
|
parser.add_argument("-gs", "--goal-style", type=str)
|
||||||
parser.add_argument("--hidden", action="store_true")
|
parser.add_argument("--hidden", action="store_true")
|
||||||
return parser.parse_args(argstring.split())
|
return parser.parse_args(argstring.split())
|
||||||
|
def divider(len):
|
||||||
|
return ansi.style(f" {cfg.div*len}", "div_style")
|
||||||
def gen_makefile():
|
def gen_makefile():
|
||||||
makefile = ""
|
makefile = ""
|
||||||
for file in os.getenv("MAKEFILE_LIST").split():
|
for file in os.getenv("MAKEFILE_LIST", "").split():
|
||||||
with open(file, "r") as f:
|
with open(file, "r") as f:
|
||||||
makefile += f.read() + "\n\n"
|
makefile += f.read() + "\n\n"
|
||||||
return makefile
|
return makefile
|
||||||
|
@ -132,58 +137,80 @@ def recipe_help_header(goal):
|
||||||
item[0].get("msgargs", ""),
|
item[0].get("msgargs", ""),
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
return f" {ansi.style(goal,'$(GOAL_STYLE)')}:"
|
return f" {ansi.style(goal,'goal')}"
|
||||||
|
def get_goal_deps(goal="task.mk"):
|
||||||
|
make = os.getenv("MAKE", "make")
|
||||||
|
cmd = [make, "-p", "-n", "-i"]
|
||||||
|
for file in os.getenv("TASK_MAKEFILE_LIST", "").split():
|
||||||
|
cmd.extend(["-f", file])
|
||||||
|
database = subprocess.check_output(cmd, universal_newlines=True)
|
||||||
|
dep_pattern = re.compile(r"^" + goal + ":(.*)?")
|
||||||
|
for line in database.splitlines():
|
||||||
|
match = dep_pattern.search(line)
|
||||||
|
if match and match.groups()[0]:
|
||||||
|
return wrap(
|
||||||
|
f"{ansi.style('deps','default')}: {ansi.style(match.groups()[0].strip(),'msg')}",
|
||||||
|
width=cfg.wrap,
|
||||||
|
initial_indent=" ",
|
||||||
|
subsequent_indent=" ",
|
||||||
|
)
|
||||||
def parse_goal(file, goal):
|
def parse_goal(file, goal):
|
||||||
goals = goal_pattern.findall(file)
|
goals = goal_pattern.findall(file)
|
||||||
matched_goal = [i for i in goals if goal in i.split()]
|
matched_goal = [i for i in goals if goal in i.split()]
|
||||||
output = []
|
output = []
|
||||||
if matched_goal:
|
if matched_goal:
|
||||||
output.append(recipe_help_header(matched_goal[0]))
|
output.append(recipe_help_header(matched_goal[0]))
|
||||||
|
deps = get_goal_deps(matched_goal[0])
|
||||||
|
if deps:
|
||||||
|
output.extend(deps)
|
||||||
lines = file.splitlines()
|
lines = file.splitlines()
|
||||||
loc = [n for n, l in enumerate(lines) if l.startswith(f"{matched_goal[0]}:")][0]
|
loc = [n for n, l in enumerate(lines) if l.startswith(f"{matched_goal[0]}:")][0]
|
||||||
recipe = []
|
recipe = []
|
||||||
for line in lines[loc + 1 :]:
|
for line in lines[loc + 1 :]:
|
||||||
if not line.startswith("\t"):
|
if not line.startswith("\t"):
|
||||||
break
|
break
|
||||||
recipe.append(line)
|
recipe.append(f" {line.strip()}")
|
||||||
output.append(divider(max((len(l) for l in recipe)) + 5))
|
output.append(divider(max((len(l.strip()) for l in recipe))))
|
||||||
output.append("\n".join(recipe) + "\n")
|
output.append("\n".join(recipe))
|
||||||
else:
|
else:
|
||||||
output.append(f"{ansi.b_red}ERROR{ansi.end} Failed to find goal: {goal}")
|
deps = get_goal_deps(goal)
|
||||||
|
if deps:
|
||||||
|
output.append(recipe_help_header(goal))
|
||||||
|
output.extend(deps)
|
||||||
|
if not output:
|
||||||
|
output.append(f"{ansi.style('ERROR','b_red')}: Failed to find goal: {goal}")
|
||||||
return output
|
return output
|
||||||
def fmt_goal(goal, msg, max_goal_len, argstr):
|
def fmt_goal(goal, msg, max_goal_len, argstr):
|
||||||
args = parseargs(argstr)
|
args = parseargs(argstr)
|
||||||
goal_style = args.goal_style.strip() if args.goal_style else "$(GOAL_STYLE)"
|
goal_style = args.goal_style.strip() if args.goal_style else "goal"
|
||||||
msg_style = args.msg_style.strip() if args.msg_style else "$(MSG_STYLE)"
|
msg_style = args.msg_style.strip() if args.msg_style else "msg"
|
||||||
return (
|
return (
|
||||||
ansi.style(f" {goal:>{max_goal_len}}", goal_style)
|
ansi.style(f" {goal:>{max_goal_len}}", goal_style)
|
||||||
+ f" $(HELP_SEP) "
|
+ f" $(HELP_SEP) "
|
||||||
+ ansi.style(msg, msg_style)
|
+ ansi.style(msg, msg_style)
|
||||||
)
|
)
|
||||||
def divider(len):
|
|
||||||
return ansi.style(f" {'$(DIVIDER)'*len}", "$(DIVIDER_STYLE)")
|
|
||||||
def fmt_rawmsg(msg, argstr, maxlens):
|
def fmt_rawmsg(msg, argstr, maxlens):
|
||||||
args = parseargs(argstr)
|
args = parseargs(argstr)
|
||||||
lines = []
|
lines = []
|
||||||
msg_style = args.msg_style.strip() if args.msg_style else "$(MSG_STYLE)"
|
msg_style = args.msg_style.strip() if args.msg_style else "msg"
|
||||||
if not os.getenv("SHOW_HIDDEN") and args.hidden:
|
if not os.getenv("SHOW_HIDDEN") and args.hidden:
|
||||||
return []
|
return []
|
||||||
if msg:
|
if msg:
|
||||||
if args.align == "sep":
|
if args.align == "sep":
|
||||||
lines.append(
|
lines.append(
|
||||||
f"{' '*(maxlens.goal+len('$(HELP_SEP)')+4)}{ansi.style(msg,msg_style)}"
|
f"{' '*(maxlens.goal+len(cfg.sep)+4)}{ansi.style(msg,msg_style)}"
|
||||||
)
|
)
|
||||||
elif args.align == "center":
|
elif args.align == "center":
|
||||||
lines.append(f" {ansi.style(msg.center(sum(maxlens)),msg_style)}")
|
lines.append(f" {ansi.style(msg.center(sum(maxlens)),msg_style)}")
|
||||||
else:
|
else:
|
||||||
lines.append(f" {ansi.style(msg,msg_style)}")
|
lines.append(f" {ansi.style(msg,msg_style)}")
|
||||||
if args.divider:
|
if args.divider:
|
||||||
lines.append(divider(len("$(HELP_SEP)") + sum(maxlens) + 2))
|
lines.append(divider(len(cfg.sep) + sum(maxlens) + 2))
|
||||||
if args.whitespace:
|
if args.whitespace:
|
||||||
lines.append("\n")
|
lines.append("\n")
|
||||||
return lines
|
return lines
|
||||||
def print_help():
|
def print_help():
|
||||||
lines = [f"""$(USAGE)"""]
|
lines = [cfg.usage]
|
||||||
items = list(parse_help(gen_makefile()))
|
items = list(parse_help(gen_makefile()))
|
||||||
maxlens = MaxLens(
|
maxlens = MaxLens(
|
||||||
*(max((len(item[x]) for item in items if x in item)) for x in ["goal", "msg"])
|
*(max((len(item[x]) for item in items if x in item)) for x in ["goal", "msg"])
|
||||||
|
@ -197,25 +224,73 @@ def print_help():
|
||||||
)
|
)
|
||||||
if "rawmsg" in item:
|
if "rawmsg" in item:
|
||||||
lines.extend(fmt_rawmsg(item["rawmsg"], item.get("rawargs", ""), maxlens))
|
lines.extend(fmt_rawmsg(item["rawmsg"], item.get("rawargs", ""), maxlens))
|
||||||
lines.append(f"""$(EPILOG)""")
|
lines.append(cfg.epilog)
|
||||||
print("\n".join(lines))
|
print("\n".join(lines))
|
||||||
def print_arg_help(help_args):
|
def print_arg_help(help_args):
|
||||||
|
print(f"{ansi.style('task.mk recipe help','header')}\n")
|
||||||
for arg in help_args.split():
|
for arg in help_args.split():
|
||||||
print(f"{ansi.style('task.mk recipe help','$(HEADER_STYLE)')}\n")
|
|
||||||
print("\n".join(parse_goal(gen_makefile(), arg)))
|
print("\n".join(parse_goal(gen_makefile(), arg)))
|
||||||
|
print()
|
||||||
def main():
|
def main():
|
||||||
help_args = os.getenv("HELP_ARGS")
|
help_args = os.getenv("HELP_ARGS")
|
||||||
if help_args:
|
if help_args:
|
||||||
quit_make()
|
|
||||||
print_arg_help(help_args)
|
print_arg_help(help_args)
|
||||||
|
sys.exit(1)
|
||||||
else:
|
else:
|
||||||
print_help()
|
print_help()
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
endef
|
endef
|
||||||
define ansi_py
|
define info_py
|
||||||
|
$(utils_py)
|
||||||
|
print(f"""$(2)""")
|
||||||
|
endef
|
||||||
|
define print_ansi_py
|
||||||
|
$(utils_py)
|
||||||
|
sep = f"$(HELP_SEP)"
|
||||||
|
codes_names = {getattr(ansi, attr): attr for attr in ansi.__dict__}
|
||||||
|
for code in sorted(codes_names.keys(), key=lambda item: (len(item), item)):
|
||||||
|
print(f"{codes_names[code]:>20} {sep} {code+'*****'+ansi.end} {sep} {repr(code)}")
|
||||||
|
endef
|
||||||
|
define vars_py
|
||||||
|
import os
|
||||||
|
$(utils_py)
|
||||||
|
vars = "$2".split()
|
||||||
|
length = max((len(v) for v in vars))
|
||||||
|
print(f"{ansi.header}vars{ansi.end}:\n")
|
||||||
|
for v in vars:
|
||||||
|
print(f" {ansi.params}{v:<{length}}{ansi.end} = {os.getenv(v)}")
|
||||||
|
print()
|
||||||
|
endef
|
||||||
|
define confirm_py
|
||||||
|
import sys
|
||||||
|
$(utils_py)
|
||||||
|
def confirm():
|
||||||
|
"""
|
||||||
|
Ask user to enter Y or N (case-insensitive).
|
||||||
|
:return: True if the answer is Y.
|
||||||
|
:rtype: bool
|
||||||
|
"""
|
||||||
|
answer = ""
|
||||||
|
while answer not in ["y", "n"]:
|
||||||
|
answer = input(f"""$(2) {a.b_red}[Y/n]{a.end} """).lower()
|
||||||
|
return answer == "y"
|
||||||
|
if confirm():
|
||||||
|
sys.exit()
|
||||||
|
else:
|
||||||
|
sys.exit(1)
|
||||||
|
endef
|
||||||
|
define utils_py
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
from dataclasses import dataclass
|
||||||
|
@dataclass
|
||||||
|
class Config:
|
||||||
|
div: str
|
||||||
|
sep: str
|
||||||
|
epilog: str
|
||||||
|
usage: str
|
||||||
|
wrap: int
|
||||||
color2byte = dict(
|
color2byte = dict(
|
||||||
black=0,
|
black=0,
|
||||||
red=1,
|
red=1,
|
||||||
|
@ -247,6 +322,7 @@ class Ansi:
|
||||||
)
|
)
|
||||||
for name, byte in state2byte.items():
|
for name, byte in state2byte.items():
|
||||||
self.setcode(name, f"\033[{byte}m")
|
self.setcode(name, f"\033[{byte}m")
|
||||||
|
self.add_cfg()
|
||||||
def setcode(self, name, escape_code):
|
def setcode(self, name, escape_code):
|
||||||
"""create attr for style and escape code"""
|
"""create attr for style and escape code"""
|
||||||
if not sys.stdout.isatty() or os.getenv("NO_COLOR", False):
|
if not sys.stdout.isatty() or os.getenv("NO_COLOR", False):
|
||||||
|
@ -277,6 +353,17 @@ class Ansi:
|
||||||
print("Expected one or three values for bg as a list")
|
print("Expected one or three values for bg as a list")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
return code + end
|
return code + end
|
||||||
|
def add_cfg(self):
|
||||||
|
cfg_styles = {
|
||||||
|
"header": "$(HEADER_STYLE)",
|
||||||
|
"accent": "$(ACCENT_STYLE)",
|
||||||
|
"params": "$(PARAMS_STYLE)",
|
||||||
|
"goal": "$(GOAL_STYLE)",
|
||||||
|
"msg": "$(MSG_STYLE)",
|
||||||
|
"div_style": "$(DIVIDER_STYLE)",
|
||||||
|
}
|
||||||
|
for name, style in cfg_styles.items():
|
||||||
|
self.setcode(name, getattr(self, style))
|
||||||
def style(self, text, style):
|
def style(self, text, style):
|
||||||
if style not in self.__dict__:
|
if style not in self.__dict__:
|
||||||
print(f"unknown style: {style}")
|
print(f"unknown style: {style}")
|
||||||
|
@ -284,49 +371,6 @@ class Ansi:
|
||||||
else:
|
else:
|
||||||
return f"{self.__dict__[style]}{text}{self.__dict__['end']}"
|
return f"{self.__dict__[style]}{text}{self.__dict__['end']}"
|
||||||
a = ansi = Ansi()
|
a = ansi = Ansi()
|
||||||
endef
|
cfg = Config(
|
||||||
define info_py
|
"$(DIVIDER)", "$(HELP_SEP)", f"""$(EPILOG)""", f"""$(USAGE)""",int('$(WRAP)'))
|
||||||
$(ansi_py)
|
|
||||||
print(f"""$(2)""")
|
|
||||||
endef
|
|
||||||
define print_ansi_py
|
|
||||||
$(ansi_py)
|
|
||||||
sep = f"$(HELP_SEP)"
|
|
||||||
codes_names = {getattr(ansi, attr): attr for attr in ansi.__dict__}
|
|
||||||
for code in sorted(codes_names.keys(), key=lambda item: (len(item), item)):
|
|
||||||
print(f"{codes_names[code]:>20} {sep} {code+'*****'+ansi.end} {sep} {repr(code)}")
|
|
||||||
endef
|
|
||||||
define vars_py
|
|
||||||
import os
|
|
||||||
$(ansi_py)
|
|
||||||
vars = "$2".split()
|
|
||||||
length = max((len(v) for v in vars))
|
|
||||||
print(f"{ansi.$(HEADER_STYLE)}vars:{ansi.end}\n")
|
|
||||||
for v in vars:
|
|
||||||
print(f" {ansi.b_magenta}{v:<{length}}{ansi.end} = {os.getenv(v)}")
|
|
||||||
print()
|
|
||||||
endef
|
|
||||||
define confirm_py
|
|
||||||
import sys
|
|
||||||
$(ansi_py)
|
|
||||||
$(quit_make_py)
|
|
||||||
def confirm():
|
|
||||||
"""
|
|
||||||
Ask user to enter Y or N (case-insensitive).
|
|
||||||
:return: True if the answer is Y.
|
|
||||||
:rtype: bool
|
|
||||||
"""
|
|
||||||
answer = ""
|
|
||||||
while answer not in ["y", "n"]:
|
|
||||||
answer = input(f"""$(2) {a.b_red}[Y/n]{a.end} """).lower()
|
|
||||||
return answer == "y"
|
|
||||||
if confirm():
|
|
||||||
sys.exit()
|
|
||||||
else:
|
|
||||||
quit_make()
|
|
||||||
endef
|
|
||||||
define quit_make_py
|
|
||||||
import os, signal
|
|
||||||
def quit_make():
|
|
||||||
os.kill(os.getppid(), signal.SIGQUIT)
|
|
||||||
endef
|
endef
|
||||||
|
|
Loading…
Reference in a new issue