[M94 Dev][Tizen] Fix for errors for generating ninja files
[platform/framework/web/chromium-efl.git] / third_party / vulkan-deps / update-commit-message.py
1 #!/usr/bin/env python3
2 # Copyright 2021 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
5 # based on an almost identical script by: jyrki@google.com (Jyrki Alakuijala)
6 """Updates the commit message used in the auto-roller.
7
8 Merges several small commit logs into a single more useful commit message.
9
10 Usage:
11   update_commit_message.py --old-revision=<sha1>
12 """
13
14 import argparse
15 import logging
16 import os
17 import platform
18 import re
19 import shutil
20 import subprocess
21 import sys
22 import tempfile
23
24 GCLIENT_LINE = r'([^:]+): ([^@]+)@(.*)'
25 CHANGE_TEMPLATE = '* %s: %s.git/+log/%s..%s'
26 EXIT_SUCCESS = 0
27 EXIT_FAILURE = 1
28 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
29 GCLIENT = """\
30 solutions = [{
31     'name': '.',
32     'url': 'https://chromium.googlesource.com/vulkan-deps.git',
33     'deps_file': 'DEPS',
34     'managed': False,
35 }]
36 """
37 INSERT_NEEDLE = 'If this roll has caused a breakage'
38
39
40 def run(cmd, args):
41     exe = ('%s.bat' % cmd) if platform.system() == 'Windows' else cmd
42     cmd_args = [exe] + list(args)
43     return subprocess.check_output(cmd_args).decode('ascii').strip()
44
45
46 def git(*args):
47     return run('git', args)
48
49
50 def gclient(*args):
51     return run('gclient', args)
52
53
54 def parse_revinfo(output):
55     expr = re.compile(GCLIENT_LINE)
56     config = dict()
57     urls = dict()
58     for line in output.split('\n'):
59         match = expr.match(line.strip())
60         if match:
61             dep = match.group(1)
62             urls[dep] = match.group(2)
63             config[dep] = match.group(3)
64     return config, urls
65
66
67 def _local_commit_amend(commit_msg, dry_run):
68     logging.info('Amending changes to local commit.')
69     old_commit_msg = git('log', '-1', '--pretty=%B')
70     logging.debug('Existing commit message:\n%s\n', old_commit_msg)
71     insert_index = old_commit_msg.rfind(INSERT_NEEDLE)
72     if insert_index == -1:
73         logging.exception('"%s" not found in commit message.' % INSERT_NEEDLE)
74
75     new_commit_msg = old_commit_msg[:insert_index] + commit_msg + '\n\n' + old_commit_msg[insert_index:]
76     logging.debug('New commit message:\n%s\n', new_commit_msg)
77     if not dry_run:
78         with tempfile.NamedTemporaryFile(delete=False, mode="w") as ntf:
79             ntf.write(new_commit_msg)
80             ntf.close()
81             git('commit', '--amend', '--no-edit', '--file=%s' % ntf.name)
82             os.unlink(ntf.name)
83
84
85 def main(raw_args):
86     parser = argparse.ArgumentParser()
87     parser.add_argument('--old-revision', help='Old git revision in the roll.', required=True)
88     parser.add_argument(
89         '--dry-run',
90         help='Test out functionality without making changes.',
91         action='store_true',
92         default=False)
93     parser.add_argument(
94         '-v', '--verbose', help='Verbose debug logging.', action='store_true', default=False)
95     args = parser.parse_args(raw_args)
96
97     if args.verbose:
98         logging.basicConfig(level=logging.DEBUG)
99     else:
100         logging.basicConfig(level=logging.INFO)
101
102     cwd = os.getcwd()
103
104     os.chdir(SCRIPT_DIR)
105     old_deps_content = git('show', '%s:DEPS' % args.old_revision)
106
107     with tempfile.TemporaryDirectory() as tempdir:
108         os.chdir(tempdir)
109
110         # Add the gclientfile.
111         with open(os.path.join(tempdir, '.gclient'), 'w') as gcfile:
112             gcfile.write(GCLIENT)
113             gcfile.close()
114
115         # Get the current config.
116         shutil.copyfile(os.path.join(SCRIPT_DIR, 'DEPS'), os.path.join(tempdir, 'DEPS'))
117         gclient_head_output = gclient('revinfo')
118
119         # Get the prior config.
120         with open('DEPS', 'w') as deps:
121             deps.write(old_deps_content)
122             deps.close()
123         gclient_old_output = gclient('revinfo')
124         os.chdir(SCRIPT_DIR)
125
126     head_config, urls = parse_revinfo(gclient_head_output)
127     old_config, _ = parse_revinfo(gclient_old_output)
128
129     changed_deps = []
130
131     for dep, new_sha1 in head_config.items():
132         if dep in old_config:
133             old_sha1 = old_config[dep]
134             if new_sha1 != old_sha1:
135                 dep_short = dep.replace('\\', '/').split('/')[0]
136                 repo = urls[dep]
137                 logging.debug('Found change: %s to %s' % (dep, new_sha1))
138                 changed_deps.append(CHANGE_TEMPLATE %
139                                     (dep_short, repo, old_sha1[:10], new_sha1[:10]))
140
141     if not changed_deps:
142         print('No changed dependencies, early exit.')
143         return EXIT_SUCCESS
144
145     commit_msg = 'Changed dependencies:\n%s' % '\n'.join(sorted(changed_deps))
146
147     os.chdir(cwd)
148     _local_commit_amend(commit_msg, args.dry_run)
149
150     return EXIT_SUCCESS
151
152
153 if __name__ == '__main__':
154     sys.exit(main(sys.argv[1:]))