| # Copyright 2024 The Chromium Authors |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| """Top-level presubmit for //third_party/rust |
| |
| See https://www.chromium.org/developers/how-tos/depottools/presubmit-scripts |
| for more details about the presubmit API built into depot_tools. |
| """ |
| |
| PRESUBMIT_VERSION = '2.0.0' |
| |
| import re |
| |
| |
| def CheckCargoMetadataLockedOffline(input_api, output_api): |
| # Allow *uploading* results of `gnrt update` even if `gnrt vendor` wasn't |
| # run yet. OTOH, continue checking if committing a CL - in this case the |
| # `Cargo.toml`, `Cargo.lock`, and the vendored files should all be valid |
| # for `cargo --offline --locked ...` processing. |
| if not input_api.is_committing: |
| return [] |
| |
| class CustomPresubmitError(output_api.PresubmitError): |
| def __init__(self, message, items=None, long_text='', locations=None, show_callstack=None): |
| custom_msg = ( |
| "ERROR: `cargo metadata --locked --offline` failed for `third_party/rust`\n" |
| "This should usually be resolved by running: `tools/crates/run_gnrt.py vendor`\n" |
| "\n" |
| ) + message |
| super().__init__(custom_msg, items, long_text, locations, show_callstack) |
| |
| repo_root = input_api.change.RepositoryRoot() |
| cmd = [ |
| input_api.python_executable, |
| input_api.os_path.join('tools', 'crates', 'run_cargo.py'), |
| '-Z', 'bindeps', |
| '-Z', 'unstable-options', |
| '-C', input_api.os_path.join('third_party', 'rust', 'chromium_crates_io'), |
| 'metadata', |
| '--locked', |
| '--offline', |
| ] |
| test = input_api.Command( |
| name='Check `cargo metadata --locked --offline` for `third_party/rust`', |
| cmd=cmd, |
| kwargs={'cwd': repo_root}, |
| message=CustomPresubmitError, |
| ) |
| return input_api.RunTests([test]) |
| |
| |
| def CheckForManualEditsOfGnrtAutogeneratedFiles(input_api, output_api): |
| GNRT_INPUTS = [ |
| "tools/crates/gnrt/.*", |
| "tools/crates/run_gnrt.py", |
| "third_party/rust/chromium_crates_io/patches/.*", |
| "third_party/rust/chromium_crates_io/Cargo.lock", |
| "third_party/rust/chromium_crates_io/Cargo.toml", |
| "third_party/rust/chromium_crates_io/BUILD.gn.hbs", |
| "third_party/rust/chromium_crates_io/README.chromium.hbs", |
| "third_party/rust/chromium_crates_io/gnrt_config.toml", |
| ] |
| GNRT_OUTPUTS = [ |
| "third_party/rust/chromium_crates_io/vendor/.*", |
| "third_party/rust/[^/]*/v[0-9_]*/BUILD.gn", |
| "third_party/rust/[^/]*/v[0-9_]*/README.chromium", |
| ] |
| |
| skip_presubmit_footer = input_api.change.GitFootersFromDescription().get( |
| 'No-Gnrt-Presubmits', []) |
| if skip_presubmit_footer: |
| return [] |
| |
| input_regexes = [re.compile(r) for r in GNRT_INPUTS] |
| output_regexes = [re.compile(r) for r in GNRT_OUTPUTS] |
| is_input_path_predicate = lambda p: any(r.match(p) for r in input_regexes) |
| is_output_path_predicate = lambda p: any( |
| r.match(p) for r in output_regexes) |
| |
| affected_paths = [ |
| f.UnixLocalPath() for f in input_api.change.AffectedFiles() |
| ] |
| affected_input_paths = filter(is_input_path_predicate, affected_paths) |
| if not any(affected_input_paths): |
| affected_output_paths = filter(is_output_path_predicate, |
| affected_paths) |
| |
| error_msg_paths_count = 0 |
| error_msg_paths_snippet = "" |
| for path in affected_output_paths: |
| if error_msg_paths_count == 5: |
| error_msg_paths_snippet += f"\n ..." |
| break |
| else: |
| error_msg_paths_snippet += f"\n {path}" |
| error_msg_paths_count += 1 |
| if error_msg_paths_count != 0: |
| # TODO(lukasza): Ideally we would give a suggestion to run `gnrt`, |
| # but `tools/crates/run_gnrt.py vendor` will only check the crate |
| # version and won't redownload if the version matches expectations |
| # (even if crate sources have been modified). |
| return [output_api.PresubmitError( |
| f"ERROR: The CL manually changes files auto-generated by `gnrt`", |
| long_text=\ |
| f"The CL modifies the following auto-generated file(s):" + |
| f"{error_msg_paths_snippet}\n" + |
| f"without modifying any generator inputs.\n" + |
| f"See `//third_party/rust/README.md` for instructions for running `gnrt`. " + |
| f"Add 'No-Gnrt-Presubmits: <reason>' to the CL description " + |
| f"to disable this presubmit (`git cl upload` may require " + |
| f"using `--bypass-hooks`)." |
| )] |
| |
| return [] |