SCons / bin /

Steven Knight fecdff5 

Greg Noel b5841c9 

Steven Knight fecdff5 

Greg Noel b5841c9 
Steven Knight fecdff5 

Greg Noel 2395d93 
Steven Knight fecdff5 

Greg Noel 450d604 
Steven Knight fecdff5 

Greg Noel 450d604 
Steven Knight fecdff5 

Steven Knight b99395d 
Steven Knight fecdff5 

Greg Noel 2395d93 
Steven Knight fecdff5 

Steven Knight 9aa3f9a 

#!/usr/bin/env python
# A script that takes an scons-src-{version}.zip file, unwraps it in
# a temporary location, and calls to execute one or more of
# its tests.
# The default is to download the latest scons-src archive from the SCons
# web site, and to execute all of the tests.
# With a little more work, this will become the basis of an automated
# testing and reporting system that anyone will be able to use to
# participate in testing SCons on their system and regularly reporting
# back the results.  A --xml option is a stab at gathering a lot of
# relevant information about the system, the Python version, etc.,
# so that problems on different platforms can be identified sooner.

import getopt
import imp
import os
import os.path
import sys
import tempfile
import time
import zipfile

    # try Python 3.x style
    from urllib.request import urlretrieve
except ImportError:
    # nope, must be 2.x; this hack is equivalent
    import imp
    # protect import from fixer
    urlretrieve = imp.load_module('urllib',

helpstr = """\
Usage: [-f zipfile] [-o outdir] [-v] [--xml] [runtest arguments]
  -f FILE                     Specify input .zip FILE name
  -o DIR, --out DIR           Change output directory name to DIR
  -v, --verbose               Print file names when extracting
  --xml                       XML output

opts, args = getopt.getopt(sys.argv[1:],
                           ['file=', 'out=', 'verbose', 'xml'])

format = None
outdir = None
printname = lambda x: x
inputfile = ''

for o, a in opts:
    if o == '-f' or o == '--file':
        inputfile = a
    elif o == '-o' or o == '--out':
        outdir = a
    elif o == '-v' or o == '--verbose':
        def printname(x):
            print x
    elif o == '--xml':
        format = o

startdir = os.getcwd()

tempfile.template = 'scons-test.'
tempdir = tempfile.mktemp()

if not os.path.exists(tempdir):
    def cleanup(tempdir=tempdir):
        import shutil
    sys.exitfunc = cleanup

# Fetch the input file if it happens to be across a network somewhere.
# Ohmigod, does Python make this simple...
inputfile, headers = urlretrieve(inputfile)

# Unzip the header file in the output directory.  We use our own code
# (lifted from to make the output subdirectory name
# match the basename of the .zip file.
zf = zipfile.ZipFile(inputfile, 'r')

if outdir is None:
    name, _ = os.path.splitext(os.path.basename(inputfile))
    outdir = os.path.join(tempdir, name)

def outname(n, outdir=outdir):
    l = []
    while True:
        n, tail = os.path.split(n)
        if not n:
    return os.path.join(*l)

for name in zf.namelist():
    dest = outname(name)
    dir = os.path.dirname(dest)
    # if the file exists, then delete it before writing
    # to it so that we don't end up trying to write to a symlink:
    if os.path.isfile(dest) or os.path.islink(dest):
    if not os.path.isdir(dest):
        open(dest, 'w').write(


# Load (by hand) the SCons modules we just unwrapped so we can
# extract their version information.  Note that we have to override
# SCons.Script.main() with a do_nothing() function, because loading up
# the 'scons' script will actually try to execute SCons...
src_script = os.path.join(outdir, 'src', 'script')
src_engine = os.path.join(outdir, 'src', 'engine')
src_engine_SCons = os.path.join(src_engine, 'SCons')

fp, pname, desc = imp.find_module('SCons', [src_engine])
SCons = imp.load_module('SCons', fp, pname, desc)

fp, pname, desc = imp.find_module('Script', [src_engine_SCons])
SCons.Script = imp.load_module('Script', fp, pname, desc)

def do_nothing():
SCons.Script.main = do_nothing

fp, pname, desc = imp.find_module('scons', [src_script])
scons = imp.load_module('scons', fp, pname, desc)

# Default is to run all the tests by passing the -a flags to
if not args:
    runtest_args = '-a'
    runtest_args = ' '.join(args)

if format == '--xml':

    print "<scons_test_run>"
    print "  <sys>"
    sys_keys = ['byteorder', 'exec_prefix', 'executable', 'maxint', 'maxunicode', 'platform', 'prefix', 'version', 'version_info']
    for k in sys_keys:
        print "    <%s>%s</%s>" % (k, sys.__dict__[k], k)
    print "  </sys>"

    fmt = '%a %b %d %H:%M:%S %Y'
    print "  <time>"
    print "    <gmtime>%s</gmtime>" % time.strftime(fmt, time.gmtime())
    print "    <localtime>%s</localtime>" % time.strftime(fmt, time.localtime())
    print "  </time>"

    print "  <tempdir>%s</tempdir>" % tempdir

    def print_version_info(tag, module):
        print "    <%s>" % tag
        print "      <version>%s</version>" % module.__version__
        print "      <build>%s</build>" % module.__build__
        print "      <buildsys>%s</buildsys>" % module.__buildsys__
        print "      <date>%s</date>" % module.__date__
        print "      <developer>%s</developer>" % module.__developer__
        print "    </%s>" % tag

    print "  <scons>"
    print_version_info("script", scons)
    print_version_info("engine", SCons)
    print "  </scons>"

    environ_keys = [



    print "  <environment>"
    for key in sorted(environ_keys):
        value = os.environ.get(key)
        if value:
            print "    <variable>"
            print "      <name>%s</name>" % key
            print "      <value>%s</value>" % value
            print "    </variable>"
    print "  </environment>"

    command = '"%s" -q -o - --xml %s' % (sys.executable, runtest_args)
    #print command
    print "</scons_test_run>"


    def print_version_info(tag, module):
        print "\t%s: v%s.%s, %s, by %s on %s" % (tag,

    print "SCons by Steven Knight et al.:"
    print_version_info("script", scons)
    print_version_info("engine", SCons)

    command = '"%s" %s' % (sys.executable, runtest_args)
    #print command

# Local Variables:
# tab-width:4
# indent-tabs-mode:nil
# End:
# vim: set expandtab tabstop=4 shiftwidth=4: