summaryrefslogtreecommitdiffstats
path: root/Mac
diff options
context:
space:
mode:
Diffstat (limited to 'Mac')
-rwxr-xr-xMac/Lib/bundlebuilder.py155
1 files changed, 81 insertions, 74 deletions
diff --git a/Mac/Lib/bundlebuilder.py b/Mac/Lib/bundlebuilder.py
index 1503f2b..3f7d5aa 100755
--- a/Mac/Lib/bundlebuilder.py
+++ b/Mac/Lib/bundlebuilder.py
@@ -35,77 +35,93 @@ __all__ = ["BundleBuilder", "AppBuilder", "buildapp"]
import sys
import os, errno, shutil
+from copy import deepcopy
import getopt
from plistlib import Plist
+from types import FunctionType as function
-plistDefaults = Plist(
- CFBundleDevelopmentRegion = "English",
- CFBundleInfoDictionaryVersion = "6.0",
-)
+class Defaults:
+ """Class attributes that don't start with an underscore and are
+ not functions or classmethods are (deep)copied to self.__dict__.
+ This allows for mutable default values.
+ """
+
+ def __init__(self, **kwargs):
+ defaults = self._getDefaults()
+ defaults.update(kwargs)
+ self.__dict__.update(defaults)
+
+ def _getDefaults(cls):
+ defaults = {}
+ for name, value in cls.__dict__.items():
+ if name[0] != "_" and not isinstance(value,
+ (function, classmethod)):
+ defaults[name] = deepcopy(value)
+ for base in cls.__bases__:
+ if hasattr(base, "_getDefaults"):
+ defaults.update(base._getDefaults())
+ return defaults
+ _getDefaults = classmethod(_getDefaults)
-class BundleBuilder:
+
+class BundleBuilder(Defaults):
"""BundleBuilder is a barebones class for assembling bundles. It
knows nothing about executables or icons, it only copies files
and creates the PkgInfo and Info.plist files.
-
- Constructor arguments:
-
- name: Name of the bundle, with or without extension.
- plist: A plistlib.Plist object.
- type: The type of the bundle. Defaults to "APPL".
- creator: The creator code of the bundle. Defaults to "????".
- resources: List of files that have to be copied to
- <bundle>/Contents/Resources. Defaults to an empty list.
- files: List of (src, dest) tuples; dest should be a path relative
- to the bundle (eg. "Contents/Resources/MyStuff/SomeFile.ext.
- Defaults to an empty list.
- builddir: Directory where the bundle will be assembled. Defaults
- to "build" (in the current directory).
- symlink: Make symlinks instead copying files. This is handy during
- debugging, but makes the bundle non-distributable. Defaults to
- False.
- verbosity: verbosity level, defaults to 1
"""
- def __init__(self, name=None, plist=None, type="APPL", creator="????",
- resources=None, files=None, builddir="build", platform="MacOS",
- symlink=0, verbosity=1):
- """See the class doc string for a description of the arguments."""
- if plist is None:
- plist = Plist()
- if resources is None:
- resources = []
- if files is None:
- files = []
- self.name = name
- self.plist = plist
- self.type = type
- self.creator = creator
- self.resources = resources
- self.files = files
- self.builddir = builddir
- self.platform = platform
- self.symlink = symlink
- self.verbosity = verbosity
+ # (Note that Defaults.__init__ (deep)copies these values to
+ # instance variables. Mutable defaults are therefore safe.)
+
+ # Name of the bundle, with or without extension.
+ name = None
+
+ # The property list ("plist")
+ plist = Plist(CFBundleDevelopmentRegion = "English",
+ CFBundleInfoDictionaryVersion = "6.0")
+
+ # The type of the bundle.
+ type = "APPL"
+ # The creator code of the bundle.
+ creator = "????"
+
+ # List of files that have to be copied to <bundle>/Contents/Resources.
+ resources = []
+
+ # List of (src, dest) tuples; dest should be a path relative to the bundle
+ # (eg. "Contents/Resources/MyStuff/SomeFile.ext).
+ files = []
+
+ # Directory where the bundle will be assembled.
+ builddir = "build"
+
+ # platform, name of the subfolder of Contents that contains the executable.
+ platform = "MacOS"
+
+ # Make symlinks instead copying files. This is handy during debugging, but
+ # makes the bundle non-distributable.
+ symlink = 0
+
+ # Verbosity level.
+ verbosity = 1
def setup(self):
+ # XXX rethink self.name munging, this is brittle.
self.name, ext = os.path.splitext(self.name)
if not ext:
ext = ".bundle"
- self.bundleextension = ext
+ bundleextension = ext
# misc (derived) attributes
- self.bundlepath = pathjoin(self.builddir, self.name + self.bundleextension)
+ self.bundlepath = pathjoin(self.builddir, self.name + bundleextension)
self.execdir = pathjoin("Contents", self.platform)
- plist = plistDefaults.copy()
+ plist = self.plist
plist.CFBundleName = self.name
plist.CFBundlePackageType = self.type
plist.CFBundleSignature = self.creator
- plist.update(self.plist)
- self.plist = plist
def build(self):
"""Build the bundle."""
@@ -200,31 +216,23 @@ pythonhomeSnippet = """os.environ["home"] = resources"""
class AppBuilder(BundleBuilder):
- """This class extends the BundleBuilder constructor with these
- arguments:
-
- mainprogram: A Python main program. If this argument is given,
- the main executable in the bundle will be a small wrapper
- that invokes the main program. (XXX Discuss why.)
- executable: The main executable. If a Python main program is
- specified the executable will be copied to Resources and
- be invoked by the wrapper program mentioned above. Else
- it will simply be used as the main executable.
- nibname: The name of the main nib, for Cocoa apps. Defaults
- to None, but must be specified when building a Cocoa app.
- symlink_exec: Symlink the executable instead of copying it.
-
- For the other keyword arguments see the BundleBuilder doc string.
- """
+ # A Python main program. If this argument is given, the main
+ # executable in the bundle will be a small wrapper that invokes
+ # the main program. (XXX Discuss why.)
+ mainprogram = None
+
+ # The main executable. If a Python main program is specified
+ # the executable will be copied to Resources and be invoked
+ # by the wrapper program mentioned above. Otherwise it will
+ # simply be used as the main executable.
+ executable = None
- def __init__(self, name=None, mainprogram=None, executable=None,
- nibname=None, symlink_exec=0, **kwargs):
- """See the class doc string for a description of the arguments."""
- self.mainprogram = mainprogram
- self.executable = executable
- self.nibname = nibname
- self.symlink_exec = symlink_exec
- BundleBuilder.__init__(self, name=name, **kwargs)
+ # The name of the main nib, for Cocoa apps. *Must* be specified
+ # when building a Cocoa app.
+ nibname = None
+
+ # Symlink the executable instead of copying it.
+ symlink_exec = 0
def setup(self):
if self.mainprogram is None and self.executable is None:
@@ -258,8 +266,7 @@ class AppBuilder(BundleBuilder):
execpath = pathjoin(resdir, os.path.basename(self.executable))
if not self.symlink_exec:
self.files.append((self.executable, execpath))
- else:
- self.execpath = execpath
+ self.execpath = execpath
# For execve wrapper
setexecutable = setExecutableTemplate % os.path.basename(self.executable)
else: