Start getting ready to eat our own dog food: prototype SConscript files.
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Tue, 15 Jan 2002 17:01:47 +0000 (17:01 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Tue, 15 Jan 2002 17:01:47 +0000 (17:01 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@208 fdb21ef1-2011-0410-befe-b5e4ea1792b1

23 files changed:
HOWTO/.aeignore
README
SConstruct [new file with mode: 0644]
admin/.aeignore
bin/.aeignore
debian/.aeignore
doc/.aeignore
doc/SConscript [new file with mode: 0644]
doc/design/.aeignore
doc/man/.aeignore
doc/user/.aeignore
etc/.aeignore
etc/SConscript [new file with mode: 0644]
rpm/.aeignore
src/.aeignore
src/engine/SCons/.aeignore
src/engine/SCons/Node/.aeignore
src/engine/SCons/Node/FS/.aeignore
src/engine/SCons/Scanner/.aeignore
src/engine/SCons/Script/.aeignore
src/engine/SCons/Sig/.aeignore
template/.aeignore
test/.aeignore

index 872e8be6e9942e161ac8e755ffe84cc06cb8e389..877ac53464660bf36b4cb09a5d3d8240b4dcb964 100644 (file)
@@ -1,3 +1,4 @@
 *,D
 .*.swp
 .consign
+.sconsign
diff --git a/README b/README
index 2a04415cb3c809e265a7bd1d1f4b2cfb708c30a0..d865b7b260cfcdc9199995a05b96e0d17086c124 100644 (file)
--- a/README
+++ b/README
@@ -40,6 +40,11 @@ runtest.py
        it with an option that requires that you've done a build
        (aeb) before running tests.
 
+SConstruct
+        The new "Makefile" for the SCons distribution, as soon as we
+        have SCons to the point where it can build itself.  THIS IS
+       NOT READY YET.
+
 src/
        Where the actual source code is kept, of course.
 
diff --git a/SConstruct b/SConstruct
new file mode 100644 (file)
index 0000000..67d3e64
--- /dev/null
@@ -0,0 +1,597 @@
+#
+# SConstruct file to build scons during development.
+#
+# THIS IS NOT READY YET.  DO NOT TRY TO BUILD SCons WITH ITSELF YET.
+#
+
+#
+# Copyright (c) 2001 Steven Knight
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+import distutils.util
+import os
+import os.path
+import stat
+import string
+import sys
+import time
+
+project = 'scons'
+
+#Default('.')       # XXX Uncomment this when we're really ready
+
+#
+# An internal "whereis" routine to figure out if we have a
+# given program available.  Put it in the "cons::" package
+# so subsidiary Conscript files can get at it easily, too.
+#
+
+def whereis(file):
+    for dir in string.split(os.environ['PATH'], os.pathsep):
+        f = os.path.join(dir, file)
+       try:
+           st = os.stat(f)
+       except:
+            continue
+        if stat.S_IMODE(st[stat.ST_MODE]) & 0111:
+            return f
+    return None
+
+#
+# We let the presence or absence of various utilities determine
+# whether or not we bother to build certain pieces of things.
+# This will allow people to still do SCons work even if they
+# don't have Aegis or RPM installed, for example.
+#
+aegis = whereis('aegis')
+aesub = whereis('aesub')
+rpm = whereis('rpm')
+dh_builddeb = whereis('dh_builddeb')
+fakeroot = whereis('fakeroot')
+
+# My installation on Red Hat doesn't like any debhelper version
+# beyond 2, so let's use 2 as the default on any non-Debian build.
+if os.path.isfile('/etc/debian_version'):
+    dh_compat = 3
+else:
+    dh_compat = 2
+
+#
+ARG = {}        # XXX Remove this when we support command-line arguments
+#
+# Now grab the information that we "build" into the files (using sed).
+#
+try:
+    date = ARG['date']
+except:
+    date = time.strftime("%Y/%m/%d %H:%M:%S", time.localtime(time.time()))
+    
+if ARG.has_key('developer'):
+    developer = ARG['developer']
+elif os.environ.has_key('USERNAME'):
+    developer = os.environ['USERNAME']
+elif os.environ.has_key('LOGNAME'):
+    developer = os.environ['LOGNAME']
+elif os.environ.has_key('USER'):
+    developer = os.environ['USER']
+
+try:
+    revision = ARG['version']
+except:
+    if aesub:
+        revision = os.popen(aesub + " \\$version", "r").read()[:-1]
+    else:
+        revision = '0.04'
+
+a = string.split(revision, '.')
+arr = [a[0]]
+for s in a[1:]:
+    if len(s) == 1:
+        s = '0' + s
+    arr.append(s)
+revision = string.join(arr, '.')
+
+# Here's how we'd turn the calculated $revision into our package $version.
+# This makes it difficult to coordinate with other files (debian/changelog
+# and rpm/scons.spec) that hard-code the version number, so just go with
+# the flow for now and hard code it here, too.
+#if len(arr) >= 2:
+#    arr = arr[:-1]
+#def xxx(str):
+#    if str[0] == 'C' or str[0] == 'D':
+#        str = str[1:]
+#    while len(str) > 2 and str[0] == '0':
+#        str = str[1:]
+#    return str
+#arr = map(lambda x, xxx=xxx: xxx(x), arr)
+#version = string.join(arr, '.')
+version = '0.04'
+
+try:
+    change = ARG['change']
+except:
+    if aesub:
+        change = os.popen(aesub + " \\$change", "r").read()[:-1]
+    else:
+        change = '0.04'
+
+python_ver = sys.version[0:3]
+
+platform = distutils.util.get_platform()
+
+if platform == "win32":
+    archsuffix = "zip"
+else:
+    archsuffix = "tar.gz"
+
+test1_dir = os.path.join(os.getcwd(), "build", "test1")
+test2_dir = os.path.join(os.getcwd(), "build", "test2")
+
+lib_project = os.path.join("lib", project)
+
+# Originally, we were going to package the build engine in a
+# private SCons library that contained the version number, so
+# we could easily have multiple side-by-side versions of SCons
+# installed.  Keep this around in case we ever want to go back
+# to that scheme.  Note that this also requires changes to
+# runtest.py and src/setup.py.
+#lib_project = os.path.join("lib", project + '-' + version)
+
+test1_lib_dir = os.path.join(test1_dir, lib_project)
+
+test2_lib_dir = os.path.join(test2_dir,
+                             "lib",
+                             "python" + python_ver,
+                             "site-packages")
+
+unpack_dir = os.path.join(os.getcwd(), "build", "unpack")
+
+env = Environment(
+                   ENV           = {
+                                     'AEGIS_PROJECT' : os.environ['AEGIS_PROJECT'],
+                                     'PATH'          : os.environ['PATH'],
+                                   },
+                   TEST1_LIB_DIR = test1_lib_dir,
+                   TEST2_LIB_DIR = test2_lib_dir,
+                   DATE          = date,
+                   DEVELOPER     = developer,
+                   REVISION      = revision,
+                   VERSION       = version,
+                   DH_COMPAT     = dh_compat,
+                   SED           = 'sed',
+                   SEDFLAGS      = "$( -e 's+__DATE__+$DATE+' $)" + \
+                                   " -e 's+__DEVELOPER__+$DEVELOPER+'" + \
+                                   " -e 's+__FILE__+$SOURCES'+" + \
+                                   " -e 's+__REVISION__+$REVISION'+" + \
+                                   " -e 's+__VERSION__+$VERSION'+",
+                   SEDCOM        = '$SED $SEDFLAGS $SOURCES > $TARGET',
+                 )
+
+#
+# Define SCons packages.
+#
+# In the original, more complicated packaging scheme, we were going
+# to have separate packages for:
+#
+#      python-scons    only the build engine
+#      scons-script    only the script
+#      scons           the script plus the build engine
+#
+# We're now only delivering a single "scons" package, but this is still
+# "built" as two sub-packages (the build engine and the script), so
+# the definitions remain here, even though we're not using them for
+# separate packages.
+#
+
+python_scons = {
+        'pkg'           : 'python-' + project,
+        'src_subdir'    : 'engine',
+        'inst_subdir'   : os.path.join('lib', 'python1.5', 'site-packages'),
+        'prefix'        : test2_dir,
+
+        'debian_deps'   : [ 'debian/rules debian/control',
+                            'debian/changelog debian/copyright',
+                            'debian/python-scons.postinst',
+                            'debian/python-scons.prerm',
+                          ],
+
+        'files'         : [ 'LICENSE.txt',
+                            'README.txt',
+                            'setup.cfg',
+                            'setup.py',
+                          ],
+
+        'filemap'       : {
+                            'LICENSE.txt' : '../LICENSE.txt'
+                          },
+}
+
+#
+# The original packaging scheme would have have required us to push
+# the Python version number into the package name (python1.5-scons,
+# python2.0-scons, etc.), which would have required a definition
+# like the following.  Leave this here in case we ever decide to do
+# this in the future, but note that this would require some modification
+# to src/engine/setup.py before it would really work.
+#
+#python2_scons = {
+#        'pkg'          : 'python2-' + project,
+#        'src_subdir'   : 'engine',
+#        'inst_subdir'  : os.path.join('lib', 'python2.1', 'site-packages'),
+#        'prefix'       : test2_dir,
+#
+#        'debian_deps'  : [ 'debian/rules debian/control',
+#                           'debian/changelog debian/copyright',
+#                           'debian/python2-scons.postinst',
+#                           'debian/python2-scons.prerm',
+#                          ],
+#
+#        'files'        : [
+#                            'LICENSE.txt',
+#                            'README.txt',
+#                            'setup.cfg',
+#                            'setup.py',
+#                          ],
+#        'filemap'      : {
+#                            'LICENSE.txt' : '../LICENSE.txt',
+#                          },
+#}
+#
+
+scons_script = {
+        'pkg'           : project + '-script',
+        'src_subdir'    : 'script',
+        'inst_subdir'   : 'bin',
+        'prefix'        : test2_dir,
+
+        'debian_deps'   : [ 'debian/rules debian/control',
+                            'debian/changelog debian/copyright',
+                            'debian/python-scons.postinst',
+                            'debian/python-scons.prerm',
+                          ],
+
+        'files'         : [
+                            'LICENSE.txt',
+                            'README.txt',
+                            'setup.cfg',
+                            'setup.py',
+                          ],
+
+        'filemap'       : {
+                            'LICENSE.txt' : '../LICENSE.txt',
+                            'scons'       : 'scons.py',
+                           }
+}
+
+scons = {
+        'pkg'           : project,
+        #'inst_subdir'   : None,
+        'prefix'        : test1_dir,
+
+        'debian_deps'   : [ 
+                            'debian/rules debian/control',
+                            'debian/changelog debian/copyright',
+                            'debian/scons.postinst',
+                            'debian/scons.prerm',
+                          ],
+
+        'files'         : [ 
+                            'CHANGES.txt',
+                            'LICENSE.txt',
+                            'README.txt',
+                            'RELEASE.txt',
+                            'os_spawnv_fix.diff',
+                            'scons.1',
+                            'script/scons.bat',
+                            'setup.cfg',
+                            'setup.py',
+                          ],
+
+        'filemap'       : {
+                            'scons.1' : '../doc/man/scons.1',
+                          },
+
+        'subpkgs'      : [ python_scons, scons_script ],
+
+        'subinst_dirs' : {
+                             'python-' + project : lib_project,
+                             project + '-script' : 'bin',
+                           },
+}
+
+src_deps = []
+
+for p in [ scons ]:
+    #
+    # Initialize variables with the right directories for this package.
+    #
+    pkg = p['pkg']
+
+    src = 'src'
+    try:
+        src = os.path.join(src, p['src_subdir'])
+    except KeyError:
+        pass
+
+    build = os.path.join('build', pkg)
+
+    prefix = p['prefix']
+    install = prefix
+    try:
+        install = os.path.join(install, p['inst_subdir'])
+    except KeyError:
+        pass
+
+    #
+    # Read up the list of source files from our MANIFEST.in.
+    # This list should *not* include LICENSE.txt, MANIFEST,
+    # README.txt, or setup.py.  Make a copy of the list for the
+    # destination files.
+    #
+    src_files = map(lambda x: x[:-1],
+                    open(os.path.join(src, 'MANIFEST.in')).readlines())
+    dst_files = map(lambda x: os.path.join(install, x), src_files)
+
+    if p.has_key('subpkgs'):
+        #
+        # This package includes some sub-packages.  Read up their
+        # MANIFEST.in files, and add them to our source and destination
+        # file lists, modifying them as appropriate to add the
+        # specified subdirs.
+        #
+        for sp in p['subpkgs']:
+            ssubdir = sp['src_subdir']
+            isubdir = p['subinst_dirs'][sp['pkg']]
+            f = map(lambda x: x[:-1],
+                    open(os.path.join(src, ssubdir, 'MANIFEST.in')).readlines())
+            src_files.extend(map(lambda x, s=sp['src_subdir']:
+                                        os.path.join(s, x),
+                                 f))
+            dst_files.extend(map(lambda x, i=install, s=isubdir:
+                                        os.path.join(i, s, x),
+                                 f))
+            for k in sp['filemap'].keys():
+                f = sp['filemap'][k]
+                if f:
+                    k = os.path.join(sp['src_subdir'], k)
+                    p['filemap'][k] = os.path.join(sp['src_subdir'], f)
+
+    #
+    # Now that we have the "normal" source files, add those files
+    # that are standard for each distribution.  Note that we don't
+    # add these to dst_files, because they don't get installed.
+    # And we still have the MANIFEST to add.
+    #
+    src_files.extend(p['files'])
+
+    #
+    # Now run everything in src_file through the sed command we
+    # concocted to expand __FILE__, __VERSION__, etc.
+    #
+    for b in src_files:
+        try:
+            s = p['filemap'][b]
+        except KeyError:
+            pass
+        env.Command(os.path.join(build, b),
+                    os.path.join(src, s),
+                    "$SEDCOM")
+
+    #
+    # NOW, finally, we can create the MANIFEST, which we do
+    # by having Perl spit out the contents of the @src_files
+    # array we've carefully created.  After we've added
+    # MANIFEST itself to the array, of course.
+    #
+    src_files.append("MANIFEST")
+    def copy(src, dest):
+        open(dest, 'wb').write(open(src, 'rb').read())
+        return 0
+    env.Command(os.path.join(build, 'MANIFEST'),
+                os.path.join(src, 'MANIFEST.in'),
+                copy)
+
+    #
+    # Use the Python distutils to generate the packages.
+    #
+    archive = os.path.join(build,
+                           'dist',
+                           "%s-%s.%s" % (pkg, version, archsuffix))
+
+    src_deps.append(archive)
+
+    build_targets = [
+        os.path.join(build, 'dist', "%s-%s.%s.%s" % (pkg, version, platform, archsuffix)),
+        archive,
+        os.path.join(build, 'dist', "%s-%s.win32.exe" % (pkg, version)),
+    ]
+    install_targets = build_targets
+
+    # We can get away with calling setup.py using a directory path
+    # like this because we put a preamble in it that will chdir()
+    # to the directory in which setup.py exists.
+    bdist_dirs = [
+        os.path.join(build, 'build', 'lib'),
+        os.path.join(build, 'build', 'scripts'),
+    ]
+    setup_py = os.path.join(build, 'setup.py')
+    commands = [
+        "rm -rf %s && python %s bdist" %
+            (string.join(map(lambda x: str(x), bdist_dirs)), setup_py),
+        "python %s sdist" % setup_py,
+        "python %s bdist_wininst" % setup_py,
+    ]
+
+    if rpm:
+        topdir = os.path.join(os.getcwd(), build, 'build',
+                              'bdist.' + platform, 'rpm')
+
+       BUILDdir = os.path.join(topdir, 'BUILD', pkg + '-' + version)
+       RPMSdir = os.path.join(topdir, 'RPMS', 'noarch')
+       SOURCESdir = os.path.join(topdir, 'SOURCES')
+       SPECSdir = os.path.join(topdir, 'SPECS')
+       SRPMSdir = os.path.join(topdir, 'SRPMS')
+
+       specfile = os.path.join(SPECSdir, "%s-%s-1.spec" % (pkg, version))
+       sourcefile = os.path.join(SOURCESdir, "%s-%s.%s" % (pkg, version, archsuffix));
+       rpm = os.path.join(RPMSdir, "%s-%s-1.noarch.rpm" % (pkg, version))
+       src_rpm = os.path.join(SRPMSdir, "%s-%s-1.src.rpm" % (pkg, version))
+
+        env.InstallAs(specfile, os.path.join('rpm', "%s.spec" % pkg))
+        env.InstallAs(sourcefile, archive)
+
+        targets = [ rpm, src_rpm ]
+        cmd = "rpm --define '_topdir %s' -ba $TARGET" % topdir
+        if os.path.isdir(BUILDdir):
+            cmd = "mkdir -p " + BUILDdir + "; " + cmd
+        env.Command(targets, specfile, cmd)
+        env.Depends(targets, sourcefile)
+
+        install_targets.extend(targets)
+
+    build_src_files = map(lambda x, b=build: os.path.join(b, x), src_files)
+
+    if dh_builddeb and fakeroot:
+        # Debian builds directly into build/dist, so we don't
+        # need to add the .debs to the install_targets.
+        deb = os.path.join('build', 'dist', "%s_%s-1.all.deb" % (pkg, version))
+        env.Command(deb, build_src_files, [
+            "fakeroot make -f debian/rules VERSION=$VERSION DH_COMPAT=$DH_COMPAT ENVOKED_BY_CONSTRUCT=1 binary-%s" % pkg,
+            "env DH_COMPAT=$DH_COMPAT dh_clean"
+                    ])
+        env.Depends(deb, p['debian_deps'])
+
+
+    #
+    # Now set up creation and installation of the packages.
+    #
+    env.Command(build_targets, build_src_files, commands)
+    env.Install(os.path.join('build', 'dist'), install_targets)
+
+    #
+    # Unpack the archive created by the distutils into build/unpack.
+    #
+    d = os.path.join(unpack_dir, "%s-%s" % (pkg, version))
+    unpack_files = map(lambda x, d=d: os.path.join(d, x), src_files)
+
+    # We'd like to replace the last three lines with the following:
+    #
+    #  tar zxf %< -C $unpack_dir
+    #
+    # but that gives heartburn to Cygwin's tar, so work around it
+    # with separate zcat-tar-rm commands.
+    env.Command(unpack_files, archive, [
+        "rm -rf " + os.path.join(unpack_dir, '%s-%s' % (pkg, version)),
+        "zcat $SOURCES > .temp",
+        "tar xf .temp -C %s" % unpack_dir,
+        "rm -f .temp",
+    ])
+
+    #
+    # Run setup.py in the unpacked subdirectory to "install" everything
+    # into our build/test subdirectory.  Auxiliary modules that we need
+    # (TestCmd.py, TestSCons.py, unittest.py) will be copied in by
+    # etc/Conscript.  The runtest.py script will set PYTHONPATH so that
+    # the tests only look under build/test.  This makes sure that our
+    # tests pass with what we really packaged, not because of something
+    # hanging around in the development directory.
+    #
+    # We can get away with calling setup.py using a directory path
+    # like this because we put a preamble in it that will chdir()
+    # to the directory in which setup.py exists.
+    env.Command(dst_files, unpack_files, [
+        "rm -rf %s" % install,
+        "python %s install --prefix=%s" % (os.path.join(unpack_dir,
+                                                        '%s-%s' % (pkg, version),
+                                                        'setup.py'),
+                                           prefix
+                                          ),
+    ])
+
+#
+# Arrange for supporting packages to be installed in the test directories.
+#
+Export('env', 'whereis')
+
+SConscript('etc/SConscript')
+
+#
+# Documentation.
+#
+BuildDir('build/doc', 'doc')
+
+SConscript('build/doc/SConscript');
+
+
+#
+# If we're running in the actual Aegis project, pack up a complete
+# source archive from the project files and files in the change,
+# so we can share it with helpful developers who don't use Aegis.
+#
+# First, lie and say that we've seen any files removed by this
+# change, so they don't get added to the source files list
+# that goes into the archive.
+#
+
+if change:
+    df = []
+    cmd = "aegis -list -unf -c %s cf 2>/dev/null" % change
+    for line in map(lambda x: x[:-1], os.popen(cmd, "r").readlines()):
+        a = string.split(line)
+        if a[1] == "remove":
+            df.append(a[3])
+
+    cmd = "aegis -list -terse pf 2>/dev/null"
+    pf = map(lambda x: x[:-1], os.popen(cmd, "r").readlines())
+    cmd = "aegis -list -terse cf 2>/dev/null"
+    cf = map(lambda x: x[:-1], os.popen(cmd, "r").readlines())
+    u = {}
+    for f in pf + cf:
+        u[f] = 1
+    for f in df:
+        del u[f]
+    src_files = filter(lambda x: x[-9:] != '.aeignore' and x[-7:] != '.consign',
+                       u.keys())
+
+    if src_files:
+        ps = "%s-src" % project
+        psv = "%s-src-%s" % (project, version)
+        b_ps = os.path.join('build', ps)
+        b_psv = os.path.join('build', psv)
+
+        for file in src_files:
+            env.Command(os.path.join(b_ps, file), file,
+                        [ "$SEDCOM", "chmod --reference=$SOURCE $TARGET" ])
+
+        b_ps_files = map(lambda x, d=b_ps: os.path.join(d, x), src_files)
+        cmds = [
+            "rm -rf %s" % b_psv,
+            "cp -rp %s %s" % (b_ps, b_psv),
+            "find %s -name .consign -exec rm {} \\;" % b_psv,
+            "tar zcf $TARGET -C build %s" % psv,
+        ]
+        env.Command(os.path.join('build',
+                                 'dist',
+                                 '%s-src-%s.tar.gz' % (project, version)),
+                    src_deps + b_ps_files, cmds)
index 43fe8513cbf8871225990fe1dbb2825a2acc43a1..22ebd62bf83a67acc5060db396a28fd9b12ea99f 100644 (file)
@@ -2,3 +2,4 @@
 *.pyc
 .*.swp
 .consign
+.sconsign
index 872e8be6e9942e161ac8e755ffe84cc06cb8e389..877ac53464660bf36b4cb09a5d3d8240b4dcb964 100644 (file)
@@ -1,3 +1,4 @@
 *,D
 .*.swp
 .consign
+.sconsign
index 872e8be6e9942e161ac8e755ffe84cc06cb8e389..877ac53464660bf36b4cb09a5d3d8240b4dcb964 100644 (file)
@@ -1,3 +1,4 @@
 *,D
 .*.swp
 .consign
+.sconsign
index 103da1c0af23460f1f93c62368d4fcf38840d234..52557a762d47bf4ab0995f990605ac2d3c0f2170 100644 (file)
@@ -1,4 +1,5 @@
 *,D
 .*.swp
 .consign
+.sconsign
 version.sgml
diff --git a/doc/SConscript b/doc/SConscript
new file mode 100644 (file)
index 0000000..f14bc43
--- /dev/null
@@ -0,0 +1,255 @@
+#
+# SConscript file for building SCons documentation.
+#
+# THIS IS NOT READY YET.  DO NOT TRY TO BUILD SCons WITH ITSELF YET.
+#
+
+#
+# Copyright (c) 2001 Steven Knight
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+import os.path
+import re
+import string
+
+Import('env', 'whereis')
+
+#
+#
+#
+doc_tar_gz = os.path.join('#build',
+                          'dist',
+                          'scons-doc-%s.tar.gz' % env.Dictionary('VERSION'))
+
+#
+# We'll only try to build text files (for some documents)
+# if lynx is available to do the dump.
+#
+fig2dev = whereis('fig2dev')
+groff = whereis('groff')
+lynx = whereis('lynx')
+man2html = whereis('man2html')
+jw = whereis('jw')
+
+tar_deps = []
+tar_list = ""
+
+entity_re = re.compile(r'<!entity\s+(?:%\s+)?(?:\S+)\s+SYSTEM\s+"([^"]*)">/', re.I)
+format_re = re.compile(r'<(?:graphic|imagedata)\s+fileref="([^"]*)"(?:\s+format="([^"]*)")?')
+
+#
+# Find internal dependencies in .sgml files:
+#
+#   <!entity bground SYSTEM "bground.sgml">
+#   <graphic fileref="file.jpg">
+#   <imagedata fileref="file.jpg">
+#
+# This only finds one per line, and assumes that anything
+# defined as a SYSTEM entity is, in fact, a file included
+# somewhere in the document.
+#
+def scansgml(contents, argument = None):
+    includes = []
+
+    matches = entity_re.findall(contents)
+    for m in matches:
+        includes.append(m[0])
+
+    matches = format_re.findall(contents)
+    for m in matches:
+        file, format = m
+        if format and file[-len(format):] != format:
+            file = file + format
+        if argument and not os.path.isabs(file):
+            file = os.path.join(argument, file)
+        includes.append(file)
+
+    return includes
+
+if jw:
+    #
+    # Always create a version.sgml file containing the version information
+    # for this run.  Ignore it for dependency purposes so we don't
+    # rebuild all the docs every time just because the date changes.
+    #
+    date, ver, rev = env.Dictionary('DATE', 'VERSION', 'REVISION')
+    verfile = str(File("version.sgml"))
+    os.unlink(verfile)
+    open(verfile, "w").write("""<!--
+THIS IS AN AUTOMATICALLY-GENERATED FILE.  DO NOT EDIT.
+-->
+<!ENTITY builddate "%s">
+<!ENTITY buildversion "%s">
+<!ENTITY buildrevision "%s">
+""" % (date, ver, rev))
+
+    #
+    # Each document will live in its own subdirectory.  List them here
+    # as hash keys, with a hash of the info to control its build.
+    #
+    docs = {
+        'design' : {
+                'htmlindex' : 'book1.html',
+                'ps'        : 1,
+                'pdf'       : 1,
+                'text'      : 0,
+                'scan'      : Scanner(name = 'design',
+                                      function = scansgml,
+                                      argument = 'design'),
+        },
+        'python10' : {
+                'htmlindex' : 't1.html',
+                'html'      : 1,
+                'ps'        : 1,
+                'pdf'       : 0,
+                'text'      : 0,
+                'graphics'  : [ 'arch', 'builder', 'job-task', 'node', 'scanner', 'sig' ],
+                'scan'      : Scanner(name = 'python10',
+                                      function = scansgml,
+                                      argument = 'python10'),
+        },
+        'user' : {
+                'htmlindex' : 'book1.html',
+                'html'      : 1,
+                'ps'        : 1,
+                'pdf'       : 1,
+                'text'      : 0,
+                'scan'      : Scanner(name = 'user',
+                                      function = scansgml,
+                                      argument = 'user'),
+        },
+    }
+
+    #
+    # We have to tell Cons to QuickScan the top-level SGML files which
+    # get included by the document SGML files in the subdirectories.
+    #
+    included_sgml = [
+        'scons.mod',
+        'copyright.sgml',
+    ]
+
+    s = Scanner(name = 'sgml', function = scansgml)
+
+    for sgml in included_sgml:
+        File(sgml).scanner_set(s)
+
+    #
+    # For each document, build the document itself in HTML, Postscript,
+    # and PDF formats.
+    #
+    for doc in docs.keys():
+        main = os.path.join(doc, 'main.sgml')
+        out = 'main.out'
+
+        htmldir = os.path.join('HTML', 'scons-%s' % doc)
+        htmlindex = os.path.join(htmldir, docs[doc]['htmlindex'])
+        html = os.path.join('HTML', 'scons-%s.html' % doc)
+        ps = os.path.join('PS', 'scons-%s.ps' % doc)
+        pdf = os.path.join('PDF', 'scons-%s.pdf' % doc)
+        text = os.path.join('TEXT', 'scons-%s.txt' % doc)
+
+        s = docs[doc].get('scan')
+        if s:
+            File(os.path.join('build', 'doc', main)).scanner_set(s)
+
+        if docs[doc].get('html'):
+            env.Command(htmlindex, main, [
+                "rm -f ${TARGET.dir}/*.html",
+                "jw -b html -o {$TARGET.dir} $SOURCES",
+                "mv -v ${TARGET.dir}/index.html $TARGET || true",
+            ])
+
+            env.Command(html, main, "jw -u -b html $SOURCES > $TARGET")
+
+            tar_deps.extend([html, htmlindex])
+            tar_list = string.join([tar_list, html, htmldir], " ")
+
+            if fig2dev:
+                for g in docs[doc].get('graphics', []):
+                    fig = os.path.join(doc, '%s.fig' % g)
+                    jpg = os.path.join(htmldir, '%s.jpg' % g)
+                    env.Command(jpg, fig,
+                                "%s -L jpeg -q 100 $SOURCES $TARGET" % fig2dev)
+                    env.Depends(ps, jpg)
+
+        if docs[doc].get('ps'):
+            env.Command(ps, main, [
+                "rm -f ${TARGET.dir}/%s" % out,
+                "jw -b ps -o ${TARGET.dir} $SOURCES",
+                "mv ${TARGET.dir}/main.ps $TARGET",
+                "rm -f ${TARGET.dir}/%s" % out,
+            ])
+            tar_deps.append(ps)
+            tar_list = tar_list + " " + ps
+            if fig2dev:
+                for g in docs[doc].get('graphics', []):
+                    fig = os.path.join(doc, '%s.fig' % g)
+                    eps = os.path.join('PS', '%s.eps' % g)
+                    env.Command(eps, fig, "%s -L eps $SOURCES $TARGET" % fig2dev)
+                    env.Depends(ps, eps)
+
+        if docs[doc].get('pdf'):
+            env.Command(pdf, main, [
+                "rm -f ${TARGET.dir}/%s" % out,
+                "jw -b pdf -o ${TARGET.dir} $SOURCES",
+                "mv ${TARGET.dir}/main.pdf $TARGET",
+                "rm -f ${TARGET.dir}/out",
+            ])
+            tar_deps.append(pdf)
+            tar_list = tar_list + " " + pdf
+
+        if docs[doc].get('text') and lynx:
+            env.Command(text, html, "lynx -dump ${SOURCE.abspath} > $TARGET")
+            tar_deps.append(text)
+            tar_list = tar_list + " " + text
+
+#
+# Man page(s), in good ol' troff format.
+#
+scons_1 = os.path.join('man', 'scons.1')
+
+if groff:
+    ps = os.path.join('PS', 'scons-man.ps')
+    text = os.path.join('TEXT', 'scons-man.txt')
+
+    env.Command(ps, scons_1, "groff -man -Tps $SOURCES > $TARGET")
+
+    env.Command(text, scons_1, "groff -man -Tascii $SOURCES > $TARGET")
+
+    tar_deps.extend([ps, text])
+    tar_list = string.join([tar_list, ps, text], " ")
+
+if man2html:
+    html = os.path.join('HTML' , 'scons-man.html')
+
+    env.Command(html, scons_1, "man2html $SOURCES > $TARGET")
+
+    tar_deps.append(html)
+    tar_list = tar_list + " " + html
+
+#
+# Now actually create the tar file of the documentation,
+# for easy distribution to the web site.
+#
+env.Command(doc_tar_gz, tar_deps,
+            "tar zchv -f $TARGET -C build/doc %s" % tar_list)
index 872e8be6e9942e161ac8e755ffe84cc06cb8e389..877ac53464660bf36b4cb09a5d3d8240b4dcb964 100644 (file)
@@ -1,3 +1,4 @@
 *,D
 .*.swp
 .consign
+.sconsign
index 872e8be6e9942e161ac8e755ffe84cc06cb8e389..877ac53464660bf36b4cb09a5d3d8240b4dcb964 100644 (file)
@@ -1,3 +1,4 @@
 *,D
 .*.swp
 .consign
+.sconsign
index 872e8be6e9942e161ac8e755ffe84cc06cb8e389..877ac53464660bf36b4cb09a5d3d8240b4dcb964 100644 (file)
@@ -1,3 +1,4 @@
 *,D
 .*.swp
 .consign
+.sconsign
index 43fe8513cbf8871225990fe1dbb2825a2acc43a1..22ebd62bf83a67acc5060db396a28fd9b12ea99f 100644 (file)
@@ -2,3 +2,4 @@
 *.pyc
 .*.swp
 .consign
+.sconsign
diff --git a/etc/SConscript b/etc/SConscript
new file mode 100644 (file)
index 0000000..a613bda
--- /dev/null
@@ -0,0 +1,45 @@
+#
+# SConscript for installing auxiliary modules, external stuff that
+# we keep checked in so everyone doesn't have to install a bunch
+# of stuff to work on SCons.
+#
+# THIS IS NOT READY YET.  DO NOT TRY TO BUILD SCons WITH ITSELF YET.
+#
+
+#
+# Copyright (c) 2001 Steven Knight
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+import os.path
+
+Import('env')
+
+modules = [ 'TestCmd.py', 'TestSCons.py', 'unittest.py' ]
+
+directories = [
+    env.Dictionary('TEST1_LIB_DIR'),
+    env.Dictionary('TEST2_LIB_DIR')
+]
+
+for module in modules:
+    for dir in directories:
+        env.Command(os.path.join(dir, module), module, "$SEDCOM")
index 872e8be6e9942e161ac8e755ffe84cc06cb8e389..877ac53464660bf36b4cb09a5d3d8240b4dcb964 100644 (file)
@@ -1,3 +1,4 @@
 *,D
 .*.swp
 .consign
+.sconsign
index 43fe8513cbf8871225990fe1dbb2825a2acc43a1..22ebd62bf83a67acc5060db396a28fd9b12ea99f 100644 (file)
@@ -2,3 +2,4 @@
 *.pyc
 .*.swp
 .consign
+.sconsign
index 43fe8513cbf8871225990fe1dbb2825a2acc43a1..22ebd62bf83a67acc5060db396a28fd9b12ea99f 100644 (file)
@@ -2,3 +2,4 @@
 *.pyc
 .*.swp
 .consign
+.sconsign
index 43fe8513cbf8871225990fe1dbb2825a2acc43a1..22ebd62bf83a67acc5060db396a28fd9b12ea99f 100644 (file)
@@ -2,3 +2,4 @@
 *.pyc
 .*.swp
 .consign
+.sconsign
index 43fe8513cbf8871225990fe1dbb2825a2acc43a1..22ebd62bf83a67acc5060db396a28fd9b12ea99f 100644 (file)
@@ -2,3 +2,4 @@
 *.pyc
 .*.swp
 .consign
+.sconsign
index 43fe8513cbf8871225990fe1dbb2825a2acc43a1..22ebd62bf83a67acc5060db396a28fd9b12ea99f 100644 (file)
@@ -2,3 +2,4 @@
 *.pyc
 .*.swp
 .consign
+.sconsign
index 43fe8513cbf8871225990fe1dbb2825a2acc43a1..22ebd62bf83a67acc5060db396a28fd9b12ea99f 100644 (file)
@@ -2,3 +2,4 @@
 *.pyc
 .*.swp
 .consign
+.sconsign
index 43fe8513cbf8871225990fe1dbb2825a2acc43a1..22ebd62bf83a67acc5060db396a28fd9b12ea99f 100644 (file)
@@ -2,3 +2,4 @@
 *.pyc
 .*.swp
 .consign
+.sconsign
index 06d4a253d2a287f8b24218f435c7dfcdad1f787d..e232fd0a7278e3cfee770d93a4fc5fd94e33df90 100644 (file)
@@ -1,2 +1,3 @@
 *,D
 .consign
+.sconsign
index 872e8be6e9942e161ac8e755ffe84cc06cb8e389..877ac53464660bf36b4cb09a5d3d8240b4dcb964 100644 (file)
@@ -1,3 +1,4 @@
 *,D
 .*.swp
 .consign
+.sconsign