forked from DGNum/colmena
nix/assets: Make assets a flake
Groundwork to make flake evaluation pure. `pure-eval` works when the git workspace is clean.
This commit is contained in:
parent
a98d1f8963
commit
271d9ae576
5 changed files with 62 additions and 21 deletions
|
@ -11,8 +11,10 @@ use std::os::unix::fs::OpenOptionsExt;
|
|||
|
||||
use tempfile::TempDir;
|
||||
|
||||
use super::HivePath;
|
||||
use super::{Flake, HivePath};
|
||||
use crate::error::ColmenaResult;
|
||||
|
||||
const FLAKE_NIX: &[u8] = include_bytes!("flake.nix");
|
||||
const EVAL_NIX: &[u8] = include_bytes!("eval.nix");
|
||||
const OPTIONS_NIX: &[u8] = include_bytes!("options.nix");
|
||||
const MODULES_NIX: &[u8] = include_bytes!("modules.nix");
|
||||
|
@ -22,17 +24,37 @@ const MODULES_NIX: &[u8] = include_bytes!("modules.nix");
|
|||
pub(super) struct Assets {
|
||||
/// Temporary directory holding the files.
|
||||
temp_dir: TempDir,
|
||||
|
||||
/// Locked Flake URI of the assets flake.
|
||||
assets_flake_uri: Option<String>,
|
||||
}
|
||||
|
||||
impl Assets {
|
||||
pub fn new() -> Self {
|
||||
pub async fn new(flake: bool) -> ColmenaResult<Self> {
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
|
||||
create_file(&temp_dir, "eval.nix", false, EVAL_NIX);
|
||||
create_file(&temp_dir, "options.nix", false, OPTIONS_NIX);
|
||||
create_file(&temp_dir, "modules.nix", false, MODULES_NIX);
|
||||
create_file(&temp_dir, "eval.nix", false, EVAL_NIX)?;
|
||||
create_file(&temp_dir, "options.nix", false, OPTIONS_NIX)?;
|
||||
create_file(&temp_dir, "modules.nix", false, MODULES_NIX)?;
|
||||
|
||||
Self { temp_dir }
|
||||
let mut assets_flake_uri = None;
|
||||
|
||||
if flake {
|
||||
// Emit a temporary flake, then resolve the locked URI
|
||||
create_file(&temp_dir, "flake.nix", false, FLAKE_NIX)?;
|
||||
|
||||
// We explicitly specify `path:` instead of letting Nix resolve
|
||||
// automatically, which would involve checking parent directories
|
||||
// for a git repository.
|
||||
let uri = format!("path:{}", temp_dir.path().to_str().unwrap());
|
||||
let assets_flake = Flake::from_uri(uri).await?;
|
||||
assets_flake_uri = Some(assets_flake.locked_uri().to_owned());
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
temp_dir,
|
||||
assets_flake_uri,
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the base expression from which the evaluated Hive can be used.
|
||||
|
@ -49,11 +71,9 @@ impl Assets {
|
|||
}
|
||||
HivePath::Flake(flake) => {
|
||||
format!(
|
||||
"with builtins; let eval = import {eval_nix}; hive = eval {{ flakeUri = \"{flake_uri}\"; colmenaOptions = import {options_nix}; colmenaModules = import {modules_nix}; }}; in ",
|
||||
flake_uri = flake.uri(),
|
||||
eval_nix = self.get_path("eval.nix"),
|
||||
options_nix = self.get_path("options.nix"),
|
||||
modules_nix = self.get_path("modules.nix"),
|
||||
"with builtins; let assets = getFlake \"{assets_flake_uri}\"; hive = assets.lib.colmenaEval {{ flakeUri = \"{flake_uri}\"; }}; in ",
|
||||
assets_flake_uri = self.assets_flake_uri.as_ref().expect("The assets flake must have been initialized"),
|
||||
flake_uri = flake.locked_uri(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -69,15 +89,16 @@ impl Assets {
|
|||
}
|
||||
}
|
||||
|
||||
fn create_file(base: &TempDir, name: &str, executable: bool, contents: &[u8]) {
|
||||
fn create_file(base: &TempDir, name: &str, executable: bool, contents: &[u8]) -> ColmenaResult<()> {
|
||||
let mode = if executable { 0o700 } else { 0o600 };
|
||||
let path = base.path().join(name);
|
||||
let mut f = OpenOptions::new()
|
||||
.create_new(true)
|
||||
.write(true)
|
||||
.mode(mode)
|
||||
.open(path)
|
||||
.unwrap();
|
||||
.open(path)?;
|
||||
|
||||
f.write_all(contents).unwrap();
|
||||
f.write_all(contents)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
15
src/nix/hive/flake.nix
Normal file
15
src/nix/hive/flake.nix
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
description = "Internal Colmena expressions";
|
||||
|
||||
outputs = { ... }: {
|
||||
lib.colmenaEval = {
|
||||
rawHive ? null,
|
||||
flakeUri ? null,
|
||||
hermetic ? flakeUri != null,
|
||||
}: import ./eval.nix {
|
||||
inherit rawHive flakeUri hermetic;
|
||||
colmenaOptions = import ./options.nix;
|
||||
colmenaModules = import ./modules.nix;
|
||||
};
|
||||
};
|
||||
}
|
|
@ -90,6 +90,10 @@ impl HivePath {
|
|||
Ok(Self::Legacy(path.canonicalize()?))
|
||||
}
|
||||
|
||||
fn is_flake(&self) -> bool {
|
||||
matches!(self, Self::Flake(_))
|
||||
}
|
||||
|
||||
fn context_dir(&self) -> Option<PathBuf> {
|
||||
match self {
|
||||
Self::Legacy(p) => p.parent().map(|d| d.to_owned()),
|
||||
|
@ -99,13 +103,14 @@ impl HivePath {
|
|||
}
|
||||
|
||||
impl Hive {
|
||||
pub fn new(path: HivePath) -> ColmenaResult<Self> {
|
||||
pub async fn new(path: HivePath) -> ColmenaResult<Self> {
|
||||
let context_dir = path.context_dir();
|
||||
let assets = Assets::new(path.is_flake()).await?;
|
||||
|
||||
Ok(Self {
|
||||
path,
|
||||
context_dir,
|
||||
assets: Assets::new(),
|
||||
assets,
|
||||
show_trace: false,
|
||||
meta_config: OnceCell::new(),
|
||||
})
|
||||
|
|
|
@ -40,7 +40,7 @@ impl TempHive {
|
|||
temp_file.write_all(text.as_bytes()).unwrap();
|
||||
|
||||
let hive_path = block_on(HivePath::from_path(temp_file.path())).unwrap();
|
||||
let hive = Hive::new(hive_path).unwrap();
|
||||
let hive = block_on(Hive::new(hive_path)).unwrap();
|
||||
|
||||
Self {
|
||||
hive,
|
||||
|
@ -168,7 +168,7 @@ fn test_parse_flake() {
|
|||
let flake = block_on(Flake::from_dir(flake_dir)).unwrap();
|
||||
|
||||
let hive_path = HivePath::Flake(flake);
|
||||
let mut hive = Hive::new(hive_path).unwrap();
|
||||
let mut hive = block_on(Hive::new(hive_path)).unwrap();
|
||||
|
||||
hive.set_show_trace(true);
|
||||
|
||||
|
|
|
@ -244,7 +244,7 @@ pub async fn hive_from_args(args: &ArgMatches) -> ColmenaResult<Hive> {
|
|||
log::info!("Using flake: {}", flake.uri());
|
||||
|
||||
let hive_path = HivePath::Flake(flake);
|
||||
let mut hive = Hive::new(hive_path)?;
|
||||
let mut hive = Hive::new(hive_path).await?;
|
||||
|
||||
if args.is_present("show-trace") {
|
||||
hive.set_show_trace(true);
|
||||
|
@ -267,7 +267,7 @@ pub async fn hive_from_args(args: &ArgMatches) -> ColmenaResult<Hive> {
|
|||
}
|
||||
}
|
||||
|
||||
let mut hive = Hive::new(hive_path)?;
|
||||
let mut hive = Hive::new(hive_path).await?;
|
||||
|
||||
if args.is_present("show-trace") {
|
||||
hive.set_show_trace(true);
|
||||
|
|
Loading…
Reference in a new issue