maint: post-release administrivia
[bison.git] / build-aux / update-test
blobdd73e25af74b8b39a1ff1e2ed7d41d83e7899968
1 #! /usr/bin/env python
3 # Update expectations in an Autotest test suite.
5 # Copyright (C) 2019-2021 Free Software Foundation, Inc.
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program. If not, see <https://www.gnu.org/licenses/>.
20 # Written by Akim Demaille.
22 # usage:
24 # update-test _build/8d/tests/testsuite.dir/*/testsuite.log
26 # from your source tree.
27 import argparse
28 import os
29 import re
32 def getargs():
33 p = argparse.ArgumentParser(description='Update test cases.')
34 opt = p.add_argument
35 opt('logs', metavar='log', nargs='+', type=str, default=None,
36 help='log files to process')
37 opt('-v', '--verbose', action='store_true',
38 help='Be verbose')
39 return p.parse_args()
41 args = getargs()
42 subst = dict()
45 def trace(*args_):
46 if args.verbose:
47 print(*args_)
50 def contents(file):
51 '''The contents of a file.'''
52 trace(file)
53 f = open(file)
54 return f.read()
57 def diff_to_re(match):
58 '''Convert a portion of patch into a regex substitution to perform.
59 No longer used, we now use the expected/effective parts.
60 '''
61 frm = []
62 to = []
63 is_diff = False
64 for l in match.group(1).splitlines():
65 print(l)
66 # t in [-+ ]
67 t = l[0]
68 l = l[1:]
69 if t in ['-', ' ']:
70 is_diff = True
71 frm.append(l)
72 if t in ['+', ' ']:
73 is_diff = True
74 to.append(l)
75 if is_diff:
76 # Do not run s//SOMETHING/g (with an emty pattern), that won't
77 # work well...
78 if frm == []:
79 trace("no from for", match.group(1))
80 return
81 frm = "\n".join(frm)
82 to = "\n".join(to)
83 subst[frm] = to
86 def update(at_file, logfile):
87 test = contents(at_file)
88 if os.path.isfile(logfile):
89 trace("LOG: ", logfile)
90 l = contents(logfile)
91 trace("LOG: ", l)
92 global subst
93 subst = {}
94 re.sub(r'(?:^@@.*\n)((?:^[-+ ].*\n)+)',
95 diff_to_re, l, flags = re.MULTILINE)
96 print(subst)
97 if subst:
98 # Turn "subst{frm} -> to" into a large RE.
99 frm = '|'.join([re.escape(x) for x in subst])
100 trace("FROM:", frm)
101 test = re.sub("(" + frm + ")",
102 lambda m: subst[m.group(1)],
103 test, flags=re.MULTILINE)
104 open(at_file, 'w').write(test)
107 def process(logfile):
108 log = contents(logfile)
109 # Look for the file to update.
110 m = re.search(r'^\d+\. ([\-\+\w]+\.at):\d+: ', log, re.MULTILINE)
111 if not m:
112 trace("no diff found:", logfile)
113 return
114 at_file = 'tests/' + m.group(1)
115 print(at_file)
116 update(at_file, logfile)
118 for logfile in args.logs:
119 trace("FILE:", logfile)
120 if os.path.isdir(logfile):
121 logfile = os.path.join(logfile, 'testsuite.log')
122 process(logfile)