1 // Copyright (C) 2023 The Android Open Source Project 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 use name_and_version::{NameAndVersion, NameAndVersionMap, NamedAndVersioned}; 16 use name_and_version_proc_macros::NameAndVersionMap; 17 use rooted_path::RootedPath; 18 19 use std::{ 20 collections::HashSet, 21 path::{Path, PathBuf}, 22 }; 23 24 use anyhow::{anyhow, Result}; 25 use semver::Version; 26 use walkdir::WalkDir; 27 28 use crate::{crate_type::Crate, CrateError}; 29 30 use std::collections::BTreeMap; 31 32 #[derive(NameAndVersionMap, Debug)] 33 pub struct CrateCollection { 34 crates: BTreeMap<NameAndVersion, Crate>, 35 repo_root: PathBuf, 36 } 37 38 impl CrateCollection { new<P: Into<PathBuf>>(repo_root: P) -> CrateCollection39 pub fn new<P: Into<PathBuf>>(repo_root: P) -> CrateCollection { 40 CrateCollection { crates: BTreeMap::new(), repo_root: repo_root.into() } 41 } add_from(&mut self, path: impl AsRef<Path>) -> Result<()>42 pub fn add_from(&mut self, path: impl AsRef<Path>) -> Result<()> { 43 for entry_or_err in WalkDir::new(self.repo_root.join(path)) { 44 let entry = entry_or_err?; 45 if entry.file_name() == "Cargo.toml" { 46 match Crate::from(RootedPath::new( 47 self.repo_root.clone(), 48 entry 49 .path() 50 .parent() 51 .ok_or(anyhow!("Failed to get parent of {}", entry.path().display()))? 52 .strip_prefix(&self.repo_root)?, 53 )?) { 54 Ok(krate) => self.crates.insert_or_error( 55 NameAndVersion::new(krate.name().to_string(), krate.version().clone()), 56 krate, 57 )?, 58 Err(e) => match e.downcast_ref() { 59 Some(CrateError::VirtualCrate(_)) => (), 60 _ => return Err(e), 61 }, 62 }; 63 } 64 } 65 Ok(()) 66 } 67 } 68