def index_doc(tenv, tcontext, output_dir=None, overwrite=False): """Generate documentation index. :param tenv: Templating environment, retrieved e.g. by :func:`sphinkydocext.templating.templating_environment`. :param output_dir: Output directory of generated document. :returns: Generated document path. """ output_dir = output_dir or os.path.abspath(".") t = tenv.get_template("sphinkydoc/index.rst") rendition = t.render(tcontext) master = "index" suffix = "rst" filename = os.path.join(output_dir, "%s.%s" % (master, suffix)) if overwrite or not os.path.exists(filename): f = open(filename, "w+") f.write(rendition) f.close() log.info("Index generated %s file." % filename) return filename
def readme_html_doc(tenv, docs_url, output_dir=None, overwrite=False): """Create README.html shortcut. Purpose is to have README.html that points to "docs/html/index.html" if it exists. If it does not exist, the distribution is most likely fetched from version control where HTML documentation is not generated, in this case the link should point to homepage which has always the versioned documentation. This way we can provide both, the end users of the project and users of version control the easiest way to access the documentation. :param tenv: Templating environment, retrieved e.g. by :func:`sphinkydocext.templating.templating_environment`. :param output_dir: Output directory of generated document. :returns: Generated document path. """ output_dir = output_dir or os.path.abspath(".") t = tenv.get_template("sphinkydoc/README.html") rendition = t.render({'docs_url' : docs_url }) filename = os.path.join(output_dir, "README.html") if overwrite or not os.path.exists(filename): f = open(filename, "w+") f.write(rendition) f.close() log.info("README.html generated %s file." % filename) return filename
def caps_doc(tenv, caps_dir, ext='rst', caps_literals=None, output_dir=None, dry_run=False, overwrite=False, allowed_exts=['rst', 'inc', 'txt', '']): """Generate documentation from caps files in ``caps_dir``. Caps files are files such as INSTALL, COPYING, README, which contain documentation worthy content outside docs directory. :param caps_dir: Directory where caps files reside. :param dst_dir: Destination directory where caps files are *copied*. :param ext: Enforce all caps files to be in this extension. :param caps_literals: Caps files that are treated as literal files. :param output_dir: Output directory of generated documents. :param dry_run: Dry run only, no copying or other harmful changes. :param overwrite: Overwrite the existing file? Defaults to :const:`False`. :param allowed_ext: List of allowed extensions. :returns: List of generated document paths. """ caps_literals = caps_literals or [] caps_files = [] dir_contents = os.listdir(caps_dir) output_dir = output_dir or os.path.abspath(".") caps_matcher = multi_matcher(caps_literals) for filename in dir_contents: if re.match(r"^[A-Z]{3,}(\.[A-Za-z]+)?$", filename): # Gather information about the file _root, _ext = os.path.splitext(filename) f_base = os.path.basename(_root) f_ext = _ext.lower()[1:] # If not allowed extension, skip if not any(f_ext == allowed_ext for allowed_ext in allowed_exts): continue output_filename = f_base + "." + ext filepath = os.path.join(caps_dir, filename) output_filepath = os.path.join(output_dir, output_filename) if not dry_run: if overwrite or not os.path.exists(output_filepath): shutil.copy(filepath, output_filepath) log.info("Caps %s copied to %s" % (filepath, output_filepath)) if caps_matcher(f_base): caps_literal(tenv, output_filepath) else: caps(tenv, output_filepath) caps_files.append(output_filepath) return caps_files
def script_doc_help(tenv, script_path, output_dir=None, source_dir="", overwrite=False): """Generates documentation file for script using ``--help``. :param tenv: Jinja2 templating environment. :param script_path: Path to script. :param source_dir: Source directory. :param output_dir: Output directory of generated documents. :returns: Generated document path. """ output_dir = output_dir or os.path.abspath(".") script_name = os.path.basename(script_path) help_text = "" # Call the script using "--help" cmd = ["python", script_path, "--help"] try: p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) except os.error: return else: help_text, _stderr = p.communicate() help_text = help_text.replace("\r", "") filename = os.path.join(source_dir, output_dir, "%s.rst" % script_name) filename_t = os.path.join(source_dir, output_dir, "%s.rst.template" % script_name) if os.path.exists(filename_t): template = tenv.from_string(open(filename_t).read()) else: template = tenv.get_template("sphinkydoc/script.rst") tcontext = {'script_path' : script_path, 'script_name' : script_name, 'help' : help_text} # Write template as "somescript.py" if overwrite or not os.path.exists(filename): file_ = open(filename, 'w+') file_.write(template.render(tcontext)) file_.close() log.info("Script generated %s file." % filename) return filename
def all_filterer(module, use_all=True): """All filterer for module. :param use_all: Use `__all__` of module, if true. """ # Explicitely defined public members if use_all and hasattr(module, "__all__"): has_all = True custom_all = lambda m,n: n in module.__all__ else: has_all = False if use_all: log.info("Module %s is missing __all__, falling back to " "public members" % module.__name__) custom_all = lambda _m,n: not n.startswith("_") return has_all, custom_all
def included_doc(tenv, docname, src_dir, ext="rst", overwrite=False): """Included documents pre-processed. Sphinx does not allow included documents to be with same prefix as the normal documents, so we have to rename them so Sphinx won't throw warnings. :param tenv: Templating environment, retrieved e.g. by :func:`sphinkydocext.templating.templating_environment`. :param docname: Name of the included doc, without extension. :param src_dir: Source directory where to look for. :param ext: Extension of source files, defaults to ".rst". :returns: Generated document path. """ src = os.path.join(src_dir, "%s.%s" % (docname, ext)) dst = os.path.join(src_dir, "%s.%s" % (docname, "inc")) if overwrite or not os.path.exists(dst): shutil.move(src, dst) log.info("Included %s, moved to %s" % (src, dst)) return dst
def conf_py(tenv, tcontext, output_dir=None, overwrite=False): """Generates sphinx conf.py, cannot be used within extension. :param tenv: Jinja2 templating environment. :param output_dir: Output directory of generated documents. :returns: Generated document path. """ template = tenv.get_template("sphinkydoc/conf.py.template") rendition = template.render(tcontext) filename = os.path.join(output_dir, "conf.py") if overwrite or not os.path.exists(filename): f = open(filename, "w+") f.write(rendition) f.close() log.info("Conf generated %s file." % filename) return filename
def script_doc_py(tenv, script_path, optparser, output_dir="", source_dir="", overwrite=False): """Generates documentation file for script using :mod:`optparser`. :param tenv: Jinja2 templating environment. :param optparser: :obj:`optparse.OptionParser` :param script_path: Path to script. :param source_dir: Source directory. :param output_dir: Output directory of generated documents, **must be relative to the source directory!** :returns: Generated document path. """ script_name = os.path.basename(script_path) filename = os.path.join(source_dir, output_dir, "%s.rst" % script_name) filename_t = os.path.join(source_dir, output_dir, "%s.rst.template" % script_name) if os.path.exists(filename_t): template = tenv.from_string(open(filename_t).read()) else: template = tenv.get_template("sphinkydoc/script_python.rst") tcontext = {'script_path' : script_path, 'output_dir' : output_dir, 'script_name' : script_name, 'optparser' : optparser} # Write template as "somescript.py" if overwrite or not os.path.exists(filename): file_ = open(filename, 'w+') file_.write(template.render(tcontext)) file_.close() log.info("Script generated %s file." % filename) return filename
def script_get_optparser(script_path): """Gets first :obj:`~optparse.OptionParser` from script, if possible. Idea is to loop all globals after :func:`execfile` and look for :obj:`optparse.OptionParser` instances. :param script_path: Path to the script. :returns: :const:`None`, or :obj:`optparse.OptionParser` """ globs = {} log.info("Looking for optparser, by execfile script: %s" % script_path) try: execfile(script_path, globs) except: log.info("Script %s cannot be executed using execfile" % script_path) return for _n, val in globs.iteritems(): # TODO: LOW: We could probably do more duck-typing friendly check here # too, but that is low priority. if isinstance(val, optparse.OptionParser): return val
except os.error, (_errno, errstr): if dry_run: names = [] else: log.error("error listing files in '%s': %s", src, errstr) sys.exit(0) if not dry_run: mkpath(dst) outputs = [] for n in names: src_name = os.path.join(src, n) dst_name = os.path.join(dst, n) # pylint: disable-msg=E1101 if preserve_symlinks and os.path.islink(src_name): link_dest = os.readlink(src_name) #@UndefinedVariable log.info("linking %s -> %s", dst_name, link_dest) if not dry_run: os.symlink(link_dest, dst_name) #@UndefinedVariable outputs.append(dst_name) # pylint: enable-msg=E1101 elif os.path.isdir(src_name): if n in skip_dirs: continue outputs.extend( copy_tree(src_name, dst_name, preserve_mode, preserve_times, preserve_symlinks, update, dry_run=dry_run)) else: copy_file(src_name, dst_name, preserve_mode, preserve_times, update, dry_run=dry_run)
members = get_module_members(module) template = tenv.get_template("sphinkydoc/module.rst") tcontext = {'module': module_name, 'output_dir' : output_dir, 'fullname' : name } tcontext.update(members) filename = os.path.join(source_dir, output_dir, "%s.rst" % name) # Write template, as "somemodule.submodule.rst" if overwrite or not os.path.exists(filename): file_ = open(filename, 'w+') file_.write(template.render(tcontext)) file_.close() log.info("Module generated %s file." % filename) return filename def script_doc_py(tenv, script_path, optparser, output_dir="", source_dir="", overwrite=False): """Generates documentation file for script using :mod:`optparser`. :param tenv: Jinja2 templating environment. :param optparser: :obj:`optparse.OptionParser` :param script_path: Path to script. :param source_dir: Source directory. :param output_dir: Output directory of generated documents, **must be relative to the source directory!** :returns: Generated document path.