This class is an instance of the Null object pattern.
"""
def __init__(self):
- self.abspath = ""
self.duplicate = 1
- self.path = ""
- self.srcpath = ""
- self.abspath_=''
- self.path_=''
- self.srcpath_=''
+ self.abspath = ''
+ self.path = ''
+ self.srcpath = ''
+ self.abspath_ = ''
+ self.path_ = ''
+ self.srcpath_ = ''
def is_under(self, dir):
return 0
drive, path_first = os.path.splitdrive(path_comp[0])
if not path_first:
# Absolute path
- drive = _my_normcase(drive)
+ drive_path = _my_normcase(drive)
try:
- directory = self.Root[drive]
+ directory = self.Root[drive_path]
except KeyError:
if not create:
raise UserError
dir.path = dir.path + os.sep
dir.abspath = dir.abspath + os.sep
dir.srcpath = dir.srcpath + os.sep
- self.Root[drive] = dir
+ self.Root[drive_path] = dir
directory = dir
path_comp = path_comp[1:]
else:
n = func(None, path)
if n:
return n
- for dir in self.Repositories:
- n = func(dir.path, path)
+ for rep in self.Repositories:
+ n = func(rep.path, path)
if n:
return n
return None
if not os.path.isabs(path):
if path[0] == '#':
path = path[1:]
- for dir in self.Repositories:
- n = func(dir.path, path)
+ for rep in self.Repositories:
+ n = func(rep.path, path)
if n:
ret.append(n)
return ret
# XXX TODO?
# Annotate with the creator
# rel_path
-# srcpath / srcdir
-# link / is_linked
# linked_targets
# is_accessible
# XXX TODO?
-# rsrcpath
-# source_exists
-# derived_exists
-# is_on_rpath
# base_suf
# suffix
# addsuffix
# accessible
-# ignore
-# bind
# relpath
class File(Entry):
return Entry.exists(self)
def rexists(self):
- if self.duplicate and not self.created:
- self.created = 1
- if self.srcpath != self.path and \
- os.path.exists(self.srcpath):
- if os.path.exists(self.path):
- os.unlink(self.path)
- self.__createDir()
- file_link(self.srcpath, self.path)
- return Entry.rexists(self)
+ if self.path != self.srcpath:
+ if os.path.exists(self.srcpath):
+ if self.duplicate and not self.created:
+ self.created = 1
+ if os.path.exists(self.path):
+ os.unlink(self.path)
+ self.__createDir()
+ file_link(self.srcpath, self.path)
+ return 1
+ for rep in self.fs.Repositories:
+ if not os.path.isabs(self.path):
+ f = os.path.join(rep.path, self.path)
+ if os.path.exists(f):
+ return 1
+ f = os.path.join(rep.path, self.srcpath)
+ if os.path.exists(f):
+ if self.duplicate and not self.created:
+ self.created = 1
+ if os.path.exists(self.path):
+ os.unlink(self.path)
+ self.__createDir()
+ file_link(f, self.path)
+ else:
+ self.srcpath = f
+ self.srcpath_ = f + os.sep
+ return 1
+ return None
+ else:
+ return Entry.rexists(self)
def scanner_key(self):
return os.path.splitext(self.name)[1]
--- /dev/null
+#!/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', ['repository', 'src'],
+ 'work1', ['work1', 'src'],
+ 'work2', ['work2', 'src'])
+
+opts = "-Y " + test.workpath('repository')
+
+#
+test.write(['repository', 'SConstruct'], r"""
+BuildDir('build0', 'src', duplicate=0)
+BuildDir('build1', 'src', duplicate=1)
+SConscript('build0/SConscript')
+SConscript('build1/SConscript')
+""")
+
+test.write(['repository', 'src', 'SConscript'], r"""
+def cat(env, source, target):
+ target = str(target[0])
+ source = map(str, source)
+ print 'cat(%s) > %s' % (source, target)
+ f = open(target, "wb")
+ for src in source:
+ f.write(open(src, "rb").read())
+ f.close()
+
+env = Environment(BUILDERS={'Build':Builder(action=cat)})
+env.Build('aaa.mid', 'aaa.in')
+env.Build('bbb.mid', 'bbb.in')
+env.Build('ccc.mid', 'ccc.in')
+env.Build('output', ['aaa.mid', 'bbb.mid', 'ccc.mid'])
+""")
+
+test.write(['repository', 'src', 'aaa.in'], "repository/src/aaa.in\n")
+test.write(['repository', 'src', 'bbb.in'], "repository/src/bbb.in\n")
+test.write(['repository', 'src', 'ccc.in'], "repository/src/ccc.in\n")
+
+# Make the entire repository non-writable, so we'll detect
+# if we try to write into it accidentally.
+test.writable('repository', 0)
+
+#
+test.run(chdir = 'work1', options = opts, arguments = '.')
+
+test.fail_test(test.read(['work1', 'build0', 'output']) !=
+"""repository/src/aaa.in
+repository/src/bbb.in
+repository/src/ccc.in
+""")
+
+test.fail_test(os.path.exists('work1/build0/aaa.in'))
+test.fail_test(os.path.exists('work1/build0/bbb.in'))
+test.fail_test(os.path.exists('work1/build0/ccc.in'))
+test.fail_test(not os.path.exists('work1/build0/aaa.mid'))
+test.fail_test(not os.path.exists('work1/build0/bbb.mid'))
+test.fail_test(not os.path.exists('work1/build0/ccc.mid'))
+
+test.fail_test(test.read(['work1', 'build1', 'output']) !=
+"""repository/src/aaa.in
+repository/src/bbb.in
+repository/src/ccc.in
+""")
+
+test.fail_test(not os.path.exists('work1/build1/aaa.in'))
+test.fail_test(not os.path.exists('work1/build1/bbb.in'))
+test.fail_test(not os.path.exists('work1/build1/ccc.in'))
+test.fail_test(not os.path.exists('work1/build1/aaa.mid'))
+test.fail_test(not os.path.exists('work1/build1/bbb.mid'))
+test.fail_test(not os.path.exists('work1/build1/ccc.mid'))
+
+test.up_to_date(chdir = 'work1', options = opts, arguments = '.')
+
+#
+test.write(['work1', 'src', 'bbb.in'], "work1/src/bbb.in\n")
+
+test.run(chdir = 'work1', options = opts, arguments = '.')
+
+test.fail_test(test.read(['work1', 'build0', 'output']) !=
+"""repository/src/aaa.in
+work1/src/bbb.in
+repository/src/ccc.in
+""")
+
+test.fail_test(os.path.exists('work1/build0/aaa.in'))
+test.fail_test(os.path.exists('work1/build0/bbb.in'))
+test.fail_test(os.path.exists('work1/build0/ccc.in'))
+test.fail_test(not os.path.exists('work1/build0/aaa.mid'))
+test.fail_test(not os.path.exists('work1/build0/bbb.mid'))
+test.fail_test(not os.path.exists('work1/build0/ccc.mid'))
+
+test.fail_test(test.read(['work1', 'build1', 'output']) !=
+"""repository/src/aaa.in
+work1/src/bbb.in
+repository/src/ccc.in
+""")
+
+test.fail_test(not os.path.exists('work1/build1/aaa.in'))
+test.fail_test(not os.path.exists('work1/build1/bbb.in'))
+test.fail_test(not os.path.exists('work1/build1/ccc.in'))
+test.fail_test(not os.path.exists('work1/build1/aaa.mid'))
+test.fail_test(not os.path.exists('work1/build1/bbb.mid'))
+test.fail_test(not os.path.exists('work1/build1/ccc.mid'))
+
+test.up_to_date(chdir = 'work1', options = opts, arguments = '.')
+
+# Now build the stuff in the repository,
+# and redo the above steps in a fresh work directory.
+test.writable('repository', 1)
+
+test.run(chdir = 'repository', arguments = '.')
+
+test.writable('repository', 0)
+
+#
+test.run(chdir = 'work2', options = opts, arguments = '.')
+
+test.fail_test(os.path.exists('work2/build0/aaa.in'))
+test.fail_test(os.path.exists('work2/build0/bbb.in'))
+test.fail_test(os.path.exists('work2/build0/ccc.in'))
+test.fail_test(os.path.exists('work2/build0/aaa.mid'))
+test.fail_test(os.path.exists('work2/build0/bbb.mid'))
+test.fail_test(os.path.exists('work2/build0/ccc.mid'))
+test.fail_test(os.path.exists('work2/build0/output'))
+
+test.fail_test(os.path.exists('work2/build1/aaa.in'))
+test.fail_test(os.path.exists('work2/build1/bbb.in'))
+test.fail_test(os.path.exists('work2/build1/ccc.in'))
+test.fail_test(os.path.exists('work2/build1/aaa.mid'))
+test.fail_test(os.path.exists('work2/build1/bbb.mid'))
+test.fail_test(os.path.exists('work2/build1/ccc.mid'))
+test.fail_test(os.path.exists('work2/build1/output'))
+
+test.up_to_date(chdir = 'work2', options = opts, arguments = '.')
+
+#
+test.write(['work2', 'src', 'bbb.in'], "work2/src/bbb.in\n")
+
+test.run(chdir = 'work2', options = opts, arguments = '.')
+
+test.fail_test(test.read(['work2', 'build0', 'output']) !=
+"""repository/src/aaa.in
+work2/src/bbb.in
+repository/src/ccc.in
+""")
+
+test.fail_test(os.path.exists('work2/build0/aaa.in'))
+test.fail_test(os.path.exists('work2/build0/bbb.in'))
+test.fail_test(os.path.exists('work2/build0/ccc.in'))
+test.fail_test(os.path.exists('work2/build0/aaa.mid'))
+test.fail_test(not os.path.exists('work2/build0/bbb.mid'))
+test.fail_test(os.path.exists('work2/build0/ccc.mid'))
+
+test.fail_test(test.read(['work2', 'build1', 'output']) !=
+"""repository/src/aaa.in
+work2/src/bbb.in
+repository/src/ccc.in
+""")
+
+test.fail_test(os.path.exists('work2/build1/aaa.in'))
+test.fail_test(not os.path.exists('work2/build1/bbb.in'))
+test.fail_test(os.path.exists('work2/build1/ccc.in'))
+test.fail_test(os.path.exists('work2/build1/aaa.mid'))
+test.fail_test(not os.path.exists('work2/build1/bbb.mid'))
+test.fail_test(os.path.exists('work2/build1/ccc.mid'))
+
+test.up_to_date(chdir = 'work2', options = opts, arguments = '.')
+
+#
+test.pass_test()