From f046e34c3f10072de7b9418c2f7b63c92776048b Mon Sep 17 00:00:00 2001 From: Wildan Mubarok Date: Mon, 3 Nov 2025 00:37:19 +0000 Subject: [PATCH] Traverse package deps from build deps --- src/bin/cook.rs | 3 +- src/bin/repo.rs | 3 +- src/cook/cook_build.rs | 32 ++++++++++++--- src/recipe.rs | 93 +++++++++++++++++++++++------------------- 4 files changed, 80 insertions(+), 51 deletions(-) diff --git a/src/bin/cook.rs b/src/bin/cook.rs index e70bf4bb0..1f5a4f332 100644 --- a/src/bin/cook.rs +++ b/src/bin/cook.rs @@ -1,7 +1,6 @@ use std::path::Path; use std::{env, process}; -use cookbook::WALK_DEPTH; use cookbook::cook::fetch::{fetch, fetch_offline}; use cookbook::cook::fs::create_target_dir; use cookbook::cook::package::package; @@ -74,7 +73,7 @@ fn main() { } if with_package_deps { - recipe_names = match CookRecipe::get_package_deps_recursive(&recipe_names, WALK_DEPTH) { + recipe_names = match CookRecipe::get_package_deps_recursive(&recipe_names, true) { Ok(ok) => ok, Err(err) => { eprintln!( diff --git a/src/bin/repo.rs b/src/bin/repo.rs index f05210459..69eecb2aa 100644 --- a/src/bin/repo.rs +++ b/src/bin/repo.rs @@ -1,6 +1,5 @@ use ansi_to_tui::IntoText; use anyhow::{Context, anyhow, bail}; -use cookbook::WALK_DEPTH; use cookbook::config::{CookConfig, get_config, init_config}; use cookbook::cook::cook_build::build; use cookbook::cook::fetch::{fetch, fetch_offline}; @@ -399,7 +398,7 @@ fn parse_args(args: Vec) -> anyhow::Result<(CliConfig, CliCommand, Vec, logger: &PtyOut, @@ -160,6 +161,20 @@ fn auto_deps( deps } +fn auto_deps_from_static_package_deps( + build_dep_pkgars: &BTreeSet<(PackageName, PathBuf)>, + dynamic_dep_pkgars: &BTreeSet, +) -> Result, PackageError> { + let static_dep_pkgars: Vec = build_dep_pkgars + .iter() + .map(|x| x.0.clone()) + .filter(|x| !dynamic_dep_pkgars.contains(x)) + .collect(); + let pkgs = CookRecipe::get_package_deps_recursive(&static_dep_pkgars, false)?; + + Ok(pkgs.into_iter().collect()) +} + pub fn build( recipe_dir: &Path, source_dir: &Path, @@ -394,8 +409,13 @@ fn build_auto_deps( toml::from_str(&toml_content).map_err(|_| "failed to deserialize cached auto_deps")?; wrapper.packages } else { - let packages = auto_deps(stage_dir, &dep_pkgars, logger); - let wrapper = AutoDeps { packages }; + let mut packages1 = auto_deps_from_dynamic_linking(stage_dir, &dep_pkgars, logger); + let packages2 = + auto_deps_from_static_package_deps(&dep_pkgars, &packages1).unwrap_or_default(); + packages1.extend(packages2); + let wrapper = AutoDeps { + packages: packages1, + }; serialize_and_write(&auto_deps_path, &wrapper)?; wrapper.packages }; @@ -481,7 +501,7 @@ pub fn build_remote( mod tests { use std::os::unix; - use super::auto_deps; + use super::auto_deps_from_dynamic_linking; #[test] fn file_system_loop_no_infinite_loop() { @@ -498,7 +518,7 @@ mod tests { "Expected a loop where {dir:?} points to {root:?}" ); - let entries = auto_deps(root, &Default::default(), &None); + let entries = auto_deps_from_dynamic_linking(root, &Default::default(), &None); assert!( entries.is_empty(), "auto_deps shouldn't have yielded any libraries" diff --git a/src/recipe.rs b/src/recipe.rs index 6dd6da09a..3c9095fd7 100644 --- a/src/recipe.rs +++ b/src/recipe.rs @@ -219,6 +219,11 @@ impl CookRecipe { pub fn new_recursive( names: &[PackageName], + recurse_build_deps: bool, + recurse_package_deps: bool, + collect_build_deps: bool, + collect_package_deps: bool, + collect_self: bool, recursion: usize, ) -> Result, PackageError> { if recursion == 0 { @@ -229,21 +234,51 @@ impl CookRecipe { for name in names { let recipe = Self::from_name(name.as_str())?; - let dependencies = - Self::new_recursive(&recipe.recipe.build.dependencies, recursion - 1).map_err( - |mut err| { - err.append_recursion(name); - err - }, - )?; + if recurse_build_deps { + let dependencies = Self::new_recursive( + &recipe.recipe.build.dependencies, + recurse_build_deps, + recurse_package_deps, + collect_build_deps, + collect_package_deps, + collect_build_deps, + recursion - 1, + ) + .map_err(|mut err| { + err.append_recursion(name); + err + })?; - for dependency in dependencies { - if !recipes.contains(&dependency) { - recipes.push(dependency); + for dependency in dependencies { + if !recipes.contains(&dependency) { + recipes.push(dependency); + } } } - if !recipes.contains(&recipe) { + if recurse_package_deps { + let dependencies = Self::new_recursive( + &recipe.recipe.package.dependencies, + recurse_build_deps, + recurse_package_deps, + collect_build_deps, + collect_package_deps, + collect_package_deps, + recursion - 1, + ) + .map_err(|mut err| { + err.append_recursion(name); + err + })?; + + for dependency in dependencies { + if !recipes.contains(&dependency) { + recipes.push(dependency); + } + } + } + + if collect_self && !recipes.contains(&recipe) { recipes.push(recipe); } } @@ -255,7 +290,7 @@ impl CookRecipe { names: &[PackageName], mark_is_deps: bool, ) -> Result, PackageError> { - let mut packages = Self::new_recursive(names, WALK_DEPTH)?; + let mut packages = Self::new_recursive(names, true, false, true, false, true, WALK_DEPTH)?; if mark_is_deps { for package in packages.iter_mut() { @@ -268,37 +303,13 @@ impl CookRecipe { pub fn get_package_deps_recursive( names: &[PackageName], - recursion: usize, + include_names: bool, ) -> Result, PackageError> { - if recursion == 0 { - return Err(PackageError::Recursion(Default::default())); - } + // recurse_build_deps == true here as libraries (build deps) can have runtime files (package deps) + let packages = + Self::new_recursive(names, true, true, false, true, include_names, WALK_DEPTH)?; - let mut recipes: Vec = Vec::new(); - for name in names { - let recipe = Self::from_name(name.as_str())?; - - let dependencies = Self::get_package_deps_recursive( - &recipe.recipe.package.dependencies, - recursion - 1, - ) - .map_err(|mut err| { - err.append_recursion(name); - err - })?; - - for dependency in dependencies { - if !recipes.contains(&dependency) { - recipes.push(dependency); - } - } - - if !recipes.contains(name) { - recipes.push(name.clone()); - } - } - - Ok(recipes) + Ok(packages.into_iter().map(|p| p.name).collect()) } }