import distutils.core as DC
import distutils.log as DL
+###--------------------------------------------------------------------------
+### Compatibility hacks.
+
+def with_metaclass(meta, *supers):
+ return meta("#<anonymous base %s>" % meta.__name__,
+ supers or (object,), dict())
+
###--------------------------------------------------------------------------
### Random utilities.
The COMMAND must produce exactly one line of output, and must exit with
status zero.
"""
- kid = SUB.Popen(command, stdout = SUB.PIPE)
- out = kid.stdout.readline()
- junk = kid.stdout.read()
- if junk != '':
- raise ValueError, \
- "Child process `%s' produced unspected output %r" % (command, junk)
+ kid = SUB.Popen(command, stdout = SUB.PIPE, universal_newlines = True)
+ try:
+ out = kid.stdout.readline()
+ junk = kid.stdout.read(1)
+ finally:
+ kid.stdout.close()
+ if junk != '': raise ValueError \
+ ("Child process `%s' produced unspected output %r" % (command, junk))
rc = kid.wait()
- if rc != 0:
- raise SubprocessFailure, (command, rc)
+ if rc != 0: raise SubprocessFailure(command, rc)
return out.rstrip('\n')
###--------------------------------------------------------------------------
library-directory names are in LIBDIRS; and the library names themselves
are in LIBS.
"""
- spec = '%s >= %s' % (pkg, version)
+
def weird(what, word):
- raise ValueError, \
- "Unexpected `%s' item `%s' from package `%s'" % (what, word, pkg)
- for word in progoutput(['pkg-config', '--cflags', spec]).split():
- if word.startswith('-I'):
- INCLUDEDIRS.append(word[2:])
- else:
- weird('--cflags', word)
- for word in progoutput(['pkg-config', '--libs', spec]).split():
- if word.startswith('-L'):
- LIBDIRS.append(word[2:])
- elif word.startswith('-l'):
- LIBS.append(word[2:])
- else:
- weird('--libs', word)
+ raise ValueError \
+ ("Unexpected `%s' item `%s' from package `%s'" % (what, word, pkg))
+
+ spec = '%s >= %s' % (pkg, version)
+
+ try: cflags = OS.environ["%s_CFLAGS" % pkg]
+ except KeyError: cflags = progoutput(['pkg-config', '--cflags', spec])
+ for word in cflags.split():
+ if word.startswith('-I'): INCLUDEDIRS.append(word[2:])
+ else: weird('CFLAGS', word)
+ try: libs = OS.environ["%s_LIBS" % pkg]
+ except KeyError: libs = progoutput(['pkg-config', '--libs', spec])
+ for word in libs.split():
+ if word.startswith('-L'): LIBDIRS.append(word[2:])
+ elif word.startswith('-l'): LIBS.append(word[2:])
+ else: weird('LIBS', word)
###--------------------------------------------------------------------------
### Substituting variables in files.
temp = me.target + '.new'
with open(temp, 'w') as ft:
rc = SUB.call([SYS.executable, me.sources[0]], stdout = ft)
- if rc != 0: raise SubprocessFailure, (me.sources[0], rc << 8)
+ if rc != 0: raise SubprocessFailure(me.sources[0], rc << 8)
OS.rename(temp, me.target)
## Backward compatibility.
else: CMDS[name] = c
return c
-class Command (DC.Command, object):
+class Command (with_metaclass(CommandClass, DC.Command, object)):
"""
Base class for `mdwsetup' command classes.
description = "print the distribution directory name to stdout"
def run(me):
d = me.distribution
- print '%s-%s' % (d.get_name(), d.get_version())
+ print('%s-%s' % (d.get_name(), d.get_version()))
-class build_gen(Command):
+class build_gen (Command):
"""
Generate files, according to the `genfiles'.
sub_commands = [('build_gen', lambda me: me.distribution.genfiles)]
sub_commands += _build.sub_commands
-class clean_gen(Command):
+class test (Command):
+ """
+ Run unit tests, according to the `unittests'.
+
+ The `unittests' keyword argument to `setup' lists module names (or other
+ things acceptable to the `loadTestsFromNames' test-loader method) to be
+ run. The build library directory is prepended to the load path before
+ running the tests to ensure that the newly built modules are tested. If
+ `unittest_dir' is set, then this is appended to the load path so that test
+ modules can be found there.
+ """
+ NAME = "test"
+ description = "run the included test suite"
+
+ user_options = \
+ [('build-lib=', 'b', "directory containing compiled moules"),
+ ('tests=', 't', "tests to run"),
+ ('verbose-test', 'V', "run tests verbosely")]
+
+ def initialize_options(me):
+ me.build_lib = None
+ me.verbose_test = False
+ me.tests = None
+ def finalize_options(me):
+ me.set_undefined_options('build', ('build_lib', 'build_lib'))
+ def run(me):
+ import unittest as U
+ d = me.distribution
+ SYS.path = [me.build_lib] + SYS.path
+ if d.unittest_dir is not None: SYS.path.append(d.unittest_dir)
+ if me.tests is not None: tests = me.tests.split(",")
+ else: tests = d.unittests
+ suite = U.defaultTestLoader.loadTestsFromNames(tests)
+ runner = U.TextTestRunner(verbosity = me.verbose_test and 2 or 1)
+ if me.dry_run: return
+ result = runner.run(suite)
+ if result.errors or result.failures or \
+ getattr(result, "unexpectedSuccesses", 0):
+ SYS.exit(2)
+
+class clean_gen (Command):
"""
Remove the generated files, as listed in `genfiles'.
d = me.distribution
for g in d.genfiles: g.clean(dry_run_p = me.dry_run)
-class clean_others(Command):
+class clean_others (Command):
"""
Remove the files listed in the `cleanfiles' argument to `setup'.
"""
## our enhanced commands.
def __init__(me, attrs = None):
me.genfiles = []
+ me.unittest_dir = None
+ me.unittests = []
me.cleanfiles = []
me._auto_version_p = False
DC.Distribution.__init__(me, attrs)