Add a TAR Builder.
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Mon, 8 Jul 2002 22:40:59 +0000 (22:40 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Mon, 8 Jul 2002 22:40:59 +0000 (22:40 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@405 fdb21ef1-2011-0410-befe-b5e4ea1792b1

12 files changed:
doc/man/scons.1
rpm/scons.spec
src/CHANGES.txt
src/engine/MANIFEST.in
src/engine/SCons/Node/FS.py
src/engine/SCons/Node/FSTests.py
src/engine/SCons/Platform/cygwin.py
src/engine/SCons/Platform/posix.py
src/engine/SCons/Platform/win32.py
src/engine/SCons/Tool/tar.py [new file with mode: 0644]
test/TAR.py [new file with mode: 0644]
test/TARFLAGS.py [new file with mode: 0644]

index f606adb74f2ec8657e44b364ad7fd4e2dabe645e..e6f6d0c3e963b2cadf434eb07971a79ce7dbd673 100644 (file)
@@ -718,6 +718,7 @@ lex
 nasm (if the GNU assembler is not available)
 pdflatex
 pdftex
+tar
 tex
 yacc
 .EE
@@ -739,6 +740,7 @@ masm
 nasm
 pdflatex
 pdftex
+tar
 tex
 yacc
 .EE
@@ -1824,6 +1826,15 @@ The linker for programs that use shared libraries.
 .IP SHLINKFLAGS
 General options passed to the linker for programs using shared libraries.
 
+.IP TAR
+The tar archiver.
+
+.IP TARCOM
+The command line used to call the tar archiver.
+
+.IP TARFLAGS
+General options passed to the tar archiver.
+
 .IP TEX
 The TeX formatter and typesetter.
 
index 6dbec21450274c5e6e5901f78d13f710f10d4dca..999605012439e8cebe70b859f2eeda0a6da5ef52 100644 (file)
@@ -132,6 +132,8 @@ rm -rf $RPM_BUILD_ROOT
 /usr/lib/scons/SCons/Tool/pdflatex.pyc
 /usr/lib/scons/SCons/Tool/pdftex.py
 /usr/lib/scons/SCons/Tool/pdftex.pyc
+/usr/lib/scons/SCons/Tool/tar.py
+/usr/lib/scons/SCons/Tool/tar.pyc
 /usr/lib/scons/SCons/Tool/tex.py
 /usr/lib/scons/SCons/Tool/tex.pyc
 /usr/lib/scons/SCons/Tool/yacc.py
index 6779ddd13ec8846296f7bf01591684968dbaa82f..69e706373988e7eeb30e21b38a4849c25668bc19 100644 (file)
@@ -75,6 +75,8 @@ RELEASE 0.08 -
     which case the target(s) are deduced from the source file(s) and the
     Builder's specified suffix.
 
+  - Add a tar archive builder.
+
   From Jeff Petkau:
 
   - Fix --implicit-cache if the scanner returns an empty list.
index 9a057876648d2ca0335954ae66977afc453a03a3..0f81470be5203df296cfde80f03d749d5bafad42 100644 (file)
@@ -41,6 +41,7 @@ SCons/Tool/msvc.py
 SCons/Tool/nasm.py
 SCons/Tool/pdflatex.py
 SCons/Tool/pdftex.py
+SCons/Tool/tar.py
 SCons/Tool/tex.py
 SCons/Tool/yacc.py
 SCons/Util.py
index 7c303339ef45656929dd627472aa5d87a338d0d0..a04790315d04eebb481b49f9f65ae8eb5b90b5ef 100644 (file)
@@ -355,6 +355,22 @@ class Entry(SCons.Node.Node):
         else:
             return self.srcpath
 
+    def get_contents(self):
+        """Fetch the contents of the entry.
+        
+        Since this should return the real contents from the file
+        system, we check to see into what sort of subclass we should
+        morph this Entry."""
+        if os.path.isfile(self.abspath):
+            self.__class__ = File
+            self._morph()
+            return File.get_contents(self)
+        if os.path.isdir(self.abspath):
+            self.__class__ = Dir
+            self._morph()
+            return Dir.get_contents(self)
+        raise AttributeError
+
     def exists(self):
         return os.path.exists(str(self))
 
@@ -477,6 +493,10 @@ class Dir(Entry):
         """A directory has no signature."""
         pass
 
+    def get_contents(self):
+        """Return a fixed "contents" value of a directory."""
+        return ''
+
     def current(self):
         """If all of our children were up-to-date, then this
         directory was up-to-date, too."""
index ee825637243f4d15d5d004d1ab9748119d9a40c6..6151f2d3599d1507960597b69952a39801b42bf6 100644 (file)
@@ -479,7 +479,27 @@ class FSTestCase(unittest.TestCase):
 
         #XXX test root()
 
-        #XXX test get_contents()
+        # test Entry.get_contents()
+        e = fs.Entry('does_not_exist')
+        exc_caught = 0
+        try:
+            e.get_contents()
+        except AttributeError:
+            exc_caught = 1
+        assert exc_caught, "Should have caught an AttributError"
+
+        test.write("file", "file\n")
+        e = fs.Entry('file')
+        c = e.get_contents()
+        assert c == "file\n", c
+        assert e.__class__ == SCons.Node.FS.File
+        test.unlink("file")
+
+        test.subdir("dir")
+        e = fs.Entry('dir')
+        c = e.get_contents()
+        assert c == "", c
+        assert e.__class__ == SCons.Node.FS.Dir
 
         #XXX test get_timestamp()
 
index 8858dd1b6f204c624a944c394be769a70555a4c0..b5a73f6f7e16f98673a23b1a5b9e700c923b7258 100644 (file)
@@ -44,7 +44,7 @@ def tool_list():
     return ['ar', 'dvipdf', 'dvips',
             'g++', 'g77', 'gcc', 'gnulink',
             'latex', 'lex',
-            'pdflatex', 'pdftex', 'tex', 'yacc',
+            'pdflatex', 'pdftex', 'tar', 'tex', 'yacc',
             assembler]
 
 def generate(env):
index 79adebd53497140e95dec7d2551b19e51de6d54e..a45dce1d4636df638a5699e149c3a9fc7f9ba2e2 100644 (file)
@@ -44,7 +44,7 @@ def tool_list():
     return ['ar', 'dvipdf', 'dvips',
             'g++', 'g77', 'gcc', 'gnulink',
             'latex', 'lex',
-            'pdflatex', 'pdftex', 'tex', 'yacc',
+            'pdflatex', 'pdftex', 'tar', 'tex', 'yacc',
             assembler]
 
 def generate(env):
index 957aead8442040b842fd019ab8121fedfc2a5b07..121fed66c0b9c276e048b50e19f462f14bb5296b 100644 (file)
@@ -43,7 +43,7 @@ def tool_list():
         assembler = 'masm'
     return ['dvipdf', 'dvips', 'g77',
             'latex', 'lex', 'lib', 'mslink', 'msvc',
-            'pdflatex', 'pdftex', 'tex', 'yacc',
+            'pdflatex', 'pdftex', 'tar', 'tex', 'yacc',
             assembler]
 
 def generate(env):
diff --git a/src/engine/SCons/Tool/tar.py b/src/engine/SCons/Tool/tar.py
new file mode 100644 (file)
index 0000000..fff9dff
--- /dev/null
@@ -0,0 +1,55 @@
+"""SCons.Tool.tar
+
+Tool-specific initialization for tar.
+
+There normally shouldn't be any need to import this module directly.
+It will usually be imported through the generic SCons.Tool.Tool()
+selection method.
+
+"""
+
+#
+# Copyright (c) 2001, 2002 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.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import SCons.Builder
+import SCons.Node.FS
+
+TarBuilder = SCons.Builder.Builder(action = '$TARCOM',
+                                   source_factory = SCons.Node.FS.default_fs.Entry,
+                                  suffix = '$TARSUFFIX',
+                                   multi = 1)
+
+def generate(env, platform):
+    """Add Builders and construction variables for tar to an Environment."""
+    try:
+        bld = env['BUILDERS']['Tar']
+    except KeyError:
+        bld = TarBuilder
+        env['BUILDERS']['Tar'] = bld
+
+    env['TAR']        = 'tar'
+    env['TARFLAGS']   = '-c'
+    env['TARCOM']     = '$TAR $TARFLAGS -f $TARGET $SOURCES'
+    env['TARSUFFIX']  = '.tar'
diff --git a/test/TAR.py b/test/TAR.py
new file mode 100644 (file)
index 0000000..0327ca9
--- /dev/null
@@ -0,0 +1,132 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2001, 2002 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.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import os
+import os.path
+import string
+import sys
+import TestSCons
+
+python = sys.executable
+
+test = TestSCons.TestSCons()
+
+test.subdir('sub1')
+
+test.write('mytar.py', r"""
+import getopt
+import os
+import os.path
+import sys
+opts, args = getopt.getopt(sys.argv[1:], 'cf:')
+for opt, arg in opts:
+    if opt == '-f': out = arg
+def process(outfile, name):
+    if os.path.isdir(name):
+        for entry in os.listdir(name):
+           process(outfile, os.path.join(name, entry))
+    else:
+        outfile.write(open(name, 'rb').read())
+outfile = open(out, 'wb')
+for infile in args:
+    process(outfile, infile)
+outfile.close()
+sys.exit(0)
+""")
+
+test.write('SConstruct', """
+env = Environment(TAR = r'%s mytar.py')
+env.Tar(target = 'aaa.tar', source = ['file1', 'file2'])
+env.Tar(target = 'aaa.tar', source = 'file3')
+env.Tar(target = 'bbb', source = 'sub1')
+env.Tar(target = 'bbb', source = 'file4')
+""" % python)
+
+test.write('file1', "file1\n")
+test.write('file2', "file2\n")
+test.write('file3', "file3\n")
+test.write('file4', "file4\n")
+
+test.write(['sub1', 'file5'], "sub1/file5\n")
+test.write(['sub1', 'file6'], "sub1/file6\n")
+
+test.run(arguments = 'aaa.tar', stderr = None)
+
+test.fail_test(test.read('aaa.tar') != "file1\nfile2\nfile3\n")
+
+test.run(arguments = 'bbb.tar', stderr = None)
+
+test.fail_test(test.read('bbb.tar') != "sub1/file5\nsub1/file6\nfile4\n")
+
+
+
+tar = test.where_is('tar')
+
+if tar:
+
+    test.write("wrapper.py", """import os
+import string
+import sys
+open('%s', 'wb').write("wrapper.py\\n")
+os.system(string.join(sys.argv[1:], " "))
+""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+
+    test.write('SConstruct', """
+foo = Environment()
+tar = foo.Dictionary('TAR')
+bar = Environment(TAR = r'%s wrapper.py ' + tar)
+foo.Tar(target = 'foo.tar', source = ['file10', 'file11'])
+foo.Tar(target = 'foo.tar', source = 'file12')
+bar.Tar(target = 'bar.tar', source = ['file13', 'file14'])
+bar.Tar(target = 'bar.tar', source = 'file15')
+""" % python)
+
+    test.write('file10', "file10\n")
+    test.write('file11', "file11\n")
+    test.write('file12', "file12\n")
+    test.write('file13', "file13\n")
+    test.write('file14', "file14\n")
+    test.write('file15', "file15\n")
+
+    test.run(arguments = 'foo.tar', stderr = None)
+
+    test.fail_test(os.path.exists(test.workpath('wrapper.out')))
+
+    test.fail_test(not os.path.exists(test.workpath('foo.tar')))
+
+    test.run(arguments = 'bar.tar', stderr = None)
+
+    test.fail_test(not os.path.exists(test.workpath('wrapper.out')))
+
+    test.fail_test(not os.path.exists(test.workpath('bar.tar')))
+
+    test.run(program = tar, arguments = "-t -f foo.tar")
+    test.fail_test(test.stdout() != "file10\nfile11\nfile12\n")
+
+    test.run(program = tar, arguments = "-t -f bar.tar")
+    test.fail_test(test.stdout() != "file13\nfile14\nfile15\n")
+
+test.pass_test()
diff --git a/test/TARFLAGS.py b/test/TARFLAGS.py
new file mode 100644 (file)
index 0000000..4701f35
--- /dev/null
@@ -0,0 +1,136 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2001, 2002 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.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import os
+import os.path
+import string
+import sys
+import TestSCons
+
+python = sys.executable
+
+test = TestSCons.TestSCons()
+
+test.subdir('sub1')
+
+test.write('mytar.py', """
+import getopt
+import os
+import os.path
+import string
+import sys
+cmd_opts, args = getopt.getopt(sys.argv[1:], 'cf:x', [])
+opt_string = ''
+for opt, arg in cmd_opts:
+    if opt == '-f': out = arg
+    else: opt_string = opt_string + ' ' + opt
+def process(outfile, name):
+    if os.path.isdir(name):
+        for entry in os.listdir(name):
+           process(outfile, os.path.join(name, entry))
+    else:
+        outfile.write(open(name, 'rb').read())
+outfile = open(out, 'wb')
+outfile.write('options: %s\\n' % opt_string)
+for infile in args:
+    process(outfile, infile)
+outfile.close()
+sys.exit(0)
+""")
+
+test.write('SConstruct', """
+env = Environment(TAR = r'%s mytar.py', TARFLAGS = '-x')
+env.Tar(target = 'aaa.tar', source = ['file1', 'file2'])
+env.Tar(target = 'aaa.tar', source = 'file3')
+env.Tar(target = 'bbb', source = 'sub1')
+env.Tar(target = 'bbb', source = 'file4')
+""" % python)
+
+test.write('file1', "file1\n")
+test.write('file2', "file2\n")
+test.write('file3', "file3\n")
+test.write('file4', "file4\n")
+
+test.write(['sub1', 'file5'], "sub1/file5\n")
+test.write(['sub1', 'file6'], "sub1/file6\n")
+
+test.run(arguments = 'aaa.tar', stderr = None)
+
+test.fail_test(test.read('aaa.tar') != "options:  -x\nfile1\nfile2\nfile3\n")
+
+test.run(arguments = 'bbb.tar', stderr = None)
+
+test.fail_test(test.read('bbb.tar') != "options:  -x\nsub1/file5\nsub1/file6\nfile4\n")
+
+
+
+tar = test.where_is('tar')
+
+if tar:
+
+    test.write("wrapper.py", """import os
+import string
+import sys
+open('%s', 'wb').write("wrapper.py\\n")
+os.system(string.join(sys.argv[1:], " "))
+""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+
+    test.write('SConstruct', """
+foo = Environment()
+tar = foo['TAR']
+bar = Environment(TAR = '', TARFLAGS = '%s wrapper.py ' + tar + ' -c -b 1')
+foo.Tar(target = 'foo.tar', source = ['file10', 'file11'])
+foo.Tar(target = 'foo.tar', source = 'file12')
+bar.Tar(target = 'bar.tar', source = ['file13', 'file14'])
+bar.Tar(target = 'bar.tar', source = 'file15')
+""" % python)
+
+    test.write('file10', "file10\n")
+    test.write('file11', "file11\n")
+    test.write('file12', "file12\n")
+    test.write('file13', "file13\n")
+    test.write('file14', "file14\n")
+    test.write('file15', "file15\n")
+
+    test.run(arguments = 'foo.tar', stderr = None)
+
+    test.fail_test(os.path.exists(test.workpath('wrapper.out')))
+
+    test.fail_test(not os.path.exists(test.workpath('foo.tar')))
+
+    test.run(arguments = 'bar.tar', stderr = None)
+
+    test.fail_test(not os.path.exists(test.workpath('wrapper.out')))
+
+    test.fail_test(not os.path.exists(test.workpath('bar.tar')))
+
+    test.run(program = tar, arguments = "-t -f foo.tar")
+    test.fail_test(test.stdout() != "file10\nfile11\nfile12\n")
+
+    test.run(program = tar, arguments = "-t -f bar.tar", stderr = None)
+    test.fail_test(test.stdout() != "file13\nfile14\nfile15\n")
+
+test.pass_test()