fix: derivation (WIP)
This commit is contained in:
@@ -127,12 +127,7 @@ const structuredAttrsExcludedKeys = new Set([
|
||||
]);
|
||||
|
||||
const specialAttrs = new Set([
|
||||
"name",
|
||||
"builder",
|
||||
"system",
|
||||
"args",
|
||||
"outputs",
|
||||
"__structuredAttrs",
|
||||
"__ignoreNulls",
|
||||
"__contentAddressed",
|
||||
"__impure",
|
||||
@@ -300,14 +295,6 @@ export const derivationStrict = (args: NixValue): NixAttrs => {
|
||||
const drvArgs = extractArgs(attrs, collectedContext);
|
||||
const env = extractEnv(attrs, structuredAttrs, ignoreNulls, collectedContext, drvName);
|
||||
|
||||
if (!structuredAttrs) {
|
||||
env.set("name", drvName);
|
||||
env.set("builder", builder);
|
||||
env.set("system", platform);
|
||||
if (outputs.length > 1 || outputs[0] !== "out") {
|
||||
env.set("outputs", outputs.join(" "));
|
||||
}
|
||||
}
|
||||
|
||||
const { inputDrvs, inputSrcs } = extractInputDrvsAndSrcs(collectedContext);
|
||||
|
||||
|
||||
@@ -193,7 +193,7 @@ export const builtins: any = {
|
||||
warn: mkPrimop(functional.warn, "warn", 2),
|
||||
break: mkPrimop(functional.breakFunc, "break", 1),
|
||||
|
||||
derivation: mkPrimop(derivation.derivation, "derivation", 1),
|
||||
derivation: undefined as any,
|
||||
derivationStrict: mkPrimop(derivation.derivationStrict, "derivationStrict", 1),
|
||||
|
||||
import: mkPrimop(io.importFunc, "import", 1),
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import type { NixValue, NixThunkInterface, NixStrictValue } from "./types";
|
||||
import { HAS_CONTEXT } from "./string-context";
|
||||
import { IS_PATH } from "./types";
|
||||
import { isAttrs } from "./builtins/type-check";
|
||||
import { isAttrs, isList } from "./builtins/type-check";
|
||||
|
||||
/**
|
||||
* Symbol used to mark objects as thunks
|
||||
@@ -165,7 +165,9 @@ export const forceDeep = (value: NixValue, seen: WeakSet<object> = new WeakSet()
|
||||
}
|
||||
return CYCLE_MARKER;
|
||||
}
|
||||
seen.add(forced);
|
||||
if (isAttrs(forced) || isList(forced)) {
|
||||
seen.add(forced);
|
||||
}
|
||||
|
||||
if (HAS_CONTEXT in forced || IS_PATH in forced) {
|
||||
return forced;
|
||||
|
||||
@@ -41,7 +41,22 @@ impl Context {
|
||||
let ctx = Ctx::new()?;
|
||||
let runtime = Runtime::new()?;
|
||||
|
||||
Ok(Self { ctx, runtime })
|
||||
let mut context = Self { ctx, runtime };
|
||||
context.init_derivation()?;
|
||||
|
||||
Ok(context)
|
||||
}
|
||||
|
||||
fn init_derivation(&mut self) -> Result<()> {
|
||||
const DERIVATION_NIX: &str = include_str!("runtime/corepkgs/derivation.nix");
|
||||
let source = Source::new_virtual(
|
||||
"<nix/derivation-internal.nix>".into(),
|
||||
DERIVATION_NIX.to_string(),
|
||||
);
|
||||
let code = self.ctx.compile(source, None)?;
|
||||
self.runtime
|
||||
.eval(format!("Nix.builtins.derivation = {}", code), &mut self.ctx)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
eval!(eval, "Nix.force({})");
|
||||
|
||||
@@ -21,6 +21,8 @@ pub enum SourceType {
|
||||
Repl(Arc<PathBuf>),
|
||||
/// file
|
||||
File(Arc<PathBuf>),
|
||||
/// virtual (name, no path)
|
||||
Virtual(Arc<str>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@@ -71,6 +73,13 @@ impl Source {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn new_virtual(name: Arc<str>, src: String) -> Self {
|
||||
Self {
|
||||
ty: SourceType::Virtual(name),
|
||||
src: src.into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_dir(&self) -> &Path {
|
||||
use SourceType::*;
|
||||
match &self.ty {
|
||||
@@ -79,6 +88,7 @@ impl Source {
|
||||
.as_path()
|
||||
.parent()
|
||||
.expect("source file must have a parent dir"),
|
||||
Virtual(_) => Path::new("/"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,6 +97,7 @@ impl Source {
|
||||
SourceType::Eval(_) => "«eval»".into(),
|
||||
SourceType::Repl(_) => "«repl»".into(),
|
||||
SourceType::File(path) => path.as_os_str().to_string_lossy().to_string(),
|
||||
SourceType::Virtual(name) => name.to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,14 +264,15 @@ pub fn op_fetch_tarball<Ctx: RuntimeContext>(
|
||||
);
|
||||
|
||||
if let Some(ref expected) = expected_sha256
|
||||
&& nar_hash != *expected {
|
||||
return Err(NixRuntimeError::from(format!(
|
||||
"NAR hash mismatch for '{}': expected {}, got {}",
|
||||
url,
|
||||
expected_hex.expect("must be Some"),
|
||||
nar_hash_hex
|
||||
)));
|
||||
}
|
||||
&& nar_hash != *expected
|
||||
{
|
||||
return Err(NixRuntimeError::from(format!(
|
||||
"NAR hash mismatch for '{}': expected {}, got {}",
|
||||
url,
|
||||
expected_hex.expect("must be Some"),
|
||||
nar_hash_hex
|
||||
)));
|
||||
}
|
||||
|
||||
info!("Adding to store");
|
||||
let ctx: &Ctx = state.get_ctx();
|
||||
|
||||
@@ -31,8 +31,10 @@ pub fn fetch_git(
|
||||
let temp_dir = tempfile::tempdir()?;
|
||||
let checkout_dir = checkout_rev_to_temp(&bare_repo, &target_rev, submodules, temp_dir.path())?;
|
||||
|
||||
let nar_hash = hex::encode(crate::nar::compute_nar_hash(&checkout_dir)
|
||||
.map_err(|e| GitError::NarHashError(e.to_string()))?);
|
||||
let nar_hash = hex::encode(
|
||||
crate::nar::compute_nar_hash(&checkout_dir)
|
||||
.map_err(|e| GitError::NarHashError(e.to_string()))?,
|
||||
);
|
||||
|
||||
let store_path = store
|
||||
.add_to_store_from_path(name, &checkout_dir, vec![])
|
||||
|
||||
@@ -10,9 +10,9 @@ mod downgrade;
|
||||
mod fetcher;
|
||||
mod ir;
|
||||
mod nar;
|
||||
mod nix_utils;
|
||||
mod runtime;
|
||||
mod store;
|
||||
mod nix_utils;
|
||||
|
||||
#[global_allocator]
|
||||
static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
|
||||
|
||||
31
nix-js/src/runtime/corepkgs/derivation.nix
Normal file
31
nix-js/src/runtime/corepkgs/derivation.nix
Normal file
@@ -0,0 +1,31 @@
|
||||
drvAttrs@{
|
||||
outputs ? [ "out" ],
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
|
||||
strict = derivationStrict drvAttrs;
|
||||
|
||||
commonAttrs =
|
||||
drvAttrs
|
||||
// (builtins.listToAttrs outputsList)
|
||||
// {
|
||||
all = map (x: x.value) outputsList;
|
||||
inherit drvAttrs;
|
||||
};
|
||||
|
||||
outputToAttrListElement = outputName: {
|
||||
name = outputName;
|
||||
value = commonAttrs // {
|
||||
outPath = builtins.getAttr outputName strict;
|
||||
drvPath = strict.drvPath;
|
||||
type = "derivation";
|
||||
inherit outputName;
|
||||
};
|
||||
};
|
||||
|
||||
outputsList = map outputToAttrListElement outputs;
|
||||
|
||||
in
|
||||
(builtins.head outputsList).value
|
||||
@@ -1,6 +1,5 @@
|
||||
use std::path::{Component, Path, PathBuf};
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
|
||||
use hashbrown::hash_map::{Entry, HashMap};
|
||||
|
||||
@@ -53,12 +52,12 @@ pub(super) fn op_import<Ctx: RuntimeContext>(
|
||||
let corepkg_name = &path[5..path.len() - 1];
|
||||
if let Some(file) = CorePkgs::get(corepkg_name) {
|
||||
tracing::info!("Importing corepkg: {}", corepkg_name);
|
||||
let source = Source {
|
||||
ty: crate::error::SourceType::Eval(Arc::new(ctx.get_current_dir().to_path_buf())),
|
||||
src: str::from_utf8(&file.data)
|
||||
let source = Source::new_virtual(
|
||||
path.into(),
|
||||
str::from_utf8(&file.data)
|
||||
.expect("corrupted corepkgs file")
|
||||
.into(),
|
||||
};
|
||||
);
|
||||
ctx.add_source(source.clone());
|
||||
return Ok(ctx.compile(source).map_err(|err| err.to_string())?);
|
||||
} else {
|
||||
@@ -445,9 +444,8 @@ pub(super) fn op_add_path<Ctx: RuntimeContext>(
|
||||
};
|
||||
|
||||
if let Some(ref expected_hash) = sha256 {
|
||||
let expected_hex =
|
||||
NixHash::from_str(expected_hash, Some(HashAlgo::Sha256))
|
||||
.map_err(|err| err.to_string())?;
|
||||
let expected_hex = NixHash::from_str(expected_hash, Some(HashAlgo::Sha256))
|
||||
.map_err(|err| err.to_string())?;
|
||||
if computed_hash != expected_hex.digest_as_bytes() {
|
||||
return Err(NixRuntimeError::from(format!(
|
||||
"hash mismatch for path '{}': expected {}, got {}",
|
||||
@@ -960,9 +958,8 @@ pub(super) fn op_add_filtered_path<Ctx: RuntimeContext>(
|
||||
};
|
||||
|
||||
if let Some(ref expected_hash) = sha256 {
|
||||
let expected_hex =
|
||||
NixHash::from_str(expected_hash, Some(HashAlgo::Sha256))
|
||||
.map_err(|err| err.to_string())?;
|
||||
let expected_hex = NixHash::from_str(expected_hash, Some(HashAlgo::Sha256))
|
||||
.map_err(|err| err.to_string())?;
|
||||
if computed_hash != expected_hex.digest_as_bytes() {
|
||||
return Err(NixRuntimeError::from(format!(
|
||||
"hash mismatch for path '{}': expected {}, got {}",
|
||||
|
||||
@@ -11,9 +11,7 @@ impl StoreConfig {
|
||||
.map(PathBuf::from)
|
||||
.unwrap_or_else(|_| PathBuf::from("/nix/var/nix/daemon-socket/socket"));
|
||||
|
||||
Self {
|
||||
daemon_socket,
|
||||
}
|
||||
Self { daemon_socket }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,13 +8,13 @@ use nix_compat::wire::ProtocolVersion;
|
||||
use nix_compat::wire::de::{NixRead, NixReader};
|
||||
use nix_compat::wire::ser::{NixSerialize, NixWrite, NixWriter, NixWriterBuilder};
|
||||
use num_enum::{IntoPrimitive, TryFromPrimitive};
|
||||
use thiserror::Error;
|
||||
use tokio::io::{AsyncReadExt, AsyncWriteExt, ReadHalf, WriteHalf, split};
|
||||
use tokio::net::UnixStream;
|
||||
use tokio::sync::Mutex;
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::error::{Error, Result};
|
||||
use super::Store;
|
||||
use crate::error::{Error, Result};
|
||||
|
||||
pub struct DaemonStore {
|
||||
runtime: tokio::runtime::Runtime,
|
||||
@@ -569,11 +569,7 @@ impl NixDaemonClient {
|
||||
traces.push(trace_hint);
|
||||
}
|
||||
|
||||
Ok(NixDaemonError {
|
||||
level,
|
||||
msg,
|
||||
traces,
|
||||
})
|
||||
Ok(NixDaemonError { level, msg, traces })
|
||||
}
|
||||
|
||||
/// Check if a path is valid in the store
|
||||
|
||||
Reference in New Issue
Block a user