egencache: handle empty --portdir-overlay
[portage.git] / bin / dohtml.py
1 #!/usr/bin/python
2 # Copyright 1999-2013 Gentoo Foundation
3 # Distributed under the terms of the GNU General Public License v2
4
5 #
6 # Typical usage:
7 # dohtml -r docs/*
8 #  - put all files and directories in docs into /usr/share/doc/${PF}/html
9 # dohtml foo.html
10 #  - put foo.html into /usr/share/doc/${PF}/html
11 #
12 #
13 # Detailed usage:
14 # dohtml <list-of-files>
15 #  - will install the files in the list of files (space-separated list) into
16 #    /usr/share/doc/${PF}/html, provided the file ends in .css, .gif, .htm,
17 #    .html, .jpeg, .jpg, .js or .png.
18 # dohtml -r <list-of-files-and-directories>
19 #  - will do as 'dohtml', but recurse into all directories, as long as the
20 #    directory name is not CVS
21 # dohtml -A jpe,java [-r] <list-of-files[-and-directories]>
22 #  - will do as 'dohtml' but add .jpe,.java (default filter list is
23 #    added to your list)
24 # dohtml -a png,gif,html,htm [-r] <list-of-files[-and-directories]>
25 #  - will do as 'dohtml' but filter on .png,.gif,.html,.htm (default filter
26 #    list is ignored)
27 # dohtml -x CVS,SCCS,RCS -r <list-of-files-and-directories>
28 #  - will do as 'dohtml -r', but ignore directories named CVS, SCCS, RCS
29 #
30
31 from __future__ import print_function
32
33 import os
34 import sys
35
36 # Change back to original cwd _after_ all imports (bug #469338).
37 os.chdir(os.environ["__PORTAGE_HELPER_CWD"])
38
39 def dodir(path):
40         os.spawnlp(os.P_WAIT, "install", "install", "-d", path)
41
42 def dofile(src,dst):
43         os.spawnlp(os.P_WAIT, "install", "install", "-m0644", src, dst)
44
45 def eqawarn(lines):
46         cmd = "source '%s/isolated-functions.sh' ; " % \
47                 os.environ["PORTAGE_BIN_PATH"]
48         for line in lines:
49                 cmd += "eqawarn \"%s\" ; " % line
50         os.spawnlp(os.P_WAIT, "bash", "bash", "-c", cmd)
51
52 skipped_directories = []
53 skipped_files = []
54 warn_on_skipped_files = os.environ.get("PORTAGE_DOHTML_WARN_ON_SKIPPED_FILES") is not None
55 unwarned_skipped_extensions = os.environ.get("PORTAGE_DOHTML_UNWARNED_SKIPPED_EXTENSIONS", "").split()
56 unwarned_skipped_files = os.environ.get("PORTAGE_DOHTML_UNWARNED_SKIPPED_FILES", "").split()
57
58 def install(basename, dirname, options, prefix=""):
59         fullpath = basename
60         if prefix:
61                 fullpath = prefix + "/" + fullpath
62         if dirname:
63                 fullpath = dirname + "/" + fullpath
64
65         if options.DOCDESTTREE:
66                 destdir = options.ED + "usr/share/doc/" + options.PF + "/" + options.DOCDESTTREE + "/" + options.doc_prefix + "/" + prefix
67         else:
68                 destdir = options.ED + "usr/share/doc/" + options.PF + "/html/" + options.doc_prefix + "/" + prefix
69
70         if not os.path.exists(fullpath):
71                 sys.stderr.write("!!! dohtml: %s does not exist\n" % fullpath)
72                 return False
73         elif os.path.isfile(fullpath):
74                 ext = os.path.splitext(basename)[1][1:]
75                 if ext in options.allowed_exts or basename in options.allowed_files:
76                         dodir(destdir)
77                         dofile(fullpath, destdir + "/" + basename)
78                 elif warn_on_skipped_files and ext not in unwarned_skipped_extensions and basename not in unwarned_skipped_files:
79                         skipped_files.append(fullpath)
80         elif options.recurse and os.path.isdir(fullpath) and \
81              basename not in options.disallowed_dirs:
82                 for i in os.listdir(fullpath):
83                         pfx = basename
84                         if prefix: pfx = prefix + "/" + pfx
85                         install(i, dirname, options, pfx)
86         elif not options.recurse and os.path.isdir(fullpath):
87                 global skipped_directories
88                 skipped_directories.append(fullpath)
89                 return False
90         else:
91                 return False
92         return True
93
94
95 class OptionsClass:
96         def __init__(self):
97                 self.PF = ""
98                 self.ED = ""
99                 self.DOCDESTTREE = ""
100
101                 if "PF" in os.environ:
102                         self.PF = os.environ["PF"]
103                 if "force-prefix" not in os.environ.get("FEATURES", "").split() and \
104                         os.environ.get("EAPI", "0") in ("0", "1", "2"):
105                         self.ED = os.environ.get("D", "")
106                 else:
107                         self.ED = os.environ.get("ED", "")
108                 if "_E_DOCDESTTREE_" in os.environ:
109                         self.DOCDESTTREE = os.environ["_E_DOCDESTTREE_"]
110
111                 self.allowed_exts = ['css', 'gif', 'htm', 'html', 'jpeg', 'jpg', 'js', 'png']
112                 if os.environ.get("EAPI", "0") in ("4-python", "5-progress"):
113                         self.allowed_exts += ['ico', 'svg', 'xhtml', 'xml']
114                 self.allowed_files = []
115                 self.disallowed_dirs = ['CVS']
116                 self.recurse = False
117                 self.verbose = False
118                 self.doc_prefix = ""
119
120 def print_help():
121         opts = OptionsClass()
122
123         print("dohtml [-a .foo,.bar] [-A .foo,.bar] [-f foo,bar] [-x foo,bar]")
124         print("       [-r] [-V] <file> [file ...]")
125         print()
126         print(" -a   Set the list of allowed to those that are specified.")
127         print("      Default:", ",".join(opts.allowed_exts))
128         print(" -A   Extend the list of allowed file types.")
129         print(" -f   Set list of allowed extensionless file names.")
130         print(" -x   Set directories to be excluded from recursion.")
131         print("      Default:", ",".join(opts.disallowed_dirs))
132         print(" -p   Set a document prefix for installed files (empty by default).")
133         print(" -r   Install files and directories recursively.")
134         print(" -V   Be verbose.")
135         print()
136
137 def parse_args():
138         options = OptionsClass()
139         args = []
140
141         x = 1
142         while x < len(sys.argv):
143                 arg = sys.argv[x]
144                 if arg in ["-h","-r","-V"]:
145                         if arg == "-h":
146                                 print_help()
147                                 sys.exit(0)
148                         elif arg == "-r":
149                                 options.recurse = True
150                         elif arg == "-V":
151                                 options.verbose = True
152                 elif sys.argv[x] in ["-A","-a","-f","-x","-p"]:
153                         x += 1
154                         if x == len(sys.argv):
155                                 print_help()
156                                 sys.exit(0)
157                         elif arg == "-p":
158                                 options.doc_prefix = sys.argv[x]
159                         else:
160                                 values = sys.argv[x].split(",")
161                                 if arg == "-A":
162                                         options.allowed_exts.extend(values)
163                                 elif arg == "-a":
164                                         options.allowed_exts = values
165                                 elif arg == "-f":
166                                         options.allowed_files = values
167                                 elif arg == "-x":
168                                         options.disallowed_dirs = values
169                 else:
170                         args.append(sys.argv[x])
171                 x += 1
172
173         return (options, args)
174
175 def main():
176
177         (options, args) = parse_args()
178
179         if options.verbose:
180                 print("Allowed extensions:", options.allowed_exts)
181                 print("Document prefix : '" + options.doc_prefix + "'")
182                 print("Allowed files :", options.allowed_files)
183
184         success = False
185
186         for x in args:
187                 basename = os.path.basename(x)
188                 dirname  = os.path.dirname(x)
189                 success |= install(basename, dirname, options)
190
191         for x in skipped_directories:
192                 eqawarn(["QA Notice: dohtml on directory '%s' without recursion option" % x])
193         for x in skipped_files:
194                 eqawarn(["dohtml: skipped file '%s'" % x])
195
196         if success:
197                 retcode = 0
198         else:
199                 retcode = 1
200
201         sys.exit(retcode)
202
203 if __name__ == "__main__":
204         main()