create builder infrastructure
This commit is contained in:
parent
ba8f7d6df1
commit
f63f1a61ea
35
builders.py
Normal file
35
builders.py
Normal file
@ -0,0 +1,35 @@
|
||||
import functools
|
||||
|
||||
def _lazy_evaluable(func):
|
||||
"""
|
||||
Decorator which makes a function lazy-evaluable: that is, when it's
|
||||
initially called, it returns a zero-argument lambda with the arguments
|
||||
initially passed wrapped up in it. Calling that lambda has the effect
|
||||
of executing the function.
|
||||
|
||||
We use this in TZK to allow the user to use function calls in her config
|
||||
to define the build steps, while not requiring her to write a bunch of
|
||||
ugly and confusing lambda:'s in the config. The functions that will be called
|
||||
are prepared during the config and executed later.
|
||||
"""
|
||||
|
||||
@functools.wraps(func)
|
||||
def new_func(*args, **kwargs):
|
||||
my_args = args
|
||||
my_kwargs = kwargs
|
||||
@functools.wraps(new_func)
|
||||
def inner():
|
||||
func(*my_args, **my_kwargs)
|
||||
return inner
|
||||
return new_func
|
||||
|
||||
# Now a more descriptive name that doesn't expose inner workings
|
||||
# if the user wants to write her own builder.
|
||||
tzk_builder = _lazy_evaluable
|
||||
|
||||
@tzk_builder
|
||||
def printer(username: str):
|
||||
if username == 'Maud':
|
||||
raise Exception("No Mauds allowed!")
|
||||
print(f"Hallelujah, {username} built a wiki!")
|
||||
printer.name = "Display the user's name"
|
@ -16,9 +16,10 @@ class ConfigurationManager:
|
||||
if child.is_file() and child.name.endswith('.py'):
|
||||
mod_name = child.name.rsplit('.', 1)[0]
|
||||
if mod_name == 'tzk_config':
|
||||
sys.path.insert(0, Path("__file__").parent)
|
||||
sys.path.insert(0, str(self.config_path))
|
||||
self.conf_mod = importlib.import_module(mod_name)
|
||||
del sys.path[0]
|
||||
del sys.path[0:1]
|
||||
break
|
||||
else:
|
||||
fail(
|
||||
|
47
tzk.py
47
tzk.py
@ -3,6 +3,7 @@ import argparse
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import traceback
|
||||
from typing import Optional
|
||||
|
||||
from config import cm
|
||||
@ -146,6 +147,52 @@ class InitCommand(CliCommand):
|
||||
tw.install(args.wiki_name, args.tiddlywiki_version_spec, args.author)
|
||||
|
||||
|
||||
class BuildCommand(CliCommand):
|
||||
cmd = "build"
|
||||
help = ("Build another wiki or derivative product, "
|
||||
"such as a public version of the wiki, "
|
||||
"from this TZK repository.")
|
||||
|
||||
@classmethod
|
||||
def setup_arguments(cls, parser: argparse.ArgumentParser) -> None:
|
||||
parser.add_argument(
|
||||
"product",
|
||||
metavar="PRODUCT",
|
||||
help="Name of the product you want to build (defined in your config file).",
|
||||
)
|
||||
|
||||
def _precheck(self, product: str) -> None:
|
||||
if cm.products is None:
|
||||
fail("No 'products' dictionary is defined in your config file.")
|
||||
if product not in cm.products:
|
||||
fail(f"No '{product}' product found in the products dictionary "
|
||||
f"in your config file. (Available: {', '.join(cm.products.keys())})")
|
||||
if not cm.products[product]:
|
||||
fail(f"No build steps are defined in the '{product}' product "
|
||||
f"in your config file.")
|
||||
|
||||
def execute(self, args: argparse.Namespace) -> None:
|
||||
self._precheck(args.product)
|
||||
|
||||
steps = cm.products[args.product]
|
||||
print(f"tzk: Starting build of product '{args.product}'.")
|
||||
print(f"tzk: Found {len(steps)} build steps.")
|
||||
|
||||
for idx, step in enumerate(steps, 1):
|
||||
if hasattr(step, 'name'):
|
||||
print(f"\ntzk: Step {idx}/{len(steps)}: {step.name}")
|
||||
else:
|
||||
print(f"\ntzk: Step {idx}/{len(steps)}")
|
||||
try:
|
||||
step()
|
||||
except Exception as e:
|
||||
print(f"\ntzk: Build of product '{args.product}' failed on step {failed}. "
|
||||
f"The original error follows:")
|
||||
traceback.print_exc()
|
||||
sys.exit(1)
|
||||
|
||||
print(f"\ntzk: Build of product '{args.product}' completed successfully.")
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
subparsers = parser.add_subparsers()
|
||||
|
Loading…
Reference in New Issue
Block a user