From a7402d0094a782b7d99d86bb006313bfc9bd4d47 Mon Sep 17 00:00:00 2001 From: Ray Speth Date: Tue, 3 Jan 2012 23:08:05 +0000 Subject: [PATCH] Added functions to automatically add files to windows install --- .../{cantera.wxs => cantera.wxs.example} | 0 platform/windows/wxsgen.py | 149 ++++++++++++------ 2 files changed, 101 insertions(+), 48 deletions(-) rename platform/windows/{cantera.wxs => cantera.wxs.example} (100%) diff --git a/platform/windows/cantera.wxs b/platform/windows/cantera.wxs.example similarity index 100% rename from platform/windows/cantera.wxs rename to platform/windows/cantera.wxs.example diff --git a/platform/windows/wxsgen.py b/platform/windows/wxsgen.py index 0ffec79df..fe9f81ccf 100644 --- a/platform/windows/wxsgen.py +++ b/platform/windows/wxsgen.py @@ -1,20 +1,17 @@ -try: - # Prefer LXML for its pretty printer, but xml.etree works fine. - import lxml.etree as et - have_lxml = True -except ImportError: - import xml.etree.ElementTree as et - have_lxml = False +import os, sys +import uuid +import xml.etree.ElementTree as et -wix = et.Element("Wix", {'xmlns': 'http://schemas.microsoft.com/wix/2006/wi'}) +CANTERA_UUID = uuid.UUID('1B36CAF0-279D-11E1-8979-001FBC085391') def Directory(parent, Id, Name): return et.SubElement(parent, 'Directory', dict(Id=Id, Name=Name)) -def FileComponent(parent, componentId, fileId, Guid, Name, Source, DiskId='1', KeyPath='yes'): +def FileComponent(parent, componentId, fileId, Name, Source, DiskId='1', KeyPath='yes'): + guid = str(uuid.uuid5(CANTERA_UUID, componentId)) c = et.SubElement(parent, "Component", - dict(Id=componentId, Guid=Guid)) + dict(Id=componentId, Guid=guid)) f = et.SubElement(c, "File", dict(Id=fileId, Name=Name, @@ -23,47 +20,103 @@ def FileComponent(parent, componentId, fileId, Guid, Name, Source, DiskId='1', K KeyPath=KeyPath)) return c,f -product = et.SubElement(wix, "Product", - dict(Name='Cantera 2.0', - Id='1B36CAF0-279D-11E1-8979-001FBC085391', - UpgradeCode='2340BEE1-279D-11E1-A4AA-001FBC085391', - Language='1033', - Codepage='1252', - Version='2.0.0', - Manufacturer='Cantera Developers')) -package = et.SubElement(product, "Package", - dict(Id='*', - Keywords='Installer', - Description="Cantera 2.0 Installer", - InstallerVersion='100', - Languages='1033', - Compressed='yes', - SummaryCodepage='1252')) +def indent(elem, level=0): + """ in-place prettyprint formatter (from lxml) """ + i = "\n" + level*" " + if len(elem): + if not elem.text or not elem.text.strip(): + elem.text = i + " " + if not elem.tail or not elem.tail.strip(): + elem.tail = i + for elem in elem: + indent(elem, level+1) + if not elem.tail or not elem.tail.strip(): + elem.tail = i + else: + if level and (not elem.tail or not elem.tail.strip()): + elem.tail = i -# Required boilerplate refering to nonexistent installation media -media = et.SubElement(product, "Media", - dict(Id='1', - Cabinet='cantera.cab', - EmbedCab='yes', - DiskPrompt='CD-ROM #1')) -diskprompt = et.SubElement(product, "Property", - dict(Id='DiskPrompt', - Value="Cantera Installation Disk")) -targetdir = Directory(product, 'TARGETDIR', 'SourceDir') -pfiles = Directory(targetdir, 'ProgramFilesFolder', 'PFiles') -instdir = Directory(pfiles, 'INSTALLDIR', 'Cantera') -bindir = Directory(instdir, 'bin', 'bin') +def addDirectoryContents(prefix, directory, parent, feature): + """ + prefix: path to the parent directory + directory: name of the directory to add + parent: the Element for the parent directory + feature: the Element for the feature to add the files to + """ + directories = {} -ck2cti = FileComponent(bindir, 'MainExecutable', 'ck2ctiEXE', - '0ABCA730-279D-11E1-984E-001FBC085391', - 'ck2cti.exe', '../../stage/bin/ck2cti.exe') + directories[directory] = Directory(parent, directory, directory) + for path, dirs, files in os.walk('/'.join((prefix, directory))): + path = path.lstrip(prefix + '/').replace('\\', '/') + for d in dirs: + dpath = '/'.join((path, d)) + ID = dpath.replace('/', '_') + directories[dpath] = Directory(directories[path], ID, d) -complete = et.SubElement(product, 'Feature', dict(Id='Complete', Level='1')) -mainExec = et.SubElement(complete, 'ComponentRef', dict(Id='MainExecutable')) + for f in files: + ID = '_'.join((path, f)).replace('/', '_') + FileComponent(directories[path], ID, ID, f, + '/'.join((prefix, path, f))) + et.SubElement(feature, 'ComponentRef', dict(Id=ID)) -if have_lxml: - print et.tostring(wix, pretty_print=True) -else: - print et.tostring(wix) + return directories + + +def make_wxs(stageDir, outFile): + wix = et.Element("Wix", {'xmlns': 'http://schemas.microsoft.com/wix/2006/wi'}) + product = et.SubElement(wix, "Product", + dict(Name='Cantera 2.0', + Id=str(CANTERA_UUID), + UpgradeCode='2340BEE1-279D-11E1-A4AA-001FBC085391', + Language='1033', + Codepage='1252', + Version='2.0.0', + Manufacturer='Cantera Developers')) + + package = et.SubElement(product, "Package", + dict(Id='*', + Keywords='Installer', + Description="Cantera 2.0 Installer", + InstallerVersion='100', + Languages='1033', + Compressed='yes', + SummaryCodepage='1252')) + + # Required boilerplate refering to nonexistent installation media + media = et.SubElement(product, "Media", + dict(Id='1', + Cabinet='cantera.cab', + EmbedCab='yes', + DiskPrompt='CD-ROM #1')) + diskprompt = et.SubElement(product, "Property", + dict(Id='DiskPrompt', + Value="Cantera Installation Disk")) + + # Directories + targetdir = Directory(product, 'TARGETDIR', 'SourceDir') + pfiles = Directory(targetdir, 'ProgramFilesFolder', 'PFiles') + instdir = Directory(pfiles, 'INSTALLDIR', 'Cantera') + + # Features + complete = et.SubElement(product, 'Feature', dict(Id='Complete', Level='1')) + + # Files + includes = addDirectoryContents(stageDir, 'include', instdir, complete) + binaries = addDirectoryContents(stageDir, 'bin', instdir, complete) + + # Format and save as XML + indent(wix) + tree = et.ElementTree(wix) + tree.write(outFile) + +def usage(): + print "Usage: wxsgen " + +if __name__ == '__main__': + if len(sys.argv) != 3: + usage() + sys.exit() + + make_wxs(sys.argv[1], sys.argv[2])