#!/usr/bin/env python """ This script will setup a jhbuild building environment for you that can build monodevelop and all of its dependencies with just a few commands. In the future, this will make a self contained MonoDevelop.app with mono and any dependencies built in. -- Christian """ import getopt import os import sys import tempfile import time from twisted.internet import defer, reactor from twisted.python import log from twisted.web import client HOME = os.path.expanduser('~') PREFIX = os.path.expanduser('~/mono') JH_HOME = '~/.local/source' URL_PREFIX = 'http://git.dronelabs.com/mono-osx-fixup/plain/' GTK_OSX_SH = 'http://github.com/jralls/gtk-osx-build/raw/master/gtk-osx-build-setup.sh' def urlFor(*args): return URL_PREFIX + '/'.join(args) @defer.inlineCallbacks def setupJHBuild(): # setup the default jhbuild from gtk+ osx yield installOSXJhbuild() # now that jhbuild is installed, copy over our overlays yield defer.DeferredList([ installMonoModuleset(), installJhbuildrc(), installJhbuildrcCustom(), ]) # modify the environment if needed if '~/.local/bin' not in os.environ['PATH']: log.msg('~/.local/bin not found in $PATH, adding') rc = os.path.expanduser('~/.bash_profile') f = file(rc, 'a') f.write('\n') f.write('export PATH="~/.local/bin:$PATH"\n') f.write('\n') f.close() os.environ['PATH'] = '~/.local/bin:' + os.environ['PATH'] # now we can bootstrap jhbuild log.msg('Bootstrapping jhbuild') os.system('jhbuild bootstrap') os.system('jhbuild build meta-gtk-osx-bootstrap') def fileFor(*args): """File pathed within the HOME of the user install""" path = os.path.join(os.path.expanduser(HOME), *args) dirname = os.path.dirname(path) if not os.path.exists(dirname): os.makedirs(dirname) return file(path, 'w') def jhfileFor(*args): """File pathed within jhbuild checkout""" path = os.path.join(os.path.expanduser(JH_HOME), 'jhbuild', *args) dirname = os.path.dirname(path) if not os.path.exists(dirname): os.makedirs(dirname) return file(path, 'w') @defer.inlineCallbacks def installOSXJhbuild(): """Install osx jhbuild from gtk+ osx""" e = os.path.expanduser(os.path.join(JH_HOME, 'jhbuild')) g = os.path.join(e, '.git') if os.path.exists(e) and not os.path.exists(g): # remove bad checkout print 'Removing bad checkout of jhbuild' os.system('rm -rf "%s"' % e) if not os.path.exists(e): log.msg('It appears you do not yet have jhbuild, installing') data = yield client.getPage(GTK_OSX_SH) data = data.replace('$HOME/Source', JH_HOME) f = tempfile.NamedTemporaryFile() f.write(data) f.flush() os.chmod(f.name, 0755) if os.system(f.name) != 0: log.err('An error occurred while setting up jhbuild!') f.close() else: log.msg('Found existing jhbuild, using it') @defer.inlineCallbacks def installMonoModuleset(): url = urlFor('modulesets', 'mono-osx.modules') log.msg('Retrieving mono-osx.modules from', url) data = yield client.getPage(url) f = jhfileFor('modulesets', 'mono-osx.modules') f.write(data) f.close() @defer.inlineCallbacks def installJhbuildrc(): url = urlFor('jhbuildrc') log.msg('Retrieving jhbuildrc from', url) data = yield client.getPage(url) f = fileFor('.jhbuildrc') f.write(data) f.close() @defer.inlineCallbacks def installJhbuildrcCustom(): url = urlFor('jhbuildrc-custom') log.msg('Retrieving jhbuildrc-custom from', url) data = yield client.getPage(url) data = data.replace('@PREFIX@', PREFIX) f = fileFor('.jhbuildrc-custom') f.write(data) f.close() def usage(argv=sys.argv, stream=sys.stdout): """Print script usage to @stream.""" print >> stream, 'Usage:' print >> stream, ' %s [OPTIONS...]' % argv[0] print >> stream, '' print >> stream, ' This script will setup jhbuild on your Mac OS X machine' print >> stream, ' to enable up to date builds of the entire monodevelop' print >> stream, ' stack including gtk+, mono, mono-debugger, and other' print >> stream, ' essential tools.' print >> stream, '' print >> stream, 'Application Options:' print >> stream, ' -h, --help Show this help menu' print >> stream, ' -p, --prefix= Set the installtion prefix [~/mono]' print >> stream, '' def main(argv=sys.argv, stdout=sys.stdout, stderr=sys.stderr): """Script entry point.""" try: shortOpts = 'hp:' longOpts = ['help', 'home=', 'prefix=', 'chergert'] opts, args = getopt.getopt(argv[1:], shortOpts, longOpts) except getopt.GetoptError, ex: print >> stderr, str(ex) print >> stderr, '' usage(argv, stderr) return 1 global HOME for o,a in opts: if o in ('-h', '--help'): return usage() or 0 elif o in ('--home',): HOME = a elif o in ('--prefix', '-p'): global PREFIX PREFIX = a elif o in ('--chergert',): HOME = '/tmp/installer' # show the *warning* and verify before continueing print >> stderr, """ You are about to install jhbuild customized for Mono on OS X. This will, however, potentially overwrite existing jhbuild scripts you may have installed on your system. Most likely, you have not used jhbuild unless you hack on gtk+ and therefore having nothing to worry about. """ answer = '' while answer not in ('y', 'n'): stderr.write('Would you like to continue? [y|n]: ') stderr.flush() answer = raw_input().strip().lower() if answer != 'y': print >> stderr, 'Okay, sorry about that!' return 1 print >> stderr, 'Great! Here we go ...' log.startLogging(stdout) # wrap in a method so that we can enforce that this isn't run # until after the main loop has started. def start(): df = setupJHBuild() df.addErrback(log.err) df.addCallback(lambda *_: reactor.stop()) reactor.callLater(0, start) reactor.run() print >> stderr, """ **************************************************************************** JHBuild is configured and setup for you to build up to date MonoDevelop and accessories. To build an up to date system, just run the following from Terminal.app jhbuild build monodevelop And to run, jhbuild shell monodevelop Cheers! -- Christian **************************************************************************** """ if __name__ == '__main__': sys.exit(main())