Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit bf52648

Browse files
committed
Issue #19106: Touch generated files to be 1s newer than their youngest source.
1 parent 600b735 commit bf52648

1 file changed

Lines changed: 26 additions & 11 deletions

File tree

Tools/hg/hgtouch.py

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from __future__ import with_statement
1111
import errno
1212
import os
13+
import time
1314

1415
def parse_config(repo):
1516
try:
@@ -36,13 +37,17 @@ def parse_config(repo):
3637
return result
3738

3839
def 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

7582
def 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

Comments
 (0)