ยปCore Development>Code coverage>Mac/Tools/Doc/setup.py

Python code coverage for Mac/Tools/Doc/setup.py

#countcontent
1n/a# Build and install an Apple Help Viewer compatible version of the Python
2n/a# documentation into the framework.
3n/a# Code by Bill Fancher, with some modifications by Jack Jansen.
4n/a#
5n/a# You must run this as a two-step process
6n/a# 1. python setupDocs.py build
7n/a# 2. Wait for Apple Help Indexing Tool to finish
8n/a# 3. python setupDocs.py install
9n/a#
10n/a# To do:
11n/a# - test whether the docs are available locally before downloading
12n/a# - fix buildDocsFromSource
13n/a# - Get documentation version from sys.version, fallback to 2.2.1
14n/a# - See if we can somehow detect that Apple Help Indexing Tool is finished
15n/a# - data_files to setup() doesn't seem the right way to pass the arguments
16n/a#
17n/aimport sys, os, re
18n/afrom distutils.cmd import Command
19n/afrom distutils.command.build import build
20n/afrom distutils.core import setup
21n/afrom distutils.file_util import copy_file
22n/afrom distutils.dir_util import copy_tree
23n/afrom distutils.log import log
24n/afrom distutils.spawn import spawn
25n/afrom distutils import sysconfig, dep_util
26n/afrom distutils.util import change_root
27n/aimport HelpIndexingTool
28n/aimport Carbon.File
29n/aimport time
30n/a
31n/aMAJOR_VERSION='2.4'
32n/aMINOR_VERSION='2.4.1'
33n/aDESTDIR='/Applications/MacPython-%s/PythonIDE.app/Contents/Resources/English.lproj/PythonDocumentation' % MAJOR_VERSION
34n/a
35n/aclass DocBuild(build):
36n/a def initialize_options(self):
37n/a build.initialize_options(self)
38n/a self.build_html = None
39n/a self.build_dest = None
40n/a self.download = 1
41n/a self.doc_version = MINOR_VERSION # Only needed if download is true
42n/a
43n/a def finalize_options(self):
44n/a build.finalize_options(self)
45n/a if self.build_html is None:
46n/a self.build_html = os.path.join(self.build_base, 'html')
47n/a if self.build_dest is None:
48n/a self.build_dest = os.path.join(self.build_base, 'PythonDocumentation')
49n/a
50n/a def spawn(self, *args):
51n/a spawn(args, 1, self.verbose, self.dry_run)
52n/a
53n/a def downloadDocs(self):
54n/a workdir = os.getcwd()
55n/a # XXX Note: the next strings may change from version to version
56n/a url = 'http://www.python.org/ftp/python/doc/%s/html-%s.tar.bz2' % \
57n/a (self.doc_version,self.doc_version)
58n/a tarfile = 'html-%s.tar.bz2' % self.doc_version
59n/a dirname = 'Python-Docs-%s' % self.doc_version
60n/a
61n/a if os.path.exists(self.build_html):
62n/a raise RuntimeError('%s: already exists, please remove and try again' % self.build_html)
63n/a os.chdir(self.build_base)
64n/a self.spawn('curl','-O', url)
65n/a self.spawn('tar', '-xjf', tarfile)
66n/a os.rename(dirname, 'html')
67n/a os.chdir(workdir)
68n/a## print "** Please unpack %s" % os.path.join(self.build_base, tarfile)
69n/a## print "** Unpack the files into %s" % self.build_html
70n/a## raise RuntimeError, "You need to unpack the docs manually"
71n/a
72n/a def buildDocsFromSource(self):
73n/a srcdir = '../../..'
74n/a docdir = os.path.join(srcdir, 'Doc')
75n/a htmldir = os.path.join(docdir, 'html')
76n/a spawn(('make','--directory', docdir, 'html'), 1, self.verbose, self.dry_run)
77n/a self.mkpath(self.build_html)
78n/a copy_tree(htmldir, self.build_html)
79n/a
80n/a def ensureHtml(self):
81n/a if not os.path.exists(self.build_html):
82n/a if self.download:
83n/a self.downloadDocs()
84n/a else:
85n/a self.buildDocsFromSource()
86n/a
87n/a def hackIndex(self):
88n/a ind_html = 'index.html'
89n/a #print 'self.build_dest =', self.build_dest
90n/a hackedIndex = file(os.path.join(self.build_dest, ind_html),'w')
91n/a origIndex = file(os.path.join(self.build_html,ind_html))
92n/a r = re.compile('<style type="text/css">.*</style>', re.DOTALL)
93n/a hackedIndex.write(r.sub('<META NAME="AppleTitle" CONTENT="Python Documentation">',origIndex.read()))
94n/a
95n/a def hackFile(self,d,f):
96n/a origPath = os.path.join(d,f)
97n/a assert(origPath[:len(self.build_html)] == self.build_html)
98n/a outPath = os.path.join(self.build_dest, d[len(self.build_html)+1:], f)
99n/a (name, ext) = os.path.splitext(f)
100n/a if os.path.isdir(origPath):
101n/a self.mkpath(outPath)
102n/a elif ext == '.html':
103n/a if self.verbose: print('hacking %s to %s' % (origPath,outPath))
104n/a hackedFile = file(outPath, 'w')
105n/a origFile = file(origPath,'r')
106n/a hackedFile.write(self.r.sub('<dl><dt><dd>', origFile.read()))
107n/a else:
108n/a copy_file(origPath, outPath)
109n/a
110n/a def hackHtml(self):
111n/a self.r = re.compile('<dl><dd>')
112n/a os.walk(self.build_html, self.visit, None)
113n/a
114n/a def visit(self, dummy, dirname, filenames):
115n/a for f in filenames:
116n/a self.hackFile(dirname, f)
117n/a
118n/a def makeHelpIndex(self):
119n/a app = '/Developer/Applications/Apple Help Indexing Tool.app'
120n/a self.spawn('open', '-a', app , self.build_dest)
121n/a print("Please wait until Apple Help Indexing Tool finishes before installing")
122n/a
123n/a def makeHelpIndex(self):
124n/a app = HelpIndexingTool.HelpIndexingTool(start=1)
125n/a app.open(Carbon.File.FSSpec(self.build_dest))
126n/a sys.stderr.write("Waiting for Help Indexing Tool to start...")
127n/a while 1:
128n/a # This is bad design in the suite generation code!
129n/a idle = app._get(HelpIndexingTool.Help_Indexing_Tool_Suite._Prop_idleStatus())
130n/a time.sleep(10)
131n/a if not idle: break
132n/a sys.stderr.write(".")
133n/a sys.stderr.write("\n")
134n/a sys.stderr.write("Waiting for Help Indexing Tool to finish...")
135n/a while 1:
136n/a # This is bad design in the suite generation code!
137n/a idle = app._get(HelpIndexingTool.Help_Indexing_Tool_Suite._Prop_idleStatus())
138n/a time.sleep(10)
139n/a if idle: break
140n/a sys.stderr.write(".")
141n/a sys.stderr.write("\n")
142n/a
143n/a
144n/a def run(self):
145n/a self.ensure_finalized()
146n/a self.mkpath(self.build_base)
147n/a self.ensureHtml()
148n/a if not os.path.isdir(self.build_html):
149n/a raise RuntimeError("Can't find source folder for documentation.")
150n/a self.mkpath(self.build_dest)
151n/a if dep_util.newer(os.path.join(self.build_html,'index.html'), os.path.join(self.build_dest,'index.html')):
152n/a self.mkpath(self.build_dest)
153n/a self.hackHtml()
154n/a self.hackIndex()
155n/a self.makeHelpIndex()
156n/a
157n/aclass AHVDocInstall(Command):
158n/a description = "install Apple Help Viewer html files"
159n/a user_options = [('install-doc=', 'd',
160n/a 'directory to install HTML tree'),
161n/a ('root=', None,
162n/a "install everything relative to this alternate root directory"),
163n/a ]
164n/a
165n/a def initialize_options(self):
166n/a self.build_dest = None
167n/a self.install_doc = None
168n/a self.prefix = None
169n/a self.root = None
170n/a
171n/a def finalize_options(self):
172n/a self.set_undefined_options('install',
173n/a ('prefix', 'prefix'),
174n/a ('root', 'root'))
175n/a# import pdb ; pdb.set_trace()
176n/a build_cmd = self.get_finalized_command('build')
177n/a if self.build_dest is None:
178n/a build_cmd = self.get_finalized_command('build')
179n/a self.build_dest = build_cmd.build_dest
180n/a if self.install_doc is None:
181n/a self.install_doc = os.path.join(self.prefix, DESTDIR)
182n/a print('INSTALL', self.build_dest, '->', self.install_doc)
183n/a
184n/a def run(self):
185n/a self.finalize_options()
186n/a self.ensure_finalized()
187n/a print("Running Installer")
188n/a instloc = self.install_doc
189n/a if self.root:
190n/a instloc = change_root(self.root, instloc)
191n/a self.mkpath(instloc)
192n/a copy_tree(self.build_dest, instloc)
193n/a print("Installation complete")
194n/a
195n/adef mungeVersion(infile, outfile):
196n/a i = file(infile,'r')
197n/a o = file(outfile,'w')
198n/a o.write(re.sub('\$\(VERSION\)',sysconfig.get_config_var('VERSION'),i.read()))
199n/a i.close()
200n/a o.close()
201n/a
202n/adef main():
203n/a # turn off warnings when deprecated modules are imported
204n/a## import warnings
205n/a## warnings.filterwarnings("ignore",category=DeprecationWarning)
206n/a setup(name = 'Documentation',
207n/a version = '%d.%d' % sys.version_info[:2],
208n/a cmdclass = {'install_data':AHVDocInstall, 'build':DocBuild},
209n/a data_files = ['dummy'],
210n/a )
211n/a
212n/aif __name__ == '__main__':
213n/a main()