#!/usr/bin/env python

"""buildpkg.py -- Build OS X packages for Apple's Installer.app.

This is an experimental command-line tool for building packages to be
installed with the Mac OS X Installer.app application. 

It is much inspired by Apple's GUI tool called PackageMaker.app, that 
seems to be part of the OS X developer tools installed in the folder 
/Developer/Applications. But apparently there are other free tools to 
do the same thing which are also named PackageMaker like Brian Hill's 
one: 

  http://personalpages.tds.net/~brian_hill/packagemaker.html

Beware of the multi-package features of Installer.app (which are not 
yet supported here) that can potentially screw-up your installation 
and are discussed in these articles on Stepwise:

  http://www.stepwise.com/Articles/Technical/Packages/InstallerWoes.html
  http://www.stepwise.com/Articles/Technical/Packages/InstallerOnX.html

Beside using the PackageMaker class directly, by importing it inside 
another module, say, there are additional ways of using this module:
the top-level buildPackage() function provides a shortcut to the same 
feature and is also called when using this module from the command-
line.

    ****************************************************************
    NOTE: For now you should be able to run this even on a non-OS X 
          system and get something similar to a package, but without
          the real archive (needs pax) and bom files (needs mkbom) 
          inside! This is only for providing a chance for testing to 
          folks without OS X.
    ****************************************************************

TODO:
  - test pre-process and post-process scripts (Python ones?)
  - handle multi-volume packages (?)
  - integrate into distutils (?)

Dinu C. Gherman, 
gherman@europemail.com
November 2001

!! USE AT YOUR OWN RISK !!
"""

__version__ = 0.2
__license__ = "FreeBSD"


import os, sys, glob, fnmatch, shutil, string, copy, getopt
from os.path import basename, dirname, join, islink, isdir, isfile

Error = "buildpkg.Error"

PKG_INFO_FIELDS = """\
Title
Version
Description
DefaultLocation
Diskname
DeleteWarning
NeedsAuthorization
DisableStop
UseUserMask
Application
Relocatable
Required
InstallOnly
RequiresReboot
RootVolumeOnly
InstallFat\
"""

######################################################################
# Helpers
######################################################################

# Convenience class, as suggested by /F.

class GlobDirectoryWalker:
    "A forward iterator that traverses files in a directory tree."

    def __init__(self, directory, pattern="*"):
        self.stack = [directory]
        self.pattern = pattern
        self.files = []
        self.index = 0


    def __getitem__(self, index):
        while 1:
            try:
                file = self.files[self.index]
                self.index = self.index + 1
            except IndexError:
                # pop next directory from stack
                self.directory = self.stack.pop()
                self.files = os.listdir(self.directory)
                self.index = 0
            else:
                # got a filename
                fullname = join(self.directory, file)
                if isdir(fullname) and not islink(fullname):
                    self.stack.append(fullname)
                if fnmatch.fnmatch(file, self.pattern):
                    return fullname


######################################################################
# The real thing
######################################################################

