git.delta.rocks / jrsonnet / refs/commits / d866c975e1c7

difftreelog

source

src/nix.rs3.7 KiBsourcehistory
1use std::{2	collections::HashMap,3	ffi::OsStr,4	path::PathBuf,5	process::{Command, Stdio},6};78use anyhow::Result;9use serde::de::DeserializeOwned;1011use crate::command::CommandOutput;1213pub const HOSTS_ATTRIBUTE: &str = ".#fleetConfigurations.default.configuredHosts";14pub const SECRETS_ATTRIBUTE: &str = ".#fleetConfigurations.default.configuredSecrets";15pub const SYSTEMS_ATTRIBUTE: &str = ".#fleetConfigurations.default.configuredSystems";1617pub struct NixCopy {18	closure: PathBuf,19}20impl NixCopy {21	pub fn new(closure: PathBuf) -> Self {22		Self { closure }23	}24	fn run_internal(&self, f: impl Fn(&mut Command)) -> Result<CommandOutput> {25		let mut cmd = Command::new("nix");26		cmd.stderr(Stdio::inherit())27			.arg("copy")28			.arg("--substitute-on-destination")29			.arg(&self.closure);30		f(&mut cmd);3132		let out = cmd.output()?;33		if !out.status.success() {34			anyhow::bail!("nix copy failed");35		}36		Ok(CommandOutput(out.stdout))37	}38	pub fn from(&self, from: impl AsRef<OsStr>) -> Result<()> {39		let from = from.as_ref();40		self.run_internal(|cmd| {41			cmd.arg("--from").arg(from);42		})?;43		Ok(())44	}45	pub fn to(&self, to: impl AsRef<OsStr>) -> Result<()> {46		let to = to.as_ref();47		self.run_internal(|cmd| {48			cmd.arg("--to").arg(to);49		})?;50		Ok(())51	}52}5354pub struct NixBuild {55	attribute: String,56	impure: bool,57	env: HashMap<String, String>,58}5960impl NixBuild {61	pub fn new(attribute: String) -> Self {62		Self {63			attribute,64			impure: false,65			env: HashMap::new(),66		}67	}68	pub fn env(&mut self, name: String, value: String) -> &mut Self {69		self.impure = true;70		self.env.insert(name, value);71		self72	}73	pub fn run(&self) -> Result<tempfile::TempDir> {74		let dir = tempfile::tempdir()?;75		std::fs::remove_dir(dir.path())?;76		let mut cmd = Command::new("nix");77		cmd.stderr(Stdio::inherit())78			.arg("build")79			.arg(&self.attribute)80			.arg("--no-link")81			.arg("--out-link")82			.arg(dir.path());83		if self.impure {84			cmd.arg("--impure");85		}86		if !self.env.is_empty() {87			cmd.envs(&self.env);88		}8990		let out = cmd.output()?;91		if !out.status.success() {92			anyhow::bail!("nix eval failed");93		}94		Ok(dir)95	}96}9798#[derive(Default)]99pub struct NixEval {100	attribute: String,101	impure: bool,102	apply: Option<String>,103	env: HashMap<String, String>,104}105106impl NixEval {107	pub fn new(attribute: String) -> Self {108		Self {109			attribute,110			..Default::default()111		}112	}113	pub fn impure(&mut self) -> &mut Self {114		self.impure = true;115		self116	}117	/// This is the only and impure way to pass something to flake118	/// - https://github.com/NixOS/nix/issues/3949119	/// - https://github.com/NixOS/nixpkgs/issues/101101120	pub fn env(&mut self, name: String, value: String) -> &mut Self {121		self.impure = true;122		self.env.insert(name, value);123		self124	}125	pub fn apply(&mut self, apply: String) -> &mut Self {126		self.apply = Some(apply);127		self128	}129	fn run_internal(&self, f: impl Fn(&mut Command)) -> Result<CommandOutput> {130		let mut cmd = Command::new("nix");131		cmd.stderr(Stdio::inherit())132			.arg("eval")133			.arg("--show-trace")134			.arg(&self.attribute);135		if let Some(apply) = &self.apply {136			cmd.arg("--apply").arg(apply);137		};138		if self.impure {139			cmd.arg("--impure");140		}141		if !self.env.is_empty() {142			cmd.envs(&self.env);143		}144		f(&mut cmd);145146		let out = cmd.output()?;147		if !out.status.success() {148			anyhow::bail!("nix eval failed");149		}150		Ok(CommandOutput(out.stdout))151	}152	pub fn run(&self) -> Result<String> {153		Ok(self.run_internal(|_cmd| {})?.as_str()?.to_owned())154	}155	pub fn run_json<T: DeserializeOwned>(&self) -> Result<T> {156		Ok(serde_json::from_slice(157			&self158				.run_internal(|cmd| {159					cmd.arg("--json");160				})?161				.0,162		)?)163	}164	pub fn run_raw(&self) -> Result<String> {165		Ok(self166			.run_internal(|cmd| {167				cmd.arg("--raw");168			})?169			.as_str()?170			.to_owned())171	}172}