Skip to content

Commit 1fcf031

Browse files
committed
Reduce the number of cargo metadata
1 parent bb52cd7 commit 1fcf031

File tree

1 file changed

+29
-12
lines changed
  • onlinejudge_verify/languages

1 file changed

+29
-12
lines changed

onlinejudge_verify/languages/rust.py

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from onlinejudge_verify.languages.models import Language, LanguageEnvironment
1818

1919
logger = getLogger(__name__)
20+
_metadata_by_manifest_path: Dict[pathlib.Path, Dict[str, Any]] = {}
2021
_cargo_checked_workspaces: Set[pathlib.Path] = set()
2122
_related_source_files_by_workspace: Dict[pathlib.Path, Dict[pathlib.Path, FrozenSet[pathlib.Path]]] = {}
2223

@@ -300,29 +301,45 @@ def list_environments(self, path: pathlib.Path, *, basedir: pathlib.Path) -> Seq
300301

301302

302303
def _cargo_metadata(cwd: pathlib.Path) -> Dict[str, Any]:
303-
"""Runs `cargo metadata` for a Cargo.toml file in `cwd` or its parent directories.
304+
"""Returns "metadata" for a Cargo.toml file in `cwd` or its parent directories.
304305
305306
:raises ValueError: if `cwd` is not absolute or contains `..`
307+
:returns: Output of `cargo metadata` command
306308
"""
307309
if not cwd.is_absolute() or '..' in cwd.parts:
308310
raise ValueError(f'the `cwd` parameter must be absolute and must not contain `..`: {cwd}')
309311

310-
def find_root_manifest_for_wd() -> pathlib.Path:
311-
# https://docs.rs/cargo/0.48.0/cargo/util/important_paths/fn.find_root_manifest_for_wd.html
312-
for directory in [cwd, *cwd.parents]:
313-
manifest_path = directory / 'Cargo.toml'
314-
if manifest_path.exists():
315-
return manifest_path
316-
raise RuntimeError(f'Could not find `Cargo.toml` in `{cwd}` or any parent directory')
317-
318-
return _cargo_metadata_by_manifest_path(find_root_manifest_for_wd())
312+
# https://docs.rs/cargo/0.49.0/src/cargo/util/important_paths.rs.html#6-20
313+
for directory in [cwd, *cwd.parents]:
314+
manifest_path = directory / 'Cargo.toml'
315+
if manifest_path.exists():
316+
return _cargo_metadata_by_manifest_path(manifest_path)
317+
raise RuntimeError(f'could not find `Cargo.toml` in `{cwd}` or any parent directory')
319318

320319

321-
@functools.lru_cache(maxsize=None)
322320
def _cargo_metadata_by_manifest_path(manifest_path: pathlib.Path) -> Dict[str, Any]:
321+
"""Returns "metadata" for a certain `Cargo.toml`.
322+
323+
:returns: Output of `cargo metadata` command
324+
"""
325+
if manifest_path in _metadata_by_manifest_path:
326+
return _metadata_by_manifest_path[manifest_path]
327+
328+
metadata = _run_cargo_metadata(manifest_path)
329+
root_manifest_path = pathlib.Path(metadata['workspace_root'], 'Cargo.toml')
330+
if root_manifest_path != manifest_path:
331+
metadata = _run_cargo_metadata(root_manifest_path)
332+
333+
for key in [root_manifest_path, *(pathlib.Path(p['manifest_path']) for p in metadata['packages'] if p['id'] in metadata['workspace_members'])]:
334+
_metadata_by_manifest_path[key] = metadata
335+
336+
return metadata
337+
338+
339+
def _run_cargo_metadata(manifest_path: pathlib.Path) -> Dict[str, Any]:
323340
"""Runs `cargo metadata` for a certain `Cargo.toml`.
324341
325-
This function is considered to be executed for every Cargo.toml in the repository.
342+
This function is considered to be executed just once for every Cargo.toml in the repository.
326343
For detailed information about `cargo metadata`, see:
327344
328345
- <https://doc.rust-lang.org/cargo/commands/cargo-metadata.html#output-format>

0 commit comments

Comments
 (0)