summaryrefslogtreecommitdiffstats
path: root/src/engine
diff options
context:
space:
mode:
authorSteven Knight <knight@baldmt.com>2005-06-10 11:59:43 (GMT)
committerSteven Knight <knight@baldmt.com>2005-06-10 11:59:43 (GMT)
commit0462645d5027fcf4286775d88d2f6fb52abad3b1 (patch)
treecc587623d5579d9c08eddfeaa1edd9efd697ec3e /src/engine
parentae6191eaaba20e630d4ea34d701bf14ebedee303 (diff)
downloadSCons-0462645d5027fcf4286775d88d2f6fb52abad3b1.zip
SCons-0462645d5027fcf4286775d88d2f6fb52abad3b1.tar.gz
SCons-0462645d5027fcf4286775d88d2f6fb52abad3b1.tar.bz2
Add a --diskcheck option to control looking on-disk for things.
Diffstat (limited to 'src/engine')
-rw-r--r--src/engine/SCons/Node/FS.py116
-rw-r--r--src/engine/SCons/Script/Main.py44
2 files changed, 128 insertions, 32 deletions
diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py
index 3b4e77f..a1cadf0 100644
--- a/src/engine/SCons/Node/FS.py
+++ b/src/engine/SCons/Node/FS.py
@@ -288,6 +288,65 @@ else:
def _my_normcase(x):
return string.upper(x)
+
+
+class DiskChecker:
+ def __init__(self, type, do, ignore):
+ self.type = type
+ self.do = do
+ self.ignore = ignore
+ self.set_do()
+ def set_do(self):
+ self.__call__ = self.do
+ def set_ignore(self):
+ self.__call__ = self.ignore
+ def set(self, list):
+ if self.type in list:
+ self.set_do()
+ else:
+ self.set_ignore()
+
+def do_diskcheck_match(node, predicate, errorfmt):
+ path = node.abspath
+ if predicate(path):
+ raise TypeError, errorfmt % path
+
+def ignore_diskcheck_match(node, predicate, errorfmt):
+ pass
+
+def do_diskcheck_rcs(node, name):
+ rcspath = 'RCS' + os.sep + name+',v'
+ return node.entry_exists_on_disk(rcspath)
+
+def ignore_diskcheck_rcs(node, name):
+ return None
+
+def do_diskcheck_sccs(node, name):
+ sccspath = 'SCCS' + os.sep + 's.'+name
+ return node.entry_exists_on_disk(sccspath)
+
+def ignore_diskcheck_sccs(node, name):
+ return None
+
+diskcheck_match = DiskChecker('match', do_diskcheck_match, ignore_diskcheck_match)
+diskcheck_rcs = DiskChecker('rcs', do_diskcheck_rcs, ignore_diskcheck_rcs)
+diskcheck_sccs = DiskChecker('sccs', do_diskcheck_sccs, ignore_diskcheck_sccs)
+
+diskcheckers = [
+ diskcheck_match,
+ diskcheck_rcs,
+ diskcheck_sccs,
+]
+
+def set_diskcheck(list):
+ for dc in diskcheckers:
+ dc.set(list)
+
+def diskcheck_types():
+ return map(lambda dc: dc.type, diskcheckers)
+
+
+
class EntryProxy(SCons.Util.Proxy):
def __get_abspath(self):
entry = self.get()
@@ -597,6 +656,9 @@ class Entry(Base):
time comes, and then call the same-named method in the transformed
class."""
+ def diskcheck_match(self):
+ pass
+
def disambiguate(self):
if self.isdir():
self.__class__ = Dir
@@ -852,14 +914,12 @@ class FS(LocalFS):
if not create:
raise SCons.Errors.UserError
- # look at the actual filesystem and make sure there isn't
- # a file already there
- path = directory.entry_abspath(orig)
- if self.isfile(path):
- raise TypeError, \
- "File %s found where directory expected." % path
-
d = Dir(orig, directory, self)
+
+ # Check the file system (or not, as configured) to make
+ # sure there isn't already a file there.
+ d.diskcheck_match()
+
directory.entries[norm] = d
directory.add_wkid(d)
directory = d
@@ -878,19 +938,13 @@ class FS(LocalFS):
if not create:
raise SCons.Errors.UserError
- # make sure we don't create File nodes when there is actually
- # a directory at that path on the disk, and vice versa
- path = directory.entry_abspath(last_orig)
- if fsclass == File:
- if self.isdir(path):
- raise TypeError, \
- "Directory %s found where file expected." % path
- elif fsclass == Dir:
- if self.isfile(path):
- raise TypeError, \
- "File %s found where directory expected." % path
-
result = fsclass(last_orig, directory, self)
+
+ # Check the file system (or not, as configured) to make
+ # sure there isn't already a directory at the path on
+ # disk where we just created a File node, and vice versa.
+ result.diskcheck_match()
+
directory.entries[last_norm] = result
directory.add_wkid(result)
else:
@@ -1080,6 +1134,10 @@ class Dir(Base):
self.builder = get_MkdirBuilder()
self.get_executor().set_action_list(self.builder.action)
+ def diskcheck_match(self):
+ diskcheck_match(self, self.fs.isfile,
+ "File %s found where directory expected.")
+
def disambiguate(self):
return self
@@ -1342,14 +1400,6 @@ class Dir(Base):
"""__cacheable__"""
return self.fs.exists(self.entry_abspath(name))
- def rcs_on_disk(self, name):
- rcspath = 'RCS' + os.sep + name+',v'
- return self.entry_exists_on_disk(rcspath)
-
- def sccs_on_disk(self, name):
- sccspath = 'SCCS' + os.sep + 's.'+name
- return self.entry_exists_on_disk(sccspath)
-
def srcdir_list(self):
"""__cacheable__"""
result = []
@@ -1417,8 +1467,8 @@ class Dir(Base):
def file_on_disk(self, name):
if self.entry_exists_on_disk(name) or \
- self.sccs_on_disk(name) or \
- self.rcs_on_disk(name):
+ diskcheck_rcs(self, name) or \
+ diskcheck_sccs(self, name):
try: return self.File(name)
except TypeError: pass
return self.srcdir_duplicate(name)
@@ -1532,6 +1582,10 @@ class BuildInfo(SCons.Node.BuildInfo):
class File(Base):
"""A class for files in a file system.
"""
+ def diskcheck_match(self):
+ diskcheck_match(self, self.fs.isdir,
+ "Directory %s found where file expected.")
+
def __init__(self, name, directory, fs):
if __debug__: logInstanceCreation(self, 'Node.FS.File')
Base.__init__(self, name, directory, fs)
@@ -1703,9 +1757,9 @@ class File(Base):
else:
scb = self.dir.src_builder()
if scb is _null:
- if self.dir.sccs_on_disk(self.name):
+ if diskcheck_sccs(self.dir, self.name):
scb = get_DefaultSCCSBuilder()
- elif self.dir.rcs_on_disk(self.name):
+ elif diskcheck_rcs(self.dir, self.name):
scb = get_DefaultRCSBuilder()
else:
scb = None
diff --git a/src/engine/SCons/Script/Main.py b/src/engine/SCons/Script/Main.py
index d5be3eb..a6b4f88 100644
--- a/src/engine/SCons/Script/Main.py
+++ b/src/engine/SCons/Script/Main.py
@@ -258,6 +258,26 @@ exit_status = 0 # exit status, assume success by default
repositories = []
num_jobs = 1 # this is modifed by SConscript.SetJobs()
+diskcheck_all = SCons.Node.FS.diskcheck_types()
+diskcheck_option_set = None
+
+def diskcheck_convert(value):
+ if value is None:
+ return []
+ if not SCons.Util.is_List(value):
+ value = string.split(value, ',')
+ result = []
+ for v in map(string.lower, value):
+ if v == 'all':
+ result = diskcheck_all
+ elif v == 'none':
+ result = []
+ elif v in diskcheck_all:
+ result.append(v)
+ else:
+ raise ValueError, v
+ return result
+
#
class Stats:
def __init__(self):
@@ -613,6 +633,20 @@ class OptParser(OptionParser):
help="Print various types of debugging information: "
"%s." % string.join(debug_options, ", "))
+ def opt_diskcheck(option, opt, value, parser):
+ try:
+ global diskcheck_option_set
+ diskcheck_option_set = diskcheck_convert(value)
+ SCons.Node.FS.set_diskcheck(diskcheck_option_set)
+ except ValueError, e:
+ raise OptionValueError("Warning: `%s' is not a valid diskcheck type" % e)
+
+
+ self.add_option('--diskcheck', action="callback", type="string",
+ callback=opt_diskcheck, dest='diskcheck',
+ metavar="TYPE",
+ help="Enable specific on-disk checks.")
+
def opt_duplicate(option, opt, value, parser):
if not value in SCons.Node.FS.Valid_Duplicates:
raise OptionValueError("`%s' is not a valid duplication style." % value)
@@ -799,7 +833,8 @@ class SConscriptSettableOptions:
'max_drift':SCons.Sig.default_max_drift,
'implicit_cache':0,
'clean':0,
- 'duplicate':'hard-soft-copy'}
+ 'duplicate':'hard-soft-copy',
+ 'diskcheck':diskcheck_all}
def get(self, name):
if not self.settable.has_key(name):
@@ -835,6 +870,13 @@ class SConscriptSettableOptions:
# Set the duplicate stye right away so it can affect linking
# of SConscript files.
SCons.Node.FS.set_duplicate(value)
+ elif name == 'diskcheck':
+ try:
+ value = diskcheck_convert(value)
+ except ValueError, v:
+ raise SCons.Errors.UserError, "Not a valid diskcheck value: %s"%v
+ if not diskcheck_option_set:
+ SCons.Node.FS.set_diskcheck(value)
self.settable[name] = value