Replaced the bundle building code with calls to the new bundlebuilder

module.
Jack: I've compared the .app output of the orginal with the new and I
can't find any significant differences. However, bundlebuilder.py
contains its' own command line interface and I think we should use
that instead. I'll have a look to see whether I can patch
Mac/OSX/Makefile.jaguar to this effect.
This commit is contained in:
Just van Rossum 2002-11-22 11:10:49 +00:00
parent 6f00a7ad84
commit 224405fcfd
1 changed files with 75 additions and 133 deletions

View File

@ -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 = """
<key>NSMainNibFile</key>
<string>%s</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>""" % nibname
else:
cocoainfo = ""
plistdata = \
"""<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
<plist version="0.9">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>%s</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>%s</string>
<key>CFBundleVersion</key>
<string>0.1</string>
%s
</dict>
</plist>
""" % (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
symlink = 0
creator = "????"
plist = None
nib = None
resources = []
SHORTOPTS = "o:ln:r:p:c:?"
LONGOPTS=("output=", "link", "nib=", "resource=", "plist=", "creator=", "help")
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()