--- a/sbsv2/raptor/util/install-windows/raptorinstallermaker.py Wed Jul 28 13:20:46 2010 +0100
+++ b/sbsv2/raptor/util/install-windows/raptorinstallermaker.py Thu Aug 12 09:00:16 2010 +0100
@@ -1,4 +1,3 @@
-#
# Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
# All rights reserved.
# This component and the accompanying materials are made available
@@ -12,110 +11,23 @@
# Contributors:
#
# Description:
-#
-#! python
+# Raptor installer maker script - generates a Windows installer for Raptor using
+# the NSIS package in the accompanying directory. Works on Windows and Linux.
-# Raptor installer maker!
-
+import optparse
import os
import os.path
+import re
+import shutil
+import stat
import subprocess
-import re
-import optparse
import sys
import tempfile
-import shutil
import unzip
+import zipfile
tempdir = ""
-parser = optparse.OptionParser()
-
-parser.add_option("-s", "--sbs-home", dest="sbshome", help="Path to use as SBS_HOME environment variable. If not present the script exits.")
-
-parser.add_option("-w", "--win32-support", dest="win32support", help="Path to Win32 support directory. If not present the script exits.")
-
-parser.add_option("-b", "--bv", dest="bv", help="Path to Binary variation CPP \"root\" directory. Can be a full/relatitve path; prefix with \"WIN32SUPPORT\\\" to be relative to the Win32 support directory. Omitting this value will assume a default to a path inside the Win32 support directory.")
-
-parser.add_option("-c", "--cygwin", dest="cygwin", help="Path to Cygwin \"root\" directory. Can be a full/relatitve path; prefix with \"WIN32SUPPORT\\\" to be relative to the Win32 support directory. Omitting this value will assume a default to a path inside the Win32 support directory.")
-
-parser.add_option("-m", "--mingw", dest="mingw", help="Path to MinGW \"root\" directory. Can be a full/relatitve path; prefix with \"WIN32SUPPORT\\\" to be relative to the Win32 support directory. Omitting this value will assume a default to a path inside the Win32 support directory.")
-
-parser.add_option("-p", "--python", dest="python", help="Path to Python \"root\" directory. Can be a full/relatitve path; prefix with \"WIN32SUPPORT\\\" to be relative to the Win32 support directory. Omitting this value will assume a default to a path inside the Win32 support directory.")
-
-parser.add_option("--prefix", dest="versionprefix", help="A string to use as a prefix to the Raptor version string. This will be present in the Raptor installer's file name, the installer's pages as well as the in output from sbs -v.", type="string", default="")
-
-parser.add_option("--postfix", dest="versionpostfix", help="A string to use as a postfix to the Raptor version string. This will be present in the Raptor installer's file name, the installer's pages as well as the in output from sbs -v.", type="string", default="")
-
-(options, args) = parser.parse_args()
-
-# Required directories inside the win32-support repository
-win32supportdirs = {"bv":"bv", "cygwin":"cygwin", "mingw":"mingw", "python":"python264"}
-
-if options.sbshome == None:
- print "ERROR: no SBS_HOME passed in. Exiting..."
- sys.exit(2)
-
-if options.win32support == None:
- print "ERROR: no win32support directory specified. Unable to proceed. Exiting..."
- sys.exit(2)
-else:
- # Check for command line overrides to defaults
- for directory in win32supportdirs:
- print "TEST %s" % directory
- value = getattr(options,directory)
- print "value = %s" % str(value)
- if value != None: # Command line override
- if value.lower().startswith("win32support"):
- # Strip off "WIN32SUPPORT\" and join to Win32 support location
- win32supportdirs[directory] = os.path.join(options.win32support, value[13:])
- else:
- # Relative to current directory
- win32supportdirs[directory] = value
-
- else: # Use default location
- win32supportdirs[directory] = os.path.join(options.win32support, win32supportdirs[directory])
-
- print "\n\nwin32supportdirs = %s\n\n" % win32supportdirs
-
- # Check that all the specified directories exist and exit if any of them is missing.
- for directory in win32supportdirs:
- dir = win32supportdirs[directory]
- if os.path.isdir(dir):
- print "Found directory %s" % dir
- else:
- print "ERROR: directory %s does not exist. Cannot build installer. Exiting..." % dir
- sys.exit(2)
-
-def generateinstallerversionheader(sbshome = None):
- shellenv = os.environ.copy()
- shellenv["PYTHONPATH"] = os.path.join(sbshome, "python")
-
- raptorversioncommand = "python -c \"import raptor_version; print raptor_version.numericversion()\""
-
- # Raptor version is obtained from raptor_version module's numericversion function.
- sbs_version_matcher = re.compile(".*(\d+\.\d+\.\d+).*", re.I)
-
- # Create Raptor subprocess
- versioncommand = subprocess.Popen(raptorversioncommand, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=shellenv)
- raptorversion = ""
- # Get all the lines matching the RE
- for line in versioncommand.stdout.readlines():
- res = sbs_version_matcher.match(line)
- if res:
- raptorversion = res.group(1)
- print "Successfully determined Raptor version %s" % raptorversion
-
- versioncommand.wait() # Wait for process to end
-
- raptorversion_nsis_header_string = "# Raptor version file\n\n!define RAPTOR_VERSION %s\n" % raptorversion
-
- fh = open("raptorversion.nsh", "w")
- fh.write(raptorversion_nsis_header_string)
- fh.close()
- print "Wrote raptorversion.nsh"
- return 0
-
def generateinstallerversion(sbshome = None):
shellenv = os.environ.copy()
shellenv["PYTHONPATH"] = os.path.join(sbshome, "python")
@@ -140,15 +52,25 @@
return raptorversion
def unzipnsis(pathtozip):
- global tempdir
- tempdir = tempfile.mkdtemp()
- un = unzip.unzip()
- print "Unzipping NSIS to %s..." % tempdir
- un.extract(pathtozip, tempdir)
- print "Done."
-
- return os.path.join(tempdir, "NSIS", "makensis.exe")
-
+ global tempdir
+ tempdir = tempfile.mkdtemp()
+ un = unzip.unzip()
+ print "Unzipping NSIS to %s..." % tempdir
+ un.extract(pathtozip, tempdir)
+ print "Done."
+
+ # Ensure the correct executable is called
+ dotexe=""
+ if "win" in sys.platform.lower():
+ dotexe=".exe"
+
+ makensispath = os.path.join(tempdir, "NSIS", "makensis" + dotexe)
+
+ if not "win" in sys.platform.lower():
+ os.chmod(makensispath, stat.S_IRWXU)
+
+ return makensispath
+
def runmakensis(nsiscommand):
# Create makensis subprocess
print "Running NSIS command\n%s" % nsiscommand
@@ -160,23 +82,198 @@
global tempdir
print "Cleaning up temporary directory %s" % tempdir
shutil.rmtree(tempdir,True)
- try:
- os.remove("raptorversion.nsh")
- print "Successfully deleted raptorversion.nsh."
- except:
- print "ERROR: failed to remove raptorversion.nsh - remove manually if needed."
print "Done."
-makensispath = unzipnsis(".\\NSIS.zip")
-# generateinstallerversionheader(options.sbshome)
+def __writeDirTreeToArchive(zip, dirlist, sbshome, win32supportdirs=False):
+ """Auxilliary function to write all files in each directory trees of dirlist into the
+ open archive "zip" assuming valid sbshome; destination path is tweaked for win32supportdirs,
+ so set this to true when writing files into $SBS_HOME/win32"""
+ for name in dirlist:
+ files = os.walk(os.path.join(sbshome, name))
+ for dirtuple in files:
+ filenames = dirtuple[2]
+ dirname = dirtuple[0]
+ for file in filenames:
+ # Filter out unwanted files
+ if not file.lower().endswith(".pyc") and \
+ not file.lower().endswith(".project") and \
+ not file.lower().endswith(".cproject") and \
+ not file.lower().endswith(".pydevproject"):
+ origin = os.path.join(dirname, file)
+
+ # For the win32 support directories, the destination is different
+ if win32supportdirs:
+ destination = os.path.join("sbs", "win32", os.path.basename(name.rstrip(os.sep)),
+ dirname.replace(name, "").strip(os.sep), file)
+ else:
+ destination = os.path.join("sbs", dirname.rstrip(os.sep).replace(sbshome, "").strip(os.sep), file)
+
+ print "Compressing", origin, "\tto\t", destination
+ zip.write(origin, destination)
+
+def writeZip(filename, sbshome, sbsbvdir, sbscygwindir, sbsmingwdir, sbspythondir):
+ """Write a zip archive with file name "filename" assuming SBS_HOME is sbshome, and
+ that sbsbvdir, sbscygwindir, sbsmingwdir, sbspythondir are the win32 support directories."""
+
+ # *Files* in the top level SBS_HOME directory
+ sbshome_files = ["RELEASE-NOTES.html", "license.txt"]
+
+ # Directories in SBS_HOME
+ sbshome_dirs = ["bin", "examples", "lib", "notes", "python",
+ "schema", "style", os.sep.join(["win32", "bin"])]
+
+ # Win32 support directories
+ win32_dirs = [sbsbvdir, sbscygwindir, sbsmingwdir, sbspythondir]
+
+ try:
+ # Open the zip archive for writing; if a file with the same
+ # name exists, it will be truncated to zero bytes before
+ # writing commences
+ zip = zipfile.ZipFile(filename, "w", zipfile.ZIP_DEFLATED)
+
+ # Write the files in the top-level of SBS_HOME into the archive
+ for name in sbshome_files:
+ origin = os.path.join(sbshome, name)
+ destination = os.path.join("sbs", name)
+ print "Compressing", origin, "\tto\t", destination
+ zip.write(origin, destination)
+
+ # Write all files in the the directories in the top-level of SBS_HOME into the archive
+ print "Reading the sbs directories..."
+ __writeDirTreeToArchive(zip, sbshome_dirs, sbshome, win32supportdirs=False)
+ print "Writing sbs directories to the archive is complete."
+
+ # Write all files in the the win32 support directories in the top-level of SBS_HOME into the archive
+ print "Reading the win32 support directories"
+ __writeDirTreeToArchive(zip, win32_dirs, sbshome, win32supportdirs=True)
+ print "Writing win32 support directories to the archive is complete."
+
+ zip.close()
+ print "Zipoutput: \"" + os.path.join(os.getcwd(), filename) + "\""
+ print "Zip file creation successful."
+ except Exception, e:
+ print "Error: failed to create zip file: %s" % str(e)
+ sys.exit(2)
+
+# Create CLI and parse it
+parser = optparse.OptionParser()
+
+parser.add_option("-s", "--sbs-home", dest="sbshome", help="Path to use as SBS_HOME environment variable. If not present the script exits.")
+
+parser.add_option("-w", "--win32-support", dest="win32support", help="Path to Win32 support directory. If not present the script exits.")
+
+parser.add_option("-b", "--bv", dest="bv", help="Path to Binary variation CPP \"root\" directory. Can be a full/relatitve path; prefix with \"WIN32SUPPORT\\\" to be relative to the Win32 support directory. Omitting this value will assume a default to a path inside the Win32 support directory.")
+
+parser.add_option("-c", "--cygwin", dest="cygwin", help="Path to Cygwin \"root\" directory. Can be a full/relatitve path; prefix with \"WIN32SUPPORT\\\" to be relative to the Win32 support directory. Omitting this value will assume a default to a path inside the Win32 support directory.")
+
+parser.add_option("-m", "--mingw", dest="mingw", help="Path to MinGW \"root\" directory. Can be a full/relatitve path; prefix with \"WIN32SUPPORT\\\" to be relative to the Win32 support directory. Omitting this value will assume a default to a path inside the Win32 support directory.")
+
+parser.add_option("-p", "--python", dest="python", help="Path to Python \"root\" directory. Can be a full/relatitve path; prefix with \"WIN32SUPPORT\\\" to be relative to the Win32 support directory. Omitting this value will assume a default to a path inside the Win32 support directory.")
+
+parser.add_option("--prefix", dest="versionprefix", help="A string to use as a prefix to the Raptor version string. This will be present in the Raptor installer's file name, the installer's pages as well as the in output from sbs -v.", type="string", default="")
+
+parser.add_option("--postfix", dest="versionpostfix", help="A string to use as a postfix to the Raptor version string. This will be present in the Raptor installer's file name, the installer's pages as well as the in output from sbs -v.", type="string", default="")
+
+parser.add_option("--noclean", dest="noclean", help="Do not clean up the temporary directory created during the run.", action="store_true" , default=False)
+
+parser.add_option("--noexe", dest="noexe", help="Do not create a Windows .exe installer of the Raptor installation.", action="store_true" , default=False)
+
+parser.add_option("--nozip", dest="nozip", help="Do not create a zip archive of the Raptor installation.", action="store_true" , default=False)
+
+(options, args) = parser.parse_args()
+
+# Required directories inside the win32-support directory (i.e. the win32-support repository).
+win32supportdirs = {"bv":"bv", "cygwin":"cygwin", "mingw":"mingw", "python":"python264"}
+
+if options.sbshome == None:
+ print "ERROR: no SBS_HOME passed in. Exiting..."
+ sys.exit(2)
+elif not os.path.isdir(options.sbshome):
+ print "ERROR: the specified SBS_HOME directory \"%s\" does not exist. Cannot build installer. Exiting..."
+ sys.exit(2)
+
+if options.win32support == None:
+ print "ERROR: no win32support directory specified. Unable to proceed. Exiting..."
+ sys.exit(2)
+else:
+ # Check for command line overrides to defaults
+ for directory in win32supportdirs:
+ print "Checking for location \"%s\"..." % directory
+ value = getattr(options,directory)
+ print "Directory is %s" % str(value)
+ if value != None: # Command line override
+ if value.lower().startswith("win32support"):
+ # Strip off "WIN32SUPPORT\" and join to Win32 support location
+ win32supportdirs[directory] = os.path.join(options.win32support, value[13:])
+ else:
+ # Relative to current directory
+ win32supportdirs[directory] = value
+
+ else: # Use default location
+ win32supportdirs[directory] = os.path.join(options.win32support, win32supportdirs[directory])
+
+ print "\n\nIdentified win32supportdirs are = %s\n\n" % win32supportdirs
+
+ # Check that all the specified directories exist and exit if any of them is missing.
+ for directory in win32supportdirs:
+ dir = win32supportdirs[directory]
+ if os.path.isdir(dir):
+ print "Found directory %s" % dir
+ else:
+ print "ERROR: directory %s does not exist. Cannot build installer. Exiting..." % dir
+ sys.exit(2)
+
+
raptorversion = options.versionprefix + generateinstallerversion(options.sbshome) + options.versionpostfix
-nsiscommand = makensispath + " /DRAPTOR_LOCATION=%s /DBV_LOCATION=%s /DCYGWIN_LOCATION=%s /DMINGW_LOCATION=%s /DPYTHON_LOCATION=%s /DRAPTOR_VERSION=%s raptorinstallerscript.nsi" % (options.sbshome,
- win32supportdirs["bv"],
+
+print "Using Raptor version %s ..." % raptorversion
+
+if not options.noexe:
+ makensispath = unzipnsis("." + os.sep + "NSIS.zip")
+ if "win" in sys.platform.lower():
+ switch="/"
+ else:
+ switch="-"
+
+ nsiscommand = (makensispath + " " +
+ switch + "DRAPTOR_LOCATION=%s " +
+ switch + "DBV_LOCATION=%s " +
+ switch + "DCYGWIN_LOCATION=%s " +
+ switch + "DMINGW_LOCATION=%s " +
+ switch + "DPYTHON_LOCATION=%s " +
+ switch + "DRAPTOR_VERSION=%s " +
+ "%s" ) % \
+ ( options.sbshome,
+ win32supportdirs["bv"],
win32supportdirs["cygwin"],
win32supportdirs["mingw"],
win32supportdirs["python"],
- raptorversion)
-print "nsiscommand = %s" % nsiscommand
-runmakensis(nsiscommand)
-cleanup()
+ raptorversion,
+ os.path.join(options.sbshome, "util", "install-windows", "raptorinstallerscript.nsi")
+ )
+
+ # On Linux, we need to run makensis via Bash, so that is can find all its
+ # internal libraries and header files etc. Makensis fails unless it
+ # is executed this way on Linux.
+ if "lin" in sys.platform.lower():
+ nsiscommand = "bash -c \"%s\"" % nsiscommand
+
+ runmakensis(nsiscommand)
+else:
+ print "Not creating .exe as requested."
+# Only clean NSIS installation in the temporary directory if requested
+if not options.noclean:
+ cleanup()
+else:
+ print "Not cleaning makensis in %s" % makensispath
+
+# Only create zip archive if required
+if not options.nozip:
+ filename = "sbs-" + raptorversion + ".zip"
+ writeZip(filename, options.sbshome, win32supportdirs["bv"], win32supportdirs["cygwin"], win32supportdirs["mingw"], win32supportdirs["python"])
+else:
+ print "Not creating zip archive as requested."
+
+print "Finished."
+