| #!/usr/bin/python -b |
| # Copyright 1999-2014 Gentoo Foundation |
| # Distributed under the terms of the GNU General Public License v2 |
| |
| # |
| # Typical usage: |
| # dohtml -r docs/* |
| # - put all files and directories in docs into /usr/share/doc/${PF}/html |
| # dohtml foo.html |
| # - put foo.html into /usr/share/doc/${PF}/html |
| # |
| # |
| # Detailed usage: |
| # dohtml <list-of-files> |
| # - will install the files in the list of files (space-separated list) into |
| # /usr/share/doc/${PF}/html, provided the file ends in .css, .gif, .htm, |
| # .html, .jpeg, .jpg, .js or .png. |
| # dohtml -r <list-of-files-and-directories> |
| # - will do as 'dohtml', but recurse into all directories, as long as the |
| # directory name is not CVS |
| # dohtml -A jpe,java [-r] <list-of-files[-and-directories]> |
| # - will do as 'dohtml' but add .jpe,.java (default filter list is |
| # added to your list) |
| # dohtml -a png,gif,html,htm [-r] <list-of-files[-and-directories]> |
| # - will do as 'dohtml' but filter on .png,.gif,.html,.htm (default filter |
| # list is ignored) |
| # dohtml -x CVS,SCCS,RCS -r <list-of-files-and-directories> |
| # - will do as 'dohtml -r', but ignore directories named CVS, SCCS, RCS |
| # |
| |
| from __future__ import print_function |
| |
| import os |
| import shutil |
| import sys |
| |
| from portage.util import normalize_path |
| |
| # Change back to original cwd _after_ all imports (bug #469338). |
| os.chdir(os.environ["__PORTAGE_HELPER_CWD"]) |
| |
| def dodir(path): |
| try: |
| os.makedirs(path, 0o755) |
| except OSError: |
| if not os.path.isdir(path): |
| raise |
| os.chmod(path, 0o755) |
| |
| def dofile(src,dst): |
| shutil.copy(src, dst) |
| os.chmod(dst, 0o644) |
| |
| def eqawarn(lines): |
| cmd = "source '%s/isolated-functions.sh' ; " % \ |
| os.environ["PORTAGE_BIN_PATH"] |
| for line in lines: |
| cmd += "eqawarn \"%s\" ; " % line |
| os.spawnlp(os.P_WAIT, "bash", "bash", "-c", cmd) |
| |
| skipped_directories = [] |
| skipped_files = [] |
| warn_on_skipped_files = os.environ.get("PORTAGE_DOHTML_WARN_ON_SKIPPED_FILES") is not None |
| unwarned_skipped_extensions = os.environ.get("PORTAGE_DOHTML_UNWARNED_SKIPPED_EXTENSIONS", "").split() |
| unwarned_skipped_files = os.environ.get("PORTAGE_DOHTML_UNWARNED_SKIPPED_FILES", "").split() |
| |
| def install(basename, dirname, options, prefix=""): |
| fullpath = basename |
| if prefix: |
| fullpath = os.path.join(prefix, fullpath) |
| if dirname: |
| fullpath = os.path.join(dirname, fullpath) |
| |
| if options.DOCDESTTREE: |
| desttree = options.DOCDESTTREE |
| else: |
| desttree = "html" |
| |
| destdir = os.path.join(options.ED, "usr", "share", "doc", |
| options.PF.lstrip(os.sep), desttree.lstrip(os.sep), |
| options.doc_prefix.lstrip(os.sep), prefix).rstrip(os.sep) |
| |
| if not os.path.exists(fullpath): |
| sys.stderr.write("!!! dohtml: %s does not exist\n" % fullpath) |
| return False |
| elif os.path.isfile(fullpath): |
| ext = os.path.splitext(basename)[1][1:] |
| if ext in options.allowed_exts or basename in options.allowed_files: |
| dodir(destdir) |
| dofile(fullpath, os.path.join(destdir, basename)) |
| elif warn_on_skipped_files and ext not in unwarned_skipped_extensions and basename not in unwarned_skipped_files: |
| skipped_files.append(fullpath) |
| elif options.recurse and os.path.isdir(fullpath) and \ |
| basename not in options.disallowed_dirs: |
| for i in os.listdir(fullpath): |
| pfx = basename |
| if prefix: |
| pfx = os.path.join(prefix, pfx) |
| install(i, dirname, options, pfx) |
| elif not options.recurse and os.path.isdir(fullpath): |
| global skipped_directories |
| skipped_directories.append(fullpath) |
| return False |
| else: |
| return False |
| return True |
| |
| |
| class OptionsClass: |
| def __init__(self): |
| self.PF = "" |
| self.ED = "" |
| self.DOCDESTTREE = "" |
| |
| if "PF" in os.environ: |
| self.PF = os.environ["PF"] |
| if self.PF: |
| self.PF = normalize_path(self.PF) |
| if "force-prefix" not in os.environ.get("FEATURES", "").split() and \ |
| os.environ.get("EAPI", "0") in ("0", "1", "2"): |
| self.ED = os.environ.get("D", "") |
| else: |
| self.ED = os.environ.get("ED", "") |
| if self.ED: |
| self.ED = normalize_path(self.ED) |
| if "_E_DOCDESTTREE_" in os.environ: |
| self.DOCDESTTREE = os.environ["_E_DOCDESTTREE_"] |
| if self.DOCDESTTREE: |
| self.DOCDESTTREE = normalize_path(self.DOCDESTTREE) |
| |
| self.allowed_exts = ['css', 'gif', 'htm', 'html', 'jpeg', 'jpg', 'js', 'png'] |
| if os.environ.get("EAPI", "0") in ("4-python", "5-progress"): |
| self.allowed_exts += ['ico', 'svg', 'xhtml', 'xml'] |
| self.allowed_files = [] |
| self.disallowed_dirs = ['CVS'] |
| self.recurse = False |
| self.verbose = False |
| self.doc_prefix = "" |
| |
| def print_help(): |
| opts = OptionsClass() |
| |
| print("dohtml [-a .foo,.bar] [-A .foo,.bar] [-f foo,bar] [-x foo,bar]") |
| print(" [-r] [-V] <file> [file ...]") |
| print() |
| print(" -a Set the list of allowed to those that are specified.") |
| print(" Default:", ",".join(opts.allowed_exts)) |
| print(" -A Extend the list of allowed file types.") |
| print(" -f Set list of allowed extensionless file names.") |
| print(" -x Set directories to be excluded from recursion.") |
| print(" Default:", ",".join(opts.disallowed_dirs)) |
| print(" -p Set a document prefix for installed files (empty by default).") |
| print(" -r Install files and directories recursively.") |
| print(" -V Be verbose.") |
| print() |
| |
| def parse_args(): |
| options = OptionsClass() |
| args = [] |
| |
| x = 1 |
| while x < len(sys.argv): |
| arg = sys.argv[x] |
| if arg in ["-h","-r","-V"]: |
| if arg == "-h": |
| print_help() |
| sys.exit(0) |
| elif arg == "-r": |
| options.recurse = True |
| elif arg == "-V": |
| options.verbose = True |
| elif sys.argv[x] in ["-A","-a","-f","-x","-p"]: |
| x += 1 |
| if x == len(sys.argv): |
| print_help() |
| sys.exit(0) |
| elif arg == "-p": |
| options.doc_prefix = sys.argv[x] |
| if options.doc_prefix: |
| options.doc_prefix = normalize_path(options.doc_prefix) |
| else: |
| values = sys.argv[x].split(",") |
| if arg == "-A": |
| options.allowed_exts.extend(values) |
| elif arg == "-a": |
| options.allowed_exts = values |
| elif arg == "-f": |
| options.allowed_files = values |
| elif arg == "-x": |
| options.disallowed_dirs = values |
| else: |
| args.append(sys.argv[x]) |
| x += 1 |
| |
| return (options, args) |
| |
| def main(): |
| |
| (options, args) = parse_args() |
| |
| if options.verbose: |
| print("Allowed extensions:", options.allowed_exts) |
| print("Document prefix : '" + options.doc_prefix + "'") |
| print("Allowed files :", options.allowed_files) |
| |
| success = False |
| endswith_slash = (os.sep, os.sep + ".") |
| |
| for x in args: |
| trailing_slash = x.endswith(endswith_slash) |
| x = normalize_path(x) |
| if trailing_slash: |
| # Modify behavior of basename and dirname |
| # as noted in bug #425214, causing foo/ to |
| # behave similarly to the way that foo/* |
| # behaves. |
| x += os.sep |
| basename = os.path.basename(x) |
| dirname = os.path.dirname(x) |
| success |= install(basename, dirname, options) |
| |
| for x in skipped_directories: |
| eqawarn(["QA Notice: dohtml on directory '%s' without recursion option" % x]) |
| for x in skipped_files: |
| eqawarn(["dohtml: skipped file '%s'" % x]) |
| |
| if success: |
| retcode = 0 |
| else: |
| retcode = 1 |
| |
| sys.exit(retcode) |
| |
| if __name__ == "__main__": |
| main() |