class PackageMaker:
    """A class to generate packages for Mac OS X.

    This is intended to create OS X packages (with extension .pkg)
    containing archives of arbitrary files that the Installer.app 
    will be able to handle.

    As of now, PackageMaker instances need to be created with the 
    title, version and description of the package to be built. 
    The package is built after calling the instance method 
    build(root, **options). It has the same name as the constructor's 
    title argument plus a '.pkg' extension and is located in the same 
    parent folder that contains the root folder.

    E.g. this will create a package folder /my/space/distutils.pkg/:

      pm = PackageMaker("distutils", "1.0.2", "Python distutils.")
      pm.build("/my/space/distutils")
    """

    packageInfoDefaults = {
        'Title': None,
        'Version': None,
        'Description': '',
        'DefaultLocation': '/',
        'Diskname': '(null)',
        'DeleteWarning': '',
        'NeedsAuthorization': 'NO',
        'DisableStop': 'NO',
        'UseUserMask': 'YES',
        'Application': 'NO',
        'Relocatable': 'YES',
        'Required': 'NO',
        'InstallOnly': 'NO',
        'RequiresReboot': 'NO',
        'RootVolumeOnly' : 'NO',
        'InstallFat': 'NO'}


    def __init__(self, title, version, desc):
        "Init. with mandatory title/version/description arguments."

        info = {"Title": title, "Version": version, "Description": desc}
        self.packageInfo = copy.deepcopy(self.packageInfoDefaults)
        self.packageInfo.update(info)
        
        # variables set later
        self.packageRootFolder = None
        self.packageResourceFolder = None
        self.sourceFolder = None
        self.resourceFolder = None


    def build(self, root, resources=None, **options):
        """Create a package for some given root folder.

        With no 'resources' argument set it is assumed to be the same 
        as the root directory. Option items replace the default ones 
        in the package info.
        """

        # set folder attributes
        self.sourceFolder = root
        if resources == None:
            self.resourceFolder = root
        else:
            self.resourceFolder = resources

        # replace default option settings with user ones if provided
        fields = self. packageInfoDefaults.keys()
        for k, v in options.items():
            if k in fields:
                self.packageInfo[k] = v
            elif not k in ["OutputDir"]:
                raise Error, "Unknown package option: %s" % k
        
        # Check where we should leave the output. Default is current directory
        outputdir = options.get("OutputDir", os.getcwd())
        packageName = self.packageInfo["Title"]
        self.PackageRootFolder = os.path.join(outputdir, packageName + ".pkg")
 
        # do what needs to be done
        self._makeFolders()
        self._addInfo()
        self._addBom()
        self._addArchive()
        self._addResources()
        self._addSizes()


    def _makeFolders(self):
        "Create package folder structure."

        # Not sure if the package name should contain the version or not...
        # packageName = "%s-%s" % (self.packageInfo["Title"], 
        #                          self.packageInfo["Version"]) # ??

        contFolder = join(self.PackageRootFolder, "Contents")
        self.packageResourceFolder = join(contFolder, "Resources")
        os.mkdir(self.PackageRootFolder)
        os.mkdir(contFolder)
        os.mkdir(self.packageResourceFolder)

    def _addInfo(self):
        "Write .info file containing installing options."

        # Not sure if options in PKG_INFO_FIELDS are complete...

        info = ""
        for f in string.split(PKG_INFO_FIELDS, "\n"):
            info = info + "%s %%(%s)s\n" % (f, f)
        info = info % self.packageInfo
        base = self.packageInfo["Title"] + ".info"
        path = join(self.packageResourceFolder, base)
        f = open(path, "w")
        f.write(info)


    def _addBom(self):
        "Write .bom file containing 'Bill of Materials'."

        # Currently ignores if the 'mkbom' tool is not available.

        try:
            base = self.packageInfo["Title"] + ".bom"
            bomPath = join(self.packageResourceFolder, base)
            cmd = "mkbom %s %s" % (self.sourceFolder, bomPath)
            res = os.system(cmd)
        except:
            pass


    def _addArchive(self):
        "Write .pax.gz file, a compressed archive using pax/gzip."

        # Currently ignores if the 'pax' tool is not available.

        cwd = os.getcwd()

        # create archive
        os.chdir(self.sourceFolder)
        base = basename(self.packageInfo["Title"]) + ".pax"
        self.archPath = join(self.packageResourceFolder, base)
        cmd = "pax -w -f %s %s" % (self.archPath, ".")
        res = os.system(cmd)
        
        # compress archive
        cmd = "gzip %s" % self.archPath
        res = os.system(cmd)
        os.chdir(cwd)


    def _addResources(self):
        "Add Welcome/ReadMe/License files, .lproj folders and scripts."

        # Currently we just copy everything that matches the allowed 
        # filenames. So, it's left to Installer.app to deal with the 
        # same file available in multiple formats...

        if not self.resourceFolder:
            return

        # find candidate resource files (txt html rtf rtfd/ or lproj/)
        allFiles = []
        for pat in string.split("*.txt *.html *.rtf *.rtfd *.lproj", " "):
            pattern = join(self.resourceFolder, pat)
            allFiles = allFiles + glob.glob(pattern)

        # find pre-process and post-process scripts
        # naming convention: packageName.{pre,post}_{upgrade,install}
        # Alternatively the filenames can be {pre,post}_{upgrade,install}
        # in which case we prepend the package name
        packageName = self.packageInfo["Title"]
        for pat in ("*upgrade", "*install", "*flight"):
            pattern = join(self.resourceFolder, packageName + pat)
            pattern2 = join(self.resourceFolder, pat)
            allFiles = allFiles + glob.glob(pattern)
            allFiles = allFiles + glob.glob(pattern2)

        # check name patterns
        files = []
        for f in allFiles:
            for s in ("Welcome", "License", "ReadMe"):
                if string.find(basename(f), s) == 0:
                    files.append((f, f))
            if f[-6:] == ".lproj":
                files.append((f, f))
            elif basename(f) in ["pre_upgrade", "pre_install", "post_upgrade", "post_install"]:
                files.append((f, packageName+"."+basename(f)))
            elif basename(f) in ["preflight", "postflight"]:
                files.append((f, f))
            elif f[-8:] == "_upgrade":
                files.append((f,f))
            elif f[-8:] == "_install":
                files.append((f,f))

        # copy files
        for src, dst in files:
            src = basename(src)
            dst = basename(dst)
            f = join(self.resourceFolder, src)
            if isfile(f):
                shutil.copy(f, os.path.join(self.packageResourceFolder, dst))
            elif isdir(f):
                # special case for .rtfd and .lproj folders...
                d = join(self.packageResourceFolder, dst)
                os.mkdir(d)
                files = GlobDirectoryWalker(f)
                for file in files:
                    shutil.copy(file, d)


    def _addSizes(self):
        "Write .sizes file with info about number and size of files."

        # Not sure if this is correct, but 'installedSize' and 
        # 'zippedSize' are now in Bytes. Maybe blocks are needed? 
        # Well, Installer.app doesn't seem to care anyway, saying 
        # the installation needs 100+ MB...

        numFiles = 0
        installedSize = 0
        zippedSize = 0

        files = GlobDirectoryWalker(self.sourceFolder)
        for f in files:
            numFiles = numFiles + 1
            installedSize = installedSize + os.lstat(f)[6]

        try:
            zippedSize = os.stat(self.archPath+ ".gz")[6]
        except OSError: # ignore error 
            pass
        base = self.packageInfo["Title"] + ".sizes"
        f = open(join(self.packageResourceFolder, base), "w")
        format = "NumFiles %d\nInstalledSize %d\nCompressedSize %d\n"
        f.write(format % (numFiles, installedSize, zippedSize))


