Initial chekin post-discontinuity.
This commit is contained in:
157
heckweasel/__main__.py
Normal file
157
heckweasel/__main__.py
Normal file
@ -0,0 +1,157 @@
|
||||
# iterate source tree
|
||||
# create directors in target tree
|
||||
# for each item:
|
||||
# run processor(s) on item, each processor could be in a chain or a branch
|
||||
# Processors also provide filename munging
|
||||
# output target based on processor output
|
||||
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import time
|
||||
from typing import Dict, List, cast
|
||||
|
||||
from .metadata import MetaTree
|
||||
from .processchain import ProcessorChains
|
||||
from .processors.processors import PassthroughException
|
||||
from .pygments import pygments_get_css, pygments_markup_contents_html
|
||||
from .template_tools import (
|
||||
date_iso8601,
|
||||
file_content,
|
||||
file_list,
|
||||
file_list_hier,
|
||||
file_json,
|
||||
file_metadata,
|
||||
file_name,
|
||||
file_raw,
|
||||
time_iso8601,
|
||||
)
|
||||
from .utils import deep_merge_dicts
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
|
||||
def setup_logging(verbose: bool = False) -> None:
|
||||
pass
|
||||
|
||||
|
||||
def parse_var(varspec: str) -> List:
|
||||
if (not ('=' in varspec)):
|
||||
return [varspec, True]
|
||||
return list(varspec.split('=', 2))
|
||||
|
||||
|
||||
def get_args(args: List[str]) -> argparse.Namespace:
|
||||
parser = argparse.ArgumentParser("Compile a Heckweasel directory into an output directory.")
|
||||
|
||||
parser.add_argument("root", help="The root of the heckweasel directory to process.")
|
||||
parser.add_argument("output", help="The output directory to export post-compiled files to.")
|
||||
|
||||
parser.add_argument(
|
||||
"-c", "--clean", help="Remove the target tree before proceeding (by renaming to .bak).", action="store_true"
|
||||
)
|
||||
parser.add_argument("-s", "--safe", help="Abort if the target directory already exists.", action="store_true")
|
||||
parser.add_argument("-f", "--follow-links", help="Follow symbolic links in the input tree.", action="store_true")
|
||||
parser.add_argument("-t", "--template", help="The template directory (default: root/templates)", default=None)
|
||||
parser.add_argument("-d", "--dry-run", help="Perform a dry-run.", action="store_true")
|
||||
parser.add_argument("-v", "--verbose", help="Output verbosely.", action="store_true")
|
||||
parser.add_argument("--processors", help="Specify a path to a processor configuration file.", default=None)
|
||||
parser.add_argument(
|
||||
"-D", "--define", help="Add a variable to the metadata.", nargs="+", action="extend", type=parse_var)
|
||||
result = parser.parse_args(args)
|
||||
# validate arguments
|
||||
if not os.path.isdir(result.root):
|
||||
raise FileNotFoundError("can't find root folder {}".format(result.root))
|
||||
|
||||
if not result.template:
|
||||
result.template = os.path.join(result.root, "templates")
|
||||
result.excludes = [result.template]
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def main() -> int:
|
||||
try:
|
||||
args = get_args(sys.argv[1:])
|
||||
except FileNotFoundError as ex:
|
||||
print("error finding arguments: {}".format(ex))
|
||||
return 1
|
||||
setup_logging(args.verbose)
|
||||
if os.path.exists(args.output) and args.clean:
|
||||
bak = "{}.bak-{}".format(args.output, int(time.time()))
|
||||
print("cleaning target {} -> {}".format(args.output, bak))
|
||||
os.rename(args.output, bak)
|
||||
|
||||
process_chains = ProcessorChains(args.processors)
|
||||
|
||||
default_metadata = {
|
||||
"templates": args.template,
|
||||
"template": "default.jinja2",
|
||||
"dir-template": "default-dir.jinja2",
|
||||
"filters": {},
|
||||
"build-time": time.time(),
|
||||
"uuid-oid-root": "heckweasel",
|
||||
"summary": "",
|
||||
"description": "",
|
||||
"author": "",
|
||||
"author_email": "",
|
||||
}
|
||||
if args.define:
|
||||
for var in args.define:
|
||||
default_metadata[var[0]] = var[1]
|
||||
meta_tree = MetaTree(args.root, default_metadata)
|
||||
file_list_cache = cast(Dict, {})
|
||||
file_cont_cache = cast(Dict, {})
|
||||
file_name_cache = cast(Dict, {})
|
||||
file_raw_cache = cast(Dict, {})
|
||||
flist = file_list(args.root, file_list_cache)
|
||||
default_metadata["globals"] = {
|
||||
"get_file_list": flist,
|
||||
"get_hier": file_list_hier(args.root, flist),
|
||||
"get_file_name": file_name(args.root, meta_tree, process_chains, file_name_cache),
|
||||
"get_file_content": file_content(args.root, meta_tree, process_chains, file_cont_cache),
|
||||
"get_json": file_json(args.root),
|
||||
"get_raw": file_raw(args.root, file_raw_cache),
|
||||
"get_file_metadata": file_metadata(meta_tree),
|
||||
"get_time_iso8601": time_iso8601("UTC"),
|
||||
"get_date_iso8601": date_iso8601("UTC"),
|
||||
"pygments_get_css": pygments_get_css,
|
||||
"pygments_markup_contents_html": pygments_markup_contents_html,
|
||||
"merge_dicts": deep_merge_dicts,
|
||||
}
|
||||
|
||||
for root, _, files in os.walk(args.root, followlinks=args.follow_links):
|
||||
workroot = os.path.relpath(root, args.root)
|
||||
if workroot == ".":
|
||||
workroot = ""
|
||||
target_dir = os.path.join(args.output, workroot)
|
||||
print("mkdir -> {}".format(target_dir))
|
||||
if not args.dry_run:
|
||||
try:
|
||||
os.mkdir(target_dir)
|
||||
except FileExistsError:
|
||||
if args.safe:
|
||||
print("error, target directory exists, aborting")
|
||||
return 1
|
||||
for f in files:
|
||||
# fixme global generic filters
|
||||
if f.endswith(".meta") or f.endswith("~"):
|
||||
continue
|
||||
metadata = meta_tree.get_metadata(os.path.join(workroot, f))
|
||||
chain = process_chains.get_chain_for_filename(os.path.join(root, f), ctx=metadata)
|
||||
print("process {} -> {} -> {}".format(os.path.join(root, f), repr(chain), os.path.join(target_dir, chain.output_filename)))
|
||||
if not args.dry_run:
|
||||
try:
|
||||
with open(os.path.join(target_dir, chain.output_filename), "w") as outfile:
|
||||
for line in chain.output:
|
||||
outfile.write(line)
|
||||
except PassthroughException:
|
||||
shutil.copyfile(os.path.join(root, f), os.path.join(target_dir, chain.output_filename))
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user