From 1a894dd5ff9405c58fa9508dc64756822dd1d613 Mon Sep 17 00:00:00 2001 From: Daylin Morgan Date: Mon, 5 Sep 2022 12:23:17 -0500 Subject: [PATCH] add src --- .gitignore | 2 ++ Makefile | 75 +++++++++++++++++++++++++++++++++++++++++++++ generate.py | 41 +++++++++++++++++++++++++ setup.cfg | 3 ++ src/builtins.mk | 36 ++++++++++++++++++++++ src/color.py | 53 ++++++++++++++++++++++++++++++++ src/config.mk | 15 +++++++++ src/help.py | 38 +++++++++++++++++++++++ src/info.py | 7 +++++ src/print-colors.py | 14 +++++++++ src/py-runner.mk | 26 ++++++++++++++++ src/py-script.mk | 5 +++ src/task.mk | 16 ++++++++++ src/vars.py | 18 +++++++++++ 14 files changed, 349 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100755 generate.py create mode 100644 setup.cfg create mode 100644 src/builtins.mk create mode 100644 src/color.py create mode 100644 src/config.mk create mode 100644 src/help.py create mode 100644 src/info.py create mode 100644 src/print-colors.py create mode 100644 src/py-runner.mk create mode 100644 src/py-script.mk create mode 100644 src/task.mk create mode 100644 src/vars.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2aa8c96 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.task.mk +env/ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..25f8abd --- /dev/null +++ b/Makefile @@ -0,0 +1,75 @@ +VERSION ?= $(shell git describe --tags --always --dirty | sed s'/dirty/dev/') +TEMPLATES := $(shell find src/ -type f) +.DEFAULT_GOAL := help + +header = $(call tprint,{c.b_magenta}==>{c.end} {c.bold}$(1){c.end} {c.b_magenta}<=={c.end}) + +## bootstrap | generate local conda environment +.PHONY: bootstrap +bootstrap: + $(call header,Bootstrap Environment) + @mamba create -p ./env python jinja2 black + +## lint | lint the python +.PHONY: lint +lint: + @black generate.py + @black src/*.py --fast + +## release | make new release of project +.PHONY: release +release: version-check + $(call header,Release Project) + @./generate.py $(VERSION) > task.mk + @sed -i 's/task.mk\/.*\/task.mk/task.mk\/v$(VERSION)\/task.mk/g' README.md + @git add task.mk README.md + @git commit -m "release: v$(VERSION)" + +## clean | remove the generated files +.PHONY: clean +clean: + @rm -f task.mk .task.mk + + +.PHONY: version-check +version-check: + @if [[ "${VERSION}" == *'-'* ]]; then\ + $(call tprint-sh,{c.red}VERSION INVALID! Uncommited Work{c.end});\ + echo ">> version: $(VERSION)"; exit 1;\ + elif [[ $(shell echo "${VERSION}" | awk -F. '{ print NF }') -lt 3 ]];then\ + $(call tprint-sh,{c.red}VERSION INVALID! Expected CalVer string{c.end});\ + echo ">> version: $(VERSION)"; exit 1;\ + else \ + $(call tprint-sh,{c.green}VERSION LOOKS GOOD!{c.end});\ + fi + +define msg +{c.b_yellow} +It can even be multiline!{c.end} +and styles can be defined{c.end} +as python {c.bold}f-string{c.end} literals +{c.end} +endef + +## info | demonstarte usage of tprint +.PHONY: task +info: + $(call header, Info Message) + $(call tprint,{c.b_magenta}This is task-print output:{c.end}) + $(call tprint,$(msg)) + + +define USAGE +{c.$(HEADER_COLOR)}usage:{c.end} + make + +A usage statement...with {c.b_green}COLOR{c.end} + +endef + +EPILOG = \nAn epilog...\nfor more help: see github.com/daylinmorgan/task.mk +PRINT_VARS := VERSION + +-include .task.mk +.task.mk: $(TEMPLATES) generate.py + ./generate.py $(VERSION) > .task.mk diff --git a/generate.py b/generate.py new file mode 100755 index 0000000..39e6c82 --- /dev/null +++ b/generate.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python3 + +import sys +from pathlib import Path + +import jinja2 + +py_script_names = ["help", "color", "info", "print-colors", "vars"] + + +def get_jinja_env(): + templateLoader = jinja2.FileSystemLoader(searchpath=Path(__file__).parent / "src") + return jinja2.Environment( + loader=templateLoader, + block_start_string="#%", + block_end_string="%#", + variable_start_string="##-", + variable_end_string="-##", + ) + + +def render(env, template, **kwargs): + template = env.get_template(template) + return template.render(**kwargs) + + +def main(): + if len(sys.argv) == 2: + version = sys.argv[1] + else: + version = "dev" + + env = get_jinja_env() + + py_scripts = [render(env, f"{name}.py") for name in py_script_names] + + print(render(env, "task.mk", py_scripts=py_scripts, version=version)) + + +if __name__ == "__main__": + main() diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..ab8626b --- /dev/null +++ b/setup.cfg @@ -0,0 +1,3 @@ +[flake8] +max_line_length = 88 +ignore = E265 \ No newline at end of file diff --git a/src/builtins.mk b/src/builtins.mk new file mode 100644 index 0000000..ae6da0d --- /dev/null +++ b/src/builtins.mk @@ -0,0 +1,36 @@ +# ---- [buitlin recipes] ---- # + + +## h, help | show this help +.PHONY: help h +help h: + $(call py,help_py) + +.PHONY: _help +_help: export SHOW_HIDDEN=true +_help: help + +ifdef PRINT_VARS + +$(foreach v,$(PRINT_VARS),$(eval export $(v))) + +.PHONY: vars v +vars v: + $(call py,vars_py,$(PRINT_VARS)) + +endif + +## _print-colors | show all possible ansi color code combinations +.PHONY: +_print-colors: + $(call py,print_colors_py) + +# functions to take f-string literals and pass to python print +tprint = $(call py,info_py,$(1)) +tprint-sh = $(call pysh,info_py,$(1)) + +_update-task.mk: + $(call tprint,Updating task.mk) + curl https://raw.githubusercontent.com/daylinmorgan/task.mk/main/task.mk -o .task.mk + +export MAKEFILE_LIST \ No newline at end of file diff --git a/src/color.py b/src/color.py new file mode 100644 index 0000000..5b5d53d --- /dev/null +++ b/src/color.py @@ -0,0 +1,53 @@ +#% extends "py-script.mk" %# +#% block name %#color#% endblock %# +#% block script %# +import os +import sys + +color2byte = dict( + black=0, + red=1, + green=2, + yellow=3, + blue=4, + magenta=5, + cyan=6, + white=7, +) + +state2byte = dict( + bold=1, faint=2, italic=3, underline=4, blink=5, fast_blink=6, crossed=9 +) + + +def fg(byte): + return 30 + byte + + +def bg(byte): + return 40 + byte + + +class Colors: + """ANSI color codes""" + + def setcolor(self, name, escape_code): + if not sys.stdout.isatty() or os.getenv("NO_COLOR", False): + setattr(self, name, "") + else: + setattr(self, name, escape_code) + + def __init__(self): + self.setcolor("end", "\033[0m") + for name, byte in color2byte.items(): + self.setcolor(name, f"\033[{fg(byte)}m") + self.setcolor(f"b_{name}", f"\033[1;{fg(byte)}m") + self.setcolor(f"d_{name}", f"\033[2;{fg(byte)}m") + for bgname, bgbyte in color2byte.items(): + self.setcolor(f"{name}_on_{bgname}", f"\033[{bg(bgbyte)};{fg(byte)}m") + for name, byte in state2byte.items(): + self.setcolor(name, f"\033[{byte}m") + + +c = colors = Colors() +#% endblock %# diff --git a/src/config.mk b/src/config.mk new file mode 100644 index 0000000..0ea3c21 --- /dev/null +++ b/src/config.mk @@ -0,0 +1,15 @@ +# ---- CONFIG ---- # +HEADER_COLOR ?= b_cyan +PARAMS_COLOR ?= b_magenta +ACCENT_COLOR ?= b_yellow +GOAL_COLOR ?= $(ACCENT_COLOR) +MSG_COLOR ?= faint +HELP_SEP ?= | +EPILOG ?= + +# python f-string literal +define USAGE ?= +{colors.$(HEADER_COLOR)}usage{colors.end}: + make + +endef diff --git a/src/help.py b/src/help.py new file mode 100644 index 0000000..99e41af --- /dev/null +++ b/src/help.py @@ -0,0 +1,38 @@ +#% extends "py-script.mk" %# +#% block name %#help#% endblock %# +#% block script %# +import os +import re + +##- '$(color_py)' -## + +pattern = re.compile(r"^## (.*) \| (.*)") + +makefile = "" +for file in os.getenv("MAKEFILE_LIST").split(): + with open(file, "r") as f: + makefile += f.read() + "\n\n" + + +def get_help(file): + for line in file.splitlines(): + match = pattern.search(line) + if match: + if not os.getenv("SHOW_HIDDEN") and match.groups()[0].startswith("_"): + continue + else: + yield match.groups() + + +print(f"""$(USAGE)""") + +goals = list(get_help(makefile)) +goal_len = max(len(goal[0]) for goal in goals) + +for goal, msg in goals: + print( + f"{colors.$(GOAL_COLOR)}{goal:>{goal_len}}{colors.end} $(HELP_SEP) {colors.$(MSG_COLOR)}{msg}{colors.end}" + ) + +print(f"""$(EPILOG)""") +#% endblock %# diff --git a/src/info.py b/src/info.py new file mode 100644 index 0000000..931d748 --- /dev/null +++ b/src/info.py @@ -0,0 +1,7 @@ +#% extends "py-script.mk" %# +#% block name %#info#% endblock %# +#% block script %# +##- '$(color_py)' -## + +print(f"""$(2)""") +#% endblock %# diff --git a/src/print-colors.py b/src/print-colors.py new file mode 100644 index 0000000..c8c0c39 --- /dev/null +++ b/src/print-colors.py @@ -0,0 +1,14 @@ +#% extends "py-script.mk" %# +#% block name %#print_colors#% endblock %# +#% block script %# +##- '$(color_py)' -## + +codes_names = { + getattr(colors, attr): attr + for attr in dir(colors) + if attr[0:1] != "_" and attr != "end" and attr != "setcolor" +} +for code in sorted(codes_names.keys(), key=lambda item: (len(item), item)): + print("{:>20} {}".format(codes_names[code], code + "******" + colors.end)) + +#% endblock %# diff --git a/src/py-runner.mk b/src/py-runner.mk new file mode 100644 index 0000000..df45a97 --- /dev/null +++ b/src/py-runner.mk @@ -0,0 +1,26 @@ +# ---- [python script runner] ---- # + +# modified from https://unix.stackexchange.com/a/223093 +define \n + + +endef + +escape_shellstring = $(subst `,\`,$(subst ",\",$(subst $$,\$$,$(subst \,\\,$1)))) + +escape_printf = $(subst \,\\,$(subst %,%%,$1)) + +create_string = $(subst $(\n),\n,$(call escape_shellstring,$(call escape_printf,$1))) + + +ifdef DEBUG +define py +@printf "Python Script:" +@printf "$(call create_string,$($(1)))" +@printf "$(call create_string,$($(1)))" | python3 +endef +else +py = @printf "$(call create_string,$($(1)))" | python3 +endif + +pysh = printf "$(call create_string,$($(1)))" | python3 diff --git a/src/py-script.mk b/src/py-script.mk new file mode 100644 index 0000000..23bd044 --- /dev/null +++ b/src/py-script.mk @@ -0,0 +1,5 @@ +define #% block name %##% endblock %#_py + +#% block script %##% endblock %# + +endef diff --git a/src/task.mk b/src/task.mk new file mode 100644 index 0000000..bd1e5d7 --- /dev/null +++ b/src/task.mk @@ -0,0 +1,16 @@ +# --------------------- [github.com/daylinmorgan/task.mk] -------------------- # +# Copyright (c) 2022 Daylin Morgan +# MIT License +# ##- version -## + +#% include 'config.mk' %# + +#% include 'builtins.mk' %# + +#% include 'py-runner.mk' %# + +# ---- [python scripts] ---- # + +#% for script in py_scripts %# +##- script -## +#% endfor %# \ No newline at end of file diff --git a/src/vars.py b/src/vars.py new file mode 100644 index 0000000..33ab0fb --- /dev/null +++ b/src/vars.py @@ -0,0 +1,18 @@ +#% extends "py-script.mk" %# +#% block name %#vars#% endblock %# +#% block script %# + +import os + +##- '$(color_py)' -## + +vars = "$2".split() +length = max((len(v) for v in vars)) + +print(f"{colors.$(HEADER_COLOR)}vars:{colors.end}\n") + +for v in vars: + print(f" {colors.b_magenta}{v:<{length}}{colors.end} = {os.getenv(v)}") + +print() +#% endblock %#