diff --git a/config.md b/config.md index 7c6ad7f..bebebae 100644 --- a/config.md +++ b/config.md @@ -19,6 +19,8 @@ sudo = "run0" package_manager = "pacman" # preferred installation method, can be limited with the package manager -# available options are: System, User, Temp +# available options are: +# - System +# - Shell (nix and guix only) install_method = "System" ``` diff --git a/core/src/config.rs b/core/src/config.rs index 6a09ea8..ed1ec8f 100644 --- a/core/src/config.rs +++ b/core/src/config.rs @@ -1,8 +1,7 @@ use serde::Deserialize; #[allow(dead_code)] -#[derive(Deserialize)] -#[derive(Default)] +#[derive(Deserialize, Default)] pub struct Config { pub sudo: Option, #[serde(default)] @@ -12,16 +11,13 @@ pub struct Config { } #[allow(dead_code)] -#[derive(Deserialize)] -#[derive(Default)] +#[derive(Deserialize, Default)] pub struct PackageManagerConfig { pub package_manager: Option, #[serde(default)] pub install_method: InstallMethod, } - - #[derive(Deserialize)] pub struct Timeout(pub u64); impl Default for Timeout { @@ -30,13 +26,14 @@ impl Default for Timeout { } } -#[derive(Deserialize)] -#[derive(Default)] +#[derive(Deserialize, Default, PartialEq)] pub enum InstallMethod { #[default] System, - User, - Temp, + // !TODO: Implement other install methods + // User, + // Temp, + Shell, } pub fn load_config() -> Config { diff --git a/core/src/modes.rs b/core/src/modes.rs index 814b625..6c3516d 100644 --- a/core/src/modes.rs +++ b/core/src/modes.rs @@ -9,9 +9,9 @@ use pay_respects_utils::files::best_match_file; use crate::data::Data; use crate::shell::shell_evaluated_commands; use crate::style::highlight_difference; -use crate::suggestions; use crate::suggestions::suggest_candidates; use crate::system; +use crate::{config, suggestions}; pub fn suggestion(data: &mut Data) { let mut last_command; @@ -191,6 +191,17 @@ pub fn cnf(data: &mut Data) { .prompt() .unwrap_or_else(|_| std::process::exit(1)); + let install_method = &data.config.package_manager.install_method; + if install_method == &config::InstallMethod::Shell { + // let the shell handle the installation and place the user in a shell + // environment with the package installed + println!( + "{}", + system::shell_package(data, &package_manager, &package) + ); + return; + } + // retry after installing package if system::install_package(data, &package_manager, &package) { let status = suggestions::run_suggestion(data, &data.command); diff --git a/core/src/system.rs b/core/src/system.rs index c9c8a73..a231737 100644 --- a/core/src/system.rs +++ b/core/src/system.rs @@ -14,6 +14,13 @@ pub fn get_package_manager(data: &mut Data) -> Option { return Some(package_manager); } + if let Some(package_manager) = data.config.package_manager.package_manager.as_ref() { + if package_manager.is_empty() { + return None; + } + return Some(package_manager.to_string()); + } + if let Some(package_manager) = option_env!("_DEF_PR_PACKAGE_MANAGER") { if package_manager.is_empty() { return None; @@ -245,3 +252,16 @@ pub fn install_package(data: &mut Data, package_manager: &str, package: &str) -> result.success() } + +pub fn shell_package(data: &Data, package_manager: &str, package: &str) -> String { + let command = data.command.clone(); + + match package_manager { + "guix" => format!("guix shell {} -- {}", package, command), + "nix" => format!( + r#"nix shell nixpkgs#{} --command "{};return""#, + package, command + ), + _ => unreachable!("Only `nix` and `guix` are supported for shell installation"), + } +}