2026-02-14 13:31:21 -05:00
|
|
|
use std::borrow::Cow;
|
|
|
|
|
use std::path::Path;
|
|
|
|
|
|
|
|
|
|
use serde::Deserialize;
|
|
|
|
|
use serde::Serialize;
|
2026-02-14 22:11:46 -05:00
|
|
|
use sha2::Digest;
|
|
|
|
|
use sha2::Sha256;
|
2026-02-14 13:31:21 -05:00
|
|
|
|
|
|
|
|
use crate::error::CustomError;
|
|
|
|
|
|
|
|
|
|
use super::Config;
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
|
|
|
|
pub(crate) struct TargetConfig {
|
|
|
|
|
pub(super) name: String,
|
|
|
|
|
|
2026-02-14 16:00:37 -05:00
|
|
|
pub(super) repo: String,
|
|
|
|
|
|
2026-02-14 13:31:21 -05:00
|
|
|
#[serde(default)]
|
|
|
|
|
pub(super) branch: Option<String>,
|
2026-02-14 16:00:37 -05:00
|
|
|
|
|
|
|
|
#[serde(default)]
|
|
|
|
|
pub(super) revision: Option<String>,
|
|
|
|
|
|
2026-02-14 13:31:21 -05:00
|
|
|
#[serde(default)]
|
|
|
|
|
pub(super) path: Option<String>,
|
2026-02-14 16:00:37 -05:00
|
|
|
|
2026-02-14 13:31:21 -05:00
|
|
|
#[serde(default)]
|
2026-02-14 19:20:52 -05:00
|
|
|
pub(super) attr: String,
|
2026-02-14 16:00:37 -05:00
|
|
|
|
2026-02-14 13:31:21 -05:00
|
|
|
#[serde(default)]
|
|
|
|
|
pub(super) update: Option<bool>,
|
2026-02-14 16:00:37 -05:00
|
|
|
|
2026-02-14 13:31:21 -05:00
|
|
|
#[serde(default)]
|
|
|
|
|
pub(super) update_branch: Option<String>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl TargetConfig {
|
2026-02-14 22:11:46 -05:00
|
|
|
/// The folder that contains the folders for the build targets.
|
|
|
|
|
pub(crate) fn get_target_root_directory<'target, 'root>(
|
|
|
|
|
&'target self,
|
|
|
|
|
config_root: &'root Config,
|
|
|
|
|
) -> Result<Cow<'target, Path>, CustomError> {
|
|
|
|
|
let output_directory = config_root.get_output_directory()?;
|
|
|
|
|
Ok(Cow::Owned(output_directory.join("target")))
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-14 19:20:52 -05:00
|
|
|
/// The root directory for this specific build target.
|
2026-02-14 13:31:21 -05:00
|
|
|
pub(crate) fn get_target_directory<'target, 'root>(
|
|
|
|
|
&'target self,
|
|
|
|
|
config_root: &'root Config,
|
|
|
|
|
) -> Result<Cow<'target, Path>, CustomError> {
|
2026-02-14 22:11:46 -05:00
|
|
|
let target_root = self.get_target_root_directory(config_root)?;
|
|
|
|
|
Ok(Cow::Owned(target_root.join(&self.name)))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// The folder that contains the folders containing the checkouts of the git repositories.
|
|
|
|
|
pub(crate) fn get_repo_root_directory<'target, 'root>(
|
|
|
|
|
&'target self,
|
|
|
|
|
config_root: &'root Config,
|
|
|
|
|
) -> Result<Cow<'target, Path>, CustomError> {
|
|
|
|
|
let output_directory = config_root.get_output_directory()?;
|
|
|
|
|
Ok(Cow::Owned(output_directory.join("repo")))
|
2026-02-14 13:31:21 -05:00
|
|
|
}
|
|
|
|
|
|
2026-02-14 19:20:52 -05:00
|
|
|
/// The root of the checkout of the git repository.
|
|
|
|
|
pub(crate) fn get_repo_directory<'target, 'root>(
|
2026-02-14 13:31:21 -05:00
|
|
|
&'target self,
|
|
|
|
|
config_root: &'root Config,
|
|
|
|
|
) -> Result<Cow<'target, Path>, CustomError> {
|
2026-02-14 22:11:46 -05:00
|
|
|
let hashed_repo = Sha256::digest(&self.repo);
|
|
|
|
|
let hashed_repo = hex_string(&hashed_repo);
|
|
|
|
|
|
|
|
|
|
let repo_root = self.get_repo_root_directory(config_root)?;
|
|
|
|
|
Ok(Cow::Owned(repo_root.join(hashed_repo)))
|
2026-02-14 19:20:52 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// The directory that contains flake.nix.
|
|
|
|
|
pub(crate) fn get_flake_directory<'target, 'root>(
|
|
|
|
|
&'target self,
|
|
|
|
|
config_root: &'root Config,
|
|
|
|
|
) -> Result<Cow<'target, Path>, CustomError> {
|
|
|
|
|
let repo_directory = self.get_repo_directory(config_root)?;
|
|
|
|
|
let subpath = self.path.as_deref();
|
|
|
|
|
if let Some(subpath) = subpath {
|
|
|
|
|
Ok(Cow::Owned(repo_directory.join(subpath)))
|
|
|
|
|
} else {
|
|
|
|
|
Ok(repo_directory)
|
|
|
|
|
}
|
2026-02-14 13:31:21 -05:00
|
|
|
}
|
2026-02-14 16:00:37 -05:00
|
|
|
|
2026-02-14 19:20:52 -05:00
|
|
|
/// The URL to the upstream git repository.
|
2026-02-14 16:00:37 -05:00
|
|
|
pub(crate) fn get_repo(&'_ self) -> Result<&String, CustomError> {
|
|
|
|
|
Ok(&self.repo)
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-14 19:20:52 -05:00
|
|
|
/// The git branch name to track.
|
2026-02-14 16:00:37 -05:00
|
|
|
pub(crate) fn get_branch(&'_ self) -> Result<Cow<'_, str>, CustomError> {
|
|
|
|
|
if let Some(b) = &self.branch {
|
|
|
|
|
Ok(Cow::Borrowed(b))
|
|
|
|
|
} else {
|
|
|
|
|
Ok(Cow::Borrowed("main"))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-14 19:20:52 -05:00
|
|
|
/// If we want to pin to a specific revision, this is the reference to that commit.
|
2026-02-14 16:00:37 -05:00
|
|
|
pub(crate) fn get_revision(&self) -> Result<&Option<String>, CustomError> {
|
|
|
|
|
Ok(&self.revision)
|
|
|
|
|
}
|
2026-02-14 19:20:52 -05:00
|
|
|
|
|
|
|
|
/// The folder where nixos-rebuild is invoked and the outputs are linked.
|
|
|
|
|
pub(crate) fn get_build_directory<'target, 'root>(
|
|
|
|
|
&'target self,
|
|
|
|
|
config_root: &'root Config,
|
|
|
|
|
) -> Result<Cow<'target, Path>, CustomError> {
|
|
|
|
|
let target_directory = self.get_target_directory(config_root)?;
|
|
|
|
|
Ok(Cow::Owned(target_directory.join("build")))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// The flake output attribute to build (the part after '#' in the build command).
|
|
|
|
|
pub(crate) fn get_attr(&'_ self) -> Result<&String, CustomError> {
|
|
|
|
|
Ok(&self.attr)
|
|
|
|
|
}
|
2026-02-16 20:42:03 -05:00
|
|
|
|
|
|
|
|
/// The name to identify this target
|
|
|
|
|
pub(crate) fn get_name(&'_ self) -> Result<&String, CustomError> {
|
|
|
|
|
Ok(&self.name)
|
|
|
|
|
}
|
2026-02-14 13:31:21 -05:00
|
|
|
}
|
2026-02-14 22:11:46 -05:00
|
|
|
|
|
|
|
|
fn hex_string(data: &[u8]) -> String {
|
|
|
|
|
let mut out = String::with_capacity(data.len() * 2);
|
|
|
|
|
for byte in data {
|
|
|
|
|
out.push_str(format!("{:02x}", byte).as_str());
|
|
|
|
|
}
|
|
|
|
|
out
|
|
|
|
|
}
|