Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
ammernico committed Jul 31, 2023
1 parent a85d6cf commit 452fb38
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 137 deletions.
246 changes: 117 additions & 129 deletions src/commands/tree_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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: ConditionCheckable + ParseDependency>(
// 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: ConditionCheckable + ParseDependency>(
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<Item = Result<(PackageName, PackageVersionConstraint, DependencyType)>> + '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<DependenciesNode, anyhow::Error> {
/// 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: ConditionCheckable + ParseDependency>(
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<Item = anyhow::Result<(PackageName, PackageVersionConstraint, DependencyType)>> + '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
Expand Down Expand Up @@ -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
Expand All @@ -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::<Vec<_>>();
//println!("{:?}", tree[0]);
print_dependencies_tree(tree.pop().unwrap(), 0, false);
let mut tree: Vec<DependenciesNode> = tree.into_iter().filter_map(|tree| tree.ok()).collect::<Vec<DependenciesNode>>();

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::<Result<()>>()
}
2 changes: 2 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#![deny(
anonymous_parameters,
bad_style,
dead_code,
deprecated_in_future,
explicit_outlives_requirements,
improper_ctypes,
Expand All @@ -28,6 +29,7 @@
unconditional_recursion,
unsafe_code,
unstable_features,
unused,
unused_allocation,
unused_comparisons,
unused_crate_dependencies,
Expand Down
8 changes: 0 additions & 8 deletions src/package/dag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,6 @@ use crate::repository::Repository;
pub struct Dag {
#[getset(get = "pub")]
dag: daggy::Dag<Package, i8>,

#[getset(get = "pub")]
root_idx: daggy::NodeIndex,
}

impl Dag {
Expand Down Expand Up @@ -195,7 +192,6 @@ impl Dag {

Ok(Dag {
dag: dag.map(|_, p: &&Package| -> Package { (*p).clone() }, |_, e| *e),
root_idx,
})
}

Expand All @@ -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)]
Expand Down

0 comments on commit 452fb38

Please sign in to comment.