blob: 3072f57303e72a2e57866ddb3533a583867ff7ce [file] [log] [blame]
Yabin Cui44e54a82022-12-07 12:04:15 -08001#!/usr/bin/env python3
2#
3# Copyright (C) 2022 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17# pylint: disable=not-callable, relative-import
18
19""" Update clang-stable """
20
21import argparse
22import logging
23from pathlib import Path
24import shutil
25import subprocess
26from typing import List, Optional
27
28import paths
29import utils
30
31
32class ArgParser(argparse.ArgumentParser):
33 def __init__(self):
34 super().__init__(description=__doc__)
35
36 self.add_argument(
37 'version', metavar='VERSION',
38 help='Version of binutil prebuilt updating to (e.g. r123456a).')
39
40 self.add_argument(
41 '-b', '--bug', type=int,
42 help='Bug to reference in commit message.')
43
44 self.add_argument(
45 '--use-current-branch', action='store_true',
46 help='Do not repo start a new branch for the update.')
47
48
49class ClangStableBuilder:
50 def __init__(self, prebuilt_dir: Path, version: str):
51 self.version = version
52 self.clang_dir = prebuilt_dir / ('clang-' + version)
53 self.stable_dir = prebuilt_dir / 'clang-stable'
54
55 def build(self):
56 shutil.rmtree(self.stable_dir)
57 self.stable_dir.mkdir()
58 (self.stable_dir / 'bin').mkdir()
59 (self.stable_dir / 'lib').mkdir()
Yabin Cui8ce2baa2023-07-12 20:34:15 +000060 (self.stable_dir / 'lib' / 'x86_64-unknown-linux-gnu').mkdir()
Yabin Cui44e54a82022-12-07 12:04:15 -080061 (self.stable_dir / 'share').mkdir()
62
63 self.copy_file(self.clang_dir / 'bin' / 'clang-format', self.stable_dir / 'bin')
64 self.copy_file(self.clang_dir / 'bin' / 'git-clang-format', self.stable_dir / 'bin')
65
66 self.copy_files((self.clang_dir / 'lib').glob('libclang.*'), self.stable_dir / 'lib')
67 self.copy_dir(self.clang_dir / 'lib' / 'python3', self.stable_dir / 'lib')
Yabin Cui8ce2baa2023-07-12 20:34:15 +000068 self.copy_files((self.clang_dir / 'lib' / 'x86_64-unknown-linux-gnu').glob('libc++*'),
69 self.stable_dir / 'lib' / 'x86_64-unknown-linux-gnu')
Yabin Cui44e54a82022-12-07 12:04:15 -080070 self.copy_dir(self.clang_dir / 'share' / 'clang', self.stable_dir / 'share')
71
72 (self.stable_dir / 'README.md').write_text(
73 f'All contents in clang-stable are copies of clang-{self.version}.')
74
75 def copy_file(self, src_file: Path, dst_dir: Path):
76 shutil.copy(src_file, dst_dir, follow_symlinks=False)
77
78 def copy_files(self, src_files: List[Path], dst_dir: Path):
79 for src_file in src_files:
80 self.copy_file(src_file, dst_dir)
81
82 def copy_dir(self, src_dir: Path, dst_parent_dir: Path):
83 shutil.copytree(src_dir, dst_parent_dir / src_dir.name,
84 symlinks=True, ignore_dangling_symlinks=True)
85
86 def test(self):
87 utils.check_call([self.stable_dir / 'bin' / 'clang-format', '-h'],
88 stdout=subprocess.DEVNULL)
89 utils.check_call([self.stable_dir / 'bin' / 'git-clang-format', '-h'],
90 stdout=subprocess.DEVNULL)
91
92
93def update_clang_stable(prebuilt_dir: Path, version: str, use_cbr: bool):
94 if not use_cbr:
95 utils.unchecked_call(['repo', 'abandon', 'update-clang-stable-' + version, prebuilt_dir],
96 stderr=subprocess.DEVNULL)
97 utils.check_call(['repo', 'start', 'update-clang-stable-' + version, prebuilt_dir])
98
99 builder = ClangStableBuilder(prebuilt_dir, version)
100 builder.build()
101 builder.test()
102
103
104def do_commit(prebuilt_dir: Path, version: str, bug_id: Optional[str]):
105 utils.check_call(['git', 'add', 'clang-stable'], cwd=prebuilt_dir)
106
107 message_lines = []
108 message_lines.append(f'Update clang-stable to {version}.')
109 message_lines.append('')
110 message_lines.append('Test: N/A')
111 if bug_id is not None:
112 message_lines.append(f'Bug: http://b/{bug_id}')
113 message = '\n'.join(message_lines)
114 utils.check_call(['git', 'commit', '-m', message], cwd=prebuilt_dir)
115
116
117def main():
118 logging.basicConfig(level=logging.DEBUG)
119 args = ArgParser().parse_args()
120 bug_id = args.bug
121 use_cbr = args.use_current_branch
122 version = args.version
123
124 prebuilt_dir = paths.PREBUILTS_DIR / 'clang' / 'host' / 'linux-x86'
125 update_clang_stable(prebuilt_dir, version, use_cbr)
126 do_commit(prebuilt_dir, version, bug_id)
127
128
129if __name__ == '__main__':
130 main()