Add Local() functionality to Repository support.
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Tue, 6 Aug 2002 05:10:28 +0000 (05:10 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Tue, 6 Aug 2002 05:10:28 +0000 (05:10 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@431 fdb21ef1-2011-0410-befe-b5e4ea1792b1

src/engine/SCons/Node/FS.py
src/engine/SCons/Script/SConscript.py
test/Repository/Local.py [new file with mode: 0644]

index 8bdfeb65b23ffb031fb9a80a1e1a1a382a1f19f7..1433f2097873976d0816e13ec0935d9f4564e85a 100644 (file)
@@ -388,6 +388,7 @@ class Entry(SCons.Node.Node):
         self.__doSrcpath(self.duplicate)
         self.srcpath_ = self.srcpath
         self.cwd = None # will hold the SConscript directory for target nodes
+        self._local = None
 
     def get_dir(self):
         return self.dir
@@ -460,6 +461,9 @@ class Entry(SCons.Node.Node):
         else:
             return self.dir.is_under(dir)
 
+    def set_local(self):
+        self._local = 1
+
 
 
 # XXX TODO?
@@ -606,7 +610,6 @@ class Dir(Entry):
 # source_exists
 # derived_exists
 # is_on_rpath
-# local
 # base_suf
 # suffix
 # addsuffix
@@ -758,8 +761,10 @@ class File(Entry):
             if r != self:
                 # ...but there is one in a Repository...
                 if calc.current(r, bsig):
-                    # ...and it's even up-to-date.
-                    # XXX Future: copy locally if requested
+                    # ...and it's even up-to-date...
+                    if self._local:
+                        # ...and they'd like a local copy.
+                        file_link(r.path, self.path)
                     return 1
             self._rfile = self
             return None
index 38fd080e13d63c5bf70d6876ec1618b36d345eb9..a1412975f95e0595663d316eacdfbb1c1e83634d 100644 (file)
@@ -206,6 +206,14 @@ def Default(*targets):
             default_targets.extend(SCons.Node.arg2nodes(t,
                                          SCons.Node.FS.default_fs.Entry))
 
+def Local(*targets):
+    for targ in targets:
+        if isinstance(targ, SCons.Node.Node):
+            targ.set_local()
+        else:
+            for t in SCons.Node.arg2nodes(targ, SCons.Node.FS.default_fs.Entry):
+               t.set_local()
+
 def Help(text):
     if print_help:
         print text
@@ -280,6 +288,7 @@ def BuildDefaultGlobals():
     globals['Help']              = Help
     globals['Import']            = Import
     globals['Library']           = SCons.Defaults.StaticLibrary
+    globals['Local']             = Local
     globals['Object']            = SCons.Defaults.StaticObject
     globals['Repository']        = SCons.Node.FS.default_fs.Repository
     globals['SetBuildSignatureType'] = SetBuildSignatureType
diff --git a/test/Repository/Local.py b/test/Repository/Local.py
new file mode 100644 (file)
index 0000000..67f43cf
--- /dev/null
@@ -0,0 +1,84 @@
+#!/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.path
+import sys
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.subdir('repository', 'work')
+
+work_aaa_mid = test.workpath('work', 'aaa.mid')
+work_aaa_out = test.workpath('work', 'aaa.out')
+
+opts = "-Y " + test.workpath('repository')
+
+#
+test.write(['repository', 'SConstruct'], r"""
+def copy(env, source, target):
+    source = str(source[0])
+    target = str(target[0])
+    print 'copy() < %s > %s' % (source, target)
+    open(target, "wb").write(open(source, "rb").read())
+
+Build = Builder(action=copy)
+env = Environment(BUILDERS={'Build':Build})
+env.Build('aaa.mid', 'aaa.in')
+env.Build('aaa.out', 'aaa.mid')
+Local('aaa.out')
+""")
+
+test.write(['repository', 'aaa.in'], "repository/aaa.in\n")
+
+#
+test.run(chdir = 'repository', options = opts, arguments = '.')
+
+# Make the entire repository non-writable, so we'll detect
+# if we try to write into it accidentally.
+test.writable('repository', 0)
+
+test.up_to_date(chdir = 'repository', options = opts, arguments = '.')
+
+#
+test.run(chdir = 'work', options = opts, arguments = '.')
+
+test.fail_test(os.path.exists(work_aaa_mid))
+test.fail_test(test.read(work_aaa_out) != "repository/aaa.in\n")
+
+#
+test.write(['work', 'aaa.in'], "work/aaa.in\n")
+
+#
+test.run(chdir = 'work', options = opts, arguments = '.')
+
+test.fail_test(test.read(work_aaa_mid) != "work/aaa.in\n")
+test.fail_test(test.read(work_aaa_out) != "work/aaa.in\n")
+
+test.up_to_date(chdir = 'work', options = opts, arguments = '.')
+
+#
+test.pass_test()