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 bstr::BString;
|
||||||
use nix_compat::derivation::{Derivation, Output};
|
use nix_compat::derivation::{Derivation, Output};
|
||||||
use nix_compat::nixhash;
|
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::collections::{btree_map, BTreeSet};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use tvix_eval::builtin_macros::builtins;
|
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() {
|
for element in full_context.iter() {
|
||||||
match element {
|
match element {
|
||||||
NixContextElement::Plain(source) => {
|
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 {
|
NixContextElement::Single {
|
||||||
|
|
|
@ -40,7 +40,7 @@ pub struct Derivation {
|
||||||
|
|
||||||
/// Plain store paths of additional inputs.
|
/// Plain store paths of additional inputs.
|
||||||
#[serde(rename = "inputSrcs")]
|
#[serde(rename = "inputSrcs")]
|
||||||
pub input_sources: BTreeSet<String>,
|
pub input_sources: BTreeSet<StorePath>,
|
||||||
|
|
||||||
/// Maps output names to Output.
|
/// Maps output names to Output.
|
||||||
pub outputs: BTreeMap<String, Output>,
|
pub outputs: BTreeMap<String, Output>,
|
||||||
|
@ -131,16 +131,12 @@ impl Derivation {
|
||||||
|
|
||||||
// collect the list of paths from input_sources and input_derivations
|
// collect the list of paths from input_sources and input_derivations
|
||||||
// into a (sorted, guaranteed by BTreeSet) list of references
|
// into a (sorted, guaranteed by BTreeSet) list of references
|
||||||
let references: BTreeSet<String> = {
|
let references: BTreeSet<String> = self
|
||||||
let mut inputs = self.input_sources.clone();
|
.input_sources
|
||||||
let input_derivation_keys: Vec<String> = self
|
.iter()
|
||||||
.input_derivations
|
.chain(self.input_derivations.keys())
|
||||||
.keys()
|
.map(StorePath::to_absolute_path)
|
||||||
.map(|k| k.to_absolute_path())
|
|
||||||
.collect();
|
.collect();
|
||||||
inputs.extend(input_derivation_keys);
|
|
||||||
inputs
|
|
||||||
};
|
|
||||||
|
|
||||||
build_text_path(name, self.to_aterm_bytes(), references)
|
build_text_path(name, self.to_aterm_bytes(), references)
|
||||||
.map(|s| s.to_owned())
|
.map(|s| s.to_owned())
|
||||||
|
|
|
@ -2,7 +2,10 @@
|
||||||
//! Derivations from ATerm.
|
//! Derivations from ATerm.
|
||||||
use nom::IResult;
|
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>>;
|
pub type NomResult<I, O> = IResult<I, O, NomError<I>>;
|
||||||
|
|
||||||
|
@ -17,7 +20,7 @@ pub enum ErrorKind {
|
||||||
DuplicateInputDerivationOutputName(String, String),
|
DuplicateInputDerivationOutputName(String, String),
|
||||||
|
|
||||||
#[error("duplicate input source: {0}")]
|
#[error("duplicate input source: {0}")]
|
||||||
DuplicateInputSource(String),
|
DuplicateInputSource(StorePath),
|
||||||
|
|
||||||
#[error("nix hash error: {0}")]
|
#[error("nix hash error: {0}")]
|
||||||
NixHashError(nixhash::Error),
|
NixHashError(nixhash::Error),
|
||||||
|
|
|
@ -186,11 +186,19 @@ fn parse_input_derivations(i: &[u8]) -> NomResult<&[u8], BTreeMap<StorePath, BTr
|
||||||
Ok((i, input_derivations))
|
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 (i, input_sources_lst) = aterm::parse_str_list(i).map_err(into_nomerror)?;
|
||||||
|
|
||||||
let mut input_sources: BTreeSet<_> = BTreeSet::new();
|
let mut input_sources: BTreeSet<_> = BTreeSet::new();
|
||||||
for input_source in input_sources_lst.into_iter() {
|
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) {
|
if input_sources.contains(&input_source) {
|
||||||
return Err(nom::Err::Failure(NomError {
|
return Err(nom::Err::Failure(NomError {
|
||||||
input: i,
|
input: i,
|
||||||
|
@ -312,6 +320,7 @@ where
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use crate::store_path::StorePathRef;
|
||||||
use std::collections::{BTreeMap, BTreeSet};
|
use std::collections::{BTreeMap, BTreeSet};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -460,7 +469,14 @@ mod tests {
|
||||||
fn parse_input_sources(input: &'static [u8], expected: &BTreeSet<String>) {
|
fn parse_input_sources(input: &'static [u8], expected: &BTreeSet<String>) {
|
||||||
let (rest, parsed) = super::parse_input_sources(input).expect("must parse");
|
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");
|
assert!(rest.is_empty(), "rest must be empty");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -474,7 +490,11 @@ mod tests {
|
||||||
nom::Err::Failure(e) => {
|
nom::Err::Failure(e) => {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
ErrorKind::DuplicateInputSource(
|
ErrorKind::DuplicateInputSource(
|
||||||
"/nix/store/55lwldka5nyxa08wnvlizyqw02ihy8ic-foo".to_string()
|
StorePathRef::from_absolute_path(
|
||||||
|
"/nix/store/55lwldka5nyxa08wnvlizyqw02ihy8ic-foo".as_bytes()
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
.to_owned()
|
||||||
),
|
),
|
||||||
e.code
|
e.code
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::derivation::{Derivation, DerivationError};
|
use crate::derivation::{Derivation, DerivationError};
|
||||||
use crate::store_path::{self, StorePathRef};
|
use crate::store_path;
|
||||||
|
|
||||||
impl Derivation {
|
impl Derivation {
|
||||||
/// validate ensures a Derivation struct is properly populated,
|
/// 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
|
// validate platform
|
||||||
if self.system.is_empty() {
|
if self.system.is_empty() {
|
||||||
return Err(DerivationError::InvalidPlatform(self.system.to_string()));
|
return Err(DerivationError::InvalidPlatform(self.system.to_string()));
|
||||||
|
|
|
@ -33,6 +33,13 @@ pub const QUOTE: char = '"';
|
||||||
/// the context a lot.
|
/// the context a lot.
|
||||||
pub(crate) trait AtermWriteable: Display {
|
pub(crate) trait AtermWriteable: Display {
|
||||||
fn aterm_write(&self, writer: &mut impl Write) -> std::io::Result<()>;
|
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<'_> {
|
impl AtermWriteable for StorePathRef<'_> {
|
||||||
|
@ -182,12 +189,15 @@ pub(crate) fn write_input_derivations(
|
||||||
|
|
||||||
pub(crate) fn write_input_sources(
|
pub(crate) fn write_input_sources(
|
||||||
writer: &mut impl Write,
|
writer: &mut impl Write,
|
||||||
input_sources: &BTreeSet<String>,
|
input_sources: &BTreeSet<StorePath>,
|
||||||
) -> Result<(), io::Error> {
|
) -> Result<(), io::Error> {
|
||||||
write_char(writer, BRACKET_OPEN)?;
|
write_char(writer, BRACKET_OPEN)?;
|
||||||
write_array_elements(
|
write_array_elements(
|
||||||
writer,
|
writer,
|
||||||
&input_sources.iter().map(String::from).collect::<Vec<_>>(),
|
&input_sources
|
||||||
|
.iter()
|
||||||
|
.map(StorePath::to_absolute_path)
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
)?;
|
)?;
|
||||||
write_char(writer, BRACKET_CLOSE)?;
|
write_char(writer, BRACKET_CLOSE)?;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue