From 25141384b40d2502d9b02ac484163a0ba30a2cd5 Mon Sep 17 00:00:00 2001 From: Wildan M Date: Sun, 27 Jul 2025 21:43:54 +0700 Subject: [PATCH 1/4] Support for metapackages --- src/bin/cook.rs | 97 ++++++++++++++++++++++++++--------------- src/bin/repo_builder.rs | 6 ++- src/recipe.rs | 45 ++++++++++++++++++- 3 files changed, 109 insertions(+), 39 deletions(-) diff --git a/src/bin/cook.rs b/src/bin/cook.rs index 6a2364de3..1f18fdfc5 100644 --- a/src/bin/cook.rs +++ b/src/bin/cook.rs @@ -1029,6 +1029,7 @@ done } BuildKind::Configure => "cookbook_configure".to_owned(), BuildKind::Custom { script } => script.clone(), + BuildKind::None => "".to_owned(), }; let command = { @@ -1075,16 +1076,12 @@ done } fn package( - _recipe_dir: &Path, stage_dir: &Path, target_dir: &Path, name: &PackageName, recipe: &Recipe, auto_deps: &BTreeSet, ) -> Result { - //TODO: metadata like dependencies, name, and version - let package = &recipe.package; - let secret_path = "build/id_ed25519.toml"; let public_path = "build/id_ed25519.pub.toml"; if !Path::new(secret_path).is_file() || !Path::new(public_path).is_file() { @@ -1122,33 +1119,65 @@ fn package( ) .map_err(|err| format!("failed to create pkgar archive: {:?}", err))?; - 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(&Package { - name: name.clone(), - version: "TODO".into(), - target: env::var("TARGET") - .map_err(|err| format!("failed to read TARGET: {:?}", err))?, - depends, - }) - .map_err(|err| format!("failed to serialize stage.toml: {:?}", err))?; - fs::write(target_dir.join("stage.toml"), stage_toml) - .map_err(|err| format!("failed to write stage.toml: {:?}", err))?; + package_toml(target_dir, name, recipe, auto_deps)?; } Ok(package_file) } +fn package_toml( + target_dir: &Path, + name: &PackageName, + recipe: &Recipe, + auto_deps: &BTreeSet, +) -> Result<(), String> { + let mut depends = recipe.package.dependencies.clone(); + for dep in auto_deps.iter() { + if !depends.contains(dep) { + depends.push(dep.clone()); + } + } + let stage_toml = toml::to_string(&Package { + name: name.clone(), + version: "TODO".into(), + target: env::var("TARGET").map_err(|err| format!("failed to read TARGET: {:?}", err))?, + depends, + }) + .map_err(|err| format!("failed to serialize stage.toml: {:?}", err))?; + fs::write(target_dir.join("stage.toml"), stage_toml) + .map_err(|err| format!("failed to write stage.toml: {:?}", err))?; + + return Ok(()); +} + +fn cook_meta( + recipe_dir: &Path, + name: &PackageName, + recipe: &Recipe, + fetch_only: bool, +) -> Result<(), String> { + if fetch_only { + return Ok(()); + } + + let target_dir = create_target_dir(recipe_dir)?; + let empty_deps = BTreeSet::new(); + let _package_file = package_toml(&target_dir, name, recipe, &empty_deps) + .map_err(|err| format!("failed to package: {}", err))?; + + Ok(()) +} + fn cook( recipe_dir: &Path, name: &PackageName, recipe: &Recipe, fetch_only: bool, ) -> Result<(), String> { + if recipe.build.kind == BuildKind::None { + return cook_meta(recipe_dir, name, recipe, fetch_only); + } + let is_offline = env::var("COOKBOOK_OFFLINE").unwrap_or("".to_string()) == "1"; let source_dir = match is_offline { true => fetch_offline(recipe_dir, &recipe.source), @@ -1160,6 +1189,18 @@ fn cook( return Ok(()); } + let target_dir = create_target_dir(recipe_dir)?; + + 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(&stage_dir, &target_dir, name, recipe, &auto_deps) + .map_err(|err| format!("failed to package: {}", err))?; + + Ok(()) +} + +fn create_target_dir(recipe_dir: &Path) -> Result { let target_parent_dir = recipe_dir.join("target"); if !target_parent_dir.is_dir() { create_dir(&target_parent_dir)?; @@ -1168,21 +1209,7 @@ fn cook( if !target_dir.is_dir() { create_dir(&target_dir)?; } - - 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, - &auto_deps, - ) - .map_err(|err| format!("failed to package: {}", err))?; - - Ok(()) + Ok(target_dir) } fn main() { diff --git a/src/bin/repo_builder.rs b/src/bin/repo_builder.rs index db66483b5..6a7a8a35d 100644 --- a/src/bin/repo_builder.rs +++ b/src/bin/repo_builder.rs @@ -46,9 +46,11 @@ fn main() -> Result<(), Box> { let toml_src = stage_dir.with_extension("toml"); let toml_dst = repo_path.join(format!("{}.toml", recipe)); - if is_newer(&pkgar_src, &pkgar_dst) { + if is_newer(&toml_src, &toml_dst) { eprintln!("\x1b[01;38;5;155mrepo - publishing {}\x1b[0m", recipe); - fs::copy(&pkgar_src, &pkgar_dst)?; + if fs::exists(&pkgar_src)? { + fs::copy(&pkgar_src, &pkgar_dst)?; + } fs::copy(&toml_src, &toml_dst)?; } diff --git a/src/recipe.rs b/src/recipe.rs index 85240dce9..4341551d7 100644 --- a/src/recipe.rs +++ b/src/recipe.rs @@ -63,6 +63,9 @@ pub enum SourceRecipe { #[derive(Debug, Deserialize, PartialEq, Serialize)] #[serde(tag = "template")] pub enum BuildKind { + /// Will not build (for meta packages) + #[serde(rename = "none")] + None, /// Will build and install using cargo #[serde(rename = "cargo")] Cargo { @@ -80,9 +83,15 @@ pub enum BuildKind { Custom { script: String }, } -#[derive(Debug, Deserialize, PartialEq, Serialize)] +impl Default for BuildKind { + fn default() -> Self { + BuildKind::None + } +} + +#[derive(Debug, Default, Deserialize, PartialEq, Serialize)] pub struct BuildRecipe { - #[serde(flatten)] + #[serde(flatten, default)] pub kind: BuildKind, #[serde(default)] pub dependencies: Vec, @@ -100,6 +109,7 @@ pub struct Recipe { /// Specifies how to download the source for this recipe pub source: Option, /// Specifies how to build this recipe + #[serde(default)] pub build: BuildRecipe, /// Specifies how to package this recipe #[serde(default)] @@ -207,6 +217,8 @@ impl CookRecipe { #[cfg(test)] mod tests { + use pkg::PackageName; + #[test] fn git_cargo_recipe() { use crate::recipe::{BuildKind, BuildRecipe, PackageRecipe, Recipe, SourceRecipe}; @@ -291,4 +303,33 @@ mod tests { } ); } + + #[test] + fn meta_recipe() { + use crate::recipe::{BuildKind, BuildRecipe, PackageRecipe, Recipe}; + + let recipe: Recipe = toml::from_str( + r#" + [package] + dependencies = [ + "gcc13", + ] + "#, + ) + .unwrap(); + + assert_eq!( + recipe, + Recipe { + source: None, + build: BuildRecipe { + kind: BuildKind::None, + dependencies: Vec::new(), + }, + package: PackageRecipe { + dependencies: vec![PackageName::new("gcc13").unwrap()], + }, + } + ); + } } From 132199cd54ed16b1e744b71f030bbdc9e66f7c1b Mon Sep 17 00:00:00 2001 From: Wildan M Date: Sun, 27 Jul 2025 21:50:37 +0700 Subject: [PATCH 2/4] Apply version meta --- src/bin/cook.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/bin/cook.rs b/src/bin/cook.rs index 1f18fdfc5..4e937957c 100644 --- a/src/bin/cook.rs +++ b/src/bin/cook.rs @@ -1139,7 +1139,7 @@ fn package_toml( } let stage_toml = toml::to_string(&Package { name: name.clone(), - version: "TODO".into(), + version: package_version(recipe), target: env::var("TARGET").map_err(|err| format!("failed to read TARGET: {:?}", err))?, depends, }) @@ -1150,6 +1150,14 @@ fn package_toml( return Ok(()); } +fn package_version(recipe: &Recipe) -> Option { + if recipe.build.kind == BuildKind::None { + None + } else { + Some("TODO".into()) + } +} + fn cook_meta( recipe_dir: &Path, name: &PackageName, From 5de3e8327af5dadff2c35c541fd7dfe83b61cf1f Mon Sep 17 00:00:00 2001 From: Wildan M Date: Sun, 27 Jul 2025 22:09:12 +0700 Subject: [PATCH 3/4] Fix build --- src/bin/cook.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/bin/cook.rs b/src/bin/cook.rs index 4e937957c..0bd8354bd 100644 --- a/src/bin/cook.rs +++ b/src/bin/cook.rs @@ -1150,11 +1150,11 @@ fn package_toml( return Ok(()); } -fn package_version(recipe: &Recipe) -> Option { +fn package_version(recipe: &Recipe) -> String { if recipe.build.kind == BuildKind::None { - None + "" } else { - Some("TODO".into()) + "TODO" } } From 519a9911d9bd815e2ba231b97e385010f36fda59 Mon Sep 17 00:00:00 2001 From: Wildan M Date: Sun, 27 Jul 2025 22:13:30 +0700 Subject: [PATCH 4/4] Fix build --- src/bin/cook.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bin/cook.rs b/src/bin/cook.rs index 0bd8354bd..4002f712d 100644 --- a/src/bin/cook.rs +++ b/src/bin/cook.rs @@ -1152,9 +1152,9 @@ fn package_toml( fn package_version(recipe: &Recipe) -> String { if recipe.build.kind == BuildKind::None { - "" + "".into() } else { - "TODO" + "TODO".into() } }