From 12e18454ba07c3b7747f8b868f6830f05de149c4 Mon Sep 17 00:00:00 2001 From: Kévin Le Gouguec Date: Sun, 12 Apr 2020 23:06:07 +0200 Subject: Add intermediate step to cache site tree Seems kind of wasteful to recompute it every time. Also, now subsequent scripts don't have to care about file extensions anymore. --- repo/www/.gitignore | 3 ++- repo/www/Makefile | 16 ++++++++++------ repo/www/generate-deps.py | 16 +++++++++------- repo/www/generate-index.py | 18 +++++++++--------- repo/www/generate-tree.py | 32 ++++++++++++++++++++++++++++++++ repo/www/helpers.py | 22 +++++++++++++++++++--- 6 files changed, 81 insertions(+), 26 deletions(-) create mode 100755 repo/www/generate-tree.py diff --git a/repo/www/.gitignore b/repo/www/.gitignore index b921cf0..edad99c 100644 --- a/repo/www/.gitignore +++ b/repo/www/.gitignore @@ -1 +1,2 @@ -deps.mk \ No newline at end of file +deps.mk +site-tree.json diff --git a/repo/www/Makefile b/repo/www/Makefile index 9050626..fdc0112 100644 --- a/repo/www/Makefile +++ b/repo/www/Makefile @@ -1,5 +1,3 @@ -# TODO: add a target for the file tree; use it in generate-* scripts. - TOP_DIR = ../.. OUT_DIR = $(TOP_DIR)/public TEXT_FILES = md org @@ -12,12 +10,18 @@ text_folders = $(call dirnames,$(shell git ls-files $(text_patterns))) all: site +# Maps folders to their contents (files and subfolders). +site_tree = site-tree.json # Defines $(pages) and $(indices). dependencies = deps.mk -include $(dependencies) -$(dependencies): $(text_folders) - ./generate-deps.py "$(TEXT_FILES)" $(OUT_DIR) +$(site_tree): $(text_folders) + ./generate-tree.py -o $@ $(TEXT_FILES) + +$(dependencies): $(site_tree) + ./generate-deps.py $< $@ $(OUT_DIR) + +include $(dependencies) site: $(pages) $(indices) @@ -33,7 +37,7 @@ $(pages): # ⚠ When tweaking this rule, check whether it still works for the # top-level index.html. $(indices): $(OUT_DIR)/%index.html: - ./generate-index.py "$(TEXT_FILES)" "$(patsubst %/,%,$*)" $@ + ./generate-index.py $(site_tree) "$(patsubst %/,%,$*)" $@ clean: -rm $(dependencies) diff --git a/repo/www/generate-deps.py b/repo/www/generate-deps.py index 8388c40..e82b691 100755 --- a/repo/www/generate-deps.py +++ b/repo/www/generate-deps.py @@ -18,19 +18,20 @@ We want to compute: OUTPUT/foo/index.html: foo | OUTPUT/foo """ +import json from os import path from sys import argv, exit from git import Repo -from helpers import compute_directories +from helpers import deserialize_directories def parse_arguments(args): - if len(args) != 3: - exit(f'Usage: {argv[0]} EXTENSIONS OUTPUT-DIR') + if len(args) != 4: + exit(f'Usage: {argv[0]} SITE-TREE OUTPUT-FILE OUTPUT-DIR') - return argv[1].split(), argv[2] + return argv[1], argv[2], argv[3] def pjoin(directory, item): @@ -84,14 +85,15 @@ def write_dependencies(deps_file, directories, top_dir, out_dir): def main(arguments): - extensions, out_dir = parse_arguments(arguments) + tree_file, deps_file, out_dir = parse_arguments(arguments) repository = Repo(search_parent_directories=True) top_dir = path.relpath(repository.working_dir, path.curdir) - directories = compute_directories(extensions, repository) + with open(tree_file) as tree: + directories = deserialize_directories(json.load(tree)) - with open('deps.mk', 'w') as deps: + with open(deps_file, 'w') as deps: write_dependencies(deps, directories, top_dir, out_dir) diff --git a/repo/www/generate-index.py b/repo/www/generate-index.py index 96c5dc6..d28c6a6 100755 --- a/repo/www/generate-index.py +++ b/repo/www/generate-index.py @@ -1,19 +1,19 @@ #!/usr/bin/env python3 from argparse import ArgumentParser +import json from os import path from subprocess import run from git import Repo -from helpers import compute_directories +from helpers import deserialize_directories def parse_arguments(): parser = ArgumentParser() parser.add_argument( - 'extensions', type=str.split, - help='File extensions to consider when recording pages.' + 'site_tree', help='JSON file describing the page tree.' ) parser.add_argument( 'target', help='Pathspec to generate an index for.' @@ -24,8 +24,9 @@ def parse_arguments(): return parser.parse_args() -def list_files(extensions, folder, repo): - directories = compute_directories(extensions, repo) +def list_files(tree_file, folder): + with open(tree_file) as tree: + directories = deserialize_directories(json.load(tree)) return directories[folder].subfolders, directories[folder].files @@ -59,16 +60,15 @@ def convert_page(content, output): def main(arguments): - repo = Repo(search_parent_directories=True) - target = arguments.target - extensions = arguments.extensions - folders, files = list_files(extensions, target, repo) + folders, files = list_files(arguments.site_tree, target) names = [] intro = None + repo = Repo(search_parent_directories=True) + for f in files: name, _ = path.splitext(f) if name == 'README': diff --git a/repo/www/generate-tree.py b/repo/www/generate-tree.py new file mode 100755 index 0000000..d858fe8 --- /dev/null +++ b/repo/www/generate-tree.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python3 + +from argparse import ArgumentParser +import json + +from git import Repo + +from helpers import compute_directories + + +def parse_arguments(): + parser = ArgumentParser() + parser.add_argument('-o', '--output', help='Path to the output file.') + parser.add_argument( + 'extensions', nargs='+', + help='File extensions to consider when recording pages.' + ) + return parser.parse_args() + + +def main(arguments): + repo = Repo(search_parent_directories=True) + + directories = compute_directories(arguments.extensions, repo) + serialized = ((d, directories[d].serialize()) for d in sorted(directories)) + + with open(arguments.output, 'w') as out: + json.dump(dict(serialized), out, sort_keys=True) + + +if __name__ == '__main__': + main(parse_arguments()) diff --git a/repo/www/helpers.py b/repo/www/helpers.py index 80115b7..6dc5bad 100644 --- a/repo/www/helpers.py +++ b/repo/www/helpers.py @@ -1,13 +1,23 @@ from collections import defaultdict from dataclasses import dataclass, field from os import path -from typing import List, Set +from typing import Iterator @dataclass class Directory: - files: List[str] = field(default_factory=list) - subfolders: Set[str] = field(default_factory=set) + files: Iterator[str] = field(default_factory=list) + subfolders: Iterator[str] = field(default_factory=set) + + def serialize(self): + return { + 'files': sorted(self.files), + 'subfolders': sorted(self.subfolders) + } + + @classmethod + def deserialize(cls, d): + return cls(**d) def _find_files(extensions, repository): @@ -36,3 +46,9 @@ def compute_directories(extensions, repository): files = _find_files(extensions, repository) top_dir = path.relpath(repository.working_dir, path.curdir) return _fill_directories(files, top_dir) + + +def deserialize_directories(directories): + return { + k: Directory.deserialize(v) for k, v in directories.items() + } -- cgit v1.2.3