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

Skip to content

Commit cfc1cc2

Browse files
committed
Issue #14642: Add "hg touch" extension, and "make touch" target.
1 parent 8f82506 commit cfc1cc2

4 files changed

Lines changed: 122 additions & 1 deletion

File tree

.hgtouch

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# -*- Makefile -*-
2+
# Define dependencies of generated files that are checked into hg.
3+
# The syntax of this file uses make rule dependencies, without actions
4+
5+
Python/importlib.h: Lib/importlib/_bootstrap.py Python/freeze_importlib.py
6+
7+
Include/ast.h: Parser/Python.asdl Parser/asdl.py Parser/asdl_c.py
8+
Python/Python-ast.c: Include/ast.h
9+
10+
Python/opcode_targets.h: Python/makeopcodetargets.py Lib/opcode.py
11+
12+
Objects/typeslots.inc: Include/typeslots.h Objects/typeslots.py

Makefile.pre.in

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1337,6 +1337,10 @@ TAGS::
13371337
etags Include/*.h; \
13381338
for i in $(SRCDIRS); do etags -a $$i/*.[ch]; done
13391339

1340+
# Touch generated files
1341+
touch:
1342+
hg --config extensions.touch=Tools/hg/hgtouch.py touch -v
1343+
13401344
# Sanitation targets -- clean leaves libraries, executables and tags
13411345
# files, which clobber removes as well
13421346
pycremoval:
@@ -1445,7 +1449,7 @@ Python/thread.o: @THREADHEADERS@
14451449
.PHONY: frameworkinstall frameworkinstallframework frameworkinstallstructure
14461450
.PHONY: frameworkinstallmaclib frameworkinstallapps frameworkinstallunixtools
14471451
.PHONY: frameworkaltinstallunixtools recheck autoconf clean clobber distclean
1448-
.PHONY: smelly funny patchcheck
1452+
.PHONY: smelly funny patchcheck touch
14491453
.PHONY: gdbhooks
14501454

14511455
# IF YOU PUT ANYTHING HERE IT WILL GO AWAY

Misc/NEWS

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,12 @@ Library
176176

177177
- Issue #14493: Use gvfs-open or xdg-open in webbrowser.
178178

179+
Build
180+
-----
181+
182+
- "make touch" will now touch generated files that are checked into Mercurial,
183+
after a "hg update" which failed to bring the timestamps into the right order.
184+
179185
Tests
180186
-----
181187

Tools/hg/hgtouch.py

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
"""Bring time stamps of generated checked-in files into the right order
2+
3+
A versioned configuration file .hgtouch specifies generated files, in the
4+
syntax of make rules.
5+
6+
output: input1 input2
7+
8+
In addition to the dependency syntax, #-comments are supported.
9+
"""
10+
import os
11+
12+
def parse_config(repo):
13+
configfile = repo.wjoin(".hgtouch")
14+
if not os.path.exists(configfile):
15+
return {}
16+
result = {}
17+
with open(configfile) as f:
18+
for line in f:
19+
# strip comments
20+
line = line.split('#')[0].strip()
21+
if ':' not in line:
22+
continue
23+
outputs, inputs = line.split(':', 1)
24+
outputs = outputs.split()
25+
inputs = inputs.split()
26+
for o in outputs:
27+
try:
28+
result[o].extend(inputs)
29+
except KeyError:
30+
result[o] = inputs
31+
return result
32+
33+
def check_rule(ui, repo, modified, output, inputs):
34+
f_output = repo.wjoin(output)
35+
try:
36+
o_time = os.stat(f_output).st_mtime
37+
except OSError:
38+
ui.warn("Generated file %s does not exist\n" % output)
39+
return False
40+
need_touch = False
41+
backdate = None
42+
backdate_source = None
43+
for i in inputs:
44+
f_i = repo.wjoin(i)
45+
try:
46+
i_time = os.stat(f_i).st_mtime
47+
except OSError:
48+
ui.warn(".hgtouch input file %s does not exist\n" % i)
49+
return False
50+
if i in modified:
51+
# input is modified. Need to backdate at least to i_time
52+
if backdate is None or backdate > i_time:
53+
backdate = i_time
54+
backdate_source = i
55+
continue
56+
if o_time <= i_time:
57+
# generated file is older, touch
58+
need_touch = True
59+
if backdate is not None:
60+
ui.warn("Input %s for file %s locally modified\n" % (backdate_source, output))
61+
# set to 1s before oldest modified input
62+
backdate -= 1
63+
os.utime(f_output, (backdate, backdate))
64+
return False
65+
if need_touch:
66+
ui.note("Touching %s\n" % output)
67+
os.utime(f_output, None)
68+
return True
69+
70+
def do_touch(ui, repo):
71+
modified = repo.status()[0]
72+
dependencies = parse_config(repo)
73+
success = True
74+
# try processing all rules in topological order
75+
hold_back = {}
76+
while dependencies:
77+
output, inputs = dependencies.popitem()
78+
# check whether any of the inputs is generated
79+
for i in inputs:
80+
if i in dependencies:
81+
hold_back[output] = inputs
82+
continue
83+
success = check_rule(ui, repo, modified, output, inputs)
84+
# put back held back rules
85+
dependencies.update(hold_back)
86+
hold_back = {}
87+
if hold_back:
88+
ui.warn("Cyclic dependency involving %s\n" % (' '.join(hold_back.keys())))
89+
return False
90+
return success
91+
92+
def touch(ui, repo):
93+
"touch generated files that are older than their sources after an update."
94+
do_touch(ui, repo)
95+
96+
cmdtable = {
97+
"touch": (touch, [],
98+
"touch generated files according to the .hgtouch configuration")
99+
}

0 commit comments

Comments
 (0)