diff --git a/Mac/scripts/buildappbundle.py b/Mac/scripts/buildappbundle.py index 49a15137821..2b007bf8753 100755 --- a/Mac/scripts/buildappbundle.py +++ b/Mac/scripts/buildappbundle.py @@ -1,149 +1,60 @@ +#! /usr/bin/env python + +# XXX This will be replaced by a main program in Mac/Lib/bundlebuilder.py, +# but for now this is kept so Jack won't need to change his scripts... + + +"""\ +buildappbundle creates an application bundle +Usage: + buildappbundle [options] executable +Options: + --output o Output file; default executable with .app appended, short -o + --link Symlink files instead of copying them, short -l + --plist file Plist file (default: generate one), short -p + --nib file Main nib file or lproj folder for Cocoa program, short -n + --resource r Extra resource file to be copied to Resources, short -r + --creator c 4-char creator code (default: '????'), short -c + --verbose increase verbosity level (default: quiet), short -v + --help This message, short -? or -h +""" + + import sys import os -import shutil import getopt +from bundlebuilder import AppBuilder +from plistlib import Plist + -def buildappbundle(executable, output=None, copyfunc=None, creator=None, - plist=None, nib=None, resources=None): - if not output: - output = os.path.split(executable)[1] + '.app' - if not copyfunc: - copyfunc = shutil.copy2 - if not creator: - creator='????' - if not resources: - resources = [] - if nib: - resources = resources + [nib] - # - # Create the main directory structure - # - if not os.path.isdir(output): - os.mkdir(output) - contents = os.path.join(output, 'Contents') - if not os.path.isdir(contents): - os.mkdir(contents) - macos = os.path.join(contents, 'MacOS') - if not os.path.isdir(macos): - os.mkdir(macos) - # - # Create the executable - # - shortname = os.path.split(executable)[1] - execname = os.path.join(macos, shortname) - try: - os.remove(execname) - except OSError: - pass - copyfunc(executable, execname) - # - # Create the PkgInfo file - # - pkginfo = os.path.join(contents, 'PkgInfo') - open(pkginfo, 'wb').write('APPL'+creator) - if plist: - # A plist file is specified. Read it. - plistdata = open(plist).read() - else: - # - # If we have a main NIB we create the extra Cocoa specific info for the plist file - # - if not nib: - nibname = "" - else: - nibname, ext = os.path.splitext(os.path.split(nib)[1]) - if ext == '.lproj': - # Special case: if the main nib is a .lproj we assum a directory - # and use the first nib from there - files = os.listdir(nib) - for f in files: - if f[-4:] == '.nib': - nibname = os.path.split(f)[1][:-4] - break - else: - nibname = "" - if nibname: - cocoainfo = """ - NSMainNibFile - %s - NSPrincipalClass - NSApplication""" % nibname - else: - cocoainfo = "" - plistdata = \ -""" - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - %s - CFBundleInfoDictionaryVersion - 6.0 - CFBundlePackageType - APPL - CFBundleSignature - %s - CFBundleVersion - 0.1 - %s - - -""" % (shortname, creator, cocoainfo) - # - # Next, we create the plist file - # - infoplist = os.path.join(contents, 'Info.plist') - open(infoplist, 'w').write(plistdata) - # - # Finally, if there are nibs or other resources to copy we do so. - # - if resources: - resdir = os.path.join(contents, 'Resources') - if not os.path.isdir(resdir): - os.mkdir(resdir) - for src in resources: - dst = os.path.join(resdir, os.path.split(src)[1]) - if os.path.isdir(src): - shutil.copytree(src, dst) - else: - shutil.copy2(src, dst) - def usage(): - print "buildappbundle creates an application bundle" - print "Usage:" - print " buildappbundle [options] executable" - print "Options:" - print " --output o Output file; default executable with .app appended, short -o" - print " --link Symlink the executable (default: copy), short -l" - print " --plist file Plist file (default: generate one), short -p" - print " --nib file Main nib file or lproj folder for Cocoa program, short -n" - print " --resource r Extra resource file to be copied to Resources, short -r" - print " --creator c 4-char creator code (default: ????), short -c" - print " --help This message, short -?" + print __doc__ sys.exit(1) + def main(): - output=None - copyfunc=None - creator=None - plist=None - nib=None - resources=[] - SHORTOPTS = "o:ln:r:p:c:?" - LONGOPTS=("output=", "link", "nib=", "resource=", "plist=", "creator=", "help") + output = None + symlink = 0 + creator = "????" + plist = None + nib = None + resources = [] + verbosity = 0 + SHORTOPTS = "o:ln:r:p:c:v?h" + LONGOPTS=("output=", "link", "nib=", "resource=", "plist=", "creator=", "help", + "verbose") try: options, args = getopt.getopt(sys.argv[1:], SHORTOPTS, LONGOPTS) except getopt.error: usage() if len(args) != 1: usage() + executable = args[0] for opt, arg in options: if opt in ('-o', '--output'): output = arg elif opt in ('-l', '--link'): - copyfunc = os.symlink + symlink = 1 elif opt in ('-n', '--nib'): nib = arg elif opt in ('-r', '--resource'): @@ -152,11 +63,42 @@ def main(): creator = arg elif opt in ('-p', '--plist'): plist = arg - elif opt in ('-?', '--help'): + elif opt in ('-v', '--verbose'): + verbosity += 1 + elif opt in ('-?', '-h', '--help'): usage() - buildappbundle(args[0], output=output, copyfunc=copyfunc, creator=creator, - plist=plist, resources=resources) - + if output is not None: + builddir, bundlename = os.path.split(output) + else: + builddir = os.curdir + bundlename = None # will be derived from executable + if plist is not None: + plist = Plist.fromFile(plist) + + builder = AppBuilder(name=bundlename, executable=executable, + builddir=builddir, creator=creator, plist=plist, resources=resources, + symlink=symlink, verbosity=verbosity) + + if nib is not None: + resources.append(nib) + nibname, ext = os.path.splitext(os.path.basename(nib)) + if ext == '.lproj': + # Special case: if the main nib is a .lproj we assum a directory + # and use the first nib from there. XXX Look: an arbitrary pick ;-) + files = os.listdir(nib) + for f in files: + if f[-4:] == '.nib': + nibname = os.path.split(f)[1][:-4] + break + else: + nibname = "" + if nibname: + builder.plist.NSMainNibFile = nibname + if not hasattr(builder.plist, "NSPrincipalClass"): + builder.plist.NSPrincipalClass = "NSApplication" + builder.setup() + builder.build() + + if __name__ == '__main__': main() - \ No newline at end of file