Don't panic during export (#501)

This commit is contained in:
Naïm Camille Favier 2022-07-21 12:20:52 +02:00 committed by GitHub
parent 79f6678b23
commit 18e5da679b
Failed to generate hash of commit
4 changed files with 80 additions and 53 deletions

View file

@ -228,10 +228,7 @@ async fn run_command(
gc, gc,
} => { } => {
let source = Source::Git { url: flake }; let source = Source::Git { url: flake };
let exports = flake_info::process_flake(&source, &kind, temp_store, extra) let (info, exports) = flake_info::process_flake(&source, &kind, temp_store, extra)
.map_err(FlakeInfoError::Flake)?;
let info = flake_info::get_flake_info(source.to_flake_ref(), temp_store, extra)
.map_err(FlakeInfoError::Flake)?; .map_err(FlakeInfoError::Flake)?;
let ident = ( let ident = (
@ -288,19 +285,21 @@ async fn run_command(
.iter() .iter()
.map(|source| match source { .map(|source| match source {
Source::Nixpkgs(nixpkgs) => flake_info::process_nixpkgs(source, &kind) Source::Nixpkgs(nixpkgs) => flake_info::process_nixpkgs(source, &kind)
.with_context(|| {
format!("While processing nixpkgs archive {}", source.to_flake_ref())
})
.map(|result| (result, nixpkgs.git_ref.to_owned())), .map(|result| (result, nixpkgs.git_ref.to_owned())),
_ => flake_info::process_flake(source, &kind, temp_store, &extra).and_then( _ => flake_info::process_flake(source, &kind, temp_store, &extra)
|result| { .with_context(|| {
flake_info::get_flake_info(source.to_flake_ref(), temp_store, extra) format!("While processing flake {}", source.to_flake_ref())
.map(|info| (result, info.revision.unwrap_or("latest".into()))) })
}, .map(|(info, result)| (result, info.revision.unwrap_or("latest".into()))),
),
}) })
.partition::<Vec<_>, _>(Result::is_ok); .partition::<Vec<_>, _>(Result::is_ok);
let (exports, hashes) = exports_and_hashes let (exports, hashes) = exports_and_hashes
.into_iter() .into_iter()
.map(|result| result.unwrap()) .map(|result| result.unwrap()) // each result is_ok
.fold( .fold(
(Vec::new(), Vec::new()), (Vec::new(), Vec::new()),
|(mut exports, mut hashes), (export, hash)| { |(mut exports, mut hashes), (export, hash)| {
@ -312,7 +311,7 @@ async fn run_command(
let errors = errors let errors = errors
.into_iter() .into_iter()
.map(Result::unwrap_err) .map(Result::unwrap_err) // each result is_err
.collect::<Vec<_>>(); .collect::<Vec<_>>();
if !errors.is_empty() { if !errors.is_empty() {
@ -425,12 +424,23 @@ struct NixosChannels {
#[derive(Clone, Debug, Deserialize)] #[derive(Clone, Debug, Deserialize)]
struct Channel { struct Channel {
branch: String branch: String,
} }
impl NixosChannels { impl NixosChannels {
fn check_channel(&self, channel: &String) -> Result<(), FlakeInfoError> { fn check_channel(&self, channel: &String) -> Result<(), FlakeInfoError> {
self.channels.iter().find(|c| &c.branch == channel).map_or_else(|| Ok(()), |_| Err(FlakeInfoError::UnknownNixOSChannel(channel.clone(), self.clone()))) self.channels
.iter()
.find(|c| &c.branch == channel)
.map_or_else(
|| Ok(()),
|_| {
Err(FlakeInfoError::UnknownNixOSChannel(
channel.clone(),
self.clone(),
))
},
)
} }
} }
@ -445,5 +455,6 @@ impl FromStr for NixosChannels {
lazy_static! { lazy_static! {
static ref NIXOS_CHANNELS: NixosChannels = std::env::var("NIXOS_CHANNELS") static ref NIXOS_CHANNELS: NixosChannels = std::env::var("NIXOS_CHANNELS")
.unwrap_or("".to_string()) .unwrap_or("".to_string())
.parse().unwrap(); .parse()
.unwrap();
} }

View file

@ -1,10 +1,17 @@
/// This module defines the unified putput format as expected by the elastic search /// This module defines the unified putput format as expected by the elastic search
/// Additionally, we implement converseions from the two possible input formats, i.e. /// Additionally, we implement converseions from the two possible input formats, i.e.
/// Flakes, or Nixpkgs. /// Flakes, or Nixpkgs.
use std::{convert::TryInto, path::PathBuf}; use std::{
convert::{TryFrom, TryInto},
path::PathBuf,
};
use super::{import::{DocValue, ModulePath}, pandoc::PandocExt}; use super::{
import::{DocValue, ModulePath},
pandoc::PandocExt,
};
use crate::data::import::NixOption; use crate::data::import::NixOption;
use anyhow::Context;
use log::error; use log::error;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json::Value; use serde_json::Value;
@ -117,9 +124,11 @@ pub enum Derivation {
// ----- Conversions // ----- Conversions
impl From<(import::FlakeEntry, super::Flake)> for Derivation { impl TryFrom<(import::FlakeEntry, super::Flake)> for Derivation {
fn from((d, f): (import::FlakeEntry, super::Flake)) -> Self { type Error = anyhow::Error;
match d {
fn try_from((d, f): (import::FlakeEntry, super::Flake)) -> Result<Self, Self::Error> {
Ok(match d {
import::FlakeEntry::Package { import::FlakeEntry::Package {
attribute_name, attribute_name,
name, name,
@ -187,14 +196,16 @@ impl From<(import::FlakeEntry, super::Flake)> for Derivation {
app_bin: bin, app_bin: bin,
app_type, app_type,
}, },
import::FlakeEntry::Option(option) => option.into(), import::FlakeEntry::Option(option) => option.try_into()?,
} })
} }
} }
impl From<import::NixpkgsEntry> for Derivation { impl TryFrom<import::NixpkgsEntry> for Derivation {
fn from(entry: import::NixpkgsEntry) -> Self { type Error = anyhow::Error;
match entry {
fn try_from(entry: import::NixpkgsEntry) -> Result<Self, Self::Error> {
Ok(match entry {
import::NixpkgsEntry::Derivation { attribute, package } => { import::NixpkgsEntry::Derivation { attribute, package } => {
let package_attr_set: Vec<_> = attribute.split(".").collect(); let package_attr_set: Vec<_> = attribute.split(".").collect();
let package_attr_set: String = (if package_attr_set.len() > 1 { let package_attr_set: String = (if package_attr_set.len() > 1 {
@ -230,8 +241,7 @@ impl From<import::NixpkgsEntry> for Derivation {
let package_maintainers_set = package_maintainers let package_maintainers_set = package_maintainers
.iter() .iter()
.filter(|m| m.name.is_some()) .flat_map(|m| m.name.to_owned())
.map(|m| m.name.to_owned().unwrap())
.collect(); .collect();
let position: Option<String> = package.meta.position.map(|p| { let position: Option<String> = package.meta.position.map(|p| {
@ -276,13 +286,15 @@ impl From<import::NixpkgsEntry> for Derivation {
package_position: position, package_position: position,
} }
} }
import::NixpkgsEntry::Option(option) => option.into(), import::NixpkgsEntry::Option(option) => option.try_into()?,
} })
} }
} }
impl From<import::NixOption> for Derivation { impl TryFrom<import::NixOption> for Derivation {
fn from( type Error = anyhow::Error;
fn try_from(
NixOption { NixOption {
declarations, declarations,
description, description,
@ -292,26 +304,26 @@ impl From<import::NixOption> for Derivation {
example, example,
flake, flake,
}: import::NixOption, }: import::NixOption,
) -> Self { ) -> Result<Self, Self::Error> {
let description = description let description = description
.as_ref() .as_ref()
.map(PandocExt::render) .map(PandocExt::render)
.transpose() .transpose()
.expect(&format!("Could not render descript of `{}`", name)); .with_context(|| format!("While rendering the description for option `{}`", name))?;
let option_default = default; let option_default = default;
// .map(TryInto::try_into) // .map(TryInto::try_into)
// .transpose() // .transpose()
// .expect(&format!("Could not render option_default of `{}`", name)); // .with_context(|| format!("While rendering the default for option `{}`", name))?;
let option_example = example; let option_example = example;
// .map(TryInto::try_into) // .map(TryInto::try_into)
// .transpose() // .transpose()
// .expect(&format!("Could not render option_example of `{}`", name)); // .with_context(|| format!("While rendering the example for option `{}`", name))?;
let option_type = option_type; let option_type = option_type;
// .map(TryInto::try_into) // .map(TryInto::try_into)
// .transpose() // .transpose()
// .expect(&format!("Could not render option_type of `{}`", name)); // .with_context(|| format!("While rendering the type for option `{}`", name))?;
Derivation::Option { Ok(Derivation::Option {
option_source: declarations.get(0).map(Clone::clone), option_source: declarations.get(0).map(Clone::clone),
option_name: name.clone(), option_name: name.clone(),
option_name_reverse: Reverse(name.clone()), option_name_reverse: Reverse(name.clone()),
@ -323,7 +335,7 @@ impl From<import::NixOption> for Derivation {
option_type, option_type,
option_name_query: AttributeQuery::new(&name), option_name_query: AttributeQuery::new(&name),
option_name_query_reverse: Reverse(AttributeQuery::new(&name)), option_name_query_reverse: Reverse(AttributeQuery::new(&name)),
} })
} }
} }
@ -387,19 +399,19 @@ pub struct Export {
impl Export { impl Export {
/// Construct Export from Flake and Flake entry /// Construct Export from Flake and Flake entry
pub fn flake(flake: Flake, item: import::FlakeEntry) -> Self { pub fn flake(flake: Flake, item: import::FlakeEntry) -> anyhow::Result<Self> {
Self { Ok(Self {
flake: Some(flake.clone()), flake: Some(flake.clone()),
item: Derivation::from((item, flake)), item: Derivation::try_from((item, flake))?,
} })
} }
/// Construct Export from NixpkgsEntry /// Construct Export from NixpkgsEntry
pub fn nixpkgs(item: import::NixpkgsEntry) -> Self { pub fn nixpkgs(item: import::NixpkgsEntry) -> anyhow::Result<Self> {
Self { Ok(Self {
flake: None, flake: None,
item: Derivation::from(item), item: Derivation::try_from(item)?,
} })
} }
} }
@ -423,7 +435,7 @@ mod tests {
"visible":true "visible":true
}"#).unwrap(); }"#).unwrap();
let option: Derivation = option.into(); let option: Derivation = option.try_into().unwrap();
println!("{}", serde_json::to_string_pretty(&option).unwrap()); println!("{}", serde_json::to_string_pretty(&option).unwrap());
} }

View file

@ -499,6 +499,7 @@ mod tests {
let exports = sources let exports = sources
.iter() .iter()
.flat_map(|s| process_flake(s, &Kind::All, false, &[])) .flat_map(|s| process_flake(s, &Kind::All, false, &[]))
.map(|(info, exports)| exports)
.flatten() .flatten()
.collect::<Vec<Export>>(); .collect::<Vec<Export>>();
println!("{}", serde_json::to_string(&exports[1]).unwrap()); println!("{}", serde_json::to_string(&exports[1]).unwrap());

View file

@ -3,7 +3,7 @@
use std::path::PathBuf; use std::path::PathBuf;
use anyhow::Result; use anyhow::Result;
use data::{import::Kind, Export, Source}; use data::{import::Kind, Export, Flake, Source};
pub mod commands; pub mod commands;
pub mod data; pub mod data;
@ -17,7 +17,7 @@ pub fn process_flake(
kind: &data::import::Kind, kind: &data::import::Kind,
temp_store: bool, temp_store: bool,
extra: &[String], extra: &[String],
) -> Result<Vec<Export>> { ) -> Result<(Flake, Vec<Export>)> {
let mut info = commands::get_flake_info(source.to_flake_ref(), temp_store, extra)?; let mut info = commands::get_flake_info(source.to_flake_ref(), temp_store, extra)?;
info.source = Some(source.clone()); info.source = Some(source.clone());
let packages = commands::get_derivation_info(source.to_flake_ref(), *kind, temp_store, extra)?; let packages = commands::get_derivation_info(source.to_flake_ref(), *kind, temp_store, extra)?;
@ -27,9 +27,9 @@ pub fn process_flake(
let exports: Vec<Export> = packages let exports: Vec<Export> = packages
.into_iter() .into_iter()
.map(|p| Export::flake(info.clone(), p)) .map(|p| Export::flake(info.clone(), p))
.collect(); .collect::<Result<Vec<Export>>>()?;
Ok(exports) Ok((info, exports))
} }
pub fn process_nixpkgs(nixpkgs: &Source, kind: &Kind) -> Result<Vec<Export>, anyhow::Error> { pub fn process_nixpkgs(nixpkgs: &Source, kind: &Kind) -> Result<Vec<Export>, anyhow::Error> {
@ -48,6 +48,9 @@ pub fn process_nixpkgs(nixpkgs: &Source, kind: &Kind) -> Result<Vec<Export>, any
let mut all = drvs; let mut all = drvs;
all.append(&mut options); all.append(&mut options);
let exports = all.into_iter().map(Export::nixpkgs).collect(); let exports = all
.into_iter()
.map(Export::nixpkgs)
.collect::<Result<Vec<Export>>>()?;
Ok(exports) Ok(exports)
} }