#![warn(missing_docs)]
pub mod addon;
pub mod declarative;
pub mod metadata;
pub mod properties;
pub mod repo;
pub mod resolve;
pub mod script_eval;
use std::{collections::HashMap, sync::Arc};
use anyhow::Context;
use async_trait::async_trait;
use declarative::{deserialize_declarative_package, validate_declarative_package};
use metadata::PackageMetadata;
use nitro_shared::pkg::{ArcPkgReq, PackageID};
use properties::PackageProperties;
#[cfg(feature = "schema")]
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
pub use nitro_parse as parse;
pub use nitro_shared::pkg::{PkgRequest, PkgRequestSource};
pub fn parse_and_validate(contents: &str, content_type: PackageContentType) -> anyhow::Result<()> {
match content_type {
PackageContentType::Script => {
let parsed = parse::parse::lex_and_parse(contents).context("Parsing failed")?;
metadata::eval_metadata(&parsed).context("Metadata evaluation failed")?;
properties::eval_properties(&parsed).context("Properties evaluation failed")?;
}
PackageContentType::Declarative => {
let contents = deserialize_declarative_package(contents).context("Parsing failed")?;
validate_declarative_package(&contents).context("Package was invalid")?;
}
}
Ok(())
}
#[derive(Deserialize, Serialize, Debug, Copy, Clone, Default, PartialEq, Eq)]
#[cfg_attr(feature = "schema", derive(JsonSchema))]
#[serde(rename_all = "snake_case")]
pub enum PackageContentType {
#[default]
Script,
Declarative,
}
#[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Serialize, Deserialize)]
pub struct RequiredPackage {
pub value: PackageID,
pub explicit: bool,
}
#[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(JsonSchema))]
pub struct RecommendedPackage {
pub value: PackageID,
#[serde(default)]
#[serde(skip_serializing_if = "is_false")]
pub invert: bool,
}
fn is_false(x: &bool) -> bool {
!x
}
#[async_trait]
pub trait PackageEvaluator<'a> {
type CommonInput;
type EvalInput: EvalInput + Clone;
type ConfiguredPackage: ConfiguredPackage<EvalInput = Self::EvalInput>;
async fn eval_package_relations(
&mut self,
pkg: &ArcPkgReq,
input: &Self::EvalInput,
common_input: &Self::CommonInput,
) -> anyhow::Result<PackageEvalRelationsResult>;
async fn get_package_properties<'b>(
&'b mut self,
pkg: &ArcPkgReq,
common_input: &Self::CommonInput,
) -> anyhow::Result<Arc<PackageProperties>>;
async fn preload_packages<'b>(
&'b mut self,
packages: &[ArcPkgReq],
common_input: &Self::CommonInput,
) -> anyhow::Result<()>;
async fn make_req_displayable<'b>(
&'b mut self,
req: &ArcPkgReq,
common_input: &Self::CommonInput,
) -> ArcPkgReq;
}
pub trait EvalInput {
fn set_content_versions(
&mut self,
required_versions: Vec<String>,
preferred_versions: Vec<String>,
);
fn set_force(&mut self, force: bool);
}
pub trait ConfiguredPackage: Clone {
type EvalInput: Clone;
fn get_package(&self) -> ArcPkgReq;
fn override_configured_package_input(
&self,
properties: &PackageProperties,
input: &mut Self::EvalInput,
) -> anyhow::Result<()>;
fn is_optional(&self) -> bool {
false
}
}
pub struct PackageEvalRelationsResult {
pub deps: Vec<Vec<RequiredPackage>>,
pub conflicts: Vec<PackageID>,
pub recommendations: Vec<RecommendedPackage>,
pub bundled: Vec<PackageID>,
pub compats: Vec<(PackageID, PackageID)>,
pub extensions: Vec<PackageID>,
pub inclusions: Vec<PackageID>,
}
pub fn is_open_source(meta: &PackageMetadata, properties: &PackageProperties) -> bool {
if let Some(open_source) = &properties.open_source {
return *open_source;
}
if let Some(license) = &meta.license
&& let "ARR" | "All Rights Reserved" = license.as_str()
{
return false;
}
true
}
#[derive(Clone, Serialize, Deserialize, Default)]
pub struct PackageMetaAndProps {
pub meta: Arc<PackageMetadata>,
pub props: Arc<PackageProperties>,
}
impl PartialEq for PackageMetaAndProps {
fn eq(&self, other: &Self) -> bool {
Arc::ptr_eq(&self.meta, &other.meta) && Arc::ptr_eq(&self.props, &other.props)
}
}
#[derive(Serialize, Deserialize, Default, Clone)]
pub struct PackageSearchResults {
pub results: Vec<String>,
pub total_results: usize,
pub previews: HashMap<String, PackageMetaAndProps>,
}