1# 2# make_pkg.py 3# 4import os 5 6print( 'Info: setup vesion info' ) 7import sys 8sys.path.insert( 0, os.path.abspath( '../../Source' ) ) 9import pysvn 10import time 11import glob 12 13package_maker = '/Developer/Applications/Utilities/PackageMaker.app/Contents/MacOS/PackageMaker' 14package_maker_kit = os.path.exists( package_maker ) 15 16os.system( 'lipo -info %s >lipo-info.tmp' % (sys.executable,) ) 17lipo_info = open( 'lipo-info.tmp' ).read() 18os.remove( 'lipo-info.tmp' ) 19 20is_x86_64 = 'x86_64' in lipo_info 21is_i386 = 'i386' in lipo_info 22 23if is_x86_64 and is_i386: 24 processor = 'intel' 25 26elif is_x86_64: 27 processor = 'x86_64' 28 29elif is_i386: 30 processor = 'i386' 31 32else: 33 assert False, 'Unknown processor type' 34 35python_vendor = os.environ.get( 'BUILDER_VENDOR', 'unknown' ) 36 37if processor == 'i386': 38 if hasattr( sys, 'maxsize' ): 39 maxsize = sys.maxsize 40 else: 41 maxsize = sys.maxint 42 43 if maxsize == (2**31-1): 44 processor = 'i386' 45 else: 46 processor = 'x86_64' 47 48print( 'Info: Process is %s' % (processor,) ) 49 50pymaj, pymin, pypat, _, _ = sys.version_info 51python_version_string = '%d.%d.%d' % (pymaj, pymin, pypat) 52pysvnmaj, pysvnmin, pysvnpat, _ = pysvn.version 53pysvn_version_string = '%d.%d.%d-%d' % (pysvn.version[0], pysvn.version[1], pysvn.version[2], pysvn.version[3]) 54pysvn_short_version_string = '%d.%d.%d' % (pysvn.version[0], pysvn.version[1], pysvn.version[2]) 55svn_version_package_string = '%d%d%d' % (pysvn.svn_version[0], pysvn.svn_version[1], pysvn.svn_version[2]) 56svn_version_string = '%d.%d.%d' % (pysvn.svn_version[0], pysvn.svn_version[1], pysvn.svn_version[2]) 57pysvn_so_string = '_pysvn_%d_%d.so' % (pymaj, pymin) 58pkg_filename = 'py%s%s-%s-pysvn-svn%s-%s-%s' % (pymaj, pymin, python_vendor, svn_version_package_string, pysvn_version_string, processor) 59 60print( 'Info: Packageing %s' % (pkg_filename,) ) 61build_time = time.time() 62build_time_str = time.strftime( '%d-%b-%Y %H:%M', time.localtime( build_time ) ) 63year = time.strftime( '%Y', time.localtime( build_time ) ) 64tmpdir = os.path.join( os.getcwd(), 'tmp' ) 65 66if pymaj == 2 and pymin == 7: 67 if python_vendor == 'apple_com': 68 install_dir = '/Library/Python/2.7/site-packages' 69 else: 70 install_dir = '/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages' 71 72elif pymaj == 3: 73 install_dir = '/Library/Frameworks/Python.framework/Versions/3.%d/lib/python3.%d/site-packages' % (pymin, pymin) 74 75else: 76 raise RuntimeError( 'Unsupported version of python' ) 77 78if os.path.exists( tmpdir ): 79 print( 'Info: Clean up tmp directory' ) 80 os.system( 'rm -rf tmp' ) 81 82print( 'Info: Create directories' ) 83 84for kit_dir in [ 85 tmpdir, 86 os.path.join( tmpdir, 'Resources' ), 87 os.path.join( tmpdir, 'Contents' ), 88 os.path.join( tmpdir, 'Contents/pysvn' ), 89 os.path.join( tmpdir, pkg_filename), 90 os.path.join( tmpdir, '%s/Examples' % pkg_filename ), 91 os.path.join( tmpdir, '%s/Examples/Client' % pkg_filename ), 92 os.path.join( tmpdir, '%s/Documentation' % pkg_filename), 93 ]: 94 if not os.path.exists( kit_dir ): 95 os.makedirs( kit_dir ) 96 97 98print( 'Info: Finding dylibs used by pysvn' ) 99 100def findDylibs( image, dylib_list, depth=0 ): 101 cmd = 'otool -L "%s" >/tmp/pysvn_otool.tmp' % image 102 #print( 'Debug: cmd %r' % cmd ) 103 os.system( cmd ) 104 # always skip the first line that lists the image being dumped 105 for line in open( '/tmp/pysvn_otool.tmp' ).readlines()[1:]: 106 line = line.strip() 107 libpath = line.split()[0] 108 #print( 'Debug: line %r' % line ) 109 if( libpath.startswith( '/' ) # lines with libs on them 110 and not libpath.startswith( '/usr/lib' ) # ignore libs shipped by Apple 111 and not libpath.startswith( '/System' ) # ignore libs shipped by Apple 112 and not libpath.endswith( '/Python' ) ): # do not need to ignore python 113 if libpath not in dylib_list: 114 #print( 'Info: ',depth,' Need lib',libpath,'for',image ) 115 dylib_list.append( libpath ) 116 findDylibs( libpath, dylib_list, depth+1 ) 117 118dylib_list = [] 119findDylibs( '../../Source/pysvn/%s' % pysvn_so_string, dylib_list ) 120 121print( 'Info: Copy files' ) 122 123cp_list = [ 124 ('../../Source/pysvn/__init__.py', 125 'Contents/pysvn'), 126 ('../../Source/pysvn/%s' % pysvn_so_string, 127 'Contents/pysvn'), 128 ('../../LICENSE.txt', 129 'Resources/License.txt'), 130 ('../../LICENSE.txt', 131 '%s/License.txt' % pkg_filename ), 132 ('../../Docs/pysvn.html', 133 '%s/Documentation' % pkg_filename ), 134 ('../../Docs/pysvn_prog_ref.html', 135 '%s/Documentation' % pkg_filename ), 136 ('../../Docs/pysvn_prog_ref.js', 137 '%s/Documentation' % pkg_filename ), 138 ('../../Docs/pysvn_prog_guide.html', 139 '%s/Documentation' % pkg_filename ), 140 ('../../Examples/Client/svn_cmd.py', 141 '%s/Examples/Client' % pkg_filename ), 142 ('../../Examples/Client/parse_datetime.py', 143 '%s/Examples/Client' % pkg_filename ), 144 ] 145 146for libpath in dylib_list: 147 cp_list.append( (libpath, 'Contents/pysvn') ) 148 149for cp_src, cp_dst_dir_fmt in cp_list: 150 cmd = 'cp -f "%s" "tmp/%s"' % (cp_src, cp_dst_dir_fmt % locals()) 151 print( 'Info: CMD %r' % cmd ) 152 os.system( cmd ) 153 154for dylib in glob.glob( 'tmp/Contents/pysvn/*.dylib' ): 155 # all the dylib need to be writable 156 cmd = 'chmod +w "%s"' % (dylib,) 157 print( 'Info: CMD %r' % cmd ) 158 os.system( cmd ) 159 160print( 'Info: Fix the install paths for the dylib files' ) 161 162fixup_path_list = ['tmp/Contents/pysvn/%s' % pysvn_so_string] 163for libpath in dylib_list: 164 fixup_path_list.append( 'tmp/Contents/pysvn/' + os.path.basename( libpath ) ) 165 166for fixup_path in fixup_path_list: 167 for libpath in dylib_list: 168 if libpath != fixup_path: 169 os.system( cmd ) 170 cmd = ('install_name_tool' 171 ' -change' 172 ' %s' 173 ' %s/pysvn/%s' 174 ' %s' % 175 (libpath, install_dir, os.path.basename( libpath ), fixup_path)) 176 print( 'Info: CMD %s' % (cmd,) ) 177 os.system( cmd ) 178 179for dylib in glob.glob( 'tmp/Contents/pysvn/*.dylib' ): 180 # can now remove the +w 181 cmd = 'chmod -w "%s"' % (dylib,) 182 print( 'Info: CMD %r' % cmd ) 183 os.system( cmd ) 184 185if python_vendor == 'apple_com': 186 readme_vendor_name = "Apple's" 187 188elif python_vendor == 'python_org': 189 readme_vendor_name = "Python.org's" 190 191else: 192 readme_vendor_name = python_vendor 193 194print( 'Info: Create tmp/Resources/ReadMe.txt' ) 195if package_maker_kit: 196 f = open( 'tmp/Resources/ReadMe.txt', 'w' ) 197 198else: 199 f = open( 'tmp/%s/ReadMe.txt' % (pkg_filename,), 'w' ) 200 201f.write('''<html> 202<body> 203<h1>PySVN %(pysvn_version_string)s for Mac OS X, %(readme_vendor_name)s Python %(pymaj)s.%(pymin)s and Subversion %(svn_version_string)s</h1> 204 205<h2>Copyright Barry A. Scott (c) 2003-%(year)s</h2> 206 207<h2>Mail <a href="mailto:barry@barrys-emacs.org">barry@barrys-emacs.org</a></h2> 208 209<h2>Pysvn home <a href="https://pysvn.sourceforge.io">https://pysvn.sourceforge.io</a></h2> 210 211<h2>     Barry Scott</h2> 212</body> 213</html> 214''' % locals() ) 215f.close() 216 217if package_maker_kit: 218 print( 'Info: Create tmp/Info.plist' ) 219 f = open( 'tmp/Info.plist', 'w' ) 220 f.write('''<?xml version="1.0" encoding="UTF-8"?> 221<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 222<plist version="1.0"> 223<dict> 224 <key>CFBundleGetInfoString</key> 225 <string>pysvn Extension %(pysvn_version_string)s for Python %(pymaj)s.%(pymin)s</string> 226 <key>CFBundleIdentifier</key> 227 <string>org.tigris.pysvn.extension.py%(pymaj)s.%(pymin)s.%(python_vendor)s</string> 228 <key>CFBundleName</key> 229 <string>pysvn Extension</string> 230 <key>CFBundleShortVersionString</key> 231 <string>%(pysvn_short_version_string)s</string> 232 <key>IFMajorVersion</key> 233 <integer>%(pysvnmaj)s</integer> 234 <key>IFMinorVersion</key> 235 <integer>%(pysvnmin)s</integer> 236 <key>IFPkgFlagAllowBackRev</key> 237 <false/> 238 <key>IFPkgFlagAuthorizationAction</key> 239 <string>AdminAuthorization</string> 240 <key>IFPkgFlagDefaultLocation</key> 241 <string>%(install_dir)s</string> 242 <key>IFPkgFlagInstallFat</key> 243 <false/> 244 <key>IFPkgFlagIsRequired</key> 245 <false/> 246 <key>IFPkgFlagRelocatable</key> 247 <false/> 248 <key>IFPkgFlagRestartAction</key> 249 <string>NoRestart</string> 250 <key>IFPkgFlagRootVolumeOnly</key> 251 <true/> 252 <key>IFPkgFlagUpdateInstalledLanguages</key> 253 <false/> 254 <key>IFPkgFormatVersion</key> 255 <real>0.10000000149011612</real> 256</dict> 257</plist> 258''' % locals() ) 259 f.close() 260 261 print( 'Info: Create tmp/Description.plist' ) 262 f = open( 'tmp/Description.plist', 'w' ) 263 f.write('''<?xml version="1.0" encoding="UTF-8"?> 264<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 265<plist version="1.0"> 266<dict> 267 <key>IFPkgDescriptionDescription</key> 268 <string>PySVN Extension 269</string> 270 <key>IFPkgDescriptionTitle</key> 271 <string>PySVN Extension</string> 272</dict> 273</plist> 274''' ) 275 f.close() 276 277 print( 'Info: PackageMaker' ) 278 cmd = [ package_maker, 279 '-build', 280 '-p %s' % os.path.abspath( 'tmp/%s/%s.pkg' % (pkg_filename, pkg_filename) ), 281 '-f %s' % os.path.abspath( 'tmp/Contents' ), 282 '-r %s' % os.path.abspath( 'tmp/Resources' ), 283 '-i %s' % os.path.abspath( 'tmp/Info.plist' ), 284 '-d %s' % os.path.abspath( 'tmp/Description.plist' ), 285 ] 286 os.system( ' '.join( cmd ) ) 287 288 print( 'Info: Make Disk Image' ) 289 os.system( 'hdiutil create -srcfolder tmp/%s tmp/tmp.dmg' % pkg_filename ) 290 os.system( 'hdiutil convert tmp/tmp.dmg -format UDZO -imagekey zlib-level=9 ' 291 '-o tmp/%s.dmg' % pkg_filename ) 292 293else: 294 print( 'Info: Create installation script' ) 295 f = open( 'tmp/%s/Install PySVN' % (pkg_filename,), 'w' ) 296 f.write( '''#!/bin/bash 297 if [ "$( id -u )" != "0" ] 298 then 299 clear 300 echo "To install PYSVN required root (administrator) privileges." 301 echo "Enter your password to proceed." 302 exec sudo "$0" 303 fi 304 305 kit_dir=$( dirname "$0" ) 306 307 echo "Installing pysvn Extension %(pysvn_version_string)s for Python %(pymaj)s.%(pymin)s" 308 309 tar xzf "${kit_dir}/%(pkg_filename)s.tar.gz" -C "%(install_dir)s" 310 311 echo "Installation complete. Press RETURN to exit." 312 read A 313 314''' % locals() ) 315 f.close() 316 os.system( 'chmod +x "tmp/%s/Install PYSVN"' % (pkg_filename,) ) 317 318 cmd = [ 'tar', 319 'czf', 320 'tmp/%s/%s.tar.gz' % (pkg_filename, pkg_filename), 321 '-C' 'tmp/Contents', 322 'pysvn'] 323 324 os.system( ' '.join( cmd ) ) 325 326 print( 'Info: Make Disk Image' ) 327 os.system( 'hdiutil create -srcfolder tmp/%s tmp/tmp.dmg' % pkg_filename ) 328 os.system( 'hdiutil convert tmp/tmp.dmg -format UDZO -imagekey zlib-level=9 ' 329 '-o tmp/%s.dmg' % pkg_filename ) 330