feat(tvix/nix-compat): input_sources as StorePath
https: //b.tvl.fyi/issues/264 Change-Id: I7a235734dc1f8e93e387a04ba369f3b702c6d5b6 Reviewed-on: https://cl.tvl.fyi/c/depot/+/10992 Autosubmit: Peter Kolloch <info@eigenvalue.net> Reviewed-by: flokli <flokli@flokli.de> Reviewed-by: Peter Kolloch <info@eigenvalue.net> Tested-by: BuildkiteCI
This commit is contained in:
parent
c06fb01b3b
commit
035f617b7f
6 changed files with 53 additions and 31 deletions
|
@ -4,7 +4,7 @@ use crate::tvix_store_io::TvixStoreIO;
|
|||
use bstr::BString;
|
||||
use nix_compat::derivation::{Derivation, Output};
|
||||
use nix_compat::nixhash;
|
||||
use nix_compat::store_path::StorePath;
|
||||
use nix_compat::store_path::{StorePath, StorePathRef};
|
||||
use std::collections::{btree_map, BTreeSet};
|
||||
use std::rc::Rc;
|
||||
use tvix_eval::builtin_macros::builtins;
|
||||
|
@ -24,7 +24,10 @@ fn populate_inputs(drv: &mut Derivation, full_context: NixContext) {
|
|||
for element in full_context.iter() {
|
||||
match element {
|
||||
NixContextElement::Plain(source) => {
|
||||
drv.input_sources.insert(source.clone());
|
||||
let sp = StorePathRef::from_absolute_path(source.as_bytes())
|
||||
.expect("invalid store path")
|
||||
.to_owned();
|
||||
drv.input_sources.insert(sp);
|
||||
}
|
||||
|
||||
NixContextElement::Single {
|
||||
|
|
|
@ -40,7 +40,7 @@ pub struct Derivation {
|
|||
|
||||
/// Plain store paths of additional inputs.
|
||||
#[serde(rename = "inputSrcs")]
|
||||
pub input_sources: BTreeSet<String>,
|
||||
pub input_sources: BTreeSet<StorePath>,
|
||||
|
||||
/// Maps output names to Output.
|
||||
pub outputs: BTreeMap<String, Output>,
|
||||
|
@ -131,16 +131,12 @@ impl Derivation {
|
|||
|
||||
// collect the list of paths from input_sources and input_derivations
|
||||
// into a (sorted, guaranteed by BTreeSet) list of references
|
||||
let references: BTreeSet<String> = {
|
||||
let mut inputs = self.input_sources.clone();
|
||||
let input_derivation_keys: Vec<String> = self
|
||||
.input_derivations
|
||||
.keys()
|
||||
.map(|k| k.to_absolute_path())
|
||||
let references: BTreeSet<String> = self
|
||||
.input_sources
|
||||
.iter()
|
||||
.chain(self.input_derivations.keys())
|
||||
.map(StorePath::to_absolute_path)
|
||||
.collect();
|
||||
inputs.extend(input_derivation_keys);
|
||||
inputs
|
||||
};
|
||||
|
||||
build_text_path(name, self.to_aterm_bytes(), references)
|
||||
.map(|s| s.to_owned())
|
||||
|
|
|
@ -2,7 +2,10 @@
|
|||
//! Derivations from ATerm.
|
||||
use nom::IResult;
|
||||
|
||||
use crate::{nixhash, store_path};
|
||||
use crate::{
|
||||
nixhash,
|
||||
store_path::{self, StorePath},
|
||||
};
|
||||
|
||||
pub type NomResult<I, O> = IResult<I, O, NomError<I>>;
|
||||
|
||||
|
@ -17,7 +20,7 @@ pub enum ErrorKind {
|
|||
DuplicateInputDerivationOutputName(String, String),
|
||||
|
||||
#[error("duplicate input source: {0}")]
|
||||
DuplicateInputSource(String),
|
||||
DuplicateInputSource(StorePath),
|
||||
|
||||
#[error("nix hash error: {0}")]
|
||||
NixHashError(nixhash::Error),
|
||||
|
|
|
@ -186,11 +186,19 @@ fn parse_input_derivations(i: &[u8]) -> NomResult<&[u8], BTreeMap<StorePath, BTr
|
|||
Ok((i, input_derivations))
|
||||
}
|
||||
|
||||
fn parse_input_sources(i: &[u8]) -> NomResult<&[u8], BTreeSet<String>> {
|
||||
fn parse_input_sources(i: &[u8]) -> NomResult<&[u8], BTreeSet<StorePath>> {
|
||||
let (i, input_sources_lst) = aterm::parse_str_list(i).map_err(into_nomerror)?;
|
||||
|
||||
let mut input_sources: BTreeSet<_> = BTreeSet::new();
|
||||
for input_source in input_sources_lst.into_iter() {
|
||||
let input_source: StorePath = StorePathRef::from_absolute_path(input_source.as_bytes())
|
||||
.map_err(|e: store_path::Error| {
|
||||
nom::Err::Failure(NomError {
|
||||
input: i,
|
||||
code: e.into(),
|
||||
})
|
||||
})?
|
||||
.to_owned();
|
||||
if input_sources.contains(&input_source) {
|
||||
return Err(nom::Err::Failure(NomError {
|
||||
input: i,
|
||||
|
@ -312,6 +320,7 @@ where
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::store_path::StorePathRef;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
|
||||
use crate::{
|
||||
|
@ -460,7 +469,14 @@ mod tests {
|
|||
fn parse_input_sources(input: &'static [u8], expected: &BTreeSet<String>) {
|
||||
let (rest, parsed) = super::parse_input_sources(input).expect("must parse");
|
||||
|
||||
assert_eq!(expected, &parsed, "parsed mismatch");
|
||||
assert_eq!(
|
||||
expected,
|
||||
&parsed
|
||||
.iter()
|
||||
.map(StorePath::to_absolute_path)
|
||||
.collect::<BTreeSet<_>>(),
|
||||
"parsed mismatch"
|
||||
);
|
||||
assert!(rest.is_empty(), "rest must be empty");
|
||||
}
|
||||
|
||||
|
@ -474,7 +490,11 @@ mod tests {
|
|||
nom::Err::Failure(e) => {
|
||||
assert_eq!(
|
||||
ErrorKind::DuplicateInputSource(
|
||||
"/nix/store/55lwldka5nyxa08wnvlizyqw02ihy8ic-foo".to_string()
|
||||
StorePathRef::from_absolute_path(
|
||||
"/nix/store/55lwldka5nyxa08wnvlizyqw02ihy8ic-foo".as_bytes()
|
||||
)
|
||||
.unwrap()
|
||||
.to_owned()
|
||||
),
|
||||
e.code
|
||||
);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::derivation::{Derivation, DerivationError};
|
||||
use crate::store_path::{self, StorePathRef};
|
||||
use crate::store_path;
|
||||
|
||||
impl Derivation {
|
||||
/// validate ensures a Derivation struct is properly populated,
|
||||
|
@ -87,16 +87,6 @@ impl Derivation {
|
|||
}
|
||||
}
|
||||
|
||||
// Validate all input_sources
|
||||
for input_source in self.input_sources.iter() {
|
||||
if let Err(e) = StorePathRef::from_absolute_path(input_source.as_bytes()) {
|
||||
return Err(DerivationError::InvalidInputSourcesPath(
|
||||
input_source.to_string(),
|
||||
e,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
// validate platform
|
||||
if self.system.is_empty() {
|
||||
return Err(DerivationError::InvalidPlatform(self.system.to_string()));
|
||||
|
|
|
@ -33,6 +33,13 @@ pub const QUOTE: char = '"';
|
|||
/// the context a lot.
|
||||
pub(crate) trait AtermWriteable: Display {
|
||||
fn aterm_write(&self, writer: &mut impl Write) -> std::io::Result<()>;
|
||||
|
||||
fn aterm_bytes(&self) -> Vec<u8> {
|
||||
let mut bytes = Vec::new();
|
||||
self.aterm_write(&mut bytes)
|
||||
.expect("unexpected write errors to Vec");
|
||||
bytes
|
||||
}
|
||||
}
|
||||
|
||||
impl AtermWriteable for StorePathRef<'_> {
|
||||
|
@ -182,12 +189,15 @@ pub(crate) fn write_input_derivations(
|
|||
|
||||
pub(crate) fn write_input_sources(
|
||||
writer: &mut impl Write,
|
||||
input_sources: &BTreeSet<String>,
|
||||
input_sources: &BTreeSet<StorePath>,
|
||||
) -> Result<(), io::Error> {
|
||||
write_char(writer, BRACKET_OPEN)?;
|
||||
write_array_elements(
|
||||
writer,
|
||||
&input_sources.iter().map(String::from).collect::<Vec<_>>(),
|
||||
&input_sources
|
||||
.iter()
|
||||
.map(StorePath::to_absolute_path)
|
||||
.collect::<Vec<_>>(),
|
||||
)?;
|
||||
write_char(writer, BRACKET_CLOSE)?;
|
||||
|
||||
|
|
Loading…
Reference in a new issue