Refactor shared dependency handling

This commit is contained in:
Jeremy Soller 2025-04-11 11:15:44 -06:00
parent e741b35ce8
commit 6909fdd9b2
No known key found for this signature in database
GPG Key ID: 670FDFB5428E05CA
34 changed files with 235 additions and 320 deletions

60
Cargo.lock generated
View File

@ -493,6 +493,15 @@ version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5"
[[package]]
name = "crc32fast"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
dependencies = [
"cfg-if 1.0.0",
]
[[package]]
name = "crossbeam-channel"
version = "0.5.14"
@ -765,12 +774,28 @@ version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d"
[[package]]
name = "flate2"
version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c"
dependencies = [
"crc32fast",
"miniz_oxide",
]
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "foldhash"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
[[package]]
name = "form_urlencoded"
version = "1.2.1"
@ -923,6 +948,9 @@ name = "hashbrown"
version = "0.15.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
dependencies = [
"foldhash",
]
[[package]]
name = "hermit-abi"
@ -1392,7 +1420,12 @@ version = "0.36.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87"
dependencies = [
"crc32fast",
"flate2",
"hashbrown",
"indexmap",
"memchr",
"ruzstd",
]
[[package]]
@ -1753,8 +1786,10 @@ name = "redox_cookbook"
version = "0.1.0"
dependencies = [
"blake3 1.5.3",
"object",
"pbr",
"pkgar 0.1.16",
"pkgar-core 0.1.16",
"pkgar-keys 0.1.16",
"redoxer",
"serde",
@ -2057,6 +2092,15 @@ version = "1.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4"
[[package]]
name = "ruzstd"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fad02996bfc73da3e301efe90b1837be9ed8f4a462b6ed410aa35d00381de89f"
dependencies = [
"twox-hash",
]
[[package]]
name = "ryu"
version = "1.0.19"
@ -2210,6 +2254,12 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "strip-ansi-escapes"
version = "0.2.1"
@ -2514,6 +2564,16 @@ version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
[[package]]
name = "twox-hash"
version = "1.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675"
dependencies = [
"cfg-if 0.1.10",
"static_assertions",
]
[[package]]
name = "typenum"
version = "1.17.0"

View File

@ -21,8 +21,10 @@ path = "src/lib.rs"
[dependencies]
blake3 = "=1.5.3" # 1.5.4 is incompatible with blake3 0.3 dependency from pkgar
object = { version = "0.36", features = ["build_core"] }
pbr = "1.0.2"
pkgar = { path = "pkgar/pkgar" }
pkgar-core = { path = "pkgar/pkgar-core" }
pkgar-keys = { path = "pkgar/pkgar-keys" }
redoxer = "0.2"
serde = { version = "=1.0.197", features = ["derive"] }

View File

@ -6,7 +6,4 @@ template = "custom"
script = """
DYNAMIC_INIT
cookbook_cargo
"""
[package]
shared-deps = ["libgcc"]
"""

View File

@ -29,15 +29,4 @@ export DEP_Z_ROOT="${COOKBOOK_SYSROOT}"
-C link-arg="-lnghttp2"
mkdir -pv "${COOKBOOK_STAGE}/bin"
cp -v "target/${TARGET}/release/cargo" "${COOKBOOK_STAGE}/bin/cargo"
"""
[package]
shared-deps = [
"curl",
"libgcc",
"libssh2",
"nghttp2",
"openssl1",
"zlib",
]
"""

View File

@ -15,7 +15,4 @@ script = """
DYNAMIC_INIT
cp -rp "$COOKBOOK_SOURCE/." ./
cookbook_configure
"""
[package]
shared-deps = ["libgcc"]
"""

View File

@ -16,11 +16,4 @@ template = "custom"
script = """
DYNAMIC_INIT
cookbook_configure
"""
[package]
shared-deps = [
"gettext",
"glib",
"libiconv",
]
"""

View File

@ -55,13 +55,4 @@ COOKBOOK_CONFIGURE_FLAGS=(
"${COOKBOOK_SOURCE}"
)
cookbook_configure
"""
[package]
shared-deps = [
"curl",
"libgcc",
"nghttp2",
"openssl1",
"zlib",
]
"""

View File

@ -23,11 +23,4 @@ COOKBOOK_CONFIGURE_FLAGS+=(
--without-libflac
)
cookbook_configure
"""
[package]
shared-deps = [
"liborbital",
"libiconv",
"libgcc",
]
"""

View File

@ -45,7 +45,4 @@ COOKBOOK_CONFIGURE_FLAGS+=(
cookbook_configure
mkdir -v "${COOKBOOK_STAGE}/bin"
cp -v devilutionx "${COOKBOOK_STAGE}/bin"
"""
[package]
shared-deps = ["bzip2", "libgcc", "libiconv", "liborbital", "sdl1", "zlib"]
"""

View File

@ -57,12 +57,4 @@ meson \
-Dxattr=false
ninja -v
DESTDIR="${COOKBOOK_STAGE}" ninja install
"""
#TODO: shared deps
[package]
shared-deps = [
"libffi",
"libgcc",
"libiconv",
]
"""

View File

@ -30,7 +30,4 @@ else
)
fi
cookbook_configure
"""
[package]
shared-deps = ["libgcc"]
"""

View File

@ -15,7 +15,4 @@ template = "custom"
script = """
DYNAMIC_INIT
cookbook_configure
"""
[package]
shared-deps = ["libgcc"]
"""

View File

@ -37,7 +37,4 @@ else
)
fi
cookbook_configure
"""
[package]
shared-deps = ["libgcc"]
"""

