Added command stack saving and loading.
[hooke.git] / doc / SConstruct
1 """
2 This is a generic SCons script for running Sphinx (http://sphinx.pocoo.org).
3
4 Type 'scons -h' for help.  This prints the available build targets on your
5 system, and the configuration options you can set.
6
7 If you set the 'cache' option, the option settings are cached into a file
8 called '.sconsrc-sphinx' in the current directory.  When running
9 subsequently, this file is reread.  A file with this name is also read from
10 your home directory, if it exists, so you can put global settings there.
11
12 The script looks into your 'conf.py' file for information about the
13 project.  This is used in various places (e.g., to print the introductory
14 message, and create package files).
15
16 Here's some examples.  To build HTML docs:
17
18    scons html
19
20 To create a package containing HTML and PDF docs, remembering the 'install'
21 setting:
22
23    scons install=html,pdf cache=True package
24
25 To clean up everything:
26
27    scons -c all
28 """
29
30 # Script info.
31 __author__  = "Glenn Hutchings"
32 __email__   = "zondo42@googlemail.com"
33 __url__     = "http://bitbucket.org/zondo/sphinx-scons"
34 __license__ = "BSD"
35 __version__ = "0.4"
36
37 import sys, os
38
39 # Build targets.
40 targets = (
41     ("html",      "make standalone HTML files"),
42     ("dirhtml",   "make HTML files named index.html in directories"),
43     ("pickle",    "make pickle files"),
44     ("json",      "make JSON files"),
45     ("htmlhelp",  "make HTML files and a HTML help project"),
46     ("qthelp",    "make HTML files and a qthelp project"),
47     ("devhelp",   "make HTML files and a GNOME DevHelp project"),
48     ("epub",      "make HTML files and an EPUB file for bookreaders"),
49     ("latex",     "make LaTeX sources"),
50     ("text",      "make text file for each RST file"),
51     ("pdf",       "make PDF file from LaTeX sources"),
52     ("ps",        "make PostScript file from LaTeX sources"),
53     ("dvi",       "make DVI file from LaTeX sources"),
54     ("changes",   "make an overview over all changed/added/deprecated items"),
55     ("linkcheck", "check all external links for integrity"),
56     ("doctest",   "run all doctests embedded in the documentation if enabled"),
57     ("source",    "run a command to generate the reStructuredText source"),
58 )
59
60 # LaTeX builders.
61 latex_builders = {"pdf": "PDF", "ps": "PostScript", "dvi": "DVI"}
62
63 # List of target names.
64 targetnames = [name for name, desc in targets]
65
66 # Configuration cache filename.
67 cachefile = ".sconsrc-sphinx"
68
69 # User cache file.
70 homedir = os.path.expanduser('~')
71 usercache = os.path.join(homedir, cachefile)
72
73 # Configuration options.
74 config = Variables([usercache, cachefile], ARGUMENTS)
75
76 config.AddVariables(
77     EnumVariable("default", "default build target", "html", targetnames),
78     PathVariable("config", "sphinx configuration file", "conf.py"),
79     PathVariable("srcdir", "source directory", ".",
80                  PathVariable.PathIsDir),
81     PathVariable("builddir", "build directory", "build",
82                  PathVariable.PathIsDirCreate),
83     PathVariable("doctrees", "place to put doctrees", None,
84                  PathVariable.PathAccept),
85     EnumVariable("paper", "LaTeX paper size", None,
86                  ["a4", "letter"], ignorecase = False),
87     ("tags", "comma-separated list of 'only' tags", None),
88     ("builder", "program to run to build things", "sphinx-build"),
89     ("opts", "extra builder options to use", None),
90     ListVariable("install", "targets to install", ["html"], targetnames),
91     PathVariable("instdir", "installation directory", "/usr/local/doc",
92                  PathVariable.PathAccept),
93     EnumVariable("pkgtype", "package type to build with 'scons package'",
94                  "zip", ["zip", "targz", "tarbz2"], ignorecase = False),
95     BoolVariable("cache", "whether to cache settings in %s" % cachefile, False),
96     BoolVariable("debug", "debugging flag", False),
97     ("genrst", "Command to regenerate reStructuredText source", None),
98 )
99
100 # Create a new environment, inheriting PATH to find builder program.  Also
101 # force LaTeX instead of TeX, since the .tex file won't exist at the right
102 # time to check which one to use.
103 env = Environment(ENV = {"PATH" : os.environ["PATH"]},
104                   TEX = "latex", PDFTEX = "pdflatex",
105                   tools = ['default', 'packaging'],
106                   variables = config)
107 if 'PYTHONPATH' in os.environ:
108     env['ENV']['PYTHONPATH'] = os.environ['PYTHONPATH']
109
110 # Get configuration values from environment.
111 sphinxconf = env["config"]
112 builder = env["builder"]
113 default = env["default"]
114
115 srcdir = env["srcdir"]
116 builddir = env["builddir"]
117 doctrees = env.get("doctrees", os.path.join(builddir, "doctrees"))
118
119 cache = env["cache"]
120 debug = env["debug"]
121
122 options = env.get("opts", None)
123 paper = env.get("paper", None)
124 tags = env.get("tags", None)
125 genrst = env.get("genrst", None)
126
127 instdir = env["instdir"]
128 install = env["install"]
129 pkgtype = env["pkgtype"]
130
131 # Dump internals if debugging.
132 if debug:
133     print "Environment:"
134     print env.Dump()
135
136 # Get parameters from Sphinx config file.
137 sphinxparams = {}
138 execfile(sphinxconf, sphinxparams)
139
140 project = sphinxparams["project"]
141 release = sphinxparams["release"]
142 copyright = sphinxparams["copyright"]
143
144 try:
145     texfilename = sphinxparams["latex_documents"][0][1]
146 except KeyError:
147     texfilename = None
148
149 name2tag = lambda name: name.replace(" ", "-").strip("()")
150 project_tag = name2tag(project)
151 release_tag = name2tag(release)
152 package_tag = project_tag.lower() + "-" + release_tag.lower()
153
154 # Build project description string.
155 description = "%(project)s, release %(release)s, " \
156                "copyright %(copyright)s" % locals()
157
158 Help(description + "\n\n")
159 help_format = "   %-10s  %s\n"
160
161 # Print banner if required.
162 if not any(map(GetOption, ("silent", "clean", "help"))):
163     print
164     print "This is", description
165     print
166
167 # Build sphinx command-line options.
168 opts = []
169
170 if tags:
171     opts.extend(["-t %s" % tag for tag in tags.split(",")])
172
173 if paper:
174     opts.append("-D latex_paper_size=%s" % paper)
175
176 if options:
177     opts.append(options)
178
179 options = " ".join(opts)
180
181 # Build Sphinx command template.
182 sphinxcmd = """
183 %(builder)s -b %(name)s -d %(doctrees)s %(options)s %(srcdir)s %(targetdir)s
184 """.strip()
185
186 # Set up LaTeX input builder if required.
187 if texfilename:
188     latexdir = Dir("latex", builddir)
189     texinput = File(texfilename, latexdir)
190     env.SideEffect(texinput, "latex")
191     env.NoClean(texinput)
192
193 # Add build targets.
194 Help("Build targets:\n\n")
195
196 if genrst != None:
197     source = env.Command('source', [], genrst, chdir = True)
198     env.AlwaysBuild(source)
199     env.Depends(srcdir, source)
200 else:
201     source = env.Command(
202         'source', [],
203         '@echo "No reStructuredText generator (genrst) given."')
204
205 for name, desc in targets:
206     target = Dir(name, builddir)
207     targetdir = str(target)
208
209     if name == 'source':
210         pass
211     elif name not in latex_builders:
212         # Standard Sphinx target.
213         targets = env.Command(name, sphinxconf,
214                               sphinxcmd % locals(), chdir = True)
215         env.Depends(targets, source)
216         env.AlwaysBuild(name)
217         env.Alias(target, name)
218     elif texinput:
219         # Target built from LaTeX sources.
220         try:
221             buildfunc = getattr(env, latex_builders[name])
222         except AttributeError:
223             continue
224
225         filename = project_tag + "." + name
226         outfile = File(filename, latexdir)
227
228         targets = buildfunc(outfile, texinput)
229         env.Depends(targets, source)
230
231         # Copy built file to separate directory.
232         target = File(filename, target)
233         env.Command(target, outfile, Move(target, outfile), chdir = True)
234
235         env.Alias(name, target)
236     else:
237         continue
238
239     env.Clean(name, [target])
240     env.Clean('all', target)
241
242     if name == default: desc += " (default)"
243     Help(help_format % (name, desc))
244
245 Clean('all', doctrees)
246 Default(default)
247
248 # Add installation targets and collect package sources.
249 Help("\nOther targets:\n\n")
250
251 Help(help_format % ("install", "install documentation"))
252 projectdir = os.path.join(instdir, project_tag)
253 sources = []
254
255 for name in install:
256     source = Dir(name, builddir)
257     sources.append(source)
258
259     inst = env.Install(projectdir, source)
260     env.Alias('install', inst)
261
262     for node in env.Glob(os.path.join(str(source), '*')):
263         filename = str(node).replace(builddir + os.path.sep, "")
264         dirname = os.path.dirname(filename)
265         dest = os.path.join(projectdir, dirname)
266         inst = env.Install(dest, node)
267         env.Alias('install', inst)
268
269 # Add uninstall target.
270 env.Command('uninstall', None, Delete(projectdir), chdir = True)
271 Help(help_format % ("uninstall", "uninstall documentation"))
272
273 ## Add package builder.
274 #packageroot = "-".join([project_tag, release_tag])
275 #archive, package = env.Package(NAME = project_tag, VERSION = release,
276 #                               PACKAGEROOT = packageroot,
277 #                               PACKAGETYPE = pkgtype,
278 #                               source = sources)
279 #
280 #env.AlwaysBuild(archive)
281 #env.AddPostAction(archive, Delete(packageroot))
282 #Help(help_format % ("package", "build documentation package"))
283 #
284 #env.Clean('all', archive)
285
286 # Add config settings to help.
287 Help("\nConfiguration variables:")
288 for line in config.GenerateHelpText(env).split("\n"):
289     Help("\n   " + line)
290
291 # Save local configuration if required.
292 if cache:
293     config.Update(env)
294     config.Save(cachefile, env)