Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit 367cf36

Browse files
committed
Add command to analyze crate imports for problems.
Bug: http://b/339424309 Test: treehugger Change-Id: Ib2e07564c0314f6196d7619f6e7d95ccb754814c
1 parent 4cbb44c commit 367cf36

File tree

2 files changed

+77
-0
lines changed

2 files changed

+77
-0
lines changed

tools/external_crates/crate_tool/src/main.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ enum Cmd {
6161
#[command(flatten)]
6262
crates: MigrationCrateList,
6363
},
64+
/// Analyze a crate to see if it can be imported.
65+
#[command(hide = true)]
66+
AnalyzeImport {
67+
/// The crate name.
68+
crate_name: String,
69+
},
6470
/// Import a crate and its dependencies into the monorepo.
6571
#[command(hide = true)]
6672
Import {
@@ -211,6 +217,7 @@ fn main() -> Result<()> {
211217
managed_repo.regenerate(crates.to_list(&managed_repo)?.into_iter(), true)
212218
}
213219
Cmd::PreuploadCheck { files } => managed_repo.preupload_check(&files),
220+
Cmd::AnalyzeImport { crate_name } => managed_repo.analyze_import(&crate_name),
214221
Cmd::Import { crate_name } => managed_repo.import(&crate_name),
215222
Cmd::FixLicenses { crates } => {
216223
managed_repo.fix_licenses(crates.to_list(&managed_repo)?.into_iter())

tools/external_crates/crate_tool/src/managed_repo.rs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use std::{
2323
};
2424

2525
use anyhow::{anyhow, Context, Result};
26+
use crates_index::DependencyKind;
2627
use glob::glob;
2728
use google_metadata::GoogleMetadata;
2829
use itertools::Itertools;
@@ -364,6 +365,75 @@ impl ManagedRepo {
364365

365366
Ok(())
366367
}
368+
pub fn analyze_import(&self, crate_name: &str) -> Result<()> {
369+
if self.contains(crate_name) {
370+
println!("Crate already imported at {}", self.managed_dir_for(crate_name));
371+
return Ok(());
372+
}
373+
let legacy_dir = self.legacy_dir_for(crate_name, None)?;
374+
if legacy_dir.abs().exists() {
375+
println!("Legacy crate already imported at {}", legacy_dir);
376+
return Ok(());
377+
}
378+
379+
let mut managed_crates = self.new_cc();
380+
managed_crates.add_from(self.managed_dir().rel())?;
381+
let legacy_crates = self.legacy_crates()?;
382+
383+
let cio_crate = self.crates_io.get_crate(crate_name)?;
384+
385+
for version in cio_crate.versions() {
386+
println!("Version {}", version.version());
387+
let mut found_problems = false;
388+
for (dep, req) in version.android_deps_with_version_reqs() {
389+
let cc = if managed_crates.contains_name(dep.crate_name()) {
390+
&managed_crates
391+
} else {
392+
&legacy_crates
393+
};
394+
if !cc.contains_name(dep.crate_name()) {
395+
found_problems = true;
396+
println!(
397+
" Dep {} {} has not been imported to Android",
398+
dep.crate_name(),
399+
dep.requirement()
400+
);
401+
if matches!(dep.kind(), DependencyKind::Dev) {
402+
println!(" But this is a dev dependency, probably only needed if you want to run the tests");
403+
}
404+
if dep.is_optional() {
405+
println!(" But this is an optional dependency, used by the following features: {}", dep.features().join(", "));
406+
}
407+
continue;
408+
}
409+
let versions = cc.get_versions(dep.crate_name()).collect::<Vec<_>>();
410+
let has_matching_version =
411+
versions.iter().any(|(nv, _)| req.matches_relaxed(nv.version()));
412+
if !has_matching_version {
413+
found_problems = true;
414+
}
415+
if !has_matching_version || versions.len() > 1 {
416+
if has_matching_version {
417+
println!(" Dep {} has multiple versions available. You may need to override the default choice in cargo_embargo.json", dep.crate_name());
418+
}
419+
for (_, dep_crate) in versions {
420+
println!(
421+
" Dep {} {} is {}satisfied by v{} at {}",
422+
dep.crate_name(),
423+
dep.requirement(),
424+
if req.matches_relaxed(dep_crate.version()) { "" } else { "not " },
425+
dep_crate.version(),
426+
dep_crate.path()
427+
);
428+
}
429+
}
430+
}
431+
if !found_problems {
432+
println!(" No problems found with this version.")
433+
}
434+
}
435+
Ok(())
436+
}
367437
pub fn import(&self, crate_name: &str) -> Result<()> {
368438
let (new_deps, pseudo_crate) = self.add_crate_and_dependencies(crate_name)?;
369439

0 commit comments

Comments
 (0)