Issue #19106: Touch generated files to be 1s newer than their youngest source.
This commit is contained in:
parent
600b735062
commit
bf52648ce1
@ -10,6 +10,7 @@ In addition to the dependency syntax, #-comments are supported.
|
|||||||
from __future__ import with_statement
|
from __future__ import with_statement
|
||||||
import errno
|
import errno
|
||||||
import os
|
import os
|
||||||
|
import time
|
||||||
|
|
||||||
def parse_config(repo):
|
def parse_config(repo):
|
||||||
try:
|
try:
|
||||||
@ -36,13 +37,17 @@ def parse_config(repo):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
def check_rule(ui, repo, modified, output, inputs):
|
def check_rule(ui, repo, modified, output, inputs):
|
||||||
|
"""Verify that the output is newer than any of the inputs.
|
||||||
|
Return (status, stamp), where status is True if the update succeeded,
|
||||||
|
and stamp is the newest time stamp assigned to any file (might be in
|
||||||
|
the future)."""
|
||||||
f_output = repo.wjoin(output)
|
f_output = repo.wjoin(output)
|
||||||
try:
|
try:
|
||||||
o_time = os.stat(f_output).st_mtime
|
o_time = os.stat(f_output).st_mtime
|
||||||
except OSError:
|
except OSError:
|
||||||
ui.warn("Generated file %s does not exist\n" % output)
|
ui.warn("Generated file %s does not exist\n" % output)
|
||||||
return False
|
return False, 0
|
||||||
need_touch = False
|
youngest = 0 # youngest dependency
|
||||||
backdate = None
|
backdate = None
|
||||||
backdate_source = None
|
backdate_source = None
|
||||||
for i in inputs:
|
for i in inputs:
|
||||||
@ -51,31 +56,34 @@ def check_rule(ui, repo, modified, output, inputs):
|
|||||||
i_time = os.stat(f_i).st_mtime
|
i_time = os.stat(f_i).st_mtime
|
||||||
except OSError:
|
except OSError:
|
||||||
ui.warn(".hgtouch input file %s does not exist\n" % i)
|
ui.warn(".hgtouch input file %s does not exist\n" % i)
|
||||||
return False
|
return False, 0
|
||||||
if i in modified:
|
if i in modified:
|
||||||
# input is modified. Need to backdate at least to i_time
|
# input is modified. Need to backdate at least to i_time
|
||||||
if backdate is None or backdate > i_time:
|
if backdate is None or backdate > i_time:
|
||||||
backdate = i_time
|
backdate = i_time
|
||||||
backdate_source = i
|
backdate_source = i
|
||||||
continue
|
continue
|
||||||
if o_time <= i_time:
|
youngest = max(i_time, youngest)
|
||||||
# generated file is older, touch
|
|
||||||
need_touch = True
|
|
||||||
if backdate is not None:
|
if backdate is not None:
|
||||||
ui.warn("Input %s for file %s locally modified\n" % (backdate_source, output))
|
ui.warn("Input %s for file %s locally modified\n" % (backdate_source, output))
|
||||||
# set to 1s before oldest modified input
|
# set to 1s before oldest modified input
|
||||||
backdate -= 1
|
backdate -= 1
|
||||||
os.utime(f_output, (backdate, backdate))
|
os.utime(f_output, (backdate, backdate))
|
||||||
return False
|
return False, 0
|
||||||
if need_touch:
|
if youngest >= o_time:
|
||||||
ui.note("Touching %s\n" % output)
|
ui.note("Touching %s\n" % output)
|
||||||
os.utime(f_output, None)
|
youngest += 1
|
||||||
return True
|
os.utime(f_output, (youngest, youngest))
|
||||||
|
return True, youngest
|
||||||
|
else:
|
||||||
|
# Nothing to update
|
||||||
|
return True, 0
|
||||||
|
|
||||||
def do_touch(ui, repo):
|
def do_touch(ui, repo):
|
||||||
modified = repo.status()[0]
|
modified = repo.status()[0]
|
||||||
dependencies = parse_config(repo)
|
dependencies = parse_config(repo)
|
||||||
success = True
|
success = True
|
||||||
|
tstamp = 0 # newest time stamp assigned
|
||||||
# try processing all rules in topological order
|
# try processing all rules in topological order
|
||||||
hold_back = {}
|
hold_back = {}
|
||||||
while dependencies:
|
while dependencies:
|
||||||
@ -85,10 +93,17 @@ def do_touch(ui, repo):
|
|||||||
if i in dependencies:
|
if i in dependencies:
|
||||||
hold_back[output] = inputs
|
hold_back[output] = inputs
|
||||||
continue
|
continue
|
||||||
success = check_rule(ui, repo, modified, output, inputs)
|
_success, _tstamp = check_rule(ui, repo, modified, output, inputs)
|
||||||
|
sucess = success and _success
|
||||||
|
tstamp = max(tstamp, _tstamp)
|
||||||
# put back held back rules
|
# put back held back rules
|
||||||
dependencies.update(hold_back)
|
dependencies.update(hold_back)
|
||||||
hold_back = {}
|
hold_back = {}
|
||||||
|
now = time.time()
|
||||||
|
if tstamp > now:
|
||||||
|
# wait until real time has passed the newest time stamp, to
|
||||||
|
# avoid having files dated in the future
|
||||||
|
time.sleep(tstamp-now)
|
||||||
if hold_back:
|
if hold_back:
|
||||||
ui.warn("Cyclic dependency involving %s\n" % (' '.join(hold_back.keys())))
|
ui.warn("Cyclic dependency involving %s\n" % (' '.join(hold_back.keys())))
|
||||||
return False
|
return False
|
||||||
|
Loading…
x
Reference in New Issue
Block a user