View File

@ -14,7 +14,4 @@ dependencies = [
script = """
DYNAMIC_INIT
cookbook_configure
"""
[package]
shared-deps = ["libgcc", "libgmp"]
"""

View File

@ -12,11 +12,4 @@ dependencies = ["openssl1"]
script = """
DYNAMIC_INIT
cookbook_configure
"""
[package]
shared-deps = [
"libgcc",
"openssl1"
]
"""

View File

@ -17,11 +17,4 @@ dependencies = [
script = """
DYNAMIC_INIT
cookbook_configure
"""
[package]
shared-deps = [
"libgcc",
"libgmp",
"libmpfr",
]
"""

View File

@ -15,7 +15,4 @@ COOKBOOK_CONFIGURE_FLAGS+=(
--enable-lib-only
)
cookbook_configure
"""
[package]
shared-deps = ["libgcc"]
"""

View File

@ -11,7 +11,4 @@ CHOST="${TARGET}" "${COOKBOOK_CONFIGURE}" --prefix="/usr"
"${COOKBOOK_MAKE}" -j "$(nproc)"
"${COOKBOOK_MAKE}" install DESTDIR="${COOKBOOK_STAGE}"
patchelf --set-soname 'libz.so.1.3' "${COOKBOOK_STAGE}/usr/lib/libz.so.1.3"
"""
[package]
shared-deps = ["libgcc"]
"""

View File

@ -33,7 +33,4 @@ if ! [[ -n "${COOKBOOK_PREFER_STATIC}" ]]; then
cp -v libbz2.so.1.0.8 "${COOKBOOK_STAGE}/lib"
cp -v libbz2.so.1.0 "${COOKBOOK_STAGE}/lib"
fi
"""
[package]
shared-deps = ["libgcc"]
"""

View File

@ -36,12 +36,4 @@ mkdir -pv "${COOKBOOK_STAGE}/usr/share/metainfo/"
cp -v "${COOKBOOK_SOURCE}/res/${APPID}.metainfo.xml" "${COOKBOOK_STAGE}/usr/share/metainfo/"
mkdir -pv "${COOKBOOK_STAGE}/usr/share/icons/"
cp -rv "${COOKBOOK_SOURCE}/res/icons/hicolor/" "${COOKBOOK_STAGE}/usr/share/icons/"
"""
[package]
shared-deps = [
"libgcc",
"gettext",
"libiconv"
]
"""

View File

@ -35,12 +35,4 @@ mkdir -pv "${COOKBOOK_STAGE}/usr/share/"
cp -rv "${COOKBOOK_SOURCE}/resources/default_schema/" "${COOKBOOK_STAGE}/usr/share/cosmic/"
mkdir -pv "${COOKBOOK_STAGE}/usr/share/icons/"
cp -rv "${COOKBOOK_SOURCE}/resources/icons/" "${COOKBOOK_STAGE}/usr/share/icons/hicolor/"
"""
[package]
shared-deps = [
"libgcc",
"gettext",
"libiconv"
]
"""

View File

@ -21,10 +21,4 @@ mkdir -pv "${COOKBOOK_STAGE}/usr/share/metainfo/"
cp -v "${COOKBOOK_SOURCE}/res/${APPID}.metainfo.xml" "${COOKBOOK_STAGE}/usr/share/metainfo/"
mkdir -pv "${COOKBOOK_STAGE}/usr/share/icons/"
cp -rv "${COOKBOOK_SOURCE}/res/icons/hicolor/" "${COOKBOOK_STAGE}/usr/share/icons/"
"""
[package]
shared-deps = [
"libgcc",
"openssl1",
]
"""

View File

@ -17,10 +17,4 @@ mkdir -pv "${COOKBOOK_STAGE}/usr/share/metainfo/"
cp -v "${COOKBOOK_SOURCE}/res/${APPID}.metainfo.xml" "${COOKBOOK_STAGE}/usr/share/metainfo/"
mkdir -pv "${COOKBOOK_STAGE}/usr/share/icons/"
cp -rv "${COOKBOOK_SOURCE}/res/icons/hicolor/" "${COOKBOOK_STAGE}/usr/share/icons/"
"""
[package]
shared-deps = [
"libgcc"
]
"""

View File

@ -35,11 +35,4 @@ COOKBOOK_CONFIGURE_FLAGS+=(
gt_cv_locale_zh_CN=false
)
cookbook_configure
"""
[package]
shared-deps = [
"libgcc",
"libiconv"
]
"""

View File

@ -34,13 +34,4 @@ COOKBOOK_CONFIGURE_FLAGS+=(
)
cookbook_configure
"""
[package]
shared-deps = [
"libgcc",
"expat",
"libgmp",
"libmpfr",
"zlib",
]
"""

View File

@ -11,8 +11,4 @@ template = "custom"
script = """
DYNAMIC_INIT
cookbook_configure
"""
[package]
shared-deps = ["libgcc"]
"""

View File

@ -39,18 +39,6 @@ cp -v "${COOKBOOK_RECIPE}/manifest" "$COOKBOOK_STAGE/ui/apps/00_netsurf"
"""
[package]
shared-deps = [
# XXX: currently only the following are dynamically linked
"curl",
"libgcc",
"libiconv",
"liborbital",
"libpng",
"nghttp2",
"openssl1",
"relibc",
"zlib",
]
dependencies = [
"ca-certificates",
"orbital",

View File

@ -77,13 +77,4 @@ COOKBOOK_CONFIGURE_FLAGS=(
# make install not possible, just copy love
mkdir -pv "${COOKBOOK_STAGE}/usr/bin"
cp -v love "${COOKBOOK_STAGE}/usr/bin/love"
"""
[package]
shared-deps = [
"libgcc",
"liborbital",
"libpng",
"luajit",
"zlib",
]
"""

View File

@ -34,16 +34,4 @@ mkdir -pv "${COOKBOOK_STAGE}/usr/share/metainfo/"
cp -v "${COOKBOOK_SOURCE}/res/${APPID}.metainfo.xml" "${COOKBOOK_STAGE}/usr/share/metainfo/"
mkdir -pv "${COOKBOOK_STAGE}/usr/share/icons/"
cp -rv "${COOKBOOK_SOURCE}/res/icons/hicolor/" "${COOKBOOK_STAGE}/usr/share/icons/"
"""
[package]
shared-deps = [
"libgcc",
"gettext",
"glib",
"gstreamer",
"libffi",
"libiconv",
"zlib",
]
"""

View File

@ -47,18 +47,4 @@ case "${TARGET}" in
;;
esac
cookbook_configure
"""
[package]
shared-deps = [
"gettext",
"glib",
"libffi",
"libgcc",
"libiconv",
"liborbital",
"libpng",
"nghttp2",
"openssl1",
"zlib",
]
"""

10
repo.sh
View File

@ -93,16 +93,6 @@ mkdir -p "$REPO"
declare -A APPSTREAM_SOURCES
# Currently, we only support runtime dependencies for recipes in the new TOML
# format. Runtime dependencies include both `[package.dependencies]` and
# [`package.shared_deps`].
#
# The following adds the package dependencies of the recipes to the repo as
# well.
#
# TODO(?): All of this script can be moved into `cook.rs`.
recipes="$recipes $(target/release/runtime_deps_of $toml_recipes)"
for recipe in $recipes
do
recipe_path=`target/release/find_recipe $recipe`

View File

@ -2,25 +2,17 @@ use cookbook::blake3::blake3_progress;
use cookbook::recipe::{BuildKind, CookRecipe, PackageRecipe, Recipe, SourceRecipe};
use cookbook::recipe_find::recipe_find;
use std::{
collections::BTreeSet,
env, fs,
io::{self, Write},
path::{Path, PathBuf},
process::{self, Command, Stdio},
str,
time::SystemTime,
};
use termion::{color, style};
use walkdir::{DirEntry, WalkDir};
fn should_build_shared() -> bool {
use std::sync::OnceLock;
static YES: OnceLock<bool> = OnceLock::new();
*YES.get_or_init(|| {
env::var("COOKBOOK_PREFER_STATIC")
.expect("COOKBOOK_PREFER_STATIC")
.is_empty()
})
}
fn remove_all(path: &Path) -> Result<(), String> {
if path.is_dir() {
fs::remove_dir_all(path)
@ -57,8 +49,15 @@ fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> io::Result<()>
}
fn symlink(original: impl AsRef<Path>, link: impl AsRef<Path>) -> Result<(), String> {
std::os::unix::fs::symlink(&original, &link)
.map_err(|err| format!("failed to symlink '{}' to '{}': {}\n{:?}", original.as_ref().display(), link.as_ref().display(), err, err))
std::os::unix::fs::symlink(&original, &link).map_err(|err| {
format!(
"failed to symlink '{}' to '{}': {}\n{:?}",
original.as_ref().display(),
link.as_ref().display(),
err,
err
)
})
}
fn modified(path: &Path) -> Result<SystemTime, String> {
@ -506,33 +505,126 @@ fi"#,
Ok(source_dir)
}
fn auto_deps(stage_dir: &Path, dep_pkgars: &BTreeSet<(String, PathBuf)>) -> BTreeSet<String> {
let mut paths = BTreeSet::new();
for dir in &[stage_dir.join("usr/bin"), stage_dir.join("usr/lib")] {
let Ok(read_dir) = fs::read_dir(&dir) else {
continue;
};
for entry_res in read_dir {
let Ok(entry) = entry_res else { continue };
let Ok(file_type) = entry.file_type() else {
continue;
};
if file_type.is_file() {
paths.insert(entry.path());
}
}
}
let mut needed = BTreeSet::new();
for path in paths {
let Ok(file) = fs::File::open(&path) else {
continue;
};
let read_cache = object::ReadCache::new(file);
let Ok(object) = object::build::elf::Builder::read(&read_cache) else {
continue;
};
let Some(dynamic_data) = object.dynamic_data() else {
continue;
};
for dynamic in dynamic_data {
let object::build::elf::Dynamic::String { tag, val } = dynamic else {
continue;
};
if *tag == object::elf::DT_NEEDED {
let Ok(name) = str::from_utf8(val) else {
continue;
};
if let Ok(relative_path) = path.strip_prefix(stage_dir) {
eprintln!("DEBUG: {} needs {}", relative_path.display(), name);
}
needed.insert(name.to_string());
}
}
}
let mut missing = needed.clone();
// relibc and friends will always be installed
for preinstalled in &[
"libc.so.6",
"libgcc_s.so.1",
"libstdc++.so.6",
] {
missing.remove(*preinstalled);
}
let mut deps = BTreeSet::new();
if let Ok(key_file) = pkgar_keys::PublicKeyFile::open("build/id_ed25519.pub.toml") {
for (dep, archive_path) in dep_pkgars.iter() {
let Ok(mut package) = pkgar::PackageFile::new(archive_path, &key_file.pkey) else {
continue;
};
let Ok(entries) = pkgar_core::PackageSrc::read_entries(&mut package) else {
continue;
};
for entry in entries {
let Ok(entry_path) = pkgar::ext::EntryExt::check_path(&entry) else {
continue;
};
for prefix in &["lib", "usr/lib"] {
let Ok(child_path) = entry_path.strip_prefix(prefix) else {
continue;
};
let Some(child_name) = child_path.to_str() else {
continue;
};
if needed.contains(child_name) {
eprintln!("DEBUG: {} provides {}", dep, child_name);
deps.insert(dep.clone());
missing.remove(child_name);
}
}
}
}
}
for name in missing {
eprintln!("WARN: {} missing", name);
}
deps
}
fn build(
recipe_dir: &Path,
source_dir: &Path,
target_dir: &Path,
name: &str,
recipe: &Recipe,
) -> Result<PathBuf, String> {
let mut dep_pkgars = vec![];
for dependency in recipe.dependencies_iter() {
) -> Result<(PathBuf, BTreeSet<String>), String> {
let mut dep_pkgars = BTreeSet::new();
for dependency in recipe.build.dependencies.iter() {
//TODO: sanitize name
let dependency_dir = recipe_find(dependency, Path::new("recipes"))?;
if dependency_dir.is_none() {
return Err(format!("failed to find recipe directory '{}'", dependency));
}
dep_pkgars.push(
dep_pkgars.insert((
dependency.to_string(),
dependency_dir
.unwrap()
.join("target")
.join(redoxer::target())
.join("stage.pkgar"),
);
));
}
let source_modified = modified_dir_ignore_git(source_dir)?;
let deps_modified = dep_pkgars
.iter()
.map(|pkgar| modified(pkgar))
.map(|(_dep, pkgar)| modified(pkgar))
.max()
.unwrap_or(Ok(SystemTime::UNIX_EPOCH))?;
@ -562,13 +654,10 @@ fn build(
create_dir(&sysroot_dir_tmp.join("usr").join(folder))?;
// Link sysroot/$folder sysroot/usr/$folder
symlink(
Path::new("usr").join(folder),
&sysroot_dir_tmp.join(folder),
)?;
symlink(Path::new("usr").join(folder), &sysroot_dir_tmp.join(folder))?;
}
for archive_path in dep_pkgars {
for (_dep, archive_path) in &dep_pkgars {
let public_path = "build/id_ed25519.pub.toml";
pkgar::extract(
public_path,
@ -836,7 +925,10 @@ done
rename(&stage_dir_tmp, &stage_dir)?;
}
Ok(stage_dir)
// Calculate automatic dependencies
let auto_deps = auto_deps(&stage_dir, &dep_pkgars);
Ok((stage_dir, auto_deps))
}
fn package(
@ -845,6 +937,7 @@ fn package(
target_dir: &Path,
name: &str,
recipe: &Recipe,
auto_deps: &BTreeSet<String>,
) -> Result<PathBuf, String> {
//TODO: metadata like dependencies, name, and version
let package = &recipe.package;
@ -894,11 +987,12 @@ fn package(
target: String,
depends: Vec<String>,
}
let depends = if should_build_shared() {
recipe.runtime_dependencies()
} else {
package.dependencies.clone()
};
let mut depends = package.dependencies.clone();
for dep in auto_deps.iter() {
if !depends.contains(dep) {
depends.push(dep.clone());
}
}
let stage_toml = toml::to_string(&StageToml {
name: name.into(),
version: "TODO".into(),
@ -931,11 +1025,18 @@ fn cook(recipe_dir: &Path, name: &str, recipe: &Recipe, fetch_only: bool) -> Res
create_dir(&target_dir)?;
}
let stage_dir = build(recipe_dir, &source_dir, &target_dir, name, &recipe)
let (stage_dir, auto_deps) = build(recipe_dir, &source_dir, &target_dir, name, &recipe)
.map_err(|err| format!("failed to build: {}", err))?;
let _package_file = package(recipe_dir, &stage_dir, &target_dir, name, &recipe)
.map_err(|err| format!("failed to package: {}", err))?;
let _package_file = package(
recipe_dir,
&stage_dir,
&target_dir,
name,
&recipe,
&auto_deps,
)
.map_err(|err| format!("failed to package: {}", err))?;
Ok(())
}
@ -956,7 +1057,7 @@ fn main() {
}
}
let recipes = match CookRecipe::new_recursive(&recipe_names, 16, false) {
let recipes = match CookRecipe::new_recursive(&recipe_names, 16) {
Ok(ok) => ok,
Err(err) => {
eprintln!(

View File

@ -1,20 +0,0 @@
use cookbook::recipe::CookRecipe;
use std::{env::args, process::ExitCode};
/// Same as `cookbook/src/bin/cook.rs`.
const DEP_DEPTH: usize = 16;
fn usage() {
eprintln!("Usage: pkg_deps_of [package1 package2 ...]");
}
fn main() -> ExitCode {
let names = args().skip(1).collect::<Vec<String>>();
let recipes = CookRecipe::new_recursive(&names, DEP_DEPTH, true).expect("recipe not found");
for recipe in recipes {
println!("{}", recipe.name);
}
ExitCode::SUCCESS
}

View File

@ -90,8 +90,6 @@ pub struct BuildRecipe {
pub struct PackageRecipe {
#[serde(default)]
pub dependencies: Vec<String>,
#[serde(rename = "shared-deps", default)]
pub shared_deps: Vec<String>,
}
/// Everything required to build a Redox package
@ -106,33 +104,7 @@ pub struct Recipe {
pub package: PackageRecipe,
}
impl Recipe {
#[inline]
pub fn dependencies_iter(&self) -> impl Iterator<Item = &String> {
self.build
.dependencies
.iter()
.chain(self.package.shared_deps.iter())
}
/// `[build.dependencies] + [package.shared_deps]`
#[inline]
pub fn dependencies(&self) -> Vec<String> {
self.dependencies_iter().cloned().collect::<Vec<_>>()
}
/// `[package.dependencies] + [package.shared_deps]`
#[inline]
pub fn runtime_dependencies(&self) -> Vec<String> {
self.package
.dependencies
.iter()
.chain(self.package.shared_deps.iter())
.cloned()
.collect::<Vec<_>>()
}
}
#[derive(Debug, PartialEq)]
pub struct CookRecipe {
pub name: String,
pub dir: PathBuf,
@ -173,12 +145,7 @@ impl CookRecipe {
Ok(Self { name, dir, recipe })
}
//TODO: make this more efficient, smarter, and not return duplicates
pub fn new_recursive(
names: &[String],
recursion: usize,
runtime_deps_only: bool,
) -> Result<Vec<Self>, String> {
pub fn new_recursive(names: &[String], recursion: usize) -> Result<Vec<Self>, String> {
if recursion == 0 {
return Err(format!(
"recursion limit while processing build dependencies: {:#?}",
@ -189,25 +156,21 @@ impl CookRecipe {
let mut recipes = Vec::new();
for name in names {
let recipe = Self::new(name.clone())?;
let all_deps = recipe.recipe.dependencies();
let runtime_deps = recipe.recipe.runtime_dependencies();
let dependencies = Self::new_recursive(
if runtime_deps_only {
&runtime_deps
} else {
&all_deps
},
recursion - 1,
runtime_deps_only,
)
.map_err(|err| format!("{}: failed on loading build dependencies:\n{}", name, err))?;
let dependencies =
Self::new_recursive(&recipe.recipe.build.dependencies, recursion - 1).map_err(
|err| format!("{}: failed on loading build dependencies:\n{}", name, err),
)?;
for dependency in dependencies {
recipes.push(dependency);
if !recipes.contains(&dependency) {
recipes.push(dependency);
}
}
recipes.push(recipe);
if !recipes.contains(&recipe) {
recipes.push(recipe);
}
}
Ok(recipes)