summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Knight <knight@baldmt.com>2002-11-05 10:16:03 (GMT)
committerSteven Knight <knight@baldmt.com>2002-11-05 10:16:03 (GMT)
commit69706b07d4bb5b71abbae236432bba2bbaf916d1 (patch)
tree971d96385aa9636f6a935deecdcc51b7c0b672ab
parent487e0e7e93e26700e80a54f1ae46cf7f780ee34c (diff)
downloadSCons-69706b07d4bb5b71abbae236432bba2bbaf916d1.zip
SCons-69706b07d4bb5b71abbae236432bba2bbaf916d1.tar.gz
SCons-69706b07d4bb5b71abbae236432bba2bbaf916d1.tar.bz2
Change runtest.py, SConstruct and the Aegis project config file to use -Y (Repository), and not symlinks, when building SCons under Aegis.
-rw-r--r--SConstruct7
-rw-r--r--config55
-rw-r--r--runtest.py120
3 files changed, 117 insertions, 65 deletions
diff --git a/SConstruct b/SConstruct
index eb08380..15e0db4 100644
--- a/SConstruct
+++ b/SConstruct
@@ -220,7 +220,7 @@ def SCons_revision(target, source, env):
into the source file package.
"""
t = str(target[0])
- s = str(source[0])
+ s = source[0].rstr()
# Note: We don't use $VERSION from the environment so that
# this routine will change when the version number changes
# and things will get rebuilt properly.
@@ -471,8 +471,9 @@ for p in [ scons ]:
# README.txt, or setup.py. Make a copy of the list for the
# destination files.
#
+ manifest_in = File(os.path.join(src, 'MANIFEST.in')).rstr()
src_files = map(lambda x: x[:-1],
- open(os.path.join(src, 'MANIFEST.in')).readlines())
+ open(manifest_in).readlines())
dst_files = src_files[:]
MANIFEST_in_list = []
@@ -487,7 +488,7 @@ for p in [ scons ]:
for sp in p['subpkgs']:
ssubdir = sp['src_subdir']
isubdir = p['subinst_dirs'][sp['pkg']]
- MANIFEST_in = os.path.join(src, ssubdir, 'MANIFEST.in')
+ MANIFEST_in = File(os.path.join(src, ssubdir, 'MANIFEST.in')).rstr()
MANIFEST_in_list.append(MANIFEST_in)
f = map(lambda x: x[:-1], open(MANIFEST_in).readlines())
src_files.extend(map(lambda x, s=ssubdir: os.path.join(s, x), f))
diff --git a/config b/config
index fc04c4b..1b35600 100644
--- a/config
+++ b/config
@@ -1,59 +1,26 @@
/*
- * aegis - project change supervisor
- * This file is in the Public Domain, 1995, Peter Miller.
- *
- * MANIFEST: example use of make in project config file
- *
- * The make(1) program exists in many forms, usually one is available with each
- * UNIX version. The one used in the writing of this section is GNU Make 3.70,
- * avaiable by anonymous FTP from your nearest GNU archive site. GNU Make was
- * chosen because it was the most powerful, it is widely avaiable (usually for
- * little or no cost) and discussion of the alternatives (SunOS make, BSD 4.3
- * make, etc), would not be universally applicable. "Plain vanilla" make
- * (with no transitive closure, no pattern rules, no functions) is not
- * sufficiently capable to satisfy the demands placed on it by aegis.
+ * MANIFEST: use of SCons in project config file to build itself
*
- * As mentioned in the Dependency Maintenance Tool chapter of the User Guide,
- * make is not really sufficient, because it lacks dynamic include dependencies.
- * However, GNU Make has a form of dynamic include dependencies, and it has a
- * few quirks, but mostly works well.
- *
- * The other feature lacking in make is a search path. While GNU Make has
- * functionality called VPATH, the implementation leaves something to be
- * desired, and can't be used for the search path functionality required by
- * aegis. Because of this, the create_symlinks_before_build field of the
- * project config file is set to true so that aegis will arrange for the
- * development directory to be fiull of symbolic links, making it appear that
- * the entire project is in each change's development directory.
+ * SCons has a Repository feature, introduced in SCons 0.09, that was
+ * designed to work well with Aegis.
*/
/*
* The build_command field of the project config file is used to invoke the
* relevant build command. This command tells make where to find the rules.
- * The ${s Makefile} expands to a path into the baseline during development
- * if the file is not in the change. Look in aesub(5) for more information
- * about command substitutions.
+ * The ${s src/script/scons.py} expands to a path into the baseline during
+ * development if the script file is not in the change. Look in aesub(5)
+ * for more information about command substitutions.
*/
-build_command = "SCONS_LIB_DIR=src/engine python ${Source src/script/scons.py} date='${DAte %Y/%m/%d %H:%M:%S}' developer=${DEVeloper} version=${VERsion} change=${Change}";
+build_command = "SCONS_LIB_DIR=src/engine python ${Source src/script/scons.py} -Y${SUBSTitute : \\ -Y $Search_Path} date='${DAte %Y/%m/%d %H:%M:%S}' developer=${DEVeloper} version=${VERsion} change=${Change}";
/*
- * The rules used in the User Guide all remove their targets before
- * constructing them, which qualifies them for the following entry in the
- * config file. The files must be removed first, otherwise the baseline would
- * cease to be self-consistent.
- */
+ * SCons removes its targets before constructing them, which qualifies it
+ * for the following entry in the config file. The files must be removed
+ * first, otherwise the baseline would cease to be self-consistent.
+ *
link_integration_directory = true;
-
-/*
- * Another field to be set in this file is one which tells aegis to maintain
- * symbolic links between the development directory and the basline. This also
- * requires that rules remove their targets before constructing them, to ensure
- * that development builds do not attempt to write their results onto the
- * read-only versions in the baseline.
*/
-create_symlinks_before_build = true;
-
-remove_symlinks_after_build = false;
/*
integrate_begin_command =
diff --git a/runtest.py b/runtest.py
index 98a24eb..158d5b6 100644
--- a/runtest.py
+++ b/runtest.py
@@ -6,12 +6,19 @@
# directories to test the SCons modules.
#
# By default, it directly uses the modules in the local tree:
-# ./src/ (source files we ship) and ./etc/ (other modules we don't)
+# ./src/ (source files we ship) and ./etc/ (other modules we don't).
#
-# When any -p option is specified, it assumes it's in a directory
-# in which a build has been performed, and sets PYTHONPATH so that it
-# *only* references the modules that have unpacked from the specified
-# built package, to test whether the packages are good.
+# HOWEVER, now that SCons has Repository support, we don't have
+# Aegis copy all of the files into the local tree. So if you're
+# using Aegis and want to run tests by hand using this script, you
+# must "aecp ." the entire source tree into your local directory
+# structure. When you're done with your change, you can then
+# "aecpu -unch ." to un-copy any files that you haven't changed.
+#
+# When any -p option is specified, this script assumes it's in a
+# directory in which a build has been performed, and sets PYTHONPATH
+# so that it *only* references the modules that have unpacked from
+# the specified built package, to test whether the packages are good.
#
# Options:
#
@@ -52,6 +59,7 @@ import glob
import os
import os.path
import re
+import stat
import string
import sys
@@ -118,28 +126,90 @@ for o, a in opts:
elif o == '-x' or o == '--exec':
scons = a
+def whereis(file):
+ for dir in string.split(os.environ['PATH'], os.pathsep):
+ f = os.path.join(dir, file)
+ if os.path.isfile(f):
+ try:
+ st = os.stat(f)
+ except:
+ continue
+ if stat.S_IMODE(st[stat.ST_MODE]) & 0111:
+ return f
+ return None
+
+aegis = whereis('aegis')
+
+spe = None
+if aegis:
+ spe = os.popen("aesub '$spe' 2>/dev/null", "r").read()[:-1]
+ spe = string.split(spe, os.pathsep)
+
class Test:
- def __init__(self, path):
+ def __init__(self, path, spe=None):
self.path = path
self.abspath = os.path.abspath(path)
+ if spe:
+ for dir in spe:
+ f = os.path.join(dir, path)
+ if os.path.isfile(f):
+ self.abspath = f
+ break
self.status = None
if args:
- for a in args:
- for g in glob.glob(a):
- tests.append(Test(g))
+ if spe:
+ for a in args:
+ if os.path.isabs(a):
+ for g in glob.glob(a):
+ tests.append(Test(g))
+ else:
+ for dir in spe:
+ x = os.path.join(dir, a)
+ globs = glob.glob(x)
+ if globs:
+ for g in globs:
+ tests.append(Test(g))
+ break
+ else:
+ for a in args:
+ for g in glob.glob(a):
+ tests.append(Test(g))
elif all:
- def find_Test_py(arg, dirname, names, t=tests):
+ tdict = {}
+
+ def find_Test_py(arg, dirname, names, tdict=tdict):
for n in filter(lambda n: n[-8:] == "Tests.py", names):
- t.append(Test(os.path.join(dirname, n)))
+ t = os.path.join(dirname, n)
+ if not tdict.has_key(t):
+ tdict[t] = Test(t)
os.path.walk('src', find_Test_py, 0)
- def find_py(arg, dirname, names, t=tests):
+ def find_py(arg, dirname, names, tdict=tdict):
for n in filter(lambda n: n[-3:] == ".py", names):
- t.append(Test(os.path.join(dirname, n)))
+ t = os.path.join(dirname, n)
+ if not tdict.has_key(t):
+ tdict[t] = Test(t)
os.path.walk('test', find_py, 0)
- tests.sort(lambda a, b: cmp(a.path, b.path))
+ if aegis:
+ cmd = "aegis -list -unf pf 2>/dev/null"
+ for line in os.popen(cmd, "r").readlines():
+ a = string.split(line)
+ if a[0] == "test" and not tdict.has_key(a[-1]):
+ tdict[a[-1]] = Test(a[-1], spe)
+ cmd = "aegis -list -unf cf 2>/dev/null"
+ for line in os.popen(cmd, "r").readlines():
+ a = string.split(line)
+ if a[0] == "test":
+ if a[1] == "remove":
+ del tdict[a[-1]]
+ elif not tdict.has_key(a[-1]):
+ tdict[a[-1]] = Test(a[-1], spe)
+
+ keys = tdict.keys()
+ keys.sort()
+ tests = map(tdict.get, keys)
if package:
@@ -173,10 +243,22 @@ if package:
lib_dir = os.path.join(test_dir, dir[package], 'lib', l)
else:
+ sd = None
+ ld = None
+ if spe:
+ if not scons:
+ for dir in spe:
+ d = os.path.join(dir, 'src', 'script')
+ f = os.path.join(d, 'scons.py')
+ if os.path.isfile(f):
+ sd = d
+ scons = f
+ spe = map(lambda x: os.path.join(x, 'src', 'engine'), spe)
+ ld = string.join(spe, os.pathsep)
- scons_dir = os.path.join(cwd, 'src', 'script')
+ scons_dir = sd or os.path.join(cwd, 'src', 'script')
- lib_dir = os.path.join(cwd, 'src', 'engine')
+ lib_dir = ld or os.path.join(cwd, 'src', 'engine')
if scons:
# Let the version of SCons that the -x option pointed to find
@@ -230,13 +312,15 @@ if len(tests) != 1:
sys.stdout.write("\nFailed the following test:\n")
else:
sys.stdout.write("\nFailed the following %d tests:\n" % len(fail))
- sys.stdout.write("\t" + string.join(fail, "\n\t") + "\n")
+ paths = map(lambda x: x.path, no_result)
+ sys.stdout.write("\t" + string.join(paths, "\n\t") + "\n")
if no_result:
if len(no_result) == 1:
sys.stdout.write("\nNO RESULT from the following test:\n")
else:
sys.stdout.write("\nNO RESULT from the following %d tests:\n" % len(no_result))
- sys.stdout.write("\t" + string.join(no_result, "\n\t") + "\n")
+ paths = map(lambda x: x.path, no_result)
+ sys.stdout.write("\t" + string.join(paths, "\n\t") + "\n")
if output:
f = open(output, 'w')