# Shortcut function interface

def buildPackage(*args, **options):
    "A Shortcut function for building a package."
    
    o = options
    title, version, desc = o["Title"], o["Version"], o["Description"]
    pm = PackageMaker(title, version, desc)
    apply(pm.build, list(args), options)


######################################################################
# Tests
######################################################################

def test0():
    "Vanilla test for the distutils distribution."

    pm = PackageMaker("distutils2", "1.0.2", "Python distutils package.")
    pm.build("/Users/dinu/Desktop/distutils2")


def test1():
    "Test for the reportlab distribution with modified options."

    pm = PackageMaker("reportlab", "1.10", 
                      "ReportLab's Open Source PDF toolkit.")
    pm.build(root="/Users/dinu/Desktop/reportlab", 
             DefaultLocation="/Applications/ReportLab",
             Relocatable="YES")

def test2():
    "Shortcut test for the reportlab distribution with modified options."

    buildPackage(
        "/Users/dinu/Desktop/reportlab", 
        Title="reportlab", 
        Version="1.10", 
        Description="ReportLab's Open Source PDF toolkit.",
        DefaultLocation="/Applications/ReportLab",
        Relocatable="YES")


######################################################################
# Command-line interface
######################################################################

def printUsage():
    "Print usage message."

    format = "Usage: %s <opts1> [<opts2>] <root> [<resources>]"
    print format % basename(sys.argv[0])
    print
    print "       with arguments:"
    print "           (mandatory) root:         the package root folder"
    print "           (optional)  resources:    the package resources folder"
    print
    print "       and options:"
    print "           (mandatory) opts1:"
    mandatoryKeys = string.split("Title Version Description", " ")
    for k in mandatoryKeys:
        print "               --%s" % k
    print "           (optional) opts2: (with default values)"

    pmDefaults = PackageMaker.packageInfoDefaults
    optionalKeys = pmDefaults.keys()
    for k in mandatoryKeys:
        optionalKeys.remove(k)
    optionalKeys.sort()
    maxKeyLen = max(map(len, optionalKeys))
    for k in optionalKeys:
        format = "               --%%s:%s %%s"
        format = format % (" " * (maxKeyLen-len(k)))
        print format % (k, repr(pmDefaults[k]))


def main():
    "Command-line interface."

    shortOpts = ""
    keys = PackageMaker.packageInfoDefaults.keys()
    longOpts = map(lambda k: k+"=", keys)

    try:
        opts, args = getopt.getopt(sys.argv[1:], shortOpts, longOpts)
    except getopt.GetoptError, details:
        print details
        printUsage()
        return

    optsDict = {}
    for k, v in opts:
        optsDict[k[2:]] = v

    ok = optsDict.keys()
    if not (1 <= len(args) <= 2):
        print "No argument given!"
    elif not ("Title" in ok and \
              "Version" in ok and \
              "Description" in ok):
        print "Missing mandatory option!"
    else:
        apply(buildPackage, args, optsDict)
        return

    printUsage()

    # sample use:
    # buildpkg.py --Title=distutils \
    #             --Version=1.0.2 \
    #             --Description="Python distutils package." \
    #             /Users/dinu/Desktop/distutils


if __name__ == "__main__":
    main()
