Yifan Hong | ace13de | 2023-04-28 15:54:04 -0700 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
| 2 | # |
| 3 | # Copyright (C) 2023 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 | """ |
| 18 | Creates the next compatibility matrix. |
Yifan Hong | ace13de | 2023-04-28 15:54:04 -0700 | [diff] [blame] | 19 | """ |
| 20 | |
| 21 | import argparse |
| 22 | import os |
| 23 | import pathlib |
| 24 | import shutil |
| 25 | import subprocess |
| 26 | import textwrap |
| 27 | |
| 28 | |
| 29 | def check_call(*args, **kwargs): |
| 30 | print(args) |
| 31 | subprocess.check_call(*args, **kwargs) |
| 32 | |
| 33 | |
| 34 | def check_output(*args, **kwargs): |
| 35 | print(args) |
| 36 | return subprocess.check_output(*args, **kwargs) |
| 37 | |
| 38 | |
| 39 | class Bump(object): |
| 40 | |
| 41 | def __init__(self, cmdline_args): |
| 42 | self.top = pathlib.Path(os.environ["ANDROID_BUILD_TOP"]) |
| 43 | self.interfaces_dir = self.top / "hardware/interfaces" |
| 44 | |
Devin Moore | 0425916 | 2024-02-06 22:52:32 +0000 | [diff] [blame] | 45 | self.current_level = cmdline_args.current_level |
| 46 | self.current_letter = cmdline_args.current_letter |
Yifan Hong | ace13de | 2023-04-28 15:54:04 -0700 | [diff] [blame] | 47 | self.current_module_name = f"framework_compatibility_matrix.{self.current_level}.xml" |
| 48 | self.current_xml = self.interfaces_dir / f"compatibility_matrices/compatibility_matrix.{self.current_level}.xml" |
Devin Moore | 4be20f7 | 2024-02-01 21:39:36 +0000 | [diff] [blame] | 49 | self.device_module_name = "framework_compatibility_matrix.device.xml" |
Yifan Hong | ace13de | 2023-04-28 15:54:04 -0700 | [diff] [blame] | 50 | |
Devin Moore | 0425916 | 2024-02-06 22:52:32 +0000 | [diff] [blame] | 51 | self.next_level = cmdline_args.next_level |
| 52 | self.next_letter = cmdline_args.next_letter |
Yifan Hong | ace13de | 2023-04-28 15:54:04 -0700 | [diff] [blame] | 53 | self.next_module_name = f"framework_compatibility_matrix.{self.next_level}.xml" |
| 54 | self.next_xml = self.interfaces_dir / f"compatibility_matrices/compatibility_matrix.{self.next_level}.xml" |
| 55 | |
Yifan Hong | ace13de | 2023-04-28 15:54:04 -0700 | [diff] [blame] | 56 | def run(self): |
| 57 | self.bump_kernel_configs() |
| 58 | self.copy_matrix() |
| 59 | self.edit_android_bp() |
| 60 | self.edit_android_mk() |
| 61 | |
Yifan Hong | ace13de | 2023-04-28 15:54:04 -0700 | [diff] [blame] | 62 | def bump_kernel_configs(self): |
| 63 | check_call([ |
| 64 | self.top / "kernel/configs/tools/bump.py", |
Devin Moore | 0425916 | 2024-02-06 22:52:32 +0000 | [diff] [blame] | 65 | self.current_letter, |
| 66 | self.next_letter, |
Yifan Hong | ace13de | 2023-04-28 15:54:04 -0700 | [diff] [blame] | 67 | ]) |
| 68 | |
| 69 | def copy_matrix(self): |
Devin Moore | 4be20f7 | 2024-02-01 21:39:36 +0000 | [diff] [blame] | 70 | with open(self.current_xml) as f_current, open(self.next_xml, "w") as f_next: |
| 71 | f_next.write(f_current.read().replace(f"level=\"{self.current_level}\"", f"level=\"{self.next_level}\"")) |
Yifan Hong | ace13de | 2023-04-28 15:54:04 -0700 | [diff] [blame] | 72 | |
| 73 | def edit_android_bp(self): |
| 74 | android_bp = self.interfaces_dir / "compatibility_matrices/Android.bp" |
| 75 | |
| 76 | with open(android_bp, "r+") as f: |
| 77 | if self.next_module_name not in f.read(): |
| 78 | f.seek(0, 2) # end of file |
| 79 | f.write("\n") |
| 80 | f.write( |
| 81 | textwrap.dedent(f"""\ |
| 82 | vintf_compatibility_matrix {{ |
| 83 | name: "{self.next_module_name}", |
| 84 | }} |
| 85 | """)) |
| 86 | |
| 87 | next_kernel_configs = check_output( |
| 88 | """grep -rh name: | sed -E 's/^.*"(.*)".*/\\1/g'""", |
| 89 | cwd=self.top / "kernel/configs" / |
Devin Moore | 0425916 | 2024-02-06 22:52:32 +0000 | [diff] [blame] | 90 | self.next_letter, |
Yifan Hong | ace13de | 2023-04-28 15:54:04 -0700 | [diff] [blame] | 91 | text=True, |
| 92 | shell=True, |
| 93 | ).splitlines() |
| 94 | print(next_kernel_configs) |
| 95 | |
| 96 | check_call([ |
| 97 | "bpmodify", "-w", "-m", self.next_module_name, "-property", "stem", |
| 98 | "-str", self.next_xml.name, android_bp |
| 99 | ]) |
| 100 | |
| 101 | check_call([ |
| 102 | "bpmodify", "-w", "-m", self.next_module_name, "-property", "srcs", |
| 103 | "-a", |
| 104 | self.next_xml.relative_to(android_bp.parent), android_bp |
| 105 | ]) |
| 106 | |
| 107 | check_call([ |
| 108 | "bpmodify", "-w", "-m", self.next_module_name, "-property", |
| 109 | "kernel_configs", "-a", " ".join(next_kernel_configs), android_bp |
| 110 | ]) |
| 111 | |
| 112 | def edit_android_mk(self): |
| 113 | android_mk = self.interfaces_dir / "compatibility_matrices/Android.mk" |
Devin Moore | 4be20f7 | 2024-02-01 21:39:36 +0000 | [diff] [blame] | 114 | lines = [] |
Yifan Hong | ace13de | 2023-04-28 15:54:04 -0700 | [diff] [blame] | 115 | with open(android_mk) as f: |
| 116 | if self.next_module_name in f.read(): |
| 117 | return |
| 118 | f.seek(0) |
Devin Moore | 4be20f7 | 2024-02-01 21:39:36 +0000 | [diff] [blame] | 119 | for line in f: |
| 120 | if f" {self.device_module_name} \\\n" in line: |
| 121 | lines.append(f" {self.current_module_name} \\\n") |
| 122 | |
| 123 | if self.current_module_name in line: |
| 124 | lines.append(f" {self.next_module_name} \\\n") |
| 125 | else: |
| 126 | lines.append(line) |
| 127 | |
Yifan Hong | ace13de | 2023-04-28 15:54:04 -0700 | [diff] [blame] | 128 | with open(android_mk, "w") as f: |
| 129 | f.write("".join(lines)) |
| 130 | |
| 131 | |
| 132 | def main(): |
| 133 | parser = argparse.ArgumentParser(description=__doc__) |
Devin Moore | 0425916 | 2024-02-06 22:52:32 +0000 | [diff] [blame] | 134 | parser.add_argument("current_level", |
Yifan Hong | ace13de | 2023-04-28 15:54:04 -0700 | [diff] [blame] | 135 | type=str, |
| 136 | help="VINTF level of the current version (e.g. 9)") |
Devin Moore | 0425916 | 2024-02-06 22:52:32 +0000 | [diff] [blame] | 137 | parser.add_argument("next_level", |
Yifan Hong | ace13de | 2023-04-28 15:54:04 -0700 | [diff] [blame] | 138 | type=str, |
| 139 | help="VINTF level of the next version (e.g. 10)") |
Devin Moore | 0425916 | 2024-02-06 22:52:32 +0000 | [diff] [blame] | 140 | parser.add_argument("current_letter", |
| 141 | type=str, |
| 142 | help="Letter of the API level of the current version (e.g. v)") |
| 143 | parser.add_argument("next_letter", |
| 144 | type=str, |
| 145 | help="Letter of the API level of the next version (e.g. w)") |
Yifan Hong | ace13de | 2023-04-28 15:54:04 -0700 | [diff] [blame] | 146 | cmdline_args = parser.parse_args() |
| 147 | |
| 148 | Bump(cmdline_args).run() |
| 149 | |
| 150 | |
| 151 | if __name__ == "__main__": |
| 152 | main() |