1*bb4ee6a4SAndroid Build Coastguard Worker# Copyright 2021 The ChromiumOS Authors 2*bb4ee6a4SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be 3*bb4ee6a4SAndroid Build Coastguard Worker# found in the LICENSE file. 4*bb4ee6a4SAndroid Build Coastguard Worker 5*bb4ee6a4SAndroid Build Coastguard Worker# Refactoring tools for moving around crates and updating dependencies 6*bb4ee6a4SAndroid Build Coastguard Worker# in toml files. 7*bb4ee6a4SAndroid Build Coastguard Worker# 8*bb4ee6a4SAndroid Build Coastguard Worker# Contains the last run refactoring for reference. Don't run this script, it'll 9*bb4ee6a4SAndroid Build Coastguard Worker# fail, but use it as a foundation for other refactorings. 10*bb4ee6a4SAndroid Build Coastguard Worker 11*bb4ee6a4SAndroid Build Coastguard Workerfrom contextlib import contextmanager 12*bb4ee6a4SAndroid Build Coastguard Workerfrom pathlib import Path 13*bb4ee6a4SAndroid Build Coastguard Workerimport os 14*bb4ee6a4SAndroid Build Coastguard Workerimport re 15*bb4ee6a4SAndroid Build Coastguard Workerimport shutil 16*bb4ee6a4SAndroid Build Coastguard Workerimport subprocess 17*bb4ee6a4SAndroid Build Coastguard Workerfrom typing import Callable, List, Tuple, Union 18*bb4ee6a4SAndroid Build Coastguard Worker 19*bb4ee6a4SAndroid Build Coastguard Worker 20*bb4ee6a4SAndroid Build Coastguard WorkerSearchPattern = Union[str, re.Pattern[str]] 21*bb4ee6a4SAndroid Build Coastguard WorkerReplacement = Union[str, Callable[[re.Match[str]], str]] 22*bb4ee6a4SAndroid Build Coastguard Worker 23*bb4ee6a4SAndroid Build Coastguard Worker 24*bb4ee6a4SAndroid Build Coastguard Workerdef append_to_file(file_path: Path, appendix: str): 25*bb4ee6a4SAndroid Build Coastguard Worker contents = file_path.read_text() 26*bb4ee6a4SAndroid Build Coastguard Worker file_path.write_text(contents.rstrip() + "\n" + appendix + "\n") 27*bb4ee6a4SAndroid Build Coastguard Worker 28*bb4ee6a4SAndroid Build Coastguard Worker 29*bb4ee6a4SAndroid Build Coastguard Workerdef replace_in_file(file_path: Path, search: SearchPattern, replace: Replacement): 30*bb4ee6a4SAndroid Build Coastguard Worker if not file_path.exists(): 31*bb4ee6a4SAndroid Build Coastguard Worker print(f"WARNING: Does not exist {file_path}") 32*bb4ee6a4SAndroid Build Coastguard Worker return 33*bb4ee6a4SAndroid Build Coastguard Worker if isinstance(search, str): 34*bb4ee6a4SAndroid Build Coastguard Worker search = re.escape(search) 35*bb4ee6a4SAndroid Build Coastguard Worker contents = file_path.read_text() 36*bb4ee6a4SAndroid Build Coastguard Worker (contents, count) = re.subn(search, replace, contents) 37*bb4ee6a4SAndroid Build Coastguard Worker if count > 0: 38*bb4ee6a4SAndroid Build Coastguard Worker print(f"replacing '{search}' with '{replace}' in {file_path}") 39*bb4ee6a4SAndroid Build Coastguard Worker file_path.write_text(contents) 40*bb4ee6a4SAndroid Build Coastguard Worker 41*bb4ee6a4SAndroid Build Coastguard Worker 42*bb4ee6a4SAndroid Build Coastguard Workerdef replace_in_files(glob: str, replacements: List[Tuple[SearchPattern, Replacement]]): 43*bb4ee6a4SAndroid Build Coastguard Worker for file in Path().glob(glob): 44*bb4ee6a4SAndroid Build Coastguard Worker for search, replace in replacements: 45*bb4ee6a4SAndroid Build Coastguard Worker replace_in_file(file, search, replace) 46*bb4ee6a4SAndroid Build Coastguard Worker 47*bb4ee6a4SAndroid Build Coastguard Worker 48*bb4ee6a4SAndroid Build Coastguard Workerdef replace_path_in_all_cargo_toml(old_path: Path, new_path: Path): 49*bb4ee6a4SAndroid Build Coastguard Worker "Replace path in all cargo.toml files, accounting for relative paths." 50*bb4ee6a4SAndroid Build Coastguard Worker for toml in Path().glob("**/Cargo.toml"): 51*bb4ee6a4SAndroid Build Coastguard Worker crate_dir = toml.parent 52*bb4ee6a4SAndroid Build Coastguard Worker old_rel = os.path.relpath(old_path, crate_dir) 53*bb4ee6a4SAndroid Build Coastguard Worker new_rel = os.path.relpath(new_path, crate_dir) 54*bb4ee6a4SAndroid Build Coastguard Worker replace_in_file(toml, re.escape(f'path = "{old_rel}"'), f'path = "{new_rel}"') 55*bb4ee6a4SAndroid Build Coastguard Worker 56*bb4ee6a4SAndroid Build Coastguard Worker 57*bb4ee6a4SAndroid Build Coastguard Workerdef update_path_deps(toml: Path, from_path: Path, to_path: Path): 58*bb4ee6a4SAndroid Build Coastguard Worker "Update path deps in toml file after moving it" 59*bb4ee6a4SAndroid Build Coastguard Worker contents = toml.read_text() 60*bb4ee6a4SAndroid Build Coastguard Worker for old_dep in re.findall('{ path = "([^"]+)"', contents): 61*bb4ee6a4SAndroid Build Coastguard Worker new_dep = os.path.relpath((from_path / old_dep).resolve(), to_path) 62*bb4ee6a4SAndroid Build Coastguard Worker contents = contents.replace(f'path = "{old_dep}"', f'path = "{new_dep}"') 63*bb4ee6a4SAndroid Build Coastguard Worker toml.write_text(contents) 64*bb4ee6a4SAndroid Build Coastguard Worker 65*bb4ee6a4SAndroid Build Coastguard Worker 66*bb4ee6a4SAndroid Build Coastguard Workerdef move_crate(from_path: Path, to_path: Path): 67*bb4ee6a4SAndroid Build Coastguard Worker "Move crate and update dependencies" 68*bb4ee6a4SAndroid Build Coastguard Worker print(f"{from_path} -> {to_path}") 69*bb4ee6a4SAndroid Build Coastguard Worker if to_path.exists(): 70*bb4ee6a4SAndroid Build Coastguard Worker shutil.rmtree(to_path) 71*bb4ee6a4SAndroid Build Coastguard Worker shutil.copytree(str(from_path), str(to_path)) 72*bb4ee6a4SAndroid Build Coastguard Worker update_path_deps(to_path / "Cargo.toml", from_path, to_path) 73*bb4ee6a4SAndroid Build Coastguard Worker replace_in_files("**/*/Cargo.toml", [(str(from_path), str(to_path))]) 74*bb4ee6a4SAndroid Build Coastguard Worker replace_in_file(Path("Cargo.toml"), str(from_path), str(to_path)) 75*bb4ee6a4SAndroid Build Coastguard Worker 76*bb4ee6a4SAndroid Build Coastguard Worker 77*bb4ee6a4SAndroid Build Coastguard Workerdef update_workspace_members(): 78*bb4ee6a4SAndroid Build Coastguard Worker members: list[str] = [] 79*bb4ee6a4SAndroid Build Coastguard Worker members.append("members = [") 80*bb4ee6a4SAndroid Build Coastguard Worker for toml in sorted(Path().glob("*/Cargo.toml")): 81*bb4ee6a4SAndroid Build Coastguard Worker members.append(f' "{toml.parent}",') 82*bb4ee6a4SAndroid Build Coastguard Worker for toml in sorted(Path().glob("common/*/Cargo.toml")): 83*bb4ee6a4SAndroid Build Coastguard Worker members.append(f' "{toml.parent}",') 84*bb4ee6a4SAndroid Build Coastguard Worker members.append(' "third_party/vmm_vhost",') 85*bb4ee6a4SAndroid Build Coastguard Worker 86*bb4ee6a4SAndroid Build Coastguard Worker members.append("]") 87*bb4ee6a4SAndroid Build Coastguard Worker replace_in_file(Path("Cargo.toml"), re.compile(r"members = \[[^\]]+\]"), "\n".join(members)) 88*bb4ee6a4SAndroid Build Coastguard Worker 89*bb4ee6a4SAndroid Build Coastguard Worker 90*bb4ee6a4SAndroid Build Coastguard Worker@contextmanager 91*bb4ee6a4SAndroid Build Coastguard Workerdef chdir(path: Union[Path, str]): 92*bb4ee6a4SAndroid Build Coastguard Worker origin = Path().absolute() 93*bb4ee6a4SAndroid Build Coastguard Worker try: 94*bb4ee6a4SAndroid Build Coastguard Worker os.chdir(path) 95*bb4ee6a4SAndroid Build Coastguard Worker yield 96*bb4ee6a4SAndroid Build Coastguard Worker finally: 97*bb4ee6a4SAndroid Build Coastguard Worker os.chdir(origin) 98*bb4ee6a4SAndroid Build Coastguard Worker 99*bb4ee6a4SAndroid Build Coastguard Worker 100*bb4ee6a4SAndroid Build Coastguard Workerdef copy_crate_src_to_module(source: str, destination: str): 101*bb4ee6a4SAndroid Build Coastguard Worker shutil.rmtree(destination, ignore_errors=True) 102*bb4ee6a4SAndroid Build Coastguard Worker shutil.copytree(source, destination) 103*bb4ee6a4SAndroid Build Coastguard Worker with chdir(destination): 104*bb4ee6a4SAndroid Build Coastguard Worker Path("lib.rs").rename("mod.rs") 105*bb4ee6a4SAndroid Build Coastguard Worker 106*bb4ee6a4SAndroid Build Coastguard Worker 107*bb4ee6a4SAndroid Build Coastguard WorkerIMPORT = """pub mod linux; 108*bb4ee6a4SAndroid Build Coastguard Worker 109*bb4ee6a4SAndroid Build Coastguard Worker#[cfg(windows)] 110*bb4ee6a4SAndroid Build Coastguard Workerpub mod windows; 111*bb4ee6a4SAndroid Build Coastguard Worker""" 112*bb4ee6a4SAndroid Build Coastguard Worker 113*bb4ee6a4SAndroid Build Coastguard WorkerBUILD_RS = """\ 114*bb4ee6a4SAndroid Build Coastguard Worker// Copyright 2022 The ChromiumOS Authors 115*bb4ee6a4SAndroid Build Coastguard Worker// Use of this source code is governed by a BSD-style license that can be 116*bb4ee6a4SAndroid Build Coastguard Worker// found in the LICENSE file. 117*bb4ee6a4SAndroid Build Coastguard Worker 118*bb4ee6a4SAndroid Build Coastguard Workerfn main() { 119*bb4ee6a4SAndroid Build Coastguard Worker cc::Build::new() 120*bb4ee6a4SAndroid Build Coastguard Worker .file("src/windows/stdio_fileno.c") 121*bb4ee6a4SAndroid Build Coastguard Worker .compile("stdio_fileno"); 122*bb4ee6a4SAndroid Build Coastguard Worker} 123*bb4ee6a4SAndroid Build Coastguard Worker""" 124*bb4ee6a4SAndroid Build Coastguard Worker 125*bb4ee6a4SAndroid Build Coastguard Worker 126*bb4ee6a4SAndroid Build Coastguard Workerdef main(): 127*bb4ee6a4SAndroid Build Coastguard Worker os.chdir(Path(__file__).parent.parent.parent) 128*bb4ee6a4SAndroid Build Coastguard Worker update_workspace_members() 129*bb4ee6a4SAndroid Build Coastguard Worker 130*bb4ee6a4SAndroid Build Coastguard Worker 131*bb4ee6a4SAndroid Build Coastguard Workermain() 132