| 229 | |
| 230 | |
| 231 | def main() -> None: |
| 232 | parser = argparse.ArgumentParser() |
| 233 | parser.add_argument( |
| 234 | "--extra-dirs", |
| 235 | action="append", |
| 236 | default=[], |
| 237 | ) |
| 238 | args = parser.parse_args() |
| 239 | |
| 240 | lint_config = [ |
| 241 | "\n" "# BEGIN LINT CONFIG\n", |
| 242 | "# DO NOT EDIT. Automatically generated by bin/gen-lints.\n", |
| 243 | "[workspace.lints.rust]\n", |
| 244 | *(f'{lint} = "allow"\n' for lint in ALLOW_RUST_LINTS), |
| 245 | *(f'{lint} = "warn"\n' for lint in WARN_RUST_LINTS), |
| 246 | f"unexpected_cfgs = {{ level = \"warn\", check-cfg = ['cfg({CHECK_CFGS})'] }}\n", |
| 247 | "\n", |
| 248 | "[workspace.lints.rustdoc]\n", |
| 249 | *(f'{lint} = "allow"\n' for lint in ALLOW_RUST_DOC_LINTS), |
| 250 | "\n", |
| 251 | "[workspace.lints.clippy]\n", |
| 252 | *( |
| 253 | f'{lint} = {{ level = "allow", priority = {priority} }}\n' |
| 254 | for (lint, priority) in ALLOW_CLIPPY_LINTS |
| 255 | ), |
| 256 | *(f'{lint} = "warn"\n' for lint in WARN_CLIPPY_LINTS), |
| 257 | "# END LINT CONFIG\n", |
| 258 | ] |
| 259 | |
| 260 | for workspace_root in [".", *args.extra_dirs]: |
| 261 | workspace_cargo_toml = Path(f"{workspace_root}/Cargo.toml") |
| 262 | |
| 263 | # Make sure the workspace Cargo.toml files have the lint config. |
| 264 | contents = workspace_cargo_toml.read_text().splitlines(keepends=True) |
| 265 | try: |
| 266 | # Overwrite existing lint configuration block. |
| 267 | start = contents.index(lint_config[1]) - 2 |
| 268 | end = contents.index(lint_config[-1]) |
| 269 | new_contents = contents[:start] + lint_config + contents[end + 1 :] |
| 270 | except ValueError: |
| 271 | # No existing lint configuration block. Add a new one to the end |
| 272 | # of the file. |
| 273 | new_contents = contents + lint_config |
| 274 | # Only write file if the content changed. |
| 275 | if "".join(new_contents) != "".join(contents): |
| 276 | tmp_file_path = None |
| 277 | try: |
| 278 | # Overwrite the file atomically so that there is never a half-written file. |
| 279 | with tempfile.NamedTemporaryFile( |
| 280 | "w", delete=False, dir=workspace_root, encoding="utf-8" |
| 281 | ) as tmp_file: |
| 282 | tmp_file.write("".join(new_contents)) |
| 283 | tmp_file_path = tmp_file.name |
| 284 | os.replace(tmp_file_path, workspace_cargo_toml) |
| 285 | except: |
| 286 | if tmp_file_path: |
| 287 | try: |
| 288 | os.remove(tmp_file_path) |