feat(tvix/glue): Implement builtins.storePath
This one's relatively simple - we just check if the store path exists, and if it does we make a new contextful string containing the store path as its only context element. Automatic testing seems tricky for this (I think?) so I tested it manually: tvix-repl> builtins.storePath /nix/store/yn46i4xx5alh7gs6fpkxk430i34rp2q9-hello-2.12.1 => "/nix/store/yn46i4xx5alh7gs6fpkxk430i34rp2q9-hello-2.12.1" :: string Change-Id: I8a0d9726e4102ab872c53c2419679c2c855a5a18 Reviewed-on: https://cl.tvl.fyi/c/depot/+/11696 Tested-by: BuildkiteCI Autosubmit: aspen <root@gws.fyi> Reviewed-by: flokli <flokli@flokli.de>
This commit is contained in:
parent
c3572048d5
commit
72b9a126b8
7 changed files with 62 additions and 2 deletions
|
|
@ -4,7 +4,7 @@ use nix_compat::{
|
|||
store_path::BuildStorePathError,
|
||||
};
|
||||
use reqwest::Url;
|
||||
use std::rc::Rc;
|
||||
use std::{path::PathBuf, rc::Rc};
|
||||
use thiserror::Error;
|
||||
use tvix_castore::import;
|
||||
|
||||
|
|
@ -65,8 +65,12 @@ pub enum FetcherError {
|
|||
pub enum ImportError {
|
||||
#[error("non-file '{0}' cannot be imported in 'flat' mode")]
|
||||
FlatImportOfNonFile(String),
|
||||
|
||||
#[error("hash mismatch at ingestion of '{0}', expected: '{1}', got: '{2}'")]
|
||||
HashMismatch(String, NixHash, NixHash),
|
||||
|
||||
#[error("path '{}' is not in the Nix store", .0.display())]
|
||||
PathNotInStore(PathBuf),
|
||||
}
|
||||
|
||||
impl From<ImportError> for tvix_eval::ErrorKind {
|
||||
|
|
|
|||
|
|
@ -104,11 +104,13 @@ async fn filtered_ingest(
|
|||
|
||||
#[builtins(state = "Rc<TvixStoreIO>")]
|
||||
mod import_builtins {
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
use std::rc::Rc;
|
||||
|
||||
use super::*;
|
||||
|
||||
use nix_compat::nixhash::{CAHash, NixHash};
|
||||
use nix_compat::store_path::StorePath;
|
||||
use tvix_eval::generators::Gen;
|
||||
use tvix_eval::{generators::GenCo, ErrorKind, Value};
|
||||
use tvix_eval::{NixContextElement, NixString};
|
||||
|
|
@ -280,6 +282,44 @@ mod import_builtins {
|
|||
.into(),
|
||||
)
|
||||
}
|
||||
|
||||
#[builtin("storePath")]
|
||||
async fn builtin_store_path(
|
||||
state: Rc<TvixStoreIO>,
|
||||
co: GenCo,
|
||||
path: Value,
|
||||
) -> Result<Value, ErrorKind> {
|
||||
let p = std::str::from_utf8(match &path {
|
||||
Value::String(s) => s.as_bytes(),
|
||||
Value::Path(p) => p.as_os_str().as_bytes(),
|
||||
_ => {
|
||||
return Err(ErrorKind::TypeError {
|
||||
expected: "string or path",
|
||||
actual: path.type_of(),
|
||||
})
|
||||
}
|
||||
})?;
|
||||
|
||||
let path_exists = if let Ok((store_path, sub_path)) = StorePath::from_absolute_path_full(p)
|
||||
{
|
||||
if !sub_path.as_os_str().is_empty() {
|
||||
false
|
||||
} else {
|
||||
state.store_path_exists(store_path.as_ref()).await?
|
||||
}
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
if !path_exists {
|
||||
return Err(ImportError::PathNotInStore(p.into()).into());
|
||||
}
|
||||
|
||||
Ok(Value::String(NixString::new_context_from(
|
||||
[NixContextElement::Plain(p.into())].into(),
|
||||
p,
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
pub use import_builtins::builtins as import_builtins;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue