diff --git a/src/bin/pkg.rs b/src/bin/pkg.rs index 1446235..c19907d 100644 --- a/src/bin/pkg.rs +++ b/src/bin/pkg.rs @@ -65,8 +65,12 @@ fn main() -> Result<()> { process::exit(1); } Some(pkg) => { - return dive::nixpkgs::install_package(pkg) - .context("failed to install package"); + if let Err(err) = dive::nixpkgs::install_package(pkg) + .context("failed to install package") + { + eprintln!("error: {err}"); + process::exit(1); + } } } } diff --git a/src/lib.rs b/src/lib.rs index 9889961..60c4dd2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -20,6 +20,8 @@ pub(crate) const USER_ENV_DIR: &str = "/nix/.env"; pub(crate) const BASE_DIR: &str = "/nix/.base"; pub(crate) const ETC_DIR: &str = "/nix/etc"; +pub(crate) const SSL_CERTS: &str = "/nix/.base/etc/ssl/certs/ca-bundle.crt"; + pub const BASE_PACKAGES: &[&str] = &[ "bash", "cacert", diff --git a/src/nixos.rs b/src/nixos.rs index 2d7a2ad..8fa245f 100644 --- a/src/nixos.rs +++ b/src/nixos.rs @@ -149,7 +149,6 @@ pub(crate) fn run_gc() -> Result<()> { let status = Command::new("nix") .args(["store", "gc"]) .envs(ENV_VARS) - .stdout(Stdio::null()) .status()?; if !status.success() { diff --git a/src/shell.rs b/src/shell.rs index 6541d5b..e0508ab 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -20,6 +20,9 @@ pub struct Shell { } impl Shell { + const NIX_ENVS: [&str; 2] = [crate::USER_ENV_DIR, crate::BASE_DIR]; + const BIN_DIRS: [&str; 2] = ["bin", "sbin"]; + pub fn new(name: &str) -> Self { Shell { name: name.to_owned(), @@ -40,6 +43,17 @@ impl Shell { self } + pub fn spawn(self) -> Result { + match unsafe { fork()? } { + Fork::Child(_) => { + let err = self.exec(); + log::error!("cannot execute shell: {err}"); + exit(1); + } + Fork::Parent(child_pid) => wait_for_child(child_pid), + } + } + fn exec(self) -> std::io::Error { // // TODO: path HOME w/ user as defined by /etc/passwd @@ -64,7 +78,7 @@ impl Shell { }; // TODO: these variable except for TERM should be initialized in zshenv - let nix_bin_path = "/nix/.base/sbin:/nix/.base/bin:/nix/.bin"; + let nix_bin_path = Self::get_bin_paths(); cmd.env("PATH", format!("{nix_bin_path}:{proc_path}")); if let Ok(term) = std::env::var("TERM") { @@ -85,39 +99,42 @@ impl Shell { ); cmd.env("PROMPT", &prompt); - let nix_base = crate::BASE_DIR; - let data_dir = format!("/usr/local/share:/usr/share:{nix_base}/share"); + let share_paths = Self::get_env_paths("share"); + let data_dir = format!("{share_paths}:/usr/local/share:/usr/share"); cmd.envs([ ("ZDOTDIR", crate::ETC_DIR), ("NIX_CONF_DIR", crate::ETC_DIR), - ( - "NIX_SSL_CERT_FILE", - "/nix/.base/etc/ssl/certs/ca-bundle.crt", - ), + ("NIX_SSL_CERT_FILE", crate::SSL_CERTS), ("XDG_CACHE_HOME", crate::CACHE_HOME), ("XDG_CONFIG_HOME", crate::CONFIG_HOME), ("XDG_DATA_DIR", &data_dir), ]); cmd.envs([ - ("TERMINFO_DIRS", format!("{nix_base}/share/terminfo")), - ("LIBEXEC_PATH", format!("{nix_base}/libexec")), - ("INFOPATH", format!("{nix_base}/share/info")), + ("TERMINFO_DIRS", Self::get_env_paths("share/terminfo")), + ("LIBEXEC_PATH", Self::get_env_paths("libexec")), + ("INFOPATH", Self::get_env_paths("share/info")), ]); let _ = create_dir_all(crate::CACHE_HOME); cmd.exec() } - pub fn spawn(self) -> Result { - match unsafe { fork()? } { - Fork::Child(_) => { - let err = self.exec(); - log::error!("cannot execute shell: {err}"); - exit(1); + fn get_bin_paths() -> String { + let res_len = Self::NIX_ENVS.len() * Self::BIN_DIRS.len(); + let mut paths = Vec::with_capacity(res_len); + + for env in Self::NIX_ENVS { + for dir in Self::BIN_DIRS { + paths.push(format!("{}/{}", env, dir)); } - Fork::Parent(child_pid) => wait_for_child(child_pid), } + + paths.join(":") + } + + fn get_env_paths(dir: &str) -> String { + Self::NIX_ENVS.map(|e| format!("{e}/{dir}")).join(":") } }