setup.py revision 1191
409N/A#!/usr/bin/python2.4
20N/A#
20N/A# CDDL HEADER START
20N/A#
20N/A# The contents of this file are subject to the terms of the
20N/A# Common Development and Distribution License (the "License").
20N/A# You may not use this file except in compliance with the License.
20N/A#
20N/A# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
20N/A# or http://www.opensolaris.org/os/licensing.
20N/A# See the License for the specific language governing permissions
20N/A# and limitations under the License.
20N/A#
20N/A# When distributing Covered Code, include this CDDL HEADER in each
20N/A# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
20N/A# If applicable, add the following below this CDDL HEADER, with the
20N/A# fields enclosed by brackets "[]" replaced with your own identifying
20N/A# information: Portions Copyright [yyyy] [name of copyright owner]
20N/A#
20N/A# CDDL HEADER END
20N/A#
814N/A# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
20N/A# Use is subject to license terms.
20N/A#
20N/A
22N/Aimport errno
0N/Aimport fnmatch
50N/Aimport os
50N/Aimport platform
50N/Aimport stat
50N/Aimport sys
50N/Aimport shutil
50N/Aimport re
50N/Aimport subprocess
50N/Aimport tarfile
50N/Aimport tempfile
50N/Aimport urllib
50N/Aimport py_compile
50N/Aimport sha
50N/A
50N/Afrom distutils.errors import DistutilsError
50N/Afrom distutils.core import setup, Extension
50N/Afrom distutils.cmd import Command
382N/Afrom distutils.command.install import install as _install
382N/Afrom distutils.command.build import build as _build
382N/Afrom distutils.command.build_py import build_py as _build_py
382N/Afrom distutils.command.bdist import bdist as _bdist
589N/Afrom distutils.command.clean import clean as _clean
589N/A
812N/Afrom distutils.sysconfig import get_python_inc
382N/Aimport distutils.file_util as file_util
812N/Aimport distutils.dir_util as dir_util
382N/Aimport distutils.util as util
382N/A
382N/A# 3rd party software required for the build
382N/ACP = 'CherryPy'
382N/ACPIDIR = 'cherrypy'
382N/ACPVER = '3.1.1'
382N/ACPARC = '%s-%s.tar.gz' % (CP, CPVER)
382N/ACPDIR = '%s-%s' % (CP, CPVER)
382N/ACPURL = 'http://download.cherrypy.org/cherrypy/%s/%s' % (CPVER, CPARC)
382N/ACPHASH = '0a8aace00ea28adc05edd41e20dd910042e6d265'
382N/A
382N/APO = 'pyOpenSSL'
382N/APOIDIR = 'OpenSSL'
382N/APOVER = '0.7'
429N/APOARC = '%s-%s.tar.gz' % (PO, POVER)
429N/APODIR = '%s-%s' % (PO, POVER)
461N/APOURL = 'http://downloads.sourceforge.net/pyopenssl/%s' % (POARC)
461N/APOHASH = 'bd072fef8eb36241852d25a9161282a051f0a63e'
382N/A
26N/AFL = 'figleaf'
689N/AFLIDIR = 'figleaf'
689N/AFLVER = 'latest'
466N/AFLARC = '%s-%s.tar.gz' % (FL, FLVER)
0N/AFLDIR = '%s-%s' % (FL, FLVER)
468N/AFLURL = 'http://darcs.idyll.org/~t/projects/%s' % FLARC
812N/A# No hash, since we always fetch the latest
812N/AFLHASH = None
812N/A
812N/AMAKO = 'Mako'
52N/AMAKOIDIR = 'mako'
812N/AMAKOVER = '0.2.2'
451N/AMAKOARC = '%s-%s.tar.gz' % (MAKO, MAKOVER)
0N/AMAKODIR = '%s-%s' % (MAKO, MAKOVER)
382N/AMAKOURL = 'http://www.makotemplates.org/downloads/%s' % (MAKOARC)
382N/AMAKOHASH = '85c04ab3a6a26a1cab47067449712d15a8b29790'
382N/A
452N/APLY = 'ply'
382N/APLYIDIR = 'ply'
452N/APLYVER = '3.1'
382N/APLYARC = '%s-%s.tar.gz' % (PLY, PLYVER)
382N/APLYDIR = '%s-%s' % (PLY, PLYVER)
751N/APLYURL = 'http://www.dabeaz.com/ply/%s' % (PLYARC)
751N/APLYHASH = '38efe9e03bc39d40ee73fa566eb9c1975f1a8003'
382N/A
22N/APC = 'pycurl'
814N/APCIDIR = 'pycurl'
812N/APCVER = '7.19.0'
812N/APCARC = '%s-%s.tar.gz' % (PC, PCVER)
26N/APCDIR = '%s-%s' % (PC, PCVER)
382N/APCURL = 'http://pycurl.sourceforge.net/download/%s' % PCARC
382N/APCHASH = '3fb59eca1461331bb9e9e8d6fe3b23eda961a416'
428N/A
466N/Aosname = platform.uname()[0].lower()
466N/Aostype = arch = 'unknown'
466N/Aif osname == 'sunos':
466N/A arch = platform.processor()
23N/A ostype = "posix"
466N/Aelif osname == 'linux':
466N/A arch = "linux_" + platform.machine()
466N/A ostype = "posix"
466N/Aelif osname == 'windows':
466N/A arch = osname
466N/A ostype = "windows"
466N/Aelif osname == 'darwin':
466N/A arch = osname
466N/A ostype = "posix"
466N/A
466N/Apwd = os.path.normpath(sys.path[0])
466N/A
26N/A#
589N/A# Unbuffer stdout and stderr. This helps to ensure that subprocess output
858N/A# is properly interleaved with output from this program.
858N/A#
858N/Asys.stdout = os.fdopen(sys.stdout.fileno(), "w", 0)
858N/Asys.stderr = os.fdopen(sys.stderr.fileno(), "w", 0)
382N/A
812N/Adist_dir = os.path.normpath(os.path.join(pwd, os.pardir, "proto", "dist_" + arch))
812N/Abuild_dir = os.path.normpath(os.path.join(pwd, os.pardir, "proto", "build_" + arch))
589N/Aif "ROOT" in os.environ and os.environ["ROOT"] != "":
589N/A root_dir = os.environ["ROOT"]
589N/Aelse:
589N/A root_dir = os.path.normpath(os.path.join(pwd, os.pardir, "proto", "root_" + arch))
858N/Apkgs_dir = os.path.normpath(os.path.join(pwd, os.pardir, "packages", arch))
858N/Aextern_dir = os.path.normpath(os.path.join(pwd, "extern"))
858N/A
466N/Acacert_dir = os.path.normpath(os.path.join(pwd, "cacert"))
466N/Acacert_install_dir = 'usr/share/pkg/cacert'
466N/A
466N/Apy_install_dir = 'usr/lib/python2.4/vendor-packages'
466N/A
466N/Ascripts_dir = 'usr/bin'
466N/Alib_dir = 'usr/lib'
466N/Asvc_method_dir = 'lib/svc/method'
466N/A
589N/Aman1_dir = 'usr/share/man/cat1'
589N/Aman1m_dir = 'usr/share/man/cat1m'
589N/Aman5_dir = 'usr/share/man/cat5'
589N/Aresource_dir = 'usr/share/lib/pkg'
589N/Asmf_dir = 'var/svc/manifest/application'
589N/Azones_dir = 'etc/zones'
589N/Abrand_dir = 'usr/lib/brand/ipkg'
589N/A
589N/Ascripts_sunos = {
812N/A scripts_dir: [
812N/A ['client.py', 'pkg'],
812N/A ['publish.py', 'pkgsend'],
812N/A ['pull.py', 'pkgrecv'],
812N/A ['packagemanager.py', 'packagemanager'],
812N/A ['updatemanager.py', 'pm-updatemanager'],
812N/A ],
812N/A lib_dir: [
812N/A ['depot.py', 'pkg.depotd'],
812N/A ['updatemanagernotifier.py', 'updatemanagernotifier'],
812N/A ['launch.py', 'pm-launch'],
812N/A ],
812N/A svc_method_dir: [
26N/A ['svc/svc-pkg-depot', 'svc-pkg-depot'],
135N/A ],
14N/A }
382N/A
429N/Ascripts_windows = {
14N/A scripts_dir: [
404N/A ['client.py', 'client.py'],
404N/A ['publish.py', 'publish.py'],
30N/A ['pull.py', 'pull.py'],
382N/A ['scripts/pkg.bat', 'pkg.bat'],
30N/A ['scripts/pkgsend.bat', 'pkgsend.bat'],
791N/A ['scripts/pkgrecv.bat', 'pkgrecv.bat'],
689N/A ],
689N/A lib_dir: [
858N/A ['depot.py', 'depot.py'],
858N/A ['scripts/pkg.depotd.bat', 'pkg.depotd.bat'],
858N/A ],
382N/A }
812N/A
382N/Ascripts_other_unix = {
382N/A scripts_dir: [
382N/A ['client.py', 'client.py'],
382N/A ['pull.py', 'pull.py'],
429N/A ['publish.py', 'publish.py'],
451N/A ['scripts/pkg.sh', 'pkg'],
461N/A ['scripts/pkgsend.sh', 'pkgsend'],
797N/A ['scripts/pkgrecv.sh', 'pkgrecv'],
812N/A ],
812N/A lib_dir: [
812N/A ['depot.py', 'depot.py'],
258N/A ['scripts/pkg.depotd.sh', 'pkg.depotd'],
382N/A ],
382N/A }
382N/A
382N/A# indexed by 'osname'
30N/Ascripts = {
589N/A "sunos": scripts_sunos,
589N/A "linux": scripts_other_unix,
589N/A "windows": scripts_windows,
589N/A "darwin": scripts_other_unix,
589N/A "unknown": scripts_sunos,
589N/A }
589N/A
589N/Aman1_files = [
589N/A 'man/packagemanager.1',
466N/A 'man/pkg.1',
466N/A 'man/pkgsend.1',
466N/A 'man/pkgrecv.1',
466N/A 'man/pm-updatemanager.1',
466N/A ]
466N/Aman1m_files = [
466N/A 'man/pkg.depotd.1m'
466N/A ]
466N/Aman5_files = [
466N/A 'man/pkg.5'
466N/A ]
466N/Apackages = [
466N/A 'pkg',
466N/A 'pkg.actions',
54N/A 'pkg.bundle',
858N/A 'pkg.client',
812N/A 'pkg.client.transport',
812N/A 'pkg.portable',
466N/A 'pkg.publish',
466N/A 'pkg.server'
382N/A ]
466N/A
135N/Aweb_files = []
135N/Afor entry in os.walk("web"):
135N/A web_dir, dirs, files = entry
135N/A if not files:
382N/A continue
135N/A web_files.append((os.path.join(resource_dir, web_dir), [
135N/A os.path.join(web_dir, f) for f in files
812N/A if f != "Makefile"
382N/A ]))
382N/A
382N/Azones_files = [
382N/A 'brand/SUNWipkg.xml',
382N/A ]
382N/Abrand_files = [
382N/A 'brand/config.xml',
382N/A 'brand/platform.xml',
382N/A 'brand/pkgcreatezone',
382N/A 'brand/attach',
812N/A 'brand/clone',
812N/A 'brand/detach',
589N/A 'brand/prestate',
589N/A 'brand/poststate',
589N/A 'brand/query',
589N/A 'brand/uninstall',
589N/A 'brand/common.ksh',
858N/A ]
858N/Asmf_files = [
858N/A 'svc/pkg-server.xml',
858N/A 'svc/pkg-update.xml',
858N/A ]
858N/Apspawn_srcs = [
858N/A 'modules/pspawn.c'
858N/A ]
858N/Aelf_srcs = [
858N/A 'modules/elf.c',
858N/A 'modules/elfextract.c',
858N/A 'modules/liblist.c',
858N/A ]
858N/Aarch_srcs = [
858N/A 'modules/arch.c'
858N/A ]
858N/A_actions_srcs = [
858N/A 'modules/actions/_actions.c'
466N/A ]
466N/Ainclude_dirs = [ 'modules' ]
466N/Alint_flags = [ '-u', '-axms', '-erroff=E_NAME_DEF_NOT_USED2' ]
466N/A
466N/A# Runs the test suite with the code coverage suite (figleaf) turned on, and
466N/A# outputs a coverage report.
589N/A# TODO: Make the cov report format an option (html, ast, cov, etc)
589N/Aclass cov_func(Command):
589N/A description = "Runs figleaf code coverage suite"
589N/A user_options = []
589N/A def initialize_options(self):
589N/A pass
589N/A def finalize_options(self):
589N/A pass
589N/A def run(self):
765N/A if not os.path.isdir(FLDIR):
765N/A install_sw(FL, FLVER, FLARC, FLDIR, FLURL, FLIDIR,
765N/A FLHASH)
765N/A # Run the test suite with coverage enabled
765N/A os.putenv('PYEXE', sys.executable)
765N/A os.chdir(os.path.join(pwd, "tests"))
765N/A # Reconstruct the cmdline and send that to run.py
589N/A os.environ["PKGCOVERAGE"] = "1"
765N/A cmd = [sys.executable, "run.py"]
765N/A subprocess.call(cmd)
765N/A print "Generating coverage report in directory: '%s/cov_report'" % \
765N/A pwd
765N/A os.system("figleaf2html -d cov_report .figleaf")
765N/A
765N/A# Runs lint on the extension module source code
765N/Aclass lint_func(Command):
589N/A description = "Runs various lint tools over IPS extension source code"
765N/A user_options = []
135N/A
382N/A def initialize_options(self):
157N/A pass
382N/A
429N/A def finalize_options(self):
429N/A pass
429N/A
429N/A # Make string shell-friendly
429N/A @staticmethod
429N/A def escape(astring):
429N/A return astring.replace(' ', '\\ ')
429N/A
429N/A def run(self):
429N/A # assumes lint is on the $PATH
429N/A if osname == 'sunos' or osname == "linux":
812N/A archcmd = ['lint'] + lint_flags + ['-D_FILE_OFFSET_BITS=64'] + \
812N/A ["%s%s" % ("-I", k) for k in include_dirs] + \
812N/A ['-I' + self.escape(get_python_inc())] + \
812N/A arch_srcs
812N/A elfcmd = ['lint'] + lint_flags + \
812N/A ["%s%s" % ("-I", k) for k in include_dirs] + \
812N/A ['-I' + self.escape(get_python_inc())] + \
812N/A ["%s%s" % ("-l", k) for k in elf_libraries] + \
812N/A elf_srcs
812N/A _actionscmd = ['lint'] + lint_flags + \
812N/A ["%s%s" % ("-I", k) for k in include_dirs] + \
812N/A ['-I' + self.escape(get_python_inc())] + \
812N/A _actions_srcs
812N/A pspawncmd = ['lint'] + lint_flags + ['-D_FILE_OFFSET_BITS=64'] + \
812N/A ["%s%s" % ("-I", k) for k in include_dirs] + \
812N/A ['-I' + self.escape(get_python_inc())] + \
812N/A pspawn_srcs
812N/A
812N/A print(" ".join(archcmd))
812N/A os.system(" ".join(archcmd))
812N/A print(" ".join(elfcmd))
812N/A os.system(" ".join(elfcmd))
812N/A print(" ".join(_actionscmd))
812N/A os.system(" ".join(_actionscmd))
812N/A print(" ".join(pspawncmd))
812N/A os.system(" ".join(pspawncmd))
812N/A
812N/A proto = os.path.join(root_dir, py_install_dir)
812N/A sys.path.insert(0, proto)
812N/A
812N/A # Insert tests directory onto sys.path so any custom checkers
812N/A # can be found.
812N/A sys.path.insert(0, os.path.join(pwd, 'tests'))
812N/A print(sys.path)
812N/A
812N/A # assumes pylint is accessible on the sys.path
812N/A from pylint import lint
812N/A scriptlist = [ 'setup.py' ]
812N/A for d, m in scripts_sunos.items():
812N/A for a in m:
812N/A # specify the filenames of the scripts, in addition
812N/A # to the package names themselves
812N/A scriptlist.append(os.path.join(root_dir, d, a[1]))
812N/A
812N/A # For some reason, the load-plugins option, when used in the
812N/A # rcfile, does not work, so we put it here instead, to load
812N/A # our custom checkers.
812N/A lint.Run(['--load-plugins=multiplatform', '--rcfile',
812N/A os.path.join(pwd, 'tests', 'pylintrc')] +
812N/A scriptlist + packages)
812N/A
812N/Aclass install_func(_install):
812N/A def initialize_options(self):
812N/A _install.initialize_options(self)
812N/A
812N/A # PRIVATE_BUILD set in the environment tells us to put the build
812N/A # directory into the .pyc files, rather than the final
812N/A # installation directory.
812N/A private_build = os.getenv("PRIVATE_BUILD", None)
812N/A
812N/A if private_build is None:
135N/A self.install_lib = py_install_dir
466N/A self.install_data = os.path.sep
382N/A self.root = root_dir
466N/A else:
382N/A self.install_lib = os.path.join(root_dir, py_install_dir)
466N/A self.install_data = root_dir
466N/A
451N/A # This is used when installing scripts, below, but it isn't a
445N/A # standard distutils variable.
466N/A self.root_dir = root_dir
461N/A
466N/A def run(self):
461N/A """
466N/A At the end of the install function, we need to rename some files
466N/A because distutils provides no way to rename files as they are
451N/A placed in their install locations.
812N/A Also, make sure that cherrypy and other external dependencies
812N/A are installed.
812N/A """
812N/A for f in man1_files + man1m_files + man5_files:
812N/A file_util.copy_file(f + ".txt", f, update=1)
812N/A
812N/A _install.run(self)
812N/A
812N/A for d, files in scripts[osname].iteritems():
429N/A for (srcname, dstname) in files:
429N/A dst_dir = util.change_root(self.root_dir, d)
429N/A dst_path = util.change_root(self.root_dir,
429N/A os.path.join(d, dstname))
429N/A dir_util.mkpath(dst_dir, verbose = True)
429N/A file_util.copy_file(srcname, dst_path, update = True)
429N/A # make scripts executable
429N/A os.chmod(dst_path,
612N/A os.stat(dst_path).st_mode
612N/A | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
612N/A
386N/A # Take cacerts in cacert_dir and install them in
589N/A # proto-area-relative cacert_install_dir
382N/A install_cacerts()
382N/A
382N/A install_sw(CP, CPVER, CPARC, CPDIR, CPURL, CPIDIR, CPHASH)
382N/A if "BUILD_PYOPENSSL" in os.environ and \
382N/A os.environ["BUILD_PYOPENSSL"] != "":
382N/A #
382N/A # Include /usr/sfw/lib in the build environment
461N/A # to ensure that this builds and runs on older
461N/A # nevada builds, before openssl moved out of /usr/sfw.
461N/A #
382N/A saveenv = os.environ.copy()
382N/A if osname == "sunos":
589N/A os.environ["CFLAGS"] = "-I/usr/sfw/include " + \
382N/A os.environ.get("CFLAGS", "")
382N/A os.environ["LDFLAGS"] = \
382N/A "-L/usr/sfw/lib -R/usr/sfw/lib " + \
382N/A os.environ.get("LDFLAGS", "")
382N/A install_sw(PO, POVER, POARC, PODIR, POURL, POIDIR,
812N/A POHASH)
812N/A os.environ = saveenv
812N/A install_sw(MAKO, MAKOVER, MAKOARC, MAKODIR, MAKOURL, MAKOIDIR,
812N/A MAKOHASH)
812N/A install_sw(PLY, PLYVER, PLYARC, PLYDIR, PLYURL, PLYIDIR,
812N/A PLYHASH)
812N/A install_sw(PC, PCVER, PCARC, PCDIR, PCURL, PCIDIR, PCHASH)
812N/A
812N/A # Remove some bits that we're not going to package, but be sure
812N/A # not to complain if we try to remove them twice.
812N/A def onerror(func, path, exc_info):
812N/A if exc_info[1].errno != errno.ENOENT:
812N/A raise
812N/A
812N/A for dir in ("cherrypy/scaffold", "cherrypy/test",
812N/A "cherrypy/tutorial"):
812N/A shutil.rmtree(os.path.join(root_dir, py_install_dir, dir),
812N/A onerror=onerror)
812N/A try:
812N/A os.remove(os.path.join(root_dir, "usr/bin/mako-render"))
812N/A except EnvironmentError, e:
812N/A if e.errno != errno.ENOENT:
812N/A raise
812N/A
812N/Adef hash_sw(swname, swarc, swhash):
812N/A if swhash == None:
812N/A return True
812N/A
812N/A print "checksumming %s" % swname
812N/A hash = sha.new()
812N/A f = open(swarc, 'r')
812N/A while True:
812N/A data = f.read(65536)
812N/A if data == "":
812N/A break
812N/A hash.update(data)
812N/A f.close()
812N/A
812N/A if hash.hexdigest() == swhash:
812N/A return True
812N/A else:
812N/A print "bad checksum! %s != %s" % (swhash, hash.hexdigest())
812N/A return False
812N/A
812N/Adef install_cacerts():
812N/A
812N/A findir = os.path.join(root_dir, cacert_install_dir)
812N/A dir_util.mkpath(findir, verbose = True)
812N/A for f in os.listdir(cacert_dir):
812N/A
812N/A # Copy certificate
812N/A srcname = os.path.normpath(os.path.join(cacert_dir, f))
452N/A dn, copied = file_util.copy_file(srcname, findir, update = True)
466N/A
858N/A if not copied:
382N/A continue
466N/A
858N/A # Call openssl to create hash symlink
452N/A cmd = ["/usr/bin/openssl", "x509", "-noout", "-hash", "-in",
382N/A srcname]
858N/A
858N/A p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
858N/A hashval = p.stdout.read()
382N/A p.wait()
742N/A
858N/A hashval = hashval.strip()
466N/A hashval += ".0"
466N/A
858N/A hashpath = os.path.join(findir, hashval)
858N/A if os.path.exists(hashpath):
858N/A os.unlink(hashpath)
858N/A os.symlink(f, hashpath)
858N/A
858N/Adef install_sw(swname, swver, swarc, swdir, swurl, swidir, swhash):
858N/A swarc = os.path.join(extern_dir, swarc)
858N/A swdir = os.path.join(extern_dir, swdir)
858N/A if not os.path.exists(extern_dir):
858N/A os.mkdir(extern_dir)
858N/A
858N/A if not os.path.exists(swarc):
466N/A print "downloading %s" % swname
466N/A try:
466N/A fname, hdr = urllib.urlretrieve(swurl, swarc)
466N/A except IOError:
466N/A pass
466N/A if not os.path.exists(swarc) or \
466N/A (hdr.gettype() != "application/x-gzip" and
466N/A hdr.gettype() != "application/x-tar"):
466N/A print "Unable to retrieve %s.\nPlease retrieve the file " \
466N/A "and place it at: %s\n" % (swurl, swarc)
466N/A # remove a partial download or error message from proxy
466N/A remove_sw(swname)
466N/A sys.exit(1)
466N/A if not os.path.exists(swdir):
466N/A if not hash_sw(swname, swarc, swhash):
466N/A sys.exit(1)
466N/A
466N/A print "unpacking %s" % swname
466N/A tar = tarfile.open(swarc)
466N/A # extractall doesn't exist until python 2.5
466N/A for m in tar.getmembers():
466N/A tar.extract(m, extern_dir)
466N/A tar.close()
466N/A
466N/A # If there are patches, apply them now.
466N/A patchdir = os.path.join("patch", swname)
466N/A already_patched = os.path.join(swdir, ".patched")
466N/A if os.path.exists(patchdir) and not os.path.exists(already_patched):
466N/A patches = os.listdir(patchdir)
466N/A for p in patches:
382N/A patchpath = os.path.join(os.path.pardir,
612N/A os.path.pardir, patchdir, p)
612N/A print "Applying %s to %s" % (p, swname)
612N/A subprocess.Popen(['patch', '-d', swdir, '-i',
612N/A patchpath]).wait()
612N/A file(already_patched, "w").close()
612N/A
617N/A swinst_dir = os.path.join(root_dir, py_install_dir, swidir)
617N/A if not os.path.exists(swinst_dir):
617N/A print "installing %s" % swname
617N/A args = ['python', 'setup.py', 'install',
617N/A '--root=%s' % root_dir,
612N/A '--install-lib=%s' % py_install_dir,
612N/A '--install-data=%s' % py_install_dir]
451N/A ret = subprocess.Popen(args, cwd = swdir).wait()
382N/A if ret != 0:
452N/A print "install failed and returned %d." % ret
452N/A print "Command was: %s" % " ".join(args)
452N/A sys.exit(1)
452N/A
452N/A
452N/Adef remove_sw(swname):
382N/A print("deleting %s" % swname)
382N/A for file in os.listdir(extern_dir):
742N/A if fnmatch.fnmatch(file, "%s*" % swname):
382N/A fpath = os.path.join(extern_dir, file)
382N/A if os.path.isfile(fpath):
382N/A os.unlink(fpath)
145N/A else:
451N/A shutil.rmtree(fpath, True)
451N/A
451N/Aclass build_func(_build):
451N/A def initialize_options(self):
451N/A _build.initialize_options(self)
451N/A self.build_base = build_dir
451N/A
451N/Adef get_hg_version():
451N/A try:
451N/A p = subprocess.Popen(['hg', 'id', '-i'], stdout = subprocess.PIPE)
451N/A return p.communicate()[0].strip()
451N/A except OSError:
451N/A print >> sys.stderr, "ERROR: unable to obtain mercurial version"
451N/A return "unknown"
451N/A
451N/Adef syntax_check(filename):
451N/A """ Run python's compiler over the file, and discard the results.
451N/A Arrange to generate an exception if the file does not compile.
466N/A This is needed because distutil's own use of pycompile (in the
814N/A distutils.utils module) is broken, and doesn't stop on error. """
814N/A try:
814N/A py_compile.compile(filename, os.devnull, doraise=True)
814N/A except py_compile.PyCompileError, e:
814N/A raise DistutilsError("%s: failed syntax check: %s" %
466N/A (filename, e))
217N/A
797N/A
797N/Aclass build_py_func(_build_py):
466N/A # override the build_module method to do VERSION substitution on pkg/__init__.py
466N/A def build_module (self, module, module_file, package):
466N/A
466N/A if module == "__init__" and package == "pkg":
466N/A versionre = '(?m)^VERSION[^"]*"([^"]*)"'
466N/A # Grab the previously-built version out of the build
812N/A # tree.
812N/A try:
812N/A ocontent = \
812N/A file(self.get_module_outfile(self.build_lib,
[package], module)).read()
ov = re.search(versionre, ocontent).group(1)
except IOError:
ov = None
v = get_hg_version()
vstr = 'VERSION = "%s"' % v
# If the versions haven't changed, there's no need to
# recompile.
if v == ov:
return
mcontent = file(module_file).read()
mcontent = re.sub(versionre, vstr, mcontent)
tmpfd, tmp_file = tempfile.mkstemp()
os.write(tmpfd, mcontent)
os.close(tmpfd)
print "doing version substitution: ", v
rv = _build_py.build_module(self, module, tmp_file, package)
os.unlink(tmp_file)
return rv
# Will raise a DistutilsError on failure.
syntax_check(module_file)
return _build_py.build_module(self, module, module_file, package)
class clean_func(_clean):
def initialize_options(self):
_clean.initialize_options(self)
self.build_base = build_dir
class clobber_func(Command):
user_options = []
description = "Deletes any and all files created by setup"
def initialize_options(self):
pass
def finalize_options(self):
pass
def run(self):
# nuke everything
print("deleting " + dist_dir)
shutil.rmtree(dist_dir, True)
print("deleting " + build_dir)
shutil.rmtree(build_dir, True)
print("deleting " + root_dir)
shutil.rmtree(root_dir, True)
print("deleting " + pkgs_dir)
shutil.rmtree(pkgs_dir, True)
print("deleting " + extern_dir)
shutil.rmtree(extern_dir, True)
class test_func(Command):
# NOTE: these options need to be in sync with tests/run.py and the
# list of options stored in initialize_options below. The first entry
# in each tuple must be the exact name of a member variable.
user_options = [("verbosemode", 'v', "run tests in verbose mode"),
("genbaseline", 'g', "generate test baseline"),
("parseable", 'p', "parseable output"),
("timing", "t", "timing file <file>"),
("baselinefile=", 'b', "baseline file <file>"),
("only=", "o", "only <regex>")]
description = "Runs unit and functional tests"
def initialize_options(self):
self.only = ""
self.baselinefile = ""
self.verbosemode = 0
self.parseable = 0
self.genbaseline = 0
self.timing = 0
def finalize_options(self):
pass
def run(self):
os.putenv('PYEXE', sys.executable)
os.chdir(os.path.join(pwd, "tests"))
# Reconstruct the cmdline and send that to run.py
cmd = [sys.executable, "run.py"]
args = ""
if "test" in sys.argv:
args = sys.argv[sys.argv.index("test")+1:]
cmd.extend(args)
subprocess.call(cmd)
class dist_func(_bdist):
def initialize_options(self):
_bdist.initialize_options(self)
self.dist_dir = dist_dir
# These are set to real values based on the platform, down below
compile_args = None
link_args = None
ext_modules = [
Extension(
'actions._actions',
_actions_srcs,
include_dirs = include_dirs,
extra_compile_args = compile_args,
extra_link_args = link_args
),
]
elf_libraries = None
data_files = web_files
cmdclasses = {
'install': install_func,
'build': build_func,
'build_py': build_py_func,
'bdist': dist_func,
'lint': lint_func,
'clean': clean_func,
'clobber': clobber_func,
'coverage': cov_func,
'test': test_func,
}
# all builds of IPS should have manpages
data_files += [
(man1_dir, man1_files),
(man1m_dir, man1m_files),
(man5_dir, man5_files),
]
if osname == 'sunos':
# Solaris-specific extensions are added here
data_files += [
(zones_dir, zones_files),
(brand_dir, brand_files),
(smf_dir, smf_files),
]
if osname == 'sunos' or osname == "linux":
# Unix platforms which the elf extension has been ported to
# are specified here, so they are built automatically
elf_libraries = ['elf']
ext_modules += [
Extension(
'elf',
elf_srcs,
include_dirs = include_dirs,
libraries = elf_libraries,
extra_compile_args = compile_args,
extra_link_args = link_args
),
]
# Solaris has built-in md library and Solaris-specific arch extension
# All others use OpenSSL and cross-platform arch module
if osname == 'sunos':
elf_libraries += [ 'md' ]
ext_modules += [
Extension(
'arch',
arch_srcs,
include_dirs = include_dirs,
extra_compile_args = compile_args,
extra_link_args = link_args,
define_macros = [('_FILE_OFFSET_BITS', '64')]
),
Extension(
'pspawn',
pspawn_srcs,
include_dirs = include_dirs,
extra_compile_args = compile_args,
extra_link_args = link_args,
define_macros = [('_FILE_OFFSET_BITS', '64')]
),
]
else:
elf_libraries += [ 'ssl' ]
setup(cmdclass = cmdclasses,
name = 'ips',
version = '1.0',
package_dir = {'pkg':'modules'},
packages = packages,
data_files = data_files,
ext_package = 'pkg',
ext_modules = ext_modules,
)