From 452fb385491958d9e08e4724dbddcd0bbd955c71 Mon Sep 17 00:00:00 2001 From: Nico Steinle Date: Thu, 27 Jul 2023 11:24:11 +0200 Subject: [PATCH] WIP --- src/commands/tree_of.rs | 246 +++++++++++++++++++--------------------- src/main.rs | 2 + src/package/dag.rs | 8 -- 3 files changed, 119 insertions(+), 137 deletions(-) diff --git a/src/commands/tree_of.rs b/src/commands/tree_of.rs index 1771f4c6..66917300 100644 --- a/src/commands/tree_of.rs +++ b/src/commands/tree_of.rs @@ -12,18 +12,16 @@ use std::convert::TryFrom; -//use anyhow::Error; use anyhow::Result; use clap::ArgMatches; -//use resiter::AndThen; -use tracing::trace; +use tracing::{error, trace}; use crate::package::condition::ConditionCheckable; use crate::package::condition::ConditionData; -use crate::package::ParseDependency; use crate::package::Package; use crate::package::PackageName; use crate::package::PackageVersionConstraint; +use crate::package::ParseDependency; use crate::repository::Repository; use crate::util::docker::ImageName; use crate::util::EnvironmentVariableName; @@ -37,139 +35,120 @@ enum DependencyType { #[derive(Debug)] struct DependenciesNode { name: String, - //dependency_type: DependencyType, dependencies: Vec<(DependenciesNode, DependencyType)>, } -//fn build_dependencies_tree(p: Package, repo: &Repository, conditional_data: &ConditionData<'_>) -> DependenciesNode { -// /// helper fn with bad name to check the dependency condition of a dependency and parse the dependency into a tuple of -// /// name and version for further processing -// fn process( -// d: &D, -// conditional_data: &ConditionData<'_>, -// ) -> Result<(bool, PackageName, PackageVersionConstraint)> { -// // Check whether the condition of the dependency matches our data -// let take = d.check_condition(conditional_data)?; -// let (name, version) = d.parse_as_name_and_version()?; -// -// // (dependency check result, name of the dependency, version of the dependency) -// Ok((take, name, version)) -// } -// let deps = p.dependencies(); -// vec![ -// (DependencyType::BUILDTIME, deps.build()), -// (DependencyType::RUNTIME, deps.runtime()), -// ].map(|(dep_type, deps)| { -// let deps = deps.iter().map(move |d| process(d, conditional_data)) -// // Now filter out all dependencies where their condition did not match our -// // `conditional_data`. -// .filter(|res| match res { -// Ok((true, _, _)) => true, -// Ok((false, _, _)) => false, -// Err(_) => true, -// }) -// // Map out the boolean from the condition, because we don't need that later on -// .map(|res| res.map(|(_, name, vers)| (name, vers))); -// }) -//} -// fn print_dependencies_tree(node: DependenciesNode, level: usize, is_runtime_dep: bool) { let ident = " ".repeat(level); let name = node.name; let suffix = if is_runtime_dep { "*" } else { "" }; println!("{ident}- {name}{suffix}"); for (node, dep_type) in node.dependencies { - print_dependencies_tree(node, level+1, dep_type == DependencyType::RUNTIME); + print_dependencies_tree(node, level + 1, dep_type == DependencyType::RUNTIME); } } -fn build_dependencies_tree(p: Package, repo: &Repository, conditional_data: &ConditionData<'_>) -> DependenciesNode { - /// helper fn with bad name to check the dependency condition of a dependency and parse the dependency into a tuple of - /// name and version for further processing - fn process( - d: &D, - conditional_data: &ConditionData<'_>, - dependency_type: DependencyType, - ) -> Result<(bool, PackageName, PackageVersionConstraint, DependencyType)> { - // Check whether the condition of the dependency matches our data - let take = d.check_condition(conditional_data)?; - let (name, version) = d.parse_as_name_and_version()?; - - // (dependency check result, name of the dependency, version of the dependency) - Ok((take, name, version, dependency_type)) - } - /// Helper fn to get the dependencies of a package - /// - /// This function helps getting the dependencies of a package as an iterator over - /// (Name, Version). - /// - /// It also filters out dependencies that do not match the `conditional_data` passed and - /// makes the dependencies unique over (name, version). - fn get_package_dependencies<'a>( - package: &'a Package, - conditional_data: &'a ConditionData<'_>, - ) -> impl Iterator> + 'a { - package - .dependencies() - .build() - .iter() - .map(move |d| process(d, conditional_data, DependencyType::BUILDTIME)) - .chain({ - package - .dependencies() - .runtime() - .iter() - .map(move |d| process(d, conditional_data, DependencyType::RUNTIME)) - }) - // Now filter out all dependencies where their condition did not match our - // `conditional_data`. - .filter(|res| match res { - Ok((true, _, _, _)) => true, - Ok((false, _, _, _)) => false, - Err(_) => true, - }) - // Map out the boolean from the condition, because we don't need that later on - .map(|res| res.map(|(_, name, vers, deptype)| (name, vers, deptype))) - } +fn build_dependencies_tree( + p: Package, + repo: &Repository, + conditional_data: &ConditionData<'_>, +) -> Result { + /// helper fn with bad name to check the dependency condition of a dependency and parse the dependency into a tuple of + /// name and version for further processing + fn process( + d: &D, + conditional_data: &ConditionData<'_>, + dependency_type: DependencyType, + ) -> Result<(bool, PackageName, PackageVersionConstraint, DependencyType)> { + // Check whether the condition of the dependency matches our data + let take = d.check_condition(conditional_data)?; + let (name, version) = d.parse_as_name_and_version()?; - let deps = get_package_dependencies(&p, conditional_data); - let mut d = Vec::new(); - //print!("{:?}", deps); - for dep in deps { - println!("{:?}", dep); - let dep = dep.unwrap(); - let pkgs = repo.find_with_version(&dep.0, &dep.1); - if pkgs.is_empty() { - panic!("dep not found"); - //return Err(anyhow!( - // "Dependency of {} {} not found: {} {}", - // p.name(), - // p.version(), - // name, - // constr - //)); + // (dependency check result, name of the dependency, version of the dependency) + Ok((take, name, version, dependency_type)) + } + + /// Helper fn to get the dependencies of a package + /// + /// This function helps getting the dependencies of a package as an iterator over + /// (Name, Version). + /// + /// It also filters out dependencies that do not match the `conditional_data` passed and + /// makes the dependencies unique over (name, version). + fn get_package_dependencies<'a>( + package: &'a Package, + conditional_data: &'a ConditionData<'_>, + ) -> impl Iterator> + 'a + { + package + .dependencies() + .build() + .iter() + .map(move |d| process(d, conditional_data, DependencyType::BUILDTIME)) + .chain({ + package + .dependencies() + .runtime() + .iter() + .map(move |d| process(d, conditional_data, DependencyType::RUNTIME)) + }) + // Now filter out all dependencies where their condition did not match our + // `conditional_data`. + .filter(|res| match res { + Ok((true, _, _, _)) => true, + Ok((false, _, _, _)) => false, + Err(_) => true, + }) + // Map out the boolean from the condition, because we don't need that later on + .map(|res| res.map(|(_, name, vers, deptype)| (name, vers, deptype))) + } + + let deps = get_package_dependencies(&p, conditional_data); + let mut d = Vec::new(); + for dep in deps { + let dep = match dep { + Ok(d) => { + trace!(""); + d + } + Err(e) => { + error!("Package dep not ok {}", e); + continue; } - trace!("Found in repo: {:?}", pkgs); - assert!(pkgs.len() == 1); - let pkg = pkgs[0]; - let subtree = build_dependencies_tree(pkg.clone(), repo, conditional_data); - //let tree = DependenciesNode { - // name: dep.as_ref().unwrap().0.to_string(), - // dependency_type: dep.unwrap().2, - // dependencies: subtree, - //}; - d.push((subtree, dep.2)); + }; + + trace!("Searching for {:?}", dep); + let pkgs = repo.find_with_version(&dep.0, &dep.1); + if pkgs.is_empty() { + error!("Package not found: {} with version: {}", dep.0, dep.1); + continue; } - println!("{:?}", d.len()); - let tree = DependenciesNode { - name: p.name().to_string(), - //dependency_type: DependencyType::BUILDTIME, - dependencies: d, + trace!("Found in repo: {:?}", pkgs); + + assert!(pkgs.len() == 1); + let pkg = pkgs[0]; + let subtree = build_dependencies_tree(pkg.clone(), repo, conditional_data); + let subtree = match subtree { + Ok(s) => { + trace!("Subtree ok"); + s + } + Err(e) => { + error!("Failed to build subtree, {}", e); + continue; + } }; - //println!("{:?}", d); - println!("{:?}", tree); - println!("{:?}", tree.dependencies); - return tree; + d.push((subtree, dep.2)); + } + trace!("d.len: {:?}", d.len()); + let tree = DependenciesNode { + name: p.name().to_string(), + //dependency_type: DependencyType::BUILDTIME, + dependencies: d, + }; + trace!("tree: {:?}", tree); + trace!("tree.dependencies: {:?}", tree.dependencies); + return Ok(tree); } /// Implementation of the "tree_of" subcommand @@ -201,7 +180,8 @@ pub async fn tree_of(matches: &ArgMatches, repo: Repository) -> Result<()> { env: &additional_env, }; - let mut tree = repo.packages() + let tree = repo + .packages() .filter(|p| pname.as_ref().map(|n| p.name() == n).unwrap_or(true)) .filter(|p| { pvers @@ -211,15 +191,23 @@ pub async fn tree_of(matches: &ArgMatches, repo: Repository) -> Result<()> { }) .map(|package| { let tree = build_dependencies_tree(package.clone(), &repo, &condition_data); - println!("{:?}", tree); + trace!("{:?}", tree); tree }) .collect::>(); - //println!("{:?}", tree[0]); - print_dependencies_tree(tree.pop().unwrap(), 0, false); + let mut tree: Vec = tree.into_iter().filter_map(|tree| tree.ok()).collect::>(); + + let popped = tree.pop(); + let popped = match popped { + Some(p) => { + trace!("Popped tree"); + p + }, + _ => { + panic!("Failed to pop tree"); + }, + }; + + print_dependencies_tree(popped, 0, false); Ok(()) - // .and_then_ok(|tree| { - // print!("{:?}", tree); - // }) - // .collect::>() } diff --git a/src/main.rs b/src/main.rs index 197ac527..868cdefd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,6 +11,7 @@ #![deny( anonymous_parameters, bad_style, + dead_code, deprecated_in_future, explicit_outlives_requirements, improper_ctypes, @@ -28,6 +29,7 @@ unconditional_recursion, unsafe_code, unstable_features, + unused, unused_allocation, unused_comparisons, unused_crate_dependencies, diff --git a/src/package/dag.rs b/src/package/dag.rs index cfc97cd4..d253b17c 100644 --- a/src/package/dag.rs +++ b/src/package/dag.rs @@ -37,9 +37,6 @@ use crate::repository::Repository; pub struct Dag { #[getset(get = "pub")] dag: daggy::Dag, - - #[getset(get = "pub")] - root_idx: daggy::NodeIndex, } impl Dag { @@ -195,7 +192,6 @@ impl Dag { Ok(Dag { dag: dag.map(|_, p: &&Package| -> Package { (*p).clone() }, |_, e| *e), - root_idx, }) } @@ -211,10 +207,6 @@ impl Dag { .filter_map(|idx| self.dag.graph().node_weight(idx)) .collect() } - - pub fn display(&self) -> DagDisplay { - DagDisplay(self, self.root_idx) - } } #[derive(Clone)]