Skip to content

Commit

Permalink
Merge pull request #873 from imageworks/platform-spec
Browse files Browse the repository at this point in the history
Platform spec for meta-packages
  • Loading branch information
rydrman authored Feb 14, 2024
2 parents 5d9bba1 + 4ca1f63 commit 1ea1eb6
Show file tree
Hide file tree
Showing 6 changed files with 807 additions and 14 deletions.
13 changes: 12 additions & 1 deletion crates/spk-schema/src/requirements_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::collections::HashSet;
use std::fmt::Write;

use serde::{Deserialize, Serialize};
use spk_schema_foundation::name::PkgName;
use spk_schema_foundation::name::{OptName, PkgName};
use spk_schema_foundation::version::Compatibility;
use spk_schema_ident::{BuildIdent, PinPolicy};

Expand Down Expand Up @@ -116,6 +116,17 @@ impl RequirementsList {
Compatibility::incompatible(format!("No request exists for {}", theirs.name()))
}

/// Remove a requirement from this list.
///
/// All requests with the same name as the given name are removed
/// from the list.
pub fn remove_all<N>(&mut self, name: &N)
where
N: AsRef<OptName> + ?Sized,
{
self.0.retain(|existing| existing.name() != name.as_ref());
}

/// Render all requests with a package pin using the given resolved packages.
pub fn render_all_pins(
&mut self,
Expand Down
73 changes: 60 additions & 13 deletions crates/spk-schema/src/spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,32 +189,40 @@ impl TemplateExt for SpecTemplate {
Ok(v) => v,
};

let api = template_value.get(&serde_yaml::Value::String("api".to_string()));

if api.is_none() {
tracing::warn!(
"Spec file is missing the 'api' field, this may be an error in the future"
);
tracing::warn!(" > for specs in the original spk format, add 'api: v0/package'");
}

let name_field = match api {
Some(serde_yaml::Value::String(api)) if api == "v0/platform" => "platform",
_ => "pkg",
};

let pkg = template_value
.get(&serde_yaml::Value::String("pkg".to_string()))
.get(&serde_yaml::Value::String(name_field.to_string()))
.ok_or_else(|| {
crate::Error::String(format!("Missing pkg field in spec file: {file_path:?}"))
crate::Error::String(format!(
"Missing {name_field} field in spec file: {file_path:?}"
))
})?;

let pkg = pkg.as_str().ok_or_else(|| {
crate::Error::String(format!(
"Invalid value for 'pkg' field: expected string, got {pkg:?} in {file_path:?}"
"Invalid value for '{name_field}' field: expected string, got {pkg:?} in {file_path:?}"
))
})?;

let name = PkgNameBuf::from_str(
// it should never be possible for split to return 0 results
// but this trick avoids the use of unwrap
pkg.split('/').next().unwrap_or(pkg),
)?;

if template_value
.get(&serde_yaml::Value::String("api".to_string()))
.is_none()
{
tracing::warn!(
"Spec file is missing the 'api' field, this may be an error in the future"
);
tracing::warn!(" > for specs in the original spk format, add 'api: v0/package'");
}

Ok(Self {
file_path,
name,
Expand All @@ -234,6 +242,8 @@ impl TemplateExt for SpecTemplate {
pub enum SpecRecipe {
#[serde(rename = "v0/package")]
V0Package(super::v0::Spec<VersionIdent>),
#[serde(rename = "v0/platform")]
V0Platform(super::v0::Platform),
}

impl Recipe for SpecRecipe {
Expand All @@ -244,6 +254,7 @@ impl Recipe for SpecRecipe {
fn ident(&self) -> &VersionIdent {
match self {
SpecRecipe::V0Package(r) => Recipe::ident(r),
SpecRecipe::V0Platform(r) => Recipe::ident(r),
}
}

Expand All @@ -268,6 +279,16 @@ impl Recipe for SpecRecipe {
.map(SpecVariant::V0)
.collect(),
),
SpecRecipe::V0Platform(r) => Cow::Owned(
// use into_owned instead of iter().cloned() in case it's
// already an owned instance
#[allow(clippy::unnecessary_to_owned)]
r.default_variants()
.into_owned()
.into_iter()
.map(SpecVariant::V0)
.collect(),
),
}
}

Expand All @@ -277,6 +298,7 @@ impl Recipe for SpecRecipe {
{
match self {
SpecRecipe::V0Package(r) => r.resolve_options(variant),
SpecRecipe::V0Platform(r) => r.resolve_options(variant),
}
}

Expand All @@ -286,6 +308,7 @@ impl Recipe for SpecRecipe {
{
match self {
SpecRecipe::V0Package(r) => r.get_build_requirements(variant),
SpecRecipe::V0Platform(r) => r.get_build_requirements(variant),
}
}

Expand All @@ -299,12 +322,18 @@ impl Recipe for SpecRecipe {
.into_iter()
.map(SpecTest::V0)
.collect()),
SpecRecipe::V0Platform(r) => Ok(r
.get_tests(stage, variant)?
.into_iter()
.map(SpecTest::V0)
.collect()),
}
}

fn generate_source_build(&self, root: &Path) -> Result<Self::Output> {
match self {
SpecRecipe::V0Package(r) => r.generate_source_build(root).map(Spec::V0Package),
SpecRecipe::V0Platform(r) => r.generate_source_build(root).map(Spec::V0Package),
}
}

Expand All @@ -318,6 +347,9 @@ impl Recipe for SpecRecipe {
SpecRecipe::V0Package(r) => r
.generate_binary_build(variant, build_env)
.map(Spec::V0Package),
SpecRecipe::V0Platform(r) => r
.generate_binary_build(variant, build_env)
.map(Spec::V0Package),
}
}
}
Expand All @@ -326,6 +358,7 @@ impl Named for SpecRecipe {
fn name(&self) -> &PkgName {
match self {
SpecRecipe::V0Package(r) => r.name(),
SpecRecipe::V0Platform(r) => r.name(),
}
}
}
Expand All @@ -334,6 +367,7 @@ impl HasVersion for SpecRecipe {
fn version(&self) -> &Version {
match self {
SpecRecipe::V0Package(r) => r.version(),
SpecRecipe::V0Platform(r) => r.version(),
}
}
}
Expand All @@ -342,6 +376,7 @@ impl Versioned for SpecRecipe {
fn compat(&self) -> &Compat {
match self {
SpecRecipe::V0Package(spec) => spec.compat(),
SpecRecipe::V0Platform(spec) => spec.compat(),
}
}
}
Expand Down Expand Up @@ -382,6 +417,11 @@ impl FromYaml for SpecRecipe {
.map_err(|err| SerdeError::new(yaml, SerdeYamlError(err)))?;
Ok(Self::V0Package(inner))
}
ApiVersion::V0Platform => {
let inner = serde_yaml::from_str(&yaml)
.map_err(|err| SerdeError::new(yaml, SerdeYamlError(err)))?;
Ok(Self::V0Platform(inner))
}
}
}
}
Expand Down Expand Up @@ -638,6 +678,11 @@ impl FromYaml for Spec {
.map_err(|err| SerdeError::new(yaml, SerdeYamlError(err)))?;
Ok(Self::V0Package(inner))
}
ApiVersion::V0Platform => {
let inner = serde_yaml::from_str(&yaml)
.map_err(|err| SerdeError::new(yaml, SerdeYamlError(err)))?;
Ok(Self::V0Package(inner))
}
}
}
}
Expand All @@ -652,6 +697,8 @@ impl AsRef<Spec> for Spec {
pub enum ApiVersion {
#[serde(rename = "v0/package")]
V0Package,
#[serde(rename = "v0/platform")]
V0Platform,
}

impl Default for ApiVersion {
Expand Down
2 changes: 2 additions & 0 deletions crates/spk-schema/src/v0/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
// SPDX-License-Identifier: Apache-2.0
// https://github.com/imageworks/spk

mod platform;
mod spec;
mod test_spec;
mod variant;
mod variant_spec;

pub use platform::Platform;
pub use spec::Spec;
pub use test_spec::TestSpec;
pub use variant::Variant;
Expand Down
Loading

0 comments on commit 1ea1eb6

Please sign in to comment.