def getExtraFiles(self, platform): """ Returns a list of extra files that will need to be included with the standalone executable in order for it to run, such as dependent libraries. The returned paths are full absolute paths. """ package = self.host.getPackages(name="p3dembed", platform=platform)[0] if not package.downloadDescFile(self.http): Standalone.notify.warning(" -> %s failed for platform %s" % (package.packageName, package.platform)) return [] if not package.downloadPackage(self.http): Standalone.notify.warning(" -> %s failed for platform %s" % (package.packageName, package.platform)) return [] filenames = [] vfs = VirtualFileSystem.getGlobalPtr() for e in package.extracts: if e.basename not in [ "p3dembed", "p3dembed.exe", "p3dembed.exe.manifest", "p3dembedw.exe", "p3dembedw.exe.manifest", ]: filename = Filename(package.getPackageDir(), e.filename) filename.makeAbsolute() if vfs.exists(filename): filenames.append(filename) else: Standalone.notify.error("%s mentioned in xml, but does not exist" % e.filename) return filenames
def getExtraFiles(self, platform): """ Returns a list of extra files that will need to be included with the standalone executable in order for it to run, such as dependent libraries. The returned paths are full absolute paths. """ package = self.host.getPackages(name="p3dembed", platform=platform)[0] if not package.downloadDescFile(self.http): Standalone.notify.warning(" -> %s failed for platform %s" % (package.packageName, package.platform)) return [] if not package.downloadPackage(self.http): Standalone.notify.warning(" -> %s failed for platform %s" % (package.packageName, package.platform)) return [] filenames = [] vfs = VirtualFileSystem.getGlobalPtr() for e in package.extracts: if e.basename not in [ "p3dembed", "p3dembed.exe", "p3dembed.exe.manifest", "p3dembedw.exe", "p3dembedw.exe.manifest" ]: filename = Filename(package.getPackageDir(), e.filename) filename.makeAbsolute() if vfs.exists(filename): filenames.append(filename) else: Standalone.notify.error( "%s mentioned in xml, but does not exist" % e.filename) return filenames
def buildNSIS(self, output, platform): # Check if we have makensis first makensis = None if sys.platform.startswith("win"): syspath = os.defpath.split(";") + os.environ["PATH"].split(";") for p in set(syspath): p1 = os.path.join(p, "makensis.exe") p2 = os.path.join(os.path.dirname(p), "nsis", "makensis.exe") if os.path.isfile(p1): makensis = p1 break elif os.path.isfile(p2): makensis = p2 break if not makensis: import pandac makensis = os.path.dirname(os.path.dirname(pandac.__file__)) makensis = os.path.join(makensis, "nsis", "makensis.exe") if not os.path.isfile(makensis): makensis = None else: for p in os.defpath.split(":") + os.environ["PATH"].split(":"): if os.path.isfile(os.path.join(p, "makensis")): makensis = os.path.join(p, "makensis") if makensis == None: Installer.notify.warning("Makensis utility not found, no Windows installer will be built!") return None output = Filename(output) if output.isDirectory(): output = Filename(output, "%s %s.exe" % (self.fullname, self.version)) Installer.notify.info("Creating %s..." % output) output.makeAbsolute() extrafiles = self.standalone.getExtraFiles(platform) exefile = Filename(Filename.getTempDirectory(), self.shortname + ".exe") exefile.unlink() if self.includeRequires: extraTokens = {"host_dir": "."} else: extraTokens = {} self.standalone.build(exefile, platform, extraTokens) # Temporary directory to store the hostdir in hostDir = Filename(self.tempDir, platform + "/") if not hostDir.exists(): hostDir.makeDir() self.installPackagesInto(hostDir, platform) nsifile = Filename(Filename.getTempDirectory(), self.shortname + ".nsi") nsifile.unlink() nsi = open(nsifile.toOsSpecific(), "w") # Some global info nsi.write('Name "%s"\n' % self.fullname) nsi.write('OutFile "%s"\n' % output.toOsSpecific()) nsi.write('InstallDir "$PROGRAMFILES\\%s"\n' % self.fullname) nsi.write("SetCompress auto\n") nsi.write("SetCompressor lzma\n") nsi.write("ShowInstDetails nevershow\n") nsi.write("ShowUninstDetails nevershow\n") nsi.write('InstType "Typical"\n') # Tell Vista that we require admin rights nsi.write("RequestExecutionLevel admin\n") nsi.write("\n") nsi.write("Function launch\n") nsi.write(' ExecShell "open" "$INSTDIR\\%s.exe"\n' % self.shortname) nsi.write("FunctionEnd\n") nsi.write("\n") nsi.write('!include "MUI2.nsh"\n') nsi.write("!define MUI_ABORTWARNING\n") nsi.write("!define MUI_FINISHPAGE_RUN\n") nsi.write("!define MUI_FINISHPAGE_RUN_FUNCTION launch\n") nsi.write('!define MUI_FINISHPAGE_RUN_TEXT "Run %s"\n' % self.fullname) nsi.write("\n") nsi.write("Var StartMenuFolder\n") nsi.write("!insertmacro MUI_PAGE_WELCOME\n") if not self.licensefile.empty(): abs = Filename(self.licensefile) abs.makeAbsolute() nsi.write('!insertmacro MUI_PAGE_LICENSE "%s"\n' % abs.toOsSpecific()) nsi.write("!insertmacro MUI_PAGE_DIRECTORY\n") nsi.write("!insertmacro MUI_PAGE_STARTMENU Application $StartMenuFolder\n") nsi.write("!insertmacro MUI_PAGE_INSTFILES\n") nsi.write("!insertmacro MUI_PAGE_FINISH\n") nsi.write("!insertmacro MUI_UNPAGE_WELCOME\n") nsi.write("!insertmacro MUI_UNPAGE_CONFIRM\n") nsi.write("!insertmacro MUI_UNPAGE_INSTFILES\n") nsi.write("!insertmacro MUI_UNPAGE_FINISH\n") nsi.write('!insertmacro MUI_LANGUAGE "English"\n') # This section defines the installer. nsi.write('Section "" SecCore\n') nsi.write(' SetOutPath "$INSTDIR"\n') nsi.write(' File "%s"\n' % exefile.toOsSpecific()) for f in extrafiles: nsi.write(' File "%s"\n' % f.toOsSpecific()) curdir = "" for root, dirs, files in self.os_walk(hostDir.toOsSpecific()): for name in files: file = Filename.fromOsSpecific(os.path.join(root, name)) file.makeAbsolute() file.makeRelativeTo(hostDir) outdir = file.getDirname().replace("/", "\\") if curdir != outdir: nsi.write(' SetOutPath "$INSTDIR\\%s"\n' % outdir) curdir = outdir nsi.write(' File "%s"\n' % os.path.join(root, name)) nsi.write(' WriteUninstaller "$INSTDIR\\Uninstall.exe"\n') nsi.write(" ; Start menu items\n") nsi.write(" !insertmacro MUI_STARTMENU_WRITE_BEGIN Application\n") nsi.write(' CreateDirectory "$SMPROGRAMS\\$StartMenuFolder"\n') nsi.write( ' CreateShortCut "$SMPROGRAMS\\$StartMenuFolder\\%s.lnk" "$INSTDIR\\%s.exe"\n' % (self.fullname, self.shortname) ) nsi.write(' CreateShortCut "$SMPROGRAMS\\$StartMenuFolder\\Uninstall.lnk" "$INSTDIR\\Uninstall.exe"\n') nsi.write(" !insertmacro MUI_STARTMENU_WRITE_END\n") nsi.write("SectionEnd\n") # This section defines the uninstaller. nsi.write("Section Uninstall\n") nsi.write(' Delete "$INSTDIR\\%s.exe"\n' % self.shortname) for f in extrafiles: nsi.write(' Delete "%s"\n' % f.getBasename()) nsi.write(' Delete "$INSTDIR\\Uninstall.exe"\n') nsi.write(' RMDir /r "$INSTDIR"\n') nsi.write(" ; Start menu items\n") nsi.write(" !insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuFolder\n") nsi.write(' Delete "$SMPROGRAMS\\$StartMenuFolder\\Uninstall.lnk"\n') nsi.write(' RMDir "$SMPROGRAMS\\$StartMenuFolder"\n') nsi.write("SectionEnd") nsi.close() cmd = [makensis] for o in ["V2"]: if sys.platform.startswith("win"): cmd.append("/" + o) else: cmd.append("-" + o) cmd.append(nsifile.toOsSpecific()) print cmd try: retcode = subprocess.call(cmd, shell=False) if retcode != 0: self.notify.warning("Failure invoking NSIS command.") except OSError: self.notify.warning("Unable to invoke NSIS command.") nsifile.unlink() return output
def buildPKG(self, output, platform): appfn = self.buildAPP(output, platform) appname = "/Applications/" + appfn.getBasename() output = Filename(output) if output.isDirectory(): output = Filename(output, "%s %s.pkg" % (self.fullname, self.version)) Installer.notify.info("Creating %s..." % output) Filename(output, "Contents/Resources/en.lproj/").makeDir() if self.licensefile: shutil.copyfile( self.licensefile.toOsSpecific(), Filename(output, "Contents/Resources/License.txt").toOsSpecific() ) pkginfo = open(Filename(output, "Contents/PkgInfo").toOsSpecific(), "w") pkginfo.write("pkmkrpkg1") pkginfo.close() pkginfo = open(Filename(output, "Contents/Resources/package_version").toOsSpecific(), "w") pkginfo.write("major: 1\nminor: 9") pkginfo.close() # Although it might make more sense to use Python's plistlib here, # it is not available on non-OSX systems before Python 2.6. plist = open(Filename(output, "Contents/Info.plist").toOsSpecific(), "w") plist.write('<?xml version="1.0" encoding="UTF-8"?>\n') plist.write( '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n' ) plist.write('<plist version="1.0">\n') plist.write("<dict>\n") plist.write("\t<key>CFBundleIdentifier</key>\n") plist.write("\t<string>%s.pkg.%s</string>\n" % (self.authorid, self.shortname)) plist.write("\t<key>CFBundleShortVersionString</key>\n") plist.write("\t<string>%s</string>\n" % self.version) plist.write("\t<key>IFMajorVersion</key>\n") plist.write("\t<integer>1</integer>\n") plist.write("\t<key>IFMinorVersion</key>\n") plist.write("\t<integer>9</integer>\n") plist.write("\t<key>IFPkgFlagAllowBackRev</key>\n") plist.write("\t<false/>\n") plist.write("\t<key>IFPkgFlagAuthorizationAction</key>\n") plist.write("\t<string>RootAuthorization</string>\n") plist.write("\t<key>IFPkgFlagDefaultLocation</key>\n") plist.write("\t<string>/</string>\n") plist.write("\t<key>IFPkgFlagFollowLinks</key>\n") plist.write("\t<true/>\n") plist.write("\t<key>IFPkgFlagIsRequired</key>\n") plist.write("\t<false/>\n") plist.write("\t<key>IFPkgFlagOverwritePermissions</key>\n") plist.write("\t<false/>\n") plist.write("\t<key>IFPkgFlagRelocatable</key>\n") plist.write("\t<false/>\n") plist.write("\t<key>IFPkgFlagRestartAction</key>\n") plist.write("\t<string>None</string>\n") plist.write("\t<key>IFPkgFlagRootVolumeOnly</key>\n") plist.write("\t<true/>\n") plist.write("\t<key>IFPkgFlagUpdateInstalledLanguages</key>\n") plist.write("\t<false/>\n") plist.write("\t<key>IFPkgFormatVersion</key>\n") plist.write("\t<real>0.10000000149011612</real>\n") plist.write("\t<key>IFPkgPathMappings</key>\n") plist.write("\t<dict>\n") plist.write("\t\t<key>%s</key>\n" % appname) plist.write("\t\t<string>{pkmk-token-2}</string>\n") plist.write("\t</dict>\n") plist.write("</dict>\n") plist.write("</plist>\n") plist.close() plist = open(Filename(output, "Contents/Resources/TokenDefinitions.plist").toOsSpecific(), "w") plist.write('<?xml version="1.0" encoding="UTF-8"?>\n') plist.write( '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n' ) plist.write('<plist version="1.0">\n') plist.write("<dict>\n") plist.write("\t<key>pkmk-token-2</key>\n") plist.write("\t<array>\n") plist.write("\t\t<dict>\n") plist.write("\t\t\t<key>identifier</key>\n") plist.write("\t\t\t<string>%s.%s</string>\n" % (self.authorid, self.shortname)) plist.write("\t\t\t<key>path</key>\n") plist.write("\t\t\t<string>%s</string>\n" % appname) plist.write("\t\t\t<key>searchPlugin</key>\n") plist.write("\t\t\t<string>CommonAppSearch</string>\n") plist.write("\t\t</dict>\n") plist.write("\t</array>\n") plist.write("</dict>\n") plist.write("</plist>\n") plist.close() plist = open(Filename(output, "Contents/Resources/en.lproj/Description.plist").toOsSpecific(), "w") plist.write('<?xml version="1.0" encoding="UTF-8"?>\n') plist.write( '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n' ) plist.write('<plist version="1.0">\n') plist.write("<dict>\n") plist.write("\t<key>IFPkgDescriptionDescription</key>\n") plist.write("\t<string></string>\n") plist.write("\t<key>IFPkgDescriptionTitle</key>\n") plist.write("\t<string>%s</string>\n" % self.fullname) plist.write("</dict>\n") plist.write("</plist>\n") plist.close() if hasattr(tarfile, "PAX_FORMAT"): archive = tarfile.open( Filename(output, "Contents/Archive.pax.gz").toOsSpecific(), "w:gz", format=tarfile.PAX_FORMAT, tarinfo=TarInfoRootOSX, ) else: archive = tarfile.open( Filename(output, "Contents/Archive.pax.gz").toOsSpecific(), "w:gz", tarinfo=TarInfoRootOSX ) archive.add(appfn.toOsSpecific(), appname) archive.close() # Put the .pkg into a zipfile archive = Filename(output.getDirname(), "%s %s.zip" % (self.fullname, self.version)) dir = Filename(output.getDirname()) dir.makeAbsolute() zip = zipfile.ZipFile(archive.toOsSpecific(), "w") for root, dirs, files in self.os_walk(output.toOsSpecific()): for name in files: file = Filename.fromOsSpecific(os.path.join(root, name)) file.makeAbsolute() file.makeRelativeTo(dir) zip.write(os.path.join(root, name), str(file)) zip.close() return output
def buildNSIS(self, output, platform): # Check if we have makensis first makensis = None if (sys.platform.startswith("win")): syspath = os.defpath.split(";") + os.environ["PATH"].split(";") for p in set(syspath): p1 = os.path.join(p, "makensis.exe") p2 = os.path.join(os.path.dirname(p), "nsis", "makensis.exe") if os.path.isfile(p1): makensis = p1 break elif os.path.isfile(p2): makensis = p2 break if not makensis: import pandac makensis = os.path.dirname(os.path.dirname(pandac.__file__)) makensis = os.path.join(makensis, "nsis", "makensis.exe") if not os.path.isfile(makensis): makensis = None else: for p in os.defpath.split(":") + os.environ["PATH"].split(":"): if os.path.isfile(os.path.join(p, "makensis")): makensis = os.path.join(p, "makensis") if makensis == None: Installer.notify.warning( "Makensis utility not found, no Windows installer will be built!" ) return None output = Filename(output) if output.isDirectory(): output = Filename(output, "%s %s.exe" % (self.fullname, self.version)) Installer.notify.info("Creating %s..." % output) output.makeAbsolute() extrafiles = self.standalone.getExtraFiles(platform) exefile = Filename(Filename.getTempDirectory(), self.shortname + ".exe") exefile.unlink() if self.includeRequires: extraTokens = {"host_dir": "."} else: extraTokens = {} self.standalone.build(exefile, platform, extraTokens) # Temporary directory to store the hostdir in hostDir = Filename(self.tempDir, platform + "/") if not hostDir.exists(): hostDir.makeDir() self.installPackagesInto(hostDir, platform) nsifile = Filename(Filename.getTempDirectory(), self.shortname + ".nsi") nsifile.unlink() nsi = open(nsifile.toOsSpecific(), "w") # Some global info nsi.write('Name "%s"\n' % self.fullname) nsi.write('OutFile "%s"\n' % output.toOsSpecific()) nsi.write('InstallDir "$PROGRAMFILES\\%s"\n' % self.fullname) nsi.write('SetCompress auto\n') nsi.write('SetCompressor lzma\n') nsi.write('ShowInstDetails nevershow\n') nsi.write('ShowUninstDetails nevershow\n') nsi.write('InstType "Typical"\n') # Tell Vista that we require admin rights nsi.write('RequestExecutionLevel admin\n') nsi.write('\n') nsi.write('Function launch\n') nsi.write(' ExecShell "open" "$INSTDIR\\%s.exe"\n' % self.shortname) nsi.write('FunctionEnd\n') nsi.write('\n') nsi.write('!include "MUI2.nsh"\n') nsi.write('!define MUI_ABORTWARNING\n') nsi.write('!define MUI_FINISHPAGE_RUN\n') nsi.write('!define MUI_FINISHPAGE_RUN_FUNCTION launch\n') nsi.write('!define MUI_FINISHPAGE_RUN_TEXT "Run %s"\n' % self.fullname) nsi.write('\n') nsi.write('Var StartMenuFolder\n') nsi.write('!insertmacro MUI_PAGE_WELCOME\n') if not self.licensefile.empty(): abs = Filename(self.licensefile) abs.makeAbsolute() nsi.write('!insertmacro MUI_PAGE_LICENSE "%s"\n' % abs.toOsSpecific()) nsi.write('!insertmacro MUI_PAGE_DIRECTORY\n') nsi.write( '!insertmacro MUI_PAGE_STARTMENU Application $StartMenuFolder\n') nsi.write('!insertmacro MUI_PAGE_INSTFILES\n') nsi.write('!insertmacro MUI_PAGE_FINISH\n') nsi.write('!insertmacro MUI_UNPAGE_WELCOME\n') nsi.write('!insertmacro MUI_UNPAGE_CONFIRM\n') nsi.write('!insertmacro MUI_UNPAGE_INSTFILES\n') nsi.write('!insertmacro MUI_UNPAGE_FINISH\n') nsi.write('!insertmacro MUI_LANGUAGE "English"\n') # This section defines the installer. nsi.write('Section "" SecCore\n') nsi.write(' SetOutPath "$INSTDIR"\n') nsi.write(' File "%s"\n' % exefile.toOsSpecific()) for f in extrafiles: nsi.write(' File "%s"\n' % f.toOsSpecific()) curdir = "" for root, dirs, files in self.os_walk(hostDir.toOsSpecific()): for name in files: file = Filename.fromOsSpecific(os.path.join(root, name)) file.makeAbsolute() file.makeRelativeTo(hostDir) outdir = file.getDirname().replace('/', '\\') if curdir != outdir: nsi.write(' SetOutPath "$INSTDIR\\%s"\n' % outdir) curdir = outdir nsi.write(' File "%s"\n' % os.path.join(root, name)) nsi.write(' WriteUninstaller "$INSTDIR\\Uninstall.exe"\n') nsi.write(' ; Start menu items\n') nsi.write(' !insertmacro MUI_STARTMENU_WRITE_BEGIN Application\n') nsi.write(' CreateDirectory "$SMPROGRAMS\\$StartMenuFolder"\n') nsi.write( ' CreateShortCut "$SMPROGRAMS\\$StartMenuFolder\\%s.lnk" "$INSTDIR\\%s.exe"\n' % (self.fullname, self.shortname)) nsi.write( ' CreateShortCut "$SMPROGRAMS\\$StartMenuFolder\\Uninstall.lnk" "$INSTDIR\\Uninstall.exe"\n' ) nsi.write(' !insertmacro MUI_STARTMENU_WRITE_END\n') nsi.write('SectionEnd\n') # This section defines the uninstaller. nsi.write('Section Uninstall\n') nsi.write(' Delete "$INSTDIR\\%s.exe"\n' % self.shortname) for f in extrafiles: nsi.write(' Delete "%s"\n' % f.getBasename()) nsi.write(' Delete "$INSTDIR\\Uninstall.exe"\n') nsi.write(' RMDir /r "$INSTDIR"\n') nsi.write(' ; Start menu items\n') nsi.write( ' !insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuFolder\n' ) nsi.write(' Delete "$SMPROGRAMS\\$StartMenuFolder\\Uninstall.lnk"\n') nsi.write(' RMDir "$SMPROGRAMS\\$StartMenuFolder"\n') nsi.write('SectionEnd') nsi.close() cmd = [makensis] for o in ["V2"]: if sys.platform.startswith("win"): cmd.append("/" + o) else: cmd.append("-" + o) cmd.append(nsifile.toOsSpecific()) print cmd try: retcode = subprocess.call(cmd, shell=False) if retcode != 0: self.notify.warning("Failure invoking NSIS command.") except OSError: self.notify.warning("Unable to invoke NSIS command.") nsifile.unlink() return output
def buildPKG(self, output, platform): appfn = self.buildAPP(output, platform) appname = "/Applications/" + appfn.getBasename() output = Filename(output) if output.isDirectory(): output = Filename(output, "%s %s.pkg" % (self.fullname, self.version)) Installer.notify.info("Creating %s..." % output) Filename(output, "Contents/Resources/en.lproj/").makeDir() if self.licensefile: shutil.copyfile( self.licensefile.toOsSpecific(), Filename(output, "Contents/Resources/License.txt").toOsSpecific()) pkginfo = open( Filename(output, "Contents/PkgInfo").toOsSpecific(), "w") pkginfo.write("pkmkrpkg1") pkginfo.close() pkginfo = open( Filename(output, "Contents/Resources/package_version").toOsSpecific(), "w") pkginfo.write("major: 1\nminor: 9") pkginfo.close() # Although it might make more sense to use Python's plistlib here, # it is not available on non-OSX systems before Python 2.6. plist = open( Filename(output, "Contents/Info.plist").toOsSpecific(), "w") plist.write('<?xml version="1.0" encoding="UTF-8"?>\n') plist.write( '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n' ) plist.write('<plist version="1.0">\n') plist.write('<dict>\n') plist.write('\t<key>CFBundleIdentifier</key>\n') plist.write('\t<string>%s.pkg.%s</string>\n' % (self.authorid, self.shortname)) plist.write('\t<key>CFBundleShortVersionString</key>\n') plist.write('\t<string>%s</string>\n' % self.version) plist.write('\t<key>IFMajorVersion</key>\n') plist.write('\t<integer>1</integer>\n') plist.write('\t<key>IFMinorVersion</key>\n') plist.write('\t<integer>9</integer>\n') plist.write('\t<key>IFPkgFlagAllowBackRev</key>\n') plist.write('\t<false/>\n') plist.write('\t<key>IFPkgFlagAuthorizationAction</key>\n') plist.write('\t<string>RootAuthorization</string>\n') plist.write('\t<key>IFPkgFlagDefaultLocation</key>\n') plist.write('\t<string>/</string>\n') plist.write('\t<key>IFPkgFlagFollowLinks</key>\n') plist.write('\t<true/>\n') plist.write('\t<key>IFPkgFlagIsRequired</key>\n') plist.write('\t<false/>\n') plist.write('\t<key>IFPkgFlagOverwritePermissions</key>\n') plist.write('\t<false/>\n') plist.write('\t<key>IFPkgFlagRelocatable</key>\n') plist.write('\t<false/>\n') plist.write('\t<key>IFPkgFlagRestartAction</key>\n') plist.write('\t<string>None</string>\n') plist.write('\t<key>IFPkgFlagRootVolumeOnly</key>\n') plist.write('\t<true/>\n') plist.write('\t<key>IFPkgFlagUpdateInstalledLanguages</key>\n') plist.write('\t<false/>\n') plist.write('\t<key>IFPkgFormatVersion</key>\n') plist.write('\t<real>0.10000000149011612</real>\n') plist.write('\t<key>IFPkgPathMappings</key>\n') plist.write('\t<dict>\n') plist.write('\t\t<key>%s</key>\n' % appname) plist.write('\t\t<string>{pkmk-token-2}</string>\n') plist.write('\t</dict>\n') plist.write('</dict>\n') plist.write('</plist>\n') plist.close() plist = open( Filename( output, "Contents/Resources/TokenDefinitions.plist").toOsSpecific(), "w") plist.write('<?xml version="1.0" encoding="UTF-8"?>\n') plist.write( '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n' ) plist.write('<plist version="1.0">\n') plist.write('<dict>\n') plist.write('\t<key>pkmk-token-2</key>\n') plist.write('\t<array>\n') plist.write('\t\t<dict>\n') plist.write('\t\t\t<key>identifier</key>\n') plist.write('\t\t\t<string>%s.%s</string>\n' % (self.authorid, self.shortname)) plist.write('\t\t\t<key>path</key>\n') plist.write('\t\t\t<string>%s</string>\n' % appname) plist.write('\t\t\t<key>searchPlugin</key>\n') plist.write('\t\t\t<string>CommonAppSearch</string>\n') plist.write('\t\t</dict>\n') plist.write('\t</array>\n') plist.write('</dict>\n') plist.write('</plist>\n') plist.close() plist = open( Filename(output, "Contents/Resources/en.lproj/Description.plist"). toOsSpecific(), "w") plist.write('<?xml version="1.0" encoding="UTF-8"?>\n') plist.write( '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n' ) plist.write('<plist version="1.0">\n') plist.write('<dict>\n') plist.write('\t<key>IFPkgDescriptionDescription</key>\n') plist.write('\t<string></string>\n') plist.write('\t<key>IFPkgDescriptionTitle</key>\n') plist.write('\t<string>%s</string>\n' % self.fullname) plist.write('</dict>\n') plist.write('</plist>\n') plist.close() if hasattr(tarfile, "PAX_FORMAT"): archive = tarfile.open(Filename( output, "Contents/Archive.pax.gz").toOsSpecific(), "w:gz", format=tarfile.PAX_FORMAT, tarinfo=TarInfoRootOSX) else: archive = tarfile.open(Filename( output, "Contents/Archive.pax.gz").toOsSpecific(), "w:gz", tarinfo=TarInfoRootOSX) archive.add(appfn.toOsSpecific(), appname) archive.close() # Put the .pkg into a zipfile archive = Filename(output.getDirname(), "%s %s.zip" % (self.fullname, self.version)) dir = Filename(output.getDirname()) dir.makeAbsolute() zip = zipfile.ZipFile(archive.toOsSpecific(), 'w') for root, dirs, files in self.os_walk(output.toOsSpecific()): for name in files: file = Filename.fromOsSpecific(os.path.join(root, name)) file.makeAbsolute() file.makeRelativeTo(dir) zip.write(os.path.join(root, name), str(file)) zip.close() return output