dohtml: optimize for bug #482290
authorZac Medico <zmedico@gentoo.org>
Sat, 24 Aug 2013 18:24:02 +0000 (11:24 -0700)
committerZac Medico <zmedico@gentoo.org>
Sat, 24 Aug 2013 18:24:02 +0000 (11:24 -0700)
Use os.makedirs and shutil.copy instead of spawning install, since
spawning install is much slower (especially with FEATURES=xattr).

bin/dohtml.py

index 1b6ba89f1d6e295cd44f5e2a75947ebd46a3b2f2..ec9a80b57f445a70e6a261772b4888db46d01dba 100755 (executable)
 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):
-       os.spawnlp(os.P_WAIT, "install", "install", "-d", path)
+       try:
+               os.makedirs(path, 0o755)
+       except OSError:
+               if not os.path.isdir(path):
+                       raise
+               os.chmod(path, 0o755)
 
 def dofile(src,dst):
-       os.spawnlp(os.P_WAIT, "install", "install", "-m0644", src, dst)
+       shutil.copy(src, dst)
+       os.chmod(dst, 0o644)
 
 def eqawarn(lines):
        cmd = "source '%s/isolated-functions.sh' ; " % \
@@ -58,14 +67,18 @@ unwarned_skipped_files = os.environ.get("PORTAGE_DOHTML_UNWARNED_SKIPPED_FILES",
 def install(basename, dirname, options, prefix=""):
        fullpath = basename
        if prefix:
-               fullpath = prefix + "/" + fullpath
+               fullpath = os.path.join(prefix, fullpath)
        if dirname:
-               fullpath = dirname + "/" + fullpath
+               fullpath = os.path.join(dirname, fullpath)
 
        if options.DOCDESTTREE:
-               destdir = options.ED + "usr/share/doc/" + options.PF + "/" + options.DOCDESTTREE + "/" + options.doc_prefix + "/" + prefix
+               desttree = options.DOCDESTTREE
        else:
-               destdir = options.ED + "usr/share/doc/" + options.PF + "/html/" + options.doc_prefix + "/" + prefix
+               desttree = "html"
+
+       destdir = os.path.join(options.ED, "usr", "share", "doc",
+               options.PF.lstrip(os.sep), desttree,
+               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)
@@ -74,14 +87,15 @@ def install(basename, dirname, options, prefix=""):
                ext = os.path.splitext(basename)[1][1:]
                if ext in options.allowed_exts or basename in options.allowed_files:
                        dodir(destdir)
-                       dofile(fullpath, destdir + "/" + basename)
+                       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 = prefix + "/" + pfx
+                       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
@@ -100,13 +114,19 @@ class OptionsClass:
 
                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"):
@@ -156,6 +176,8 @@ def parse_args():
                                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":
@@ -184,6 +206,7 @@ def main():
        success = False
 
        for x in args:
+               x = normalize_path(x)
                basename = os.path.basename(x)
                dirname  = os.path.dirname(x)
                success |= install(basename, dirname, options)