From e6b6ea7b40d0c6972ff5ada0c815440b46d76e63 Mon Sep 17 00:00:00 2001 From: "Martin A. Brown" Date: Sun, 6 Mar 2016 11:29:13 -0800 Subject: [PATCH] add support for --doctypes and --statustypes provide CLI-discoverable listing of supported source document types and status types --- tldp/config.py | 8 ++++ tldp/doctypes/docbook4xml.py | 2 +- tldp/driver.py | 75 ++++++++++++++++++++++++++++++------ tldp/inventory.py | 26 +++++++------ 4 files changed, 86 insertions(+), 25 deletions(-) diff --git a/tldp/config.py b/tldp/config.py index ce77c06..e72bc64 100644 --- a/tldp/config.py +++ b/tldp/config.py @@ -33,6 +33,14 @@ def collectconfiguration(tag, argv): '-t', action='store_true', default=False, help='dump inventory summary report [%(default)s]') + g.add_argument('--doctypes', '--formats', '--format', + '--list-doctypes', '--list-formats', + '-T', + action='store_true', default=False, + help='show supported doctypes [%(default)s]') + g.add_argument('--statustypes', '--list-statustypes', + action='store_true', default=False, + help='show status types and classes [%(default)s]') ap.add_argument('--verbose', action='store_true', default=False, diff --git a/tldp/doctypes/docbook4xml.py b/tldp/doctypes/docbook4xml.py index a277240..631bbdb 100644 --- a/tldp/doctypes/docbook4xml.py +++ b/tldp/doctypes/docbook4xml.py @@ -166,7 +166,7 @@ class Docbook4XML(BaseDoctype, SignatureChecker): s = 'ln -svr -- "{output.name_html}" "{output.name_indexhtml}"' return self.shellscript(s) - @depends(make_name_html) + @depends(make_html, make_name_pdf, make_name_htmls) def remove_validated_source(self): '''create final index.html symlink''' s = 'rm --verbose -- "{output.validsource}"' diff --git a/tldp/driver.py b/tldp/driver.py index 75ff322..c05bc5d 100644 --- a/tldp/driver.py +++ b/tldp/driver.py @@ -6,12 +6,13 @@ from __future__ import absolute_import, division, print_function import os import sys import logging +import inspect from argparse import Namespace from tldp.typeguesser import knowndoctypes from tldp.sources import SourceDocument, arg_issourcedoc from tldp.outputs import OutputDirectory -from tldp.inventory import Inventory, status_classes, status_types +from tldp.inventory import Inventory, status_classes, status_types, stypes from tldp.config import collectconfiguration from tldp.utils import arg_isloglevel from tldp.doctypes.common import preamble, postamble @@ -21,6 +22,44 @@ logging.basicConfig(stream=sys.stderr, format=logformat, level=logging.ERROR) logger = logging.getLogger(__name__) +def show_doctypes(config, **kwargs): + file = kwargs.get('file', sys.stdout) + print("Supported source document types:", file=file) + print(file=file) + for doctype in knowndoctypes: + classname = doctype.__name__ + fname = os.path.abspath(inspect.getmodule(doctype).__file__) + extensions = ', '.join(doctype.extensions) + print('{}'.format(classname), file=file) + print(' format name: {}'.format(doctype.formatname), file=file) + print(' code location: {}'.format(fname), file=file) + print(' file extensions: {}'.format(extensions), file=file) + for signature in doctype.signatures: + print(' signature: {}'.format(signature), file=file) + print(file=file) + print(file=file) + return 0 + +def show_statustypes(config, **kwargs): + file = kwargs.get('file', sys.stdout) + width = 2 + max([len(x) for x in status_types]) + print("Basic status types:", file=file) + print(file=file) + for status, descrip in stypes.items(): + fmt = '{status:>{width}}: {descrip}' + text = fmt.format(status=status, descrip=descrip, width=width) + print(text, file=file) + print(file=file) + print("Synonyms and groups:", file=file) + print(file=file) + for status, descrip in status_classes.items(): + fmt = '{status:>{width}}: {descrip}' + descrip = ', '.join(descrip) + text = fmt.format(status=status, descrip=descrip, width=width) + print(text, file=file) + print(file=file) + return 0 + def summary(config, inv=None, **kwargs): if inv is None: inv = Inventory(config.pubdir, config.sourcedir) @@ -213,17 +252,29 @@ def run(argv): logger.debug(" %s = %r", param, value) logger.debug(" args: %r", args) - # -- summary does not require any args - if config.summary: + need_repos_p = "Option --pubdir (and --sourcedir) required " + need_repos_s = "Option --sourcedir (and --pubdir) required " + + # -- --summary, --doctypes, --statustypes do not require any args + # + if any((config.summary, config.doctypes, config.statustypes)): if args: - return "Unknown args received for --summary: " + ' '.join(args) - if not config.pubdir: - return "Option --pubdir (and --sourcedir) required for --summary." - if not config.sourcedir: - return "Option --sourcedir (and --pubdir) required for --summary." + return "Unknown args received: " + ' '.join(args) - return summary(config) + if config.doctypes: + return show_doctypes(config) + + if config.statustypes: + return show_statustypes(config) + + if config.summary: + if not config.pubdir: + return need_repos_p + "for --summary" + if not config.sourcedir: + return need_repos_s + "for --summary" + + return summary(config) # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # -- argument handling logic; try to avoid creating an inventory unless it @@ -252,9 +303,9 @@ def run(argv): # if need_inventory: if not config.pubdir: - return " --pubdir (and --sourcedir) required for inventory." + return need_repos_p + "for inventory" if not config.sourcedir: - return " --sourcedir (and --pubdir) required for inventory." + return need_repos_s + "for inventory" inv = Inventory(config.pubdir, config.sourcedir) logger.info("Collected inventory containing %s documents.", len(inv.all.keys())) @@ -312,7 +363,7 @@ def run(argv): config.build = True if not config.pubdir: - return " --pubdir required to --build." + return need_repos_p + "to --build" return build(config, docs) diff --git a/tldp/inventory.py b/tldp/inventory.py index e3be9f1..e37b3d7 100644 --- a/tldp/inventory.py +++ b/tldp/inventory.py @@ -5,6 +5,7 @@ from __future__ import absolute_import, division, print_function import copy import logging +from collections import OrderedDict from tldp.utils import max_mtime, mtime_gt @@ -16,28 +17,29 @@ logger = logging.getLogger(__name__) # -- any individual document (source or output) will have a status # from the following list of status_types # -status_types = [ - 'source', - 'output', - 'published', - 'new', - 'orphan', - 'broken', - 'stale', - ] +stypes = OrderedDict() +stypes['source'] = 'found in source repository' +stypes['output'] = 'found in output repository' +stypes['published'] = 'matching stem in source/output; doc is up to date' +stypes['stale'] = 'matching stem in source/output; but source is newer' +stypes['orphan'] = 'stem located in output, but no source found (i.e. old?)' +stypes['broken'] = 'output is missing an expected output format (e.g. PDF)' +stypes['new'] = 'stem located in source, but missing in output; unpublished' + +status_types = stypes.keys() # -- the user probably doesn't usually care (too much) about listing # every single published document and source document, but is probably # mostly interested in specific documents grouped by status; so the # status_classes are just sets of status_types # -status_classes = dict(zip(status_types, [[x] for x in status_types])) +status_classes = OrderedDict(zip(status_types, [[x] for x in status_types])) status_classes['outputs'] = ['output'] status_classes['sources'] = ['source'] -status_classes['problems'] = ['orphan', 'broken', 'stale'] -status_classes['work'] = ['new', 'orphan', 'broken', 'stale'] status_classes['orphans'] = ['orphan'] status_classes['orphaned'] = ['orphan'] +status_classes['problems'] = ['orphan', 'broken', 'stale'] +status_classes['work'] = ['new', 'orphan', 'broken', 'stale'] status_classes['all'] = ['published', 'new', 'orphan', 'broken', 'stale']