Merge changes Ic1e88d3c,I86805b5f into main
* changes:
Get rid of pseudo_crate from crate struct.
Add a RepoPath struct.
diff --git a/tools/external_crates/crate_health/src/android_bp.rs b/tools/external_crates/crate_health/src/android_bp.rs
index 5b400d7..ec5b937 100644
--- a/tools/external_crates/crate_health/src/android_bp.rs
+++ b/tools/external_crates/crate_health/src/android_bp.rs
@@ -24,7 +24,7 @@
use anyhow::{anyhow, Context, Result};
use threadpool::ThreadPool;
-use crate::{Crate, NameAndVersion, NameAndVersionMap, NamedAndVersioned};
+use crate::{Crate, NameAndVersion, NameAndVersionMap, NamedAndVersioned, RepoPath};
pub fn generate_android_bps<'a, T: Iterator<Item = &'a Crate>>(
crates: T,
@@ -38,10 +38,9 @@
let tx = tx.clone();
let crate_name = krate.name().to_string();
let crate_version = krate.version().clone();
- let repo_root = krate.root().to_path_buf();
- let test_path = krate.staging_path();
+ let staging_path = krate.staging_path();
pool.execute(move || {
- tx.send((crate_name, crate_version, generate_android_bp(&repo_root, &test_path)))
+ tx.send((crate_name, crate_version, generate_android_bp(&staging_path)))
.expect("Failed to send");
});
}
@@ -52,15 +51,12 @@
Ok(results)
}
-pub(crate) fn generate_android_bp(
- repo_root: &impl AsRef<Path>,
- staging_path: &impl AsRef<Path>,
-) -> Result<Output> {
- let generate_android_bp_output = run_cargo_embargo(repo_root, staging_path)?;
+pub(crate) fn generate_android_bp(staging_path: &RepoPath) -> Result<Output> {
+ let generate_android_bp_output = run_cargo_embargo(staging_path)?;
if !generate_android_bp_output.status.success() {
println!(
"cargo_embargo failed for {}\nstdout:\n{}\nstderr:\n{}",
- staging_path.as_ref().display(),
+ staging_path,
from_utf8(&generate_android_bp_output.stdout)?,
from_utf8(&generate_android_bp_output.stderr)?
);
@@ -68,12 +64,9 @@
Ok(generate_android_bp_output)
}
-fn run_cargo_embargo(
- repo_root: &impl AsRef<Path>,
- staging_path: &impl AsRef<Path>,
-) -> Result<Output> {
+fn run_cargo_embargo(staging_path: &RepoPath) -> Result<Output> {
// Make sure we can find bpfmt.
- let host_bin = repo_root.as_ref().join("out/host/linux-x86/bin");
+ let host_bin = staging_path.with_same_root(&"out/host/linux-x86/bin").abs();
let new_path = match env::var_os("PATH") {
Some(p) => {
let mut paths = vec![host_bin];
@@ -83,12 +76,12 @@
None => host_bin.as_os_str().into(),
};
- let staging_path_absolute = repo_root.as_ref().join(staging_path);
- let mut cmd = Command::new(repo_root.as_ref().join("out/host/linux-x86/bin/cargo_embargo"));
+ let mut cmd =
+ Command::new(staging_path.with_same_root(&"out/host/linux-x86/bin/cargo_embargo").abs());
cmd.args(["generate", "cargo_embargo.json"])
.env("PATH", new_path)
- .env("ANDROID_BUILD_TOP", repo_root.as_ref())
- .current_dir(&staging_path_absolute)
+ .env("ANDROID_BUILD_TOP", staging_path.root())
+ .current_dir(staging_path.abs())
.output()
.context(format!("Failed to execute {:?}", cmd.get_program()))
}
diff --git a/tools/external_crates/crate_health/src/bin/health_report.rs b/tools/external_crates/crate_health/src/bin/health_report.rs
index 7a4ffdb..bb78b33 100644
--- a/tools/external_crates/crate_health/src/bin/health_report.rs
+++ b/tools/external_crates/crate_health/src/bin/health_report.rs
@@ -40,7 +40,7 @@
maybe_build_cargo_embargo(&args.repo_root, false)?;
let mut cc = CrateCollection::new(args.repo_root);
- cc.add_from(&"external/rust/crates", None::<&&str>)?;
+ cc.add_from(&"external/rust/crates")?;
cc.map_field_mut().retain(|_nv, krate| krate.is_crates_io());
cc.stage_crates()?;
diff --git a/tools/external_crates/crate_health/src/bin/migration_report.rs b/tools/external_crates/crate_health/src/bin/migration_report.rs
index 900d9aa..0901f53 100644
--- a/tools/external_crates/crate_health/src/bin/migration_report.rs
+++ b/tools/external_crates/crate_health/src/bin/migration_report.rs
@@ -17,7 +17,8 @@
use anyhow::Result;
use clap::Parser;
use crate_health::{
- default_output_dir, default_repo_root, maybe_build_cargo_embargo, migrate, ReportEngine,
+ default_output_dir, default_repo_root, maybe_build_cargo_embargo, migrate, RepoPath,
+ ReportEngine,
};
/// Generate a health report for crates in external/rust/crates
@@ -38,8 +39,10 @@
maybe_build_cargo_embargo(&args.repo_root, false)?;
- let migration =
- migrate(args.repo_root, &"external/rust/crates", &"out/rust-crate-migration-report")?;
+ let migration = migrate(
+ RepoPath::new(args.repo_root.clone(), &"external/rust/crates"),
+ RepoPath::new(args.repo_root.clone(), &"out/rust-crate-migration-report"),
+ )?;
let re = ReportEngine::new()?;
diff --git a/tools/external_crates/crate_health/src/crate_collection.rs b/tools/external_crates/crate_health/src/crate_collection.rs
index 413b5bc..7aef6ce 100644
--- a/tools/external_crates/crate_health/src/crate_collection.rs
+++ b/tools/external_crates/crate_health/src/crate_collection.rs
@@ -40,19 +40,11 @@
pub fn new<P: Into<PathBuf>>(repo_root: P) -> CrateCollection {
CrateCollection { crates: BTreeMap::new(), repo_root: repo_root.into() }
}
- pub fn add_from(
- &mut self,
- path: &impl AsRef<Path>,
- pseudo_crate: Option<&impl AsRef<Path>>,
- ) -> Result<()> {
+ pub fn add_from(&mut self, path: &impl AsRef<Path>) -> Result<()> {
for entry_or_err in WalkDir::new(self.repo_root.join(path)) {
let entry = entry_or_err?;
if entry.file_name() == "Cargo.toml" {
- match Crate::from(
- &entry.path(),
- &self.repo_root.as_path(),
- pseudo_crate.map(|p| p.as_ref()),
- ) {
+ match Crate::from(&entry.path(), &self.repo_root.as_path()) {
Ok(krate) => self.crates.insert_or_error(
NameAndVersion::new(krate.name().to_string(), krate.version().clone()),
krate,
diff --git a/tools/external_crates/crate_health/src/crate_type.rs b/tools/external_crates/crate_health/src/crate_type.rs
index c2d93a9..bfe7d91 100644
--- a/tools/external_crates/crate_health/src/crate_type.rs
+++ b/tools/external_crates/crate_health/src/crate_type.rs
@@ -29,19 +29,15 @@
use crate::{
copy_dir, ensure_exists_and_empty, name_and_version::IsUpgradableTo, CrateError,
- NameAndVersionRef, NamedAndVersioned,
+ NameAndVersionRef, NamedAndVersioned, RepoPath,
};
#[derive(Debug)]
pub struct Crate {
manifest: Manifest,
- // root is absolute. All other paths are relative to it.
- root: PathBuf,
- relpath: PathBuf,
- pseudo_crate: Option<PathBuf>,
+ path: RepoPath,
- // compatible_dest_version: Option<Version>,
patch_output: Vec<Output>,
generate_android_bp_output: Option<Output>,
android_bp_diff: Option<Output>,
@@ -62,28 +58,21 @@
impl IsUpgradableTo for Crate {}
impl Crate {
- pub fn new<P: Into<PathBuf>, Q: Into<PathBuf>, R: Into<PathBuf>>(
+ pub fn new<P: Into<PathBuf>, Q: Into<PathBuf>>(
manifest: Manifest,
root: P,
relpath: Q,
- pseudo_crate: Option<R>,
) -> Crate {
+ let root: PathBuf = root.into();
Crate {
manifest,
- root: root.into(),
- relpath: relpath.into(),
- pseudo_crate: pseudo_crate.map(|p| p.into()),
- // compatible_dest_version: None,
+ path: RepoPath::new(root.clone(), relpath),
patch_output: Vec::new(),
generate_android_bp_output: None,
android_bp_diff: None,
}
}
- pub fn from<P: Into<PathBuf>, Q: Into<PathBuf>>(
- cargo_toml: &impl AsRef<Path>,
- root: P,
- pseudo_crate: Option<Q>,
- ) -> Result<Crate> {
+ pub fn from<P: Into<PathBuf>>(cargo_toml: &impl AsRef<Path>, root: P) -> Result<Crate> {
let root: PathBuf = root.into();
let manifest_dir = cargo_toml.as_ref().parent().ok_or(anyhow!(
"Failed to get parent directory of manifest at {}",
@@ -94,36 +83,32 @@
let (manifest, _nested) =
read_manifest(cargo_toml.as_ref(), source_id, &Config::default()?)?;
match manifest {
- cargo::core::EitherManifest::Real(r) => Ok(Crate::new(r, root, relpath, pseudo_crate)),
+ cargo::core::EitherManifest::Real(r) => Ok(Crate::new(r, root, relpath)),
cargo::core::EitherManifest::Virtual(_) => {
Err(anyhow!(CrateError::VirtualCrate(cargo_toml.as_ref().to_path_buf())))
}
}
}
- pub fn root(&self) -> &Path {
- self.root.as_path()
+ pub fn path(&self) -> &RepoPath {
+ &self.path
}
- pub fn relpath(&self) -> &Path {
- &self.relpath.as_path()
+ pub fn android_bp(&self) -> RepoPath {
+ self.path.join(&"Android.bp")
}
- pub fn path(&self) -> PathBuf {
- self.root.join(&self.relpath)
+ pub fn cargo_embargo_json(&self) -> RepoPath {
+ self.path.join(&"cargo_embargo.json")
}
- pub fn android_bp(&self) -> PathBuf {
- self.relpath().join("Android.bp")
+ pub fn staging_path(&self) -> RepoPath {
+ self.path.with_same_root(
+ Path::new("out/rust-crate-temporary-build").join(self.staging_dir_name()),
+ )
}
- pub fn cargo_embargo_json(&self) -> PathBuf {
- self.path().join("cargo_embargo.json")
- }
- pub fn staging_path(&self) -> PathBuf {
- Path::new("out/rust-crate-temporary-build").join(self.staging_dir_name())
- }
- pub fn patch_dir(&self) -> PathBuf {
- self.staging_path().join("patches")
+ pub fn patch_dir(&self) -> RepoPath {
+ self.staging_path().join(&"patches")
}
pub fn staging_dir_name(&self) -> String {
- if let Some(dirname) = self.relpath.file_name().and_then(|x| x.to_str()) {
+ if let Some(dirname) = self.path.rel().file_name().and_then(|x| x.to_str()) {
if dirname == self.name() {
return dirname.to_string();
}
@@ -132,17 +117,17 @@
}
pub fn aosp_url(&self) -> Option<String> {
- if self.relpath.starts_with("external/rust/crates") {
- if self.relpath.ends_with(self.name()) {
+ if self.path.rel().starts_with("external/rust/crates") {
+ if self.path.rel().ends_with(self.name()) {
Some(format!(
"https://android.googlesource.com/platform/{}/+/refs/heads/main",
- self.relpath().display()
+ self.path()
))
- } else if self.relpath.parent()?.ends_with(self.name()) {
+ } else if self.path.rel().parent()?.ends_with(self.name()) {
Some(format!(
"https://android.googlesource.com/platform/{}/+/refs/heads/main/{}",
- self.relpath().parent()?.display(),
- self.relpath().file_name()?.to_str()?
+ self.path().rel().parent()?.display(),
+ self.path().rel().file_name()?.to_str()?
))
} else {
None
@@ -155,9 +140,6 @@
format!("https://crates.io/crates/{}", self.name())
}
- pub fn is_vendored(&self) -> bool {
- self.pseudo_crate.is_some()
- }
pub fn is_crates_io(&self) -> bool {
const NOT_CRATES_IO: &'static [&'static str] = &[
"external/rust/beto-rust/", // Google crates
@@ -166,19 +148,19 @@
"external/rust/cxx/third-party/", // Internal/example code
"external/rust/cxx/demo/", // Internal/example code
];
- !NOT_CRATES_IO.iter().any(|prefix| self.relpath.starts_with(prefix))
+ !NOT_CRATES_IO.iter().any(|prefix| self.path().rel().starts_with(prefix))
}
pub fn is_migration_denied(&self) -> bool {
const MIGRATION_DENYLIST: &'static [&'static str] = &[
"external/rust/crates/openssl/", // It's complicated.
"external/rust/cxx/", // It's REALLY complicated.
];
- MIGRATION_DENYLIST.iter().any(|prefix| self.relpath.starts_with(prefix))
+ MIGRATION_DENYLIST.iter().any(|prefix| self.path().rel().starts_with(prefix))
}
pub fn is_android_bp_healthy(&self) -> bool {
!self.is_migration_denied()
- && self.root().join(self.android_bp()).exists()
- && self.cargo_embargo_json().exists()
+ && self.android_bp().abs().exists()
+ && self.cargo_embargo_json().abs().exists()
&& self.generate_android_bp_success()
&& self.android_bp_unchanged()
}
@@ -193,7 +175,7 @@
}
pub fn print(&self) -> Result<()> {
- println!("{} {} {}", self.name(), self.version(), self.relpath.display());
+ println!("{} {} {}", self.name(), self.version(), self.path());
if let Some(output) = &self.generate_android_bp_output {
println!("generate Android.bp exit status: {}", output.status);
println!("{}", from_utf8(&output.stdout)?);
@@ -209,14 +191,14 @@
// Make a clean copy of the crate in out/
pub fn stage_crate(&self) -> Result<()> {
- let staging_path_absolute = self.root().join(self.staging_path());
+ let staging_path_absolute = self.staging_path().abs();
ensure_exists_and_empty(&staging_path_absolute)?;
remove_dir_all(&staging_path_absolute)
.context(format!("Failed to remove {}", staging_path_absolute.display()))?;
- copy_dir(&self.path(), &staging_path_absolute).context(format!(
+ copy_dir(&self.path().abs(), &staging_path_absolute).context(format!(
"Failed to copy {} to {}",
- self.path().display(),
- staging_path_absolute.display()
+ self.path(),
+ self.staging_path()
))?;
if staging_path_absolute.join(".git").is_dir() {
remove_dir_all(staging_path_absolute.join(".git"))
@@ -228,9 +210,9 @@
pub fn diff_android_bp(&mut self) -> Result<()> {
self.set_diff_output(
diff_android_bp(
- &self.android_bp(),
- &self.staging_path().join("Android.bp"),
- &self.root(),
+ &self.android_bp().rel(),
+ &self.staging_path().join(&"Android.bp").rel(),
+ &self.path.root(),
)
.context("Failed to diff Android.bp".to_string())?,
);
@@ -238,7 +220,7 @@
}
pub fn apply_patches(&mut self) -> Result<()> {
- let patch_dir_absolute = self.root().join(self.patch_dir());
+ let patch_dir_absolute = self.patch_dir().abs();
if patch_dir_absolute.exists() {
for entry in read_dir(&patch_dir_absolute)
.context(format!("Failed to read_dir {}", patch_dir_absolute.display()))?
@@ -254,7 +236,7 @@
let output = Command::new("patch")
.args(["-p1", "-l", "--no-backup-if-mismatch", "-i"])
.arg(&entry_path)
- .current_dir(self.root().join(self.staging_path()))
+ .current_dir(self.staging_path().abs())
.output()?;
if !output.status.success() {
println!(
@@ -296,8 +278,8 @@
fn is_migration_eligible(&self) -> bool {
self.is_crates_io()
&& !self.is_migration_denied()
- && self.root.join(self.android_bp()).exists()
- && self.cargo_embargo_json().exists()
+ && self.android_bp().abs().exists()
+ && self.cargo_embargo_json().abs().exists()
}
fn is_migratable(&self) -> bool {
self.patch_success() && self.generate_android_bp_success() && self.android_bp_unchanged()
@@ -328,12 +310,15 @@
fn test_from_and_properties() -> Result<()> {
let temp_crate_dir = tempdir()?;
let cargo_toml = write_test_manifest(temp_crate_dir.path(), "foo", "1.2.0")?;
- let krate = Crate::from(&cargo_toml, &"/", None::<&&str>)?;
+ let krate = Crate::from(&cargo_toml, &"/")?;
assert_eq!(krate.name(), "foo");
assert_eq!(krate.version().to_string(), "1.2.0");
assert!(krate.is_crates_io());
- assert_eq!(krate.root().join(krate.android_bp()), temp_crate_dir.path().join("Android.bp"));
- assert_eq!(krate.cargo_embargo_json(), temp_crate_dir.path().join("cargo_embargo.json"));
+ assert_eq!(krate.android_bp().abs(), temp_crate_dir.path().join("Android.bp"));
+ assert_eq!(
+ krate.cargo_embargo_json().abs(),
+ temp_crate_dir.path().join("cargo_embargo.json")
+ );
Ok(())
}
@@ -341,7 +326,7 @@
fn test_from_error() -> Result<()> {
let temp_crate_dir = tempdir()?;
let cargo_toml = write_test_manifest(temp_crate_dir.path(), "foo", "1.2.0")?;
- assert!(Crate::from(&cargo_toml, &"/blah", None::<&&str>).is_err());
+ assert!(Crate::from(&cargo_toml, &"/blah").is_err());
Ok(())
}
}
diff --git a/tools/external_crates/crate_health/src/lib.rs b/tools/external_crates/crate_health/src/lib.rs
index c6e66a0..a6f88a1 100644
--- a/tools/external_crates/crate_health/src/lib.rs
+++ b/tools/external_crates/crate_health/src/lib.rs
@@ -48,6 +48,9 @@
};
mod name_and_version;
+pub use self::repo_path::RepoPath;
+mod repo_path;
+
#[cfg(test)]
pub use self::name_and_version_map::try_name_version_map_from_iter;
pub use self::name_and_version_map::{
diff --git a/tools/external_crates/crate_health/src/main.rs b/tools/external_crates/crate_health/src/main.rs
index 15d8865..46cd8bc 100644
--- a/tools/external_crates/crate_health/src/main.rs
+++ b/tools/external_crates/crate_health/src/main.rs
@@ -18,7 +18,7 @@
use clap::{Parser, Subcommand};
use crate_health::{
default_repo_root, maybe_build_cargo_embargo, migrate, CrateCollection, Migratable,
- NameAndVersionMap, NamedAndVersioned,
+ NameAndVersionMap, NamedAndVersioned, RepoPath,
};
#[derive(Parser)]
@@ -145,7 +145,7 @@
}
let mut cc = CrateCollection::new(&args.repo_root);
- cc.add_from(&PathBuf::from("external/rust/crates").join(&crate_name), None::<&&str>)?;
+ cc.add_from(&PathBuf::from("external/rust/crates").join(&crate_name))?;
cc.map_field_mut().retain(|_nv, krate| krate.is_crates_io());
if cc.map_field().len() != 1 {
return Err(anyhow!(
@@ -160,34 +160,23 @@
cc.diff_android_bps()?;
let krate = cc.map_field().values().next().unwrap();
- println!(
- "Found {} v{} in {}",
- krate.name(),
- krate.version(),
- krate.relpath().display()
- );
+ println!("Found {} v{} in {}", krate.name(), krate.version(), krate.path());
let migratable;
if !krate.is_android_bp_healthy() {
if krate.is_migration_denied() {
println!("This crate is on the migration denylist");
}
- if !krate.root().join(krate.android_bp()).exists() {
- println!("There is no Android.bp file in {}", krate.relpath().display());
+ if !krate.android_bp().abs().exists() {
+ println!("There is no Android.bp file in {}", krate.path());
}
- if !krate.cargo_embargo_json().exists() {
- println!(
- "There is no cargo_embargo.json file in {}",
- krate.relpath().display()
- );
+ if !krate.cargo_embargo_json().abs().exists() {
+ println!("There is no cargo_embargo.json file in {}", krate.path());
} else if !krate.generate_android_bp_success() {
- println!(
- "cargo_embargo execution did not succeed for {}",
- krate.relpath().display()
- );
+ println!("cargo_embargo execution did not succeed for {}", krate.path());
} else if !krate.android_bp_unchanged() {
println!(
"Running cargo_embargo on {} produced changes to the Android.bp file:",
- krate.relpath().display()
+ krate.path()
);
println!(
"{}",
@@ -202,9 +191,11 @@
migratable = false;
} else {
let migration = migrate(
- &args.repo_root,
- &PathBuf::from("external/rust/crates").join(&crate_name),
- &"out/rust-crate-migration-report",
+ RepoPath::new(
+ args.repo_root.clone(),
+ PathBuf::from("external/rust/crates").join(&crate_name),
+ ),
+ RepoPath::new(args.repo_root.clone(), &"out/rust-crate-migration-report"),
)?;
let compatible_pairs = migration.compatible_pairs().collect::<Vec<_>>();
if compatible_pairs.len() != 1 {
@@ -243,23 +234,23 @@
let diff_status = Command::new("diff")
.args(["-u", "-r", "-w", "--no-dereference"])
.args(IGNORED_FILES.iter().map(|ignored| format!("--exclude={}", ignored)))
- .arg(pair.source.relpath())
- .arg(pair.dest.staging_path())
+ .arg(pair.source.path().rel())
+ .arg(pair.dest.staging_path().rel())
.current_dir(&args.repo_root)
.spawn()?
.wait()?;
if !diff_status.success() {
println!(
"Found differences between {} and {}",
- pair.source.relpath().display(),
- pair.dest.staging_path().display()
+ pair.source.path(),
+ pair.dest.staging_path()
);
}
println!("All diffs:");
Command::new("diff")
.args(["-u", "-r", "-w", "-q", "--no-dereference"])
- .arg(pair.source.relpath())
- .arg(pair.dest.staging_path())
+ .arg(pair.source.path().rel())
+ .arg(pair.dest.staging_path().rel())
.current_dir(&args.repo_root)
.spawn()?
.wait()?;
diff --git a/tools/external_crates/crate_health/src/migration.rs b/tools/external_crates/crate_health/src/migration.rs
index 318a4c0..b996e04 100644
--- a/tools/external_crates/crate_health/src/migration.rs
+++ b/tools/external_crates/crate_health/src/migration.rs
@@ -15,7 +15,6 @@
use std::{
fs::{copy, read_link, remove_dir_all},
os::unix::fs::symlink,
- path::{Path, PathBuf},
process::Output,
};
@@ -24,7 +23,7 @@
use crate::{
copy_dir, crate_type::diff_android_bp, most_recent_version, CompatibleVersionPair, Crate,
- CrateCollection, Migratable, NameAndVersionMap, PseudoCrate, VersionMatch,
+ CrateCollection, Migratable, NameAndVersionMap, PseudoCrate, RepoPath, VersionMatch,
};
static CUSTOMIZATIONS: &'static [&'static str] =
@@ -34,13 +33,14 @@
impl<'a> CompatibleVersionPair<'a, Crate> {
pub fn copy_customizations(&self) -> Result<()> {
- let dest_dir_absolute = self.dest.root().join(self.dest.staging_path());
+ let dest_dir_absolute = self.dest.staging_path().abs();
for pattern in CUSTOMIZATIONS {
let full_pattern = self.source.path().join(pattern);
for entry in glob(
full_pattern
+ .abs()
.to_str()
- .ok_or(anyhow!("Failed to convert path {} to str", full_pattern.display()))?,
+ .ok_or(anyhow!("Failed to convert path {} to str", full_pattern))?,
)? {
let entry = entry?;
let filename = entry
@@ -51,7 +51,7 @@
copy_dir(&entry, &dest_dir_absolute.join(filename)).context(format!(
"Failed to copy {} to {}",
entry.display(),
- dest_dir_absolute.display()
+ self.dest.staging_path()
))?;
} else {
let dest_file = dest_dir_absolute.join(&filename);
@@ -68,8 +68,8 @@
}
for link in SYMLINKS {
let src_path = self.source.path().join(link);
- if src_path.is_symlink() {
- let dest = read_link(src_path)?;
+ if src_path.abs().is_symlink() {
+ let dest = read_link(src_path.abs())?;
if dest.exists() {
return Err(anyhow!(
"Can't symlink {} -> {} because destination exists",
@@ -84,27 +84,26 @@
}
pub fn diff_android_bps(&self) -> Result<Output> {
diff_android_bp(
- &self.source.android_bp(),
- &self.dest.staging_path().join("Android.bp"),
- &self.source.root(),
+ &self.source.android_bp().rel(),
+ &self.dest.staging_path().join(&"Android.bp").rel(),
+ &self.source.path().root(),
)
.context("Failed to diff Android.bp".to_string())
}
}
-pub fn migrate<P: Into<PathBuf>>(
- repo_root: P,
- source_dir: &impl AsRef<Path>,
- pseudo_crate_dir: &impl AsRef<Path>,
+pub fn migrate(
+ source_dir: RepoPath,
+ pseudo_crate_dir: RepoPath,
) -> Result<VersionMatch<CrateCollection>> {
- let mut source = CrateCollection::new(repo_root);
- source.add_from(source_dir, None::<&&str>)?;
+ let mut source = CrateCollection::new(source_dir.root());
+ source.add_from(&source_dir.rel())?;
source.map_field_mut().retain(|_nv, krate| krate.is_crates_io());
- let pseudo_crate = PseudoCrate::new(source.repo_root().join(pseudo_crate_dir));
- if pseudo_crate.get_path().exists() {
- remove_dir_all(pseudo_crate.get_path())
- .context(format!("Failed to remove {}", pseudo_crate.get_path().display()))?;
+ let pseudo_crate = PseudoCrate::new(pseudo_crate_dir);
+ if pseudo_crate.get_path().abs().exists() {
+ remove_dir_all(pseudo_crate.get_path().abs())
+ .context(format!("Failed to remove {}", pseudo_crate.get_path()))?;
}
pseudo_crate.init(
source
@@ -114,7 +113,7 @@
)?;
let mut dest = CrateCollection::new(source.repo_root());
- dest.add_from(&pseudo_crate_dir.as_ref().join("vendor"), Some(pseudo_crate_dir))?;
+ dest.add_from(&pseudo_crate.get_path().join(&"vendor").rel())?;
let mut version_match = VersionMatch::new(source, dest)?;
diff --git a/tools/external_crates/crate_health/src/pseudo_crate.rs b/tools/external_crates/crate_health/src/pseudo_crate.rs
index 55472c0..bcde2f3 100644
--- a/tools/external_crates/crate_health/src/pseudo_crate.rs
+++ b/tools/external_crates/crate_health/src/pseudo_crate.rs
@@ -14,7 +14,6 @@
use std::{
fs::{create_dir, write},
- path::{Path, PathBuf},
process::Command,
str::from_utf8,
};
@@ -23,7 +22,7 @@
use serde::Serialize;
use tinytemplate::TinyTemplate;
-use crate::{ensure_exists_and_empty, NamedAndVersioned};
+use crate::{ensure_exists_and_empty, NamedAndVersioned, RepoPath};
static CARGO_TOML_TEMPLATE: &'static str = include_str!("templates/Cargo.toml.template");
@@ -39,25 +38,21 @@
}
pub struct PseudoCrate {
- // Absolute path to pseudo-crate.
- path: PathBuf,
+ path: RepoPath,
}
impl PseudoCrate {
- pub fn new<P: Into<PathBuf>>(path: P) -> PseudoCrate {
- PseudoCrate { path: path.into() }
+ pub fn new(path: RepoPath) -> PseudoCrate {
+ PseudoCrate { path }
}
pub fn init<'a>(
&self,
crates: impl Iterator<Item = &'a (impl NamedAndVersioned + 'a)>,
) -> Result<()> {
- if self.path.exists() {
- return Err(anyhow!(
- "Can't init pseudo-crate because {} already exists",
- self.path.display()
- ));
+ if self.path.abs().exists() {
+ return Err(anyhow!("Can't init pseudo-crate because {} already exists", self.path));
}
- ensure_exists_and_empty(&self.path)?;
+ ensure_exists_and_empty(&self.path.abs())?;
let mut deps = Vec::new();
for krate in crates {
@@ -80,23 +75,24 @@
let mut tt = TinyTemplate::new();
tt.add_template("cargo_toml", CARGO_TOML_TEMPLATE)?;
- let cargo_toml = self.path.join("Cargo.toml");
+ let cargo_toml = self.path.join(&"Cargo.toml").abs();
write(&cargo_toml, tt.render("cargo_toml", &CargoToml { deps })?)?;
- create_dir(self.path.join("src")).context("Failed to create src dir")?;
- write(self.path.join("src/lib.rs"), "// Nothing").context("Failed to create src/lib.rs")?;
+ create_dir(self.path.join(&"src").abs()).context("Failed to create src dir")?;
+ write(self.path.join(&"src/lib.rs").abs(), "// Nothing")
+ .context("Failed to create src/lib.rs")?;
self.vendor()
// TODO: Run "cargo deny"
}
- pub fn get_path(&self) -> &Path {
- self.path.as_path()
+ pub fn get_path(&self) -> &RepoPath {
+ &self.path
}
pub fn add(&self, krate: &impl NamedAndVersioned) -> Result<()> {
let status = Command::new("cargo")
.args(["add", format!("{}@={}", krate.name(), krate.version()).as_str()])
- .current_dir(&self.path)
+ .current_dir(self.path.abs())
.spawn()
.context("Failed to spawn 'cargo add'")?
.wait()
@@ -107,7 +103,8 @@
Ok(())
}
pub fn vendor(&self) -> Result<()> {
- let output = Command::new("cargo").args(["vendor"]).current_dir(&self.path).output()?;
+ let output =
+ Command::new("cargo").args(["vendor"]).current_dir(self.path.abs()).output()?;
if !output.status.success() {
return Err(anyhow!(
"cargo vendor failed with exit code {}\nstdout:\n{}\nstderr:\n{}",
diff --git a/tools/external_crates/crate_health/src/repo_path.rs b/tools/external_crates/crate_health/src/repo_path.rs
new file mode 100644
index 0000000..2092b79
--- /dev/null
+++ b/tools/external_crates/crate_health/src/repo_path.rs
@@ -0,0 +1,68 @@
+// Copyright (C) 2024 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use core::fmt::Display;
+use std::path::{Path, PathBuf};
+
+#[derive(Debug, PartialEq, Eq)]
+pub struct RepoPath {
+ root: PathBuf,
+ path: PathBuf,
+}
+
+impl Display for RepoPath {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ write!(f, "{}", self.path.display())
+ }
+}
+
+impl RepoPath {
+ pub fn new<P: Into<PathBuf>, Q: Into<PathBuf>>(root: P, path: Q) -> RepoPath {
+ let root: PathBuf = root.into();
+ let path: PathBuf = path.into();
+ assert!(root.is_absolute());
+ assert!(path.is_relative());
+ RepoPath { root, path }
+ }
+ pub fn root(&self) -> &Path {
+ self.root.as_path()
+ }
+ pub fn rel(&self) -> &Path {
+ self.path.as_path()
+ }
+ pub fn abs(&self) -> PathBuf {
+ self.root.join(&self.path)
+ }
+ pub fn join(&self, path: &impl AsRef<Path>) -> RepoPath {
+ RepoPath::new(self.root.clone(), self.path.join(path))
+ }
+ pub fn with_same_root<P: Into<PathBuf>>(&self, path: P) -> RepoPath {
+ RepoPath::new(self.root.clone(), path)
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_basic() {
+ let p = RepoPath::new(&"/foo", &"bar");
+ assert_eq!(p.root(), Path::new("/foo"));
+ assert_eq!(p.rel(), Path::new("bar"));
+ assert_eq!(p.abs(), PathBuf::from("/foo/bar"));
+ assert_eq!(p.join(&"baz"), RepoPath::new("/foo", "bar/baz"));
+ assert_eq!(p.with_same_root(&"baz"), RepoPath::new("/foo", "baz"));
+ }
+}
diff --git a/tools/external_crates/crate_health/src/reports.rs b/tools/external_crates/crate_health/src/reports.rs
index 488bc58..49756c0 100644
--- a/tools/external_crates/crate_health/src/reports.rs
+++ b/tools/external_crates/crate_health/src/reports.rs
@@ -80,9 +80,9 @@
table.add_row(&[
&linkify(&krate.name(), &krate.crates_io_url()),
&krate.version().to_string(),
- &krate.aosp_url().map_or(format!("{}", krate.relpath().display()), |url| {
- linkify(&krate.relpath().display(), &url)
- }),
+ &krate
+ .aosp_url()
+ .map_or(format!("{}", krate.path()), |url| linkify(&krate.path(), &url)),
]);
}
Ok(self.tt.render("table", &table)?)
@@ -103,10 +103,10 @@
table.add_row(&[
&linkify(&krate.name(), &krate.crates_io_url()),
&krate.version().to_string(),
- &krate.aosp_url().map_or(format!("{}", krate.relpath().display()), |url| {
- linkify(&krate.relpath().display(), &url)
- }),
- &prefer_yes(krate.root().join(krate.android_bp()).exists()),
+ &krate
+ .aosp_url()
+ .map_or(format!("{}", krate.path()), |url| linkify(&krate.path(), &url)),
+ &prefer_yes(krate.android_bp().abs().exists()),
&prefer_yes_or_summarize(
krate.generate_android_bp_success(),
krate
@@ -126,7 +126,7 @@
.android_bp_diff()
.map_or("Error", |o| from_utf8(&o.stdout).unwrap_or("Error")),
),
- &prefer_yes(krate.cargo_embargo_json().exists()),
+ &prefer_yes(krate.cargo_embargo_json().abs().exists()),
&prefer_no(krate.is_migration_denied()),
]);
}
@@ -149,9 +149,9 @@
&linkify(&source.name(), &source.crates_io_url()),
&source.version().to_string(),
&dest_version,
- &source.aosp_url().map_or(format!("{}", source.relpath().display()), |url| {
- linkify(&source.relpath().display(), &url)
- }),
+ &source
+ .aosp_url()
+ .map_or(format!("{}", source.path()), |url| linkify(&source.path(), &url)),
]);
}
Ok(self.tt.render("table", &table)?)
@@ -174,13 +174,13 @@
table.add_row(&[
&linkify(&krate.name(), &krate.crates_io_url()),
&krate.version().to_string(),
- &krate.aosp_url().map_or(format!("{}", krate.relpath().display()), |url| {
- linkify(&krate.relpath().display(), &url)
- }),
+ &krate
+ .aosp_url()
+ .map_or(format!("{}", krate.path()), |url| linkify(&krate.path(), &url)),
&prefer_yes(krate.is_crates_io()),
&prefer_no(krate.is_migration_denied()),
- &prefer_yes(krate.root().join(krate.android_bp()).exists()),
- &prefer_yes(krate.cargo_embargo_json().exists()),
+ &prefer_yes(krate.android_bp().abs().exists()),
+ &prefer_yes(krate.cargo_embargo_json().abs().exists()),
]);
}
Ok(self.tt.render("table", &table)?)
@@ -205,9 +205,9 @@
table.add_row(&[
&linkify(&source.name(), &source.crates_io_url()),
&source.version().to_string(),
- &source.aosp_url().map_or(format!("{}", source.relpath().display()), |url| {
- linkify(&source.relpath().display(), &url)
- }),
+ &source
+ .aosp_url()
+ .map_or(format!("{}", source.path()), |url| linkify(&source.path(), &url)),
maybe_dest.map_or(&"None", |dest| {
if dest.version() != source.version() {
dest.version()