1# Copyright (c) 2002 Douglas Gregor <doug.gregor -at- gmail.com> 2# 3# Distributed under the Boost Software License, Version 1.0. 4# (See accompanying file LICENSE_1_0.txt or copy at 5# http://www.boost.org/LICENSE_1_0.txt) 6 7# This is a rewrite of setup_boostbook.sh in Python 8# It will work on Posix and Windows systems 9# The rewrite is not finished yet, so please don't use it 10# right now it is used only be release scripts 11 12# User configuration 13# (MAINTANERS: please, keep in synch with setup_boostbook.sh) 14DOCBOOK_XSL_VERSION = "1.75.2" 15DOCBOOK_DTD_VERSION = "4.2" 16FOP_VERSION = "0.94" 17FOP_JDK_VERSION="1.4" 18# FOP_MIRROR = "http://mirrors.ibiblio.org/pub/mirrors/apache/xmlgraphics/fop/binaries" 19FOP_MIRROR = "http://archive.apache.org/dist/xmlgraphics/fop/binaries/" 20SOURCEFORGE_DOWNLOAD = "http://sourceforge.net/projects/docbook/files" 21 22# No user configuration below this point------------------------------------- 23 24import os 25import re 26import sys 27import optparse 28import shutil 29 30sys.path.append( os.path.join( os.path.dirname( sys.modules[ __name__ ].__file__ ) 31 , "../regression/xsl_reports/utils" ) ) 32 33import checked_system 34import urllib2 35import tarfile 36import zipfile 37 38def accept_args( args ): 39 parser = optparse.OptionParser() 40 parser.add_option( "-t", "--tools", dest="tools", help="directory downloaded tools will be installed into. Optional. Used by release scripts to put the tools separately from the tree to be archived." ) 41 parser.usage = "setup_boostbook [options]" 42 43 ( options, args ) = parser.parse_args( args ) 44 if options.tools is None: 45 options.tools = os.getcwd() 46 47 48 return options.tools 49 50def to_posix( path ): 51 return path.replace( "\\", "/" ) 52 53def unzip( archive_path, result_dir ): 54 z = zipfile.ZipFile( archive_path, 'r', zipfile.ZIP_DEFLATED ) 55 for f in z.infolist(): 56 print f.filename 57 if not os.path.exists( os.path.join( result_dir, os.path.dirname( f.filename ) ) ): 58 os.makedirs( os.path.join( result_dir, os.path.dirname( f.filename ) ) ) 59 result = open( os.path.join( result_dir, f.filename ), 'wb' ) 60 result.write( z.read( f.filename ) ) 61 result.close() 62 63 z.close() 64 65def gunzip( archive_path, result_dir ): 66 tar = tarfile.open( archive_path, 'r:gz' ) 67 for tarinfo in tar: 68 tar.extract( tarinfo, result_dir ) 69 tar.close() 70 71def http_get( file, url ): 72 f = open( file, "wb" ) 73 f.write( urllib2.urlopen( url ).read() ) 74 f.close() 75 76def find_executable( executable_name, env_variable, test_args, error_message ): 77 print "Looking for %s ..." % executable_name 78 if os.environ.has_key( env_variable ): 79 specified = os.environ[ env_variable ] 80 print " Trying %s specified in env. variable %s" % ( specified, env_variable ) 81 if os.path.exists( specified ): 82 return specified.replace( "\\", "/" ) 83 else: 84 print "Cannot find %s specified in env. variable %s" % ( specified, env_variable ) 85 86 rc = checked_system.system( [ "%s %s" % ( executable_name, test_args ) ] ) 87 print "" 88 if rc != 0: 89 print error_message 90 return None 91 else: 92 return executable_name.replace( "\\", "/" ) 93 94def adjust_user_config( config_file 95 , docbook_xsl_dir 96 , docbook_dtd_dir 97 , xsltproc 98 , doxygen 99 , fop 100 , java 101 ): 102 print "Modifying user-config.jam ..." 103 r = [] 104 using_boostbook = 0 105 eaten=0 106 lines = open( config_file, "r" ).readlines() 107 for line in lines: 108 if re.match( "^\s*using boostbook", line ): 109 using_boostbook = 1 110 r.append( "using boostbook\n" ) 111 r.append( " : %s\n" % docbook_xsl_dir ) 112 r.append( " : %s\n" % docbook_dtd_dir ) 113 r.append( " ; \n" ) 114 eaten = 1 115 116 elif using_boostbook == 1 and re.match( ";", line ): 117 using_boostbook = 2 118 elif using_boostbook == 1: 119 eaten=1 120 elif re.match( "^\s*using xsltproc.*$", line ): 121 eaten=1 122 elif re.match( "^\s*using doxygen.*$", line ): 123 eaten=1 124 elif re.match( "^\s*using fop.*$", line ): 125 eaten=1 126 else: 127 if eaten == 0: 128 r.append( line ) 129 eaten=0 130 131 if using_boostbook==0: 132 r.append( "using boostbook\n" ) 133 r.append( " : %s\n" % docbook_xsl_dir ) 134 r.append( " : %s\n" % docbook_dtd_dir ) 135 r.append( " ;\n" ) 136 137 r.append( "using xsltproc : %s ;\n" % xsltproc ) 138 if doxygen is not None: 139 r.append( "using doxygen : %s ;\n" % doxygen ) 140 if fop is not None: 141 print r.append( "using fop : %s : : %s ;\n" % ( fop, java ) ) 142 143 open( config_file + ".tmp", "w" ).writelines( r ) 144 try: 145 os.rename( config_file + ".tmp", config_file ) 146 except OSError, e: 147 os.unlink( config_file ) 148 os.rename( config_file + ".tmp", config_file ) 149 150 151def setup_docbook_xsl( tools_directory ): 152 print "DocBook XSLT Stylesheets ..." 153 DOCBOOK_XSL_TARBALL = os.path.join( tools_directory, "docbook-xsl-%s.tar.gz" % DOCBOOK_XSL_VERSION ) 154 DOCBOOK_XSL_URL = "%s/docbook-xsl/%s/%s/download" % (SOURCEFORGE_DOWNLOAD, DOCBOOK_XSL_VERSION, os.path.basename( DOCBOOK_XSL_TARBALL ) ) 155 156 if os.path.exists( DOCBOOK_XSL_TARBALL ): 157 print " Using existing DocBook XSLT Stylesheets (version %s)." % DOCBOOK_XSL_VERSION 158 else: 159 print " Downloading DocBook XSLT Stylesheets version %s..." % DOCBOOK_XSL_VERSION 160 print " from %s" % DOCBOOK_XSL_URL 161 http_get( DOCBOOK_XSL_TARBALL, DOCBOOK_XSL_URL ) 162 163 DOCBOOK_XSL_DIR = to_posix( os.path.join( tools_directory, "docbook-xsl-%s" % DOCBOOK_XSL_VERSION ) ) 164 165 if not os.path.exists( DOCBOOK_XSL_DIR ): 166 print " Expanding DocBook XSLT Stylesheets into %s..." % DOCBOOK_XSL_DIR 167 gunzip( DOCBOOK_XSL_TARBALL, tools_directory ) 168 print " done." 169 170 return DOCBOOK_XSL_DIR 171 172def setup_docbook_dtd( tools_directory ): 173 print "DocBook DTD ..." 174 DOCBOOK_DTD_ZIP = to_posix( os.path.join( tools_directory, "docbook-xml-%s.zip" % DOCBOOK_DTD_VERSION ) ) 175 DOCBOOK_DTD_URL = "http://www.oasis-open.org/docbook/xml/%s/%s" % ( DOCBOOK_DTD_VERSION, os.path.basename( DOCBOOK_DTD_ZIP ) ) 176 if os.path.exists( DOCBOOK_DTD_ZIP ): 177 print " Using existing DocBook XML DTD (version %s)." % DOCBOOK_DTD_VERSION 178 else: 179 print " Downloading DocBook XML DTD version %s..." % DOCBOOK_DTD_VERSION 180 http_get( DOCBOOK_DTD_ZIP, DOCBOOK_DTD_URL ) 181 182 DOCBOOK_DTD_DIR = to_posix( os.path.join( tools_directory, "docbook-dtd-%s" % DOCBOOK_DTD_VERSION ) ) 183 if not os.path.exists( DOCBOOK_DTD_DIR ): 184 print "Expanding DocBook XML DTD into %s... " % DOCBOOK_DTD_DIR 185 unzip( DOCBOOK_DTD_ZIP, DOCBOOK_DTD_DIR ) 186 print "done." 187 188 return DOCBOOK_DTD_DIR 189 190def find_xsltproc(): 191 return to_posix( find_executable( "xsltproc", "XSLTPROC", "--version" 192 , "If you have already installed xsltproc, please set the environment\n" 193 + "variable XSLTPROC to the xsltproc executable. If you do not have\n" 194 + "xsltproc, you may download it from http://xmlsoft.org/XSLT/." ) ) 195 196def find_doxygen(): 197 return to_posix( find_executable( "doxygen", "DOXYGEN", "--version" 198 , "Warning: unable to find Doxygen executable. You will not be able to\n" 199 + " use Doxygen to generate BoostBook documentation. If you have Doxygen,\n" 200 + " please set the DOXYGEN environment variable to the path of the doxygen\n" 201 + " executable." ) ) 202 203 204def find_java(): 205 return to_posix( find_executable( "java", "JAVA", "-version" 206 , "Warning: unable to find Java executable. You will not be able to\n" 207 + " generate PDF documentation. If you have Java, please set the JAVA\n" 208 + " environment variable to the path of the java executable." ) ) 209 210def setup_fop( tools_directory ): 211 print "FOP ..." 212 FOP_TARBALL = os.path.join( tools_directory, "fop-%s-bin-jdk%s.tar.gz" % ( FOP_VERSION, FOP_JDK_VERSION ) ) 213 FOP_URL = "%s/%s" % ( FOP_MIRROR, os.path.basename( FOP_TARBALL ) ) 214 FOP_DIR = to_posix( "%s/fop-%s" % ( tools_directory, FOP_VERSION ) ) 215 if sys.platform == 'win32': 216 fop_driver = "fop.bat" 217 else: 218 fop_driver = "fop" 219 220 FOP = to_posix( os.path.join( FOP_DIR, fop_driver ) ) 221 222 if os.path.exists( FOP_TARBALL ) : 223 print " Using existing FOP distribution (version %s)." % FOP_VERSION 224 else: 225 print " Downloading FOP distribution version %s..." % FOP_VERSION 226 http_get( FOP_TARBALL, FOP_URL ) 227 228 if not os.path.exists( FOP_DIR ): 229 print " Expanding FOP distribution into %s... " % FOP_DIR 230 gunzip( FOP_TARBALL, tools_directory ) 231 print " done." 232 233 return FOP 234 235def find_user_config(): 236 print "Looking for user-config.jam ..." 237 JAM_CONFIG_OUT = os.path.join( os.environ[ "HOME" ], "user-config.jam" ) 238 if os.path.exists( JAM_CONFIG_OUT ): 239 JAM_CONFIG_IN ="user-config-backup.jam" 240 print " Found user-config.jam in HOME directory (%s)" % JAM_CONFIG_IN 241 shutil.copyfile( JAM_CONFIG_OUT, os.path.join( os.environ[ "HOME" ], "user-config-backup.jam" ) ) 242 JAM_CONFIG_IN_TEMP="yes" 243 print " Updating Boost.Jam configuration in %s... " % JAM_CONFIG_OUT 244 return JAM_CONFIG_OUT 245 elif os.environ.has_key( "BOOST_ROOT" ) and os.path.exists( os.path.join( os.environ[ "BOOST_ROOT" ], "tools/build/user-config.jam" ) ): 246 JAM_CONFIG_IN=os.path.join( os.environ[ "BOOST_ROOT" ], "tools/build/user-config.jam" ) 247 print " Found user-config.jam in BOOST_ROOT directory (%s)" % JAM_CONFIG_IN 248 JAM_CONFIG_IN_TEMP="no" 249 print " Writing Boost.Jam configuration to %s... " % JAM_CONFIG_OUT 250 return JAM_CONFIG_IN 251 return None 252 253def setup_boostbook( tools_directory ): 254 print "Setting up boostbook tools..." 255 print "-----------------------------" 256 print "" 257 258 DOCBOOK_XSL_DIR = setup_docbook_xsl( tools_directory ) 259 DOCBOOK_DTD_DIR = setup_docbook_dtd( tools_directory ) 260 XSLTPROC = find_xsltproc() 261 DOXYGEN = find_doxygen() 262 JAVA = find_java() 263 264 FOP = None 265 if JAVA is not None: 266 print "Java is present." 267 FOP = setup_fop( tools_directory ) 268 269 user_config = find_user_config() 270 271 # Find the input jamfile to configure 272 273 if user_config is None: 274 print "ERROR: Please set the BOOST_ROOT environment variable to refer to your" 275 print "Boost installation or copy user-config.jam into your home directory." 276 sys.exit() 277 278 adjust_user_config( config_file = user_config 279 , docbook_xsl_dir = DOCBOOK_XSL_DIR 280 , docbook_dtd_dir = DOCBOOK_DTD_DIR 281 , xsltproc = XSLTPROC 282 , doxygen = DOXYGEN 283 , fop = FOP 284 , java = JAVA 285 ) 286 287 print "done." 288 289 print "Done! Execute \"b2\" in a documentation directory to generate" 290 print "documentation with BoostBook. If you have not already, you will need" 291 print "to compile Boost.Jam." 292 293def main(): 294 ( tools_directory ) = accept_args( sys.argv[ 1: ] ) 295 setup_boostbook( tools_directory ) 296 297if __name__ == "__main__": 298 main() 299 300 301