diff --git a/clean.sh b/clean.sh index f4c2eb619564de3ff02127400dc5917ec1fbc86b..d0b85abc22b9656cd310575426f4ee77ea52e734 100755 --- a/clean.sh +++ b/clean.sh @@ -5,7 +5,7 @@ source config.sh if [ $# = 0 ] then - recipes="$(ls -1 recipes)" + recipes="$(target/release/list_recipes)" else recipes="$@" fi diff --git a/cook.sh b/cook.sh index ba4a7a12a3f8a2b277b6a6cc2e22efb22da1fec2..fb0104414ff0e498d93b54efa222d1412509143d 100755 --- a/cook.sh +++ b/cook.sh @@ -368,9 +368,10 @@ function op { if [ -n "$1" ] then - if [ -d "$ROOT/recipes/$1" ] + recipe_path=`target/release/find_recipe $1` + if [ -d "$ROOT/$recipe_path" ] then - export COOKBOOK_RECIPE="${ROOT}/recipes/$1" + export COOKBOOK_RECIPE="${ROOT}/$recipe_path" TARGET_DIR="${COOKBOOK_RECIPE}/target/${TARGET}" mkdir -p "${TARGET_DIR}" diff --git a/fetch.sh b/fetch.sh index 03368c77a54082273bcc0bd52ab3214fef41873c..1c5c57a8d82e5a9cfbbf75364a9143ce7c54676a 100755 --- a/fetch.sh +++ b/fetch.sh @@ -5,14 +5,15 @@ source config.sh if [ $# = 0 ] then - recipes="$(ls -1 recipes)" + recipes="$(target/release/list_recipes)" else recipes="$@" fi for recipe in $recipes do - if [ -e "recipes/$recipe/recipe.toml" ] + recipe_path=`target/release/find_recipe $recipe` + if [ -e "$recipe_path/recipe.toml" ] then target/release/cook --fetch-only "$recipe" continue diff --git a/repo.sh b/repo.sh index 1ca42d9983875db8ba7df0dcf96870506aebb8c5..2fad01da22e095f893cbe822744e1ee5269b855a 100755 --- a/repo.sh +++ b/repo.sh @@ -17,12 +17,14 @@ done if [ "$recipes" == "" ] then - recipes="$(ls -1 recipes)" + recipes="$(target/release/list_recipes)" fi for recipe in $recipes do - COOKBOOK_RECIPE="recipes/$recipe" + recipe_path=`target/release/find_recipe $recipe` + echo recipe path is $recipe_path + COOKBOOK_RECIPE="$recipe_path" TARGET_DIR="${COOKBOOK_RECIPE}/target/${TARGET}" COOKBOOK_BUILD="${TARGET_DIR}/build" COOKBOOK_STAGE="${TARGET_DIR}/stage" @@ -113,7 +115,8 @@ mkdir -p "$REPO" for recipe in $recipes do - COOKBOOK_RECIPE="recipes/$recipe" + recipe_path=`target/release/find_recipe $recipe` + COOKBOOK_RECIPE="$recipe_path" TARGET_DIR="${COOKBOOK_RECIPE}/target/${TARGET}" COOKBOOK_STAGE="${TARGET_DIR}/stage" diff --git a/src/bin/cook.rs b/src/bin/cook.rs index 9fe35867b6602e24674f8da1542a3a551fa3bbdb..6b00832e5ee4b3219f464cd22ca61be0d5479cb1 100644 --- a/src/bin/cook.rs +++ b/src/bin/cook.rs @@ -1,6 +1,7 @@ use cookbook::blake3::blake3_progress; use cookbook::recipe::{Recipe, SourceRecipe, BuildKind, BuildRecipe, PackageRecipe}; use cookbook::sha256::sha256_progress; +use cookbook::recipe_find::recipe_find; use std::{ env, fs, @@ -399,7 +400,14 @@ fn build(recipe_dir: &Path, source_dir: &Path, target_dir: &Path, build: &BuildR for dependency in build.dependencies.iter() { let public_path = "build/id_ed25519.pub.toml"; //TODO: sanitize name - let archive_path = format!("recipes/{}/target/{}/stage.pkgar", dependency, redoxer::target()); + let dependency_dir = recipe_find(dependency, Path::new("recipes"))?; + if dependency_dir.is_none() { + return Err(format!( + "failed to find recipe directory '{}'", + dependency + )); + } + let archive_path = format!("{}/target/{}/stage.pkgar", dependency_dir.unwrap().display(), redoxer::target()); pkgar::extract( public_path, &archive_path, @@ -668,14 +676,14 @@ pub struct CookRecipe { impl CookRecipe { pub fn new(name: String) -> Result<Self, String> { //TODO: sanitize recipe name? - let dir = Path::new("recipes").join(&name); - if ! dir.is_dir() { + let dir = recipe_find(&name, Path::new("recipes"))?; + if dir.is_none() { return Err(format!( "failed to find recipe directory '{}'", - dir.display() + name )); } - + let dir = dir.unwrap(); let file = dir.join("recipe.toml"); if ! file.is_file() { return Err(format!( diff --git a/src/bin/find_recipe.rs b/src/bin/find_recipe.rs new file mode 100644 index 0000000000000000000000000000000000000000..ea84db432804b57bc9b934f261981ba7302305be --- /dev/null +++ b/src/bin/find_recipe.rs @@ -0,0 +1,26 @@ +use cookbook::recipe_find::recipe_find; +use std::env::args; +use std::path::Path; +use std::process::exit; +// use clap::Parser; + +fn usage() { + println!("Usage: find_recipe recipe_name"); +} +fn main() { + if args().len() != 2 { + usage(); + exit(2); + } + let result = recipe_find(&args().last().unwrap(), Path::new("recipes")); + if result.is_err() { + eprintln!("{}", result.err().unwrap()); + exit(2); + } else if result.as_ref().unwrap().is_none() { + eprintln!("recipe {} not found", &args().last().unwrap()); + exit(1); + } else { + println!("{}", result.unwrap().unwrap().display()); + exit(0); + } +} diff --git a/src/bin/list_recipes.rs b/src/bin/list_recipes.rs new file mode 100644 index 0000000000000000000000000000000000000000..da3171e1e4e79a6d4cb3e85846c64f07a8e9b06c --- /dev/null +++ b/src/bin/list_recipes.rs @@ -0,0 +1,19 @@ +use cookbook::recipe_find::list_recipes; +use std::path::Path; +use std::process::exit; +// use clap::Parser; + +fn main() { + + let result = list_recipes( Path::new("recipes")); + if result.is_err() { + eprintln!("{}", result.err().unwrap()); + exit(2); + } else if result.as_ref().unwrap().is_empty() { + eprintln!("recipes not found"); + exit(1); + } else { + result.unwrap().iter().for_each(|recipe| println!("{}", recipe)); + exit(0); + } +} diff --git a/src/lib.rs b/src/lib.rs index 2fbe53530eb8fd54eb204d29a87ae69c30fb6eea..572b1716f87dfa24d4175702651507d0fe4ac17f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,6 @@ pub mod blake3; pub mod recipe; pub mod sha256; +pub mod recipe_find; mod progress_bar; diff --git a/src/recipe_find.rs b/src/recipe_find.rs new file mode 100644 index 0000000000000000000000000000000000000000..286e62a895ff60b0340ffb84df12153bef3a2831 --- /dev/null +++ b/src/recipe_find.rs @@ -0,0 +1,72 @@ +use std::fs::{self}; +use std::path::{Path, PathBuf}; + +pub fn recipe_find(recipe: &str, dir: &Path) -> Result<Option<PathBuf>, String> { + let mut recipe_path = None; + if !dir.is_dir() { + return Ok(None); + } + for entry in fs::read_dir(dir).map_err(|e| e.to_string())? { + let entry = entry.map_err(|e| e.to_string())?; + if entry.file_name().to_string_lossy() == "recipe.sh" + || entry.file_name().to_string_lossy() == "recipe.toml" + { + // println!("recipe is {:?}", dir.file_name()); + if dir.file_name().unwrap().to_string_lossy() != recipe { + return Ok(None); + } else { + return Ok(Some(dir.to_path_buf())); + } + } + } + + for entry in fs::read_dir(dir).map_err(|e| e.to_string())? { + let entry = entry.map_err(|e| e.to_string())?; + if !entry.file_type().map_err(|e| e.to_string())?.is_dir() { + continue; + } + let found = recipe_find(recipe, entry.path().as_path())?; + if found.is_none() { + continue; + } + if recipe_path.is_none() { + recipe_path = found; + } else { + return Err(format!( + "recipe {} has two or more entries {}, {}", + recipe, + recipe_path.unwrap().display(), + found.unwrap().display() + )); + } + } + + Ok(recipe_path) +} + +pub fn list_recipes(dir: &Path) -> Result<Vec<String>, String> { + let mut recipes = Vec::<String>::new(); + if !dir.is_dir() { + return Ok(recipes); + } + for entry in fs::read_dir(dir).map_err(|e| e.to_string())? { + let entry = entry.map_err(|e| e.to_string())?; + if entry.file_name().to_string_lossy() == "recipe.sh" + || entry.file_name().to_string_lossy() == "recipe.toml" + { + recipes.push(dir.file_name().ok_or(format!("could not unwrap the filename for {:?}", dir))?.to_string_lossy().to_string()); + return Ok(recipes); + } + } + + for entry in fs::read_dir(dir).map_err(|e| e.to_string())? { + let entry = entry.map_err(|e| e.to_string())?; + if !entry.file_type().map_err(|e| e.to_string())?.is_dir() { + continue; + } + let mut found = list_recipes(entry.path().as_path())?; + recipes.append(&mut found); + } + recipes.sort(); + Ok(recipes) +} diff --git a/status.sh b/status.sh index fe715ffcfd506b0953f20cfa5e8044485a6a5e46..19aa856e7124cf05f06123d1e9035e14bbf88cdf 100755 --- a/status.sh +++ b/status.sh @@ -5,14 +5,15 @@ source config.sh if [ $# = 0 ] then - recipes="$(ls -1 recipes)" + recipes="$(target/release/list_recipes)" else recipes="$@" fi for recipe in $recipes do - if [ -d "recipes/$recipe/source" ] + recipe_path=`target/release/find_recipe $recipe` + if [ -d "$recipe_path/source" ] then status="$(COOK_QUIET=1 ./cook.sh "$recipe" status)" diff --git a/status_origin.sh b/status_origin.sh index cf3e1ab43c9a4659d999778628788cbddd9876b5..b82bcedc74549f296a67ed6feef63129fafd3275 100755 --- a/status_origin.sh +++ b/status_origin.sh @@ -5,14 +5,15 @@ source config.sh if [ $# = 0 ] then - recipes="$(ls -1 recipes)" + recipes="$(target/release/list_recipes)" else recipes="$@" fi for recipe in $recipes do - if [ -d "recipes/$recipe/source" ] + recipe_path=`target/release/find_recipe $recipe` + if [ -d "$recipe_path/source" ] then status="$(COOK_QUIET=1 ./cook.sh "$recipe" status_origin)" diff --git a/status_upstream.sh b/status_upstream.sh index defd1c5399e54e2917f93ff0ef7bfa1ade5192c0..eb150c004f362e09fbc5fb67e50d2e4450e8699c 100755 --- a/status_upstream.sh +++ b/status_upstream.sh @@ -5,14 +5,15 @@ source config.sh if [ $# = 0 ] then - recipes="$(ls -1 recipes)" + recipes="$(target/release/list_recipes)" else recipes="$@" fi for recipe in $recipes do - if [ -d "recipes/$recipe/source" ] + recipe_path=`target/release/find_recipe $recipe` + if [ -d "$recipe_path/source" ] then status="$(COOK_QUIET=1 ./cook.sh "$recipe" status_upstream)" diff --git a/unfetch.sh b/unfetch.sh index a63be6a73edcec22674398f28fd8727021de865c..b6877cc3084510925f7d96a2e1da7b80113692d0 100755 --- a/unfetch.sh +++ b/unfetch.sh @@ -5,7 +5,7 @@ source config.sh if [ $# = 0 ] then - recipes="$(ls -1 recipes)" + recipes="$(target/release/list_recipes)" else recipes="$@" fi