1010from __future__ import with_statement
1111import errno
1212import os
13+ import time
1314
1415def parse_config (repo ):
1516 try :
@@ -36,13 +37,17 @@ def parse_config(repo):
3637 return result
3738
3839def check_rule (ui , repo , modified , output , inputs ):
40+ """Verify that the output is newer than any of the inputs.
41+ Return (status, stamp), where status is True if the update succeeded,
42+ and stamp is the newest time stamp assigned to any file (might be in
43+ the future)."""
3944 f_output = repo .wjoin (output )
4045 try :
4146 o_time = os .stat (f_output ).st_mtime
4247 except OSError :
4348 ui .warn ("Generated file %s does not exist\n " % output )
44- return False
45- need_touch = False
49+ return False , 0
50+ youngest = 0 # youngest dependency
4651 backdate = None
4752 backdate_source = None
4853 for i in inputs :
@@ -51,31 +56,34 @@ def check_rule(ui, repo, modified, output, inputs):
5156 i_time = os .stat (f_i ).st_mtime
5257 except OSError :
5358 ui .warn (".hgtouch input file %s does not exist\n " % i )
54- return False
59+ return False , 0
5560 if i in modified :
5661 # input is modified. Need to backdate at least to i_time
5762 if backdate is None or backdate > i_time :
5863 backdate = i_time
5964 backdate_source = i
6065 continue
61- if o_time <= i_time :
62- # generated file is older, touch
63- need_touch = True
66+ youngest = max (i_time , youngest )
6467 if backdate is not None :
6568 ui .warn ("Input %s for file %s locally modified\n " % (backdate_source , output ))
6669 # set to 1s before oldest modified input
6770 backdate -= 1
6871 os .utime (f_output , (backdate , backdate ))
69- return False
70- if need_touch :
72+ return False , 0
73+ if youngest >= o_time :
7174 ui .note ("Touching %s\n " % output )
72- os .utime (f_output , None )
73- return True
75+ youngest += 1
76+ os .utime (f_output , (youngest , youngest ))
77+ return True , youngest
78+ else :
79+ # Nothing to update
80+ return True , 0
7481
7582def do_touch (ui , repo ):
7683 modified = repo .status ()[0 ]
7784 dependencies = parse_config (repo )
7885 success = True
86+ tstamp = 0 # newest time stamp assigned
7987 # try processing all rules in topological order
8088 hold_back = {}
8189 while dependencies :
@@ -85,10 +93,17 @@ def do_touch(ui, repo):
8593 if i in dependencies :
8694 hold_back [output ] = inputs
8795 continue
88- success = check_rule (ui , repo , modified , output , inputs )
96+ _success , _tstamp = check_rule (ui , repo , modified , output , inputs )
97+ sucess = success and _success
98+ tstamp = max (tstamp , _tstamp )
8999 # put back held back rules
90100 dependencies .update (hold_back )
91101 hold_back = {}
102+ now = time .time ()
103+ if tstamp > now :
104+ # wait until real time has passed the newest time stamp, to
105+ # avoid having files dated in the future
106+ time .sleep (tstamp - now )
92107 if hold_back :
93108 ui .warn ("Cyclic dependency involving %s\n " % (' ' .join (hold_back .keys ())))
94109 return False
0 commit comments