diff options
author | Steven Knight <knight@baldmt.com> | 2001-10-28 12:51:44 (GMT) |
---|---|---|
committer | Steven Knight <knight@baldmt.com> | 2001-10-28 12:51:44 (GMT) |
commit | 3bce8a9e6e70d61723e4824bd7ba84a7b9547456 (patch) | |
tree | 27e3b6c55dd969ce1e98bf8138a8d0c9125bac59 /src/engine/SCons/Sig | |
parent | e5410ac77d8740375b43cb154bedf7219279bf67 (diff) | |
download | SCons-3bce8a9e6e70d61723e4824bd7ba84a7b9547456.zip SCons-3bce8a9e6e70d61723e4824bd7ba84a7b9547456.tar.gz SCons-3bce8a9e6e70d61723e4824bd7ba84a7b9547456.tar.bz2 |
Change node and .sconsign handling to separate build and content signatures.
Diffstat (limited to 'src/engine/SCons/Sig')
-rw-r--r-- | src/engine/SCons/Sig/SigTests.py | 85 | ||||
-rw-r--r-- | src/engine/SCons/Sig/__init__.py | 107 |
2 files changed, 115 insertions, 77 deletions
diff --git a/src/engine/SCons/Sig/SigTests.py b/src/engine/SCons/Sig/SigTests.py index 4a303db..95789e8 100644 --- a/src/engine/SCons/Sig/SigTests.py +++ b/src/engine/SCons/Sig/SigTests.py @@ -52,8 +52,11 @@ class DummyNode: self.builder = file.builder self.depends = [] self.use_signature = 1 + self.bsig = None + self.csig = None self.oldtime = 0 - self.oldsig = 0 + self.oldbsig = 0 + self.oldcsig = 0 def get_contents(self): # a file that doesn't exist has no contents: @@ -78,17 +81,14 @@ class DummyNode: return 0 return None - def has_signature(self): - return hasattr(self, "sig") + def set_bsig(self, bsig): + self.bsig = bsig - def set_signature(self, sig): - self.sig = sig + def get_bsig(self): + return self.bsig - def get_signature(self): - return self.sig - - def get_oldentry(self): - return (self.oldtime, self.oldsig) + def get_prevsiginfo(self): + return (self.oldtime, self.oldbsig, self.oldcsig) def create_files(test): @@ -132,7 +132,8 @@ def current(calc, node): def write(calc, nodes): for node in nodes: node.oldtime = node.file.timestamp - node.oldsig = calc.get_signature(node) + node.oldbsig = calc.bsig(node) + node.oldcsig = calc.csig(node) class SigTestBase: @@ -246,30 +247,33 @@ class CalcTestCase(unittest.TestCase): def current(self, newsig, oldsig): return newsig == oldsig def signature(self, node): - return node.get_signature() + return node.get_csig() class MyNode: - def __init__(self, name, sig): + def __init__(self, name, bsig, csig): self.name = name - self.sig = sig + self.bsig = bsig + self.csig = csig self.kids = [] self.builder = None self.use_signature = 1 def children(self): return self.kids - def has_signature(self): - return self.sig != None - def get_signature(self): - return self.sig - def get_oldentry(self): - return 0, self.sig + def exists(self): + return 1 + def get_bsig(self): + return self.bsig + def get_csig(self): + return self.csig + def get_prevsiginfo(self): + return 0, self.bsig, self.csig def get_timestamp(self): return 1 self.module = MySigModule() self.nodeclass = MyNode self.test_Calc___init__() - self.test_Calc_collect() + self.test_Calc_bsig() self.test_Calc_get_signature() self.test_Calc_current() @@ -277,14 +281,19 @@ class CalcTestCase(unittest.TestCase): self.calc = SCons.Sig.Calculator(self.module) assert self.calc.module == self.module - def test_Calc_collect(self): - n1 = self.nodeclass('n1', 11) - n2 = self.nodeclass('n2', 22) - n3 = self.nodeclass('n3', 33) + def test_Calc_bsig(self): + n1 = self.nodeclass('n1', 11, 12) + n2 = self.nodeclass('n2', 22, 23) + n3 = self.nodeclass('n3', 33, 34) n1.builder = 1 n1.kids = [n2, n3] - assert self.calc.collect(n1) == 55 + assert self.calc.bsig(n1) == 55 + + def test_Calc_bsig(self): + n = self.nodeclass('n', 11, 12) + + assert self.calc.csig(n) == 12 def test_Calc_get_signature(self): class NE(self.nodeclass): @@ -298,24 +307,24 @@ class CalcTestCase(unittest.TestCase): def has_signature(self): return None - n1 = self.nodeclass('n1', 11) + n1 = self.nodeclass('n1', 11, 12) n1.use_signature = 0 assert self.calc.get_signature(n1) is None - n2 = self.nodeclass('n2', 22) - assert self.calc.get_signature(n2) == 22 + n2 = self.nodeclass('n2', 22, 23) + assert self.calc.get_signature(n2) == 23 - n3 = self.nodeclass('n3', 33) - n4 = self.nodeclass('n4', None) + n3 = self.nodeclass('n3', 33, 34) + n4 = self.nodeclass('n4', None, None) n4.builder = 1 n4.kids = [n2, n3] - assert self.calc.get_signature(n4) == 55 + assert self.calc.get_signature(n4) == 57 - n5 = NE('n5', 55) + n5 = NE('n5', 55, 56) assert self.calc.get_signature(n5) is None - n6 = NN('n6', 66) - assert self.calc.get_signature(n6) == 66 + n6 = NN('n6', 66, 67) + assert self.calc.get_signature(n6) == 67 def test_Calc_current(self): class N0(self.nodeclass): @@ -328,15 +337,15 @@ class CalcTestCase(unittest.TestCase): def current(self): return None - n0 = N0('n0', 11) + n0 = N0('n0', 11, 12) assert not self.calc.current(n0, 10) assert not self.calc.current(n0, 11) - n1 = N1('n1', 22) + n1 = N1('n1', 22, 23) assert self.calc.current(n1, 20) assert self.calc.current(n1, 22) - nn = NN('nn', 33) + nn = NN('nn', 33, 34) assert not self.calc.current(nn, 30) assert self.calc.current(nn, 33) diff --git a/src/engine/SCons/Sig/__init__.py b/src/engine/SCons/Sig/__init__.py index 2a2667f..4095792 100644 --- a/src/engine/SCons/Sig/__init__.py +++ b/src/engine/SCons/Sig/__init__.py @@ -52,54 +52,75 @@ class SConsignFile: module - the signature module being used """ - self.path = os.path.join(dir, '.sconsign') + self.dir = dir + self.module = module + self.sconsign = os.path.join(dir.path, '.sconsign') self.entries = {} + self.dirty = None try: - file = open(self.path, 'rt') + file = open(self.sconsign, 'rt') except: pass else: for line in file.readlines(): filename, rest = map(string.strip, string.split(line, ":")) - time, signature = map(string.strip, string.split(rest, " ")) - self.entries[filename] = (int(time), module.from_string(signature)) + self.entries[filename] = rest global sig_files sig_files.append(self) def get(self, filename): """ - Get the signature for a file + Get the .sconsign entry for a file filename - the filename whose signature will be returned - returns - (timestamp, signature) + returns - (timestamp, bsig, csig) """ try: - return self.entries[filename] + arr = map(string.strip, string.split(self.entries[filename], " ")) except KeyError: - return (0, None) + return (None, None, None) + try: + if arr[1] == '-': bsig = None + else: bsig = self.module.from_string(arr[1]) + except IndexError: + bsig = None + try: + if arr[2] == '-': csig = None + else: csig = self.module.from_string(arr[2]) + except IndexError: + csig = None + return (int(arr[0]), bsig, csig) - def set(self, filename, timestamp, signature, module): + def set(self, filename, timestamp, bsig = None, csig = None): """ - Set the signature for a file + Set the .sconsign entry for a file filename - the filename whose signature will be set timestamp - the timestamp - signature - the signature module - the signature module being used + bsig - the file's build signature + csig - the file's content signature """ - self.entries[filename] = (timestamp, module.to_string(signature)) + if bsig is None: bsig = '-' + else: bsig = self.module.to_string(bsig) + if csig is None: csig = '' + else: csig = ' ' + self.module.to_string(csig) + self.entries[filename] = "%d %s%s" % (timestamp, bsig, csig) + self.dirty = 1 def write(self): """ Write the .sconsign file to disk. """ - - file = open(self.path, 'wt') - for item in self.entries.items(): - file.write("%s: %d %s\n" % (item[0], item[1][0], item[1][1])) + if self.dirty: + file = open(self.sconsign, 'wt') + keys = self.entries.keys() + keys.sort() + for name in keys: + file.write("%s: %s\n" % (name, self.entries[name])) class Calculator: @@ -116,24 +137,39 @@ class Calculator: """ self.module = module - - def collect(self, node): + def bsig(self, node): """ - Collect the signatures of a node's sources. + Generate a node's build signature, the digested signatures + of its dependency files and build information. node - the node whose sources will be collected + returns - the build signature This no longer handles the recursive descent of the node's children's signatures. We expect that they're already built and updated by someone else, if that's what's wanted. """ + #XXX If configured, use the content signatures from the + #XXX .sconsign file if the timestamps match. sigs = map(lambda n,s=self: s.get_signature(n), node.children()) return self.module.collect(filter(lambda x: not x is None, sigs)) + def csig(self, node): + """ + Generate a node's content signature, the digested signature + of its content. + + node - the node + returns - the content signature + """ + #XXX If configured, use the content signatures from the + #XXX .sconsign file if the timestamps match. + return self.module.signature(node) + def get_signature(self, node): """ - Get the signature for a node. + Get the appropriate signature for a node. node - the node returns - the signature or None if the signature could not @@ -147,27 +183,22 @@ class Calculator: # This node type doesn't use a signature (e.g. a # directory) so bail right away. return None - elif node.has_signature(): - sig = node.get_signature() elif node.builder: - sig = self.collect(node) + return self.bsig(node) + elif not node.exists(): + return None else: - if not node.exists(): - return None - - # XXX handle nodes that are not under the source root - sig = self.module.signature(node) - - return sig + return self.csig(node) def current(self, node, newsig): """ - Check if a node is up to date. + Check if a signature is up to date with respect to a node. node - the node whose signature will be checked + newsig - the (presumably current) signature of the file - returns - 0 if the signature has changed since the last invocation, - and 1 if it hasn't + returns - 1 if the file is current with the specified signature, + 0 if it isn't """ c = node.current() @@ -178,11 +209,9 @@ class Calculator: # that doesn't exist, or a directory. return c - oldtime, oldsig = node.get_oldentry() - - newtime = node.get_timestamp() + oldtime, oldbsig, oldcsig = node.get_prevsiginfo() - if not node.builder and newtime == oldtime: - newsig = oldsig + if not node.builder and node.get_timestamp() == oldtime: + return 1 - return self.module.current(newsig, oldsig) + return self.module.current(newsig, oldbsig) |