From 2b34b31956b4d6af594831908ac954e44cbb0848 Mon Sep 17 00:00:00 2001 From: Ron Williams Date: Sat, 4 Nov 2023 18:33:52 +0000 Subject: [PATCH] Allow package spec "binary" or "recipe" to override REPO_BINARY=0 or REPO_BINARY=1 --- src/bin/installer.rs | 99 +++++++++++++++++++++++++------------------ src/config/general.rs | 5 +-- src/lib.rs | 3 +- 3 files changed, 62 insertions(+), 45 deletions(-) diff --git a/src/bin/installer.rs b/src/bin/installer.rs index 1ba226a922..eb43526e0f 100644 --- a/src/bin/installer.rs +++ b/src/bin/installer.rs @@ -3,9 +3,9 @@ extern crate redox_installer; extern crate serde; extern crate toml; -use std::{env, fs, io, process}; use std::io::{Read, Write}; use std::path::Path; +use std::{env, fs, io, process}; use arg_parser::ArgParser; @@ -18,34 +18,29 @@ fn main() { let mut parser = ArgParser::new(4) .add_opt("b", "cookbook") .add_opt("c", "config") - .add_flag(&["p", "cooking"]) + .add_flag(&["r", "repo-binary"]) .add_flag(&["l", "list-packages"]) .add_flag(&["live"]); parser.parse(env::args()); - // Allow filesystem config to specify recipe or package, enabling mixed recipe/binary build - let cooking = parser.found("cooking"); + // Use pre-built binaries for packages as the default. + // If not set on the command line or the filesystem config, then build packages from source. + let repo_binary = parser.found("repo-binary"); let mut config_data = String::new(); let mut config = if let Some(path) = parser.get_opt("config") { match fs::File::open(&path) { - Ok(mut config_file) => { - match config_file.read_to_string(&mut config_data) { - Ok(_) => { - match toml::from_str(&config_data) { - Ok(config) => { - config - }, - Err(err) => { - writeln!(stderr, "installer: {}: failed to decode: {}", path, err).unwrap(); - process::exit(1); - } - } - }, + Ok(mut config_file) => match config_file.read_to_string(&mut config_data) { + Ok(_) => match toml::from_str(&config_data) { + Ok(config) => config, Err(err) => { - writeln!(stderr, "installer: {}: failed to read: {}", path, err).unwrap(); + writeln!(stderr, "installer: {}: failed to decode: {}", path, err).unwrap(); process::exit(1); } + }, + Err(err) => { + writeln!(stderr, "installer: {}: failed to read: {}", path, err).unwrap(); + process::exit(1); } }, Err(err) => { @@ -65,30 +60,33 @@ fn main() { }); // Add command line flags to config, command line takes priority - if cooking { - config.general.cooking = Some(true); + if repo_binary { + config.general.repo_binary = Some(true); } if parser.found("list-packages") { + // List the packages that should be fetched or built by the cookbook for (packagename, package) in &config.packages { - if config.general.cooking == Some(true) { - // Only print the names of packages that are relevant to the cookbook - match package { - PackageConfig::Build(rule) if rule == "recipe" => { - println!("{}", packagename); - } - PackageConfig::Build(rule) if rule == "recipe_no_fetch" => { - println!("{}", packagename); - } - _ => {} + match package { + PackageConfig::Build(rule) if rule == "recipe" => { + println!("{}", packagename); + } + PackageConfig::Build(rule) if rule == "binary" => { + // skip this package + } + _ => { + if config.general.repo_binary == Some(true) { + // default action is to not build this package, skip it + } else { + // default action is to build + println!("{}", packagename); + } } - } else { - println!("{}", packagename); } } } else { let cookbook = if let Some(path) = parser.get_opt("cookbook") { - if ! Path::new(&path).is_dir() { + if !Path::new(&path).is_dir() { writeln!(stderr, "installer: {}: cookbook not found", path).unwrap(); process::exit(1); } @@ -103,31 +101,50 @@ fn main() { ..Default::default() }); Some(path) - }, + } Err(err) => { // if there are no recipes coming from the cookbook, this is not a fatal error - if config.packages.clone().into_iter().any(| (_packagename, package) | - match package { + if config + .packages + .clone() + .into_iter() + .any(|(_packagename, package)| match package { PackageConfig::Empty => false, - PackageConfig::Spec { version: None, git: None, path: None, } => false, + PackageConfig::Spec { + version: None, + git: None, + path: None, + } => false, _ => true, }) { - writeln!(stderr, "installer: {}: failed to read cookbook key: {}", key_path.display(), err).unwrap(); + writeln!( + stderr, + "installer: {}: failed to read cookbook key: {}", + key_path.display(), + err + ) + .unwrap(); process::exit(1); } else { - writeln!(stderr, "installer: {}: (non-fatal) missing cookbook key: {}", key_path.display(), err).unwrap(); + writeln!( + stderr, + "installer: {}: (non-fatal) missing cookbook key: {}", + key_path.display(), + err + ) + .unwrap(); None } } } - } else { None }; if let Some(path) = parser.args.get(0) { - if let Err(err) = redox_installer::install(config, path, cookbook, parser.found("live")) { + if let Err(err) = redox_installer::install(config, path, cookbook, parser.found("live")) + { writeln!(stderr, "installer: failed to install: {}", err).unwrap(); process::exit(1); } diff --git a/src/config/general.rs b/src/config/general.rs index 20a591b3bd..4df0f529ec 100644 --- a/src/config/general.rs +++ b/src/config/general.rs @@ -1,7 +1,6 @@ #[derive(Clone, Debug, Default, Deserialize)] pub struct GeneralConfig { pub prompt: bool, - // Allow filesystem config to select recipe or package - #[serde(skip)] - pub cooking: Option, + // Allow config to specify cookbook recipe or binary package as default + pub repo_binary: Option, } diff --git a/src/lib.rs b/src/lib.rs index 8f56261202..b2136edb13 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -104,9 +104,10 @@ fn install_packages>(config: &Config, dest: &str, cookbook: Option let pkgar_path = format!("{}/{}/repo/{}/{}.pkgar", env::current_dir().unwrap().to_string_lossy(), cookbook.as_ref(), target, packagename); - let from_remote = match (config.general.cooking, package) { + let from_remote = match (config.general.repo_binary, package) { (Some(true), PackageConfig::Empty) => true, (Some(true), PackageConfig::Spec { version: None, git: None, path: None }) => true, + (_, PackageConfig::Build(rule)) if rule == "binary" => true, _ => false }; if from_remote {