use std::path::PathBuf;
use crate::cmd::pkexec_guix_cmd;
use crate::error::GuixError;
use crate::operation::{spawn_operation_with, ExitClassifier, Operation};
use crate::repl;
use crate::system::{preflight_auth_agent, GUIX_PROFILES_ROOT};
use crate::Guix;
#[derive(Clone)]
pub struct PullOps {
guix: Guix,
}
impl PullOps {
pub(crate) fn new(guix: Guix) -> Self {
Self { guix }
}
pub fn user(&self) -> Result<Operation, GuixError> {
repl::op::spawn_repl_op(self.guix.binary_path(), repl::op::PULL_SCHEME)
}
pub fn as_root(&self, opts: SystemPullOptions) -> Result<Operation, GuixError> {
preflight_auth_agent()?;
let mut args: Vec<String> = vec!["pull".into()];
if opts.dry_run {
args.push("--dry-run".into());
}
let c = pkexec_guix_cmd(&args)?;
spawn_operation_with(c, ExitClassifier::Pkexec)
}
pub fn user_path() -> PathBuf {
let user = std::env::var("USER").unwrap_or_else(|_| "root".to_string());
PathBuf::from(format!(
"{}/per-user/{}/current-guix",
GUIX_PROFILES_ROOT, user
))
}
pub fn root_path() -> PathBuf {
PathBuf::from(format!("{}/per-user/root/current-guix", GUIX_PROFILES_ROOT))
}
}
#[derive(Debug, Clone, Default)]
pub struct SystemPullOptions {
pub dry_run: bool,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default_pull_options_are_quiet() {
let o = SystemPullOptions::default();
assert!(!o.dry_run);
}
#[test]
fn pull_path_helpers_return_expected_layout() {
let root = PullOps::root_path();
assert_eq!(
root,
PathBuf::from("/var/guix/profiles/per-user/root/current-guix")
);
let user = PullOps::user_path();
let s = user.to_string_lossy();
assert!(
s.starts_with("/var/guix/profiles/per-user/"),
"user path under wrong root: {s}"
);
assert!(
s.ends_with("/current-guix"),
"user path doesn't end in /current-guix: {s}"
);
}
}