blob: 8e1265e12b69cf0df6d21c41b226ac8e3f9ab36a [file] [log] [blame]
Jack Jansen278a3a22002-08-28 22:22:10 +00001# Build and install an Apple Help Viewer compatible version of the Python
2# documentation into the framework.
3# Code by Bill Fancher, with some modifications by Jack Jansen.
4#
5# You must run this as a two-step process
6# 1. python setupDocs.py build
7# 2. Wait for Apple Help Indexing Tool to finish
8# 3. python setupDocs.py install
9#
10# To do:
11# - test whether the docs are available locally before downloading
12# - fix buildDocsFromSource
13# - Get documentation version from sys.version, fallback to 2.2.1
14# - See if we can somehow detect that Apple Help Indexing Tool is finished
15# - data_files to setup() doesn't seem the right way to pass the arguments
16#
17import sys, os, re
18from distutils.cmd import Command
19from distutils.command.build import build
20from distutils.core import setup
21from distutils.file_util import copy_file
22from distutils.dir_util import copy_tree
23from distutils.log import log
24from distutils.spawn import spawn
25from distutils import sysconfig, dep_util
Jack Jansend2c684f2003-02-14 23:46:22 +000026from distutils.util import change_root
Jack Jansen278a3a22002-08-28 22:22:10 +000027
Jack Jansen278a3a22002-08-28 22:22:10 +000028
29class DocBuild(build):
30 def initialize_options(self):
31 build.initialize_options(self)
Jack Jansend2c684f2003-02-14 23:46:22 +000032 self.build_html = None
33 self.build_dest = None
Jack Jansen278a3a22002-08-28 22:22:10 +000034 self.download = 1
35 self.doc_version = '2.2.1'
36
37 def finalize_options(self):
38 build.finalize_options(self)
Jack Jansend2c684f2003-02-14 23:46:22 +000039 if self.build_html is None:
40 self.build_html = os.path.join(self.build_base, 'html')
41 if self.build_dest is None:
42 self.build_dest = os.path.join(self.build_base, 'processed-html')
Jack Jansen278a3a22002-08-28 22:22:10 +000043
44 def spawn(self, *args):
45 spawn(args, 1, self.verbose, self.dry_run)
46
47 def downloadDocs(self):
48 workdir = os.getcwd()
Jack Jansend2c684f2003-02-14 23:46:22 +000049 self.mkpath(self.build_html)
50 os.chdir(self.build_base)
Jack Jansen278a3a22002-08-28 22:22:10 +000051 self.spawn('curl','-O', 'http://www.python.org/ftp/python/doc/%s/html-%s.tgz' % (self.doc_version,self.doc_version))
Jack Jansend2c684f2003-02-14 23:46:22 +000052 os.chdir(workdir)
53 os.chdir(self.build_html)
Jack Jansen278a3a22002-08-28 22:22:10 +000054 self.spawn('tar', '-xzf', '../html-%s.tgz' % self.doc_version)
Jack Jansend2c684f2003-02-14 23:46:22 +000055 os.chdir(workdir)
Jack Jansen278a3a22002-08-28 22:22:10 +000056
Jack Jansenf68043c2003-02-14 12:47:14 +000057 def buildDocsFromSource(self):
Jack Jansend2c684f2003-02-14 23:46:22 +000058 srcdir = '../../..'
59 docdir = os.path.join(srcdir, 'Doc')
60 htmldir = os.path.join(docdir, 'html')
61 spawn(('make','--directory', docdir, 'html'), 1, self.verbose, self.dry_run)
62 self.mkpath(self.build_html)
63 copy_tree(htmldir, self.build_html)
Jack Jansen278a3a22002-08-28 22:22:10 +000064
65 def ensureHtml(self):
Jack Jansend2c684f2003-02-14 23:46:22 +000066 if not os.path.exists(self.build_html):
Jack Jansen278a3a22002-08-28 22:22:10 +000067 if self.download:
68 self.downloadDocs()
69 else:
70 self.buildDocsFromSource()
71
72 def hackIndex(self):
73 ind_html = 'index.html'
74 #print 'self.build_dest =', self.build_dest
75 hackedIndex = file(os.path.join(self.build_dest, ind_html),'w')
Jack Jansend2c684f2003-02-14 23:46:22 +000076 origIndex = file(os.path.join(self.build_html,ind_html))
Jack Jansen278a3a22002-08-28 22:22:10 +000077 r = re.compile('<style type="text/css">.*</style>', re.DOTALL)
78 hackedIndex.write(r.sub('<META NAME="AppleTitle" CONTENT="Python Help">',origIndex.read()))
79
80 def hackFile(self,d,f):
81 origPath = os.path.join(d,f)
Jack Jansend2c684f2003-02-14 23:46:22 +000082 assert(origPath[:len(self.build_html)] == self.build_html)
83 outPath = os.path.join(self.build_dest, d[len(self.build_html)+1:], f)
Jack Jansen278a3a22002-08-28 22:22:10 +000084 (name, ext) = os.path.splitext(f)
85 if os.path.isdir(origPath):
86 self.mkpath(outPath)
87 elif ext == '.html':
88 if self.verbose: print 'hacking %s to %s' % (origPath,outPath)
89 hackedFile = file(outPath, 'w')
90 origFile = file(origPath,'r')
91 hackedFile.write(self.r.sub('<dl><dt><dd>', origFile.read()))
92 else:
93 copy_file(origPath, outPath)
94
95 def hackHtml(self):
96 self.r = re.compile('<dl><dd>')
Jack Jansend2c684f2003-02-14 23:46:22 +000097 os.path.walk(self.build_html, self.visit, None)
98
99 def visit(self, dummy, dirname, filenames):
100 for f in filenames:
101 self.hackFile(dirname, f)
Jack Jansen278a3a22002-08-28 22:22:10 +0000102
103 def makeHelpIndex(self):
104 app = '/Developer/Applications/Apple Help Indexing Tool.app'
105 self.spawn('open', '-a', app , self.build_dest)
106 print "Please wait until Apple Help Indexing Tool finishes before installing"
107
108 def run(self):
109 self.ensure_finalized()
110 self.ensureHtml()
Jack Jansend2c684f2003-02-14 23:46:22 +0000111 if not os.path.isdir(self.build_html):
Jack Jansen278a3a22002-08-28 22:22:10 +0000112 raise RuntimeError, \
113 "Can't find source folder for documentation."
Jack Jansend2c684f2003-02-14 23:46:22 +0000114 self.mkpath(self.build_dest)
115 if dep_util.newer(os.path.join(self.build_html,'index.html'), os.path.join(self.build_dest,'index.html')):
Jack Jansen278a3a22002-08-28 22:22:10 +0000116 self.mkpath(self.build_dest)
117 self.hackHtml()
118 self.hackIndex()
119 self.makeHelpIndex()
120
Jack Jansend2c684f2003-02-14 23:46:22 +0000121class AHVDocInstall(Command):
122 description = "install Apple Help Viewer html files"
123 user_options = [('install-doc=', 'd',
124 'directory to install HTML tree'),
125 ('root=', None,
126 "install everything relative to this alternate root directory"),
127 ]
128
Jack Jansen278a3a22002-08-28 22:22:10 +0000129 def initialize_options(self):
130 self.build_dest = None
Jack Jansend2c684f2003-02-14 23:46:22 +0000131 self.install_doc = None
132 self.prefix = None
133 self.root = None
Jack Jansen278a3a22002-08-28 22:22:10 +0000134
Jack Jansend2c684f2003-02-14 23:46:22 +0000135 def finalize_options(self):
136 self.set_undefined_options('install',
137 ('prefix', 'prefix'),
138 ('root', 'root'))
139# import pdb ; pdb.set_trace()
Jack Jansen278a3a22002-08-28 22:22:10 +0000140 build_cmd = self.get_finalized_command('build')
141 if self.build_dest == None:
Jack Jansend2c684f2003-02-14 23:46:22 +0000142 build_cmd = self.get_finalized_command('build')
Jack Jansen278a3a22002-08-28 22:22:10 +0000143 self.build_dest = build_cmd.build_dest
Jack Jansend2c684f2003-02-14 23:46:22 +0000144 if self.install_doc == None:
145 self.install_doc = os.path.join(self.prefix, 'Resources/English.lproj/Documentation')
146 print 'INSTALL', self.build_dest, '->', self.install_doc
Jack Jansen278a3a22002-08-28 22:22:10 +0000147
148 def run(self):
149 self.finalize_options()
150 self.ensure_finalized()
151 print "Running Installer"
Jack Jansend2c684f2003-02-14 23:46:22 +0000152 instloc = self.install_doc
153 if self.root:
154 instloc = change_root(self.root, instloc)
155 self.mkpath(instloc)
156 copy_tree(self.build_dest, instloc)
Jack Jansen278a3a22002-08-28 22:22:10 +0000157 print "Installation complete"
158
159def mungeVersion(infile, outfile):
160 i = file(infile,'r')
161 o = file(outfile,'w')
162 o.write(re.sub('\$\(VERSION\)',sysconfig.get_config_var('VERSION'),i.read()))
163 i.close()
164 o.close()
165
166def main():
167 # turn off warnings when deprecated modules are imported
Jack Jansend2c684f2003-02-14 23:46:22 +0000168## import warnings
169## warnings.filterwarnings("ignore",category=DeprecationWarning)
170 setup(name = 'Documentation',
Jack Jansen278a3a22002-08-28 22:22:10 +0000171 version = '%d.%d' % sys.version_info[:2],
Jack Jansend2c684f2003-02-14 23:46:22 +0000172 cmdclass = {'install_data':AHVDocInstall, 'build':DocBuild},
173 data_files = ['dummy'],
174 )
Jack Jansen278a3a22002-08-28 22:22:10 +0000175
176if __name__ == '__main__':
177 main()