Skip to content

Commit

Permalink
Merge pull request #1129 from spkenv/preserve-install-environment
Browse files Browse the repository at this point in the history
Preserve install environment
  • Loading branch information
jrray authored Sep 19, 2024
2 parents 4b6dac1 + ae9258a commit 662e4fa
Show file tree
Hide file tree
Showing 26 changed files with 395 additions and 105 deletions.
11 changes: 11 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ codegen-units = 1

[workspace]
members = [
"crates/is_default_derive_macro",
"crates/progress_bar_derive_macro",
"crates/spfs",
"crates/spfs-encoding",
Expand Down Expand Up @@ -64,6 +65,7 @@ glob = "0.3"
indicatif = "0.17.8"
indexmap = "2.2"
itertools = "0.12"
is_default_derive_macro = { path = "crates/is_default_derive_macro" }
libc = "0.2.80"
miette = "7.0"
nix = { version = "0.27.1", features = ["mount", "sched", "user"] }
Expand Down
23 changes: 23 additions & 0 deletions crates/is_default_derive_macro/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[package]
name = "is_default_derive_macro"
version = { workspace = true }
license-file = { workspace = true }
homepage = { workspace = true }
repository = { workspace = true }
readme = { workspace = true }
description = { workspace = true }
edition = { workspace = true }

[lints]
workspace = true

[lib]
proc-macro = true

[dependencies]
syn = "2.0"
quote = "1.0"
indicatif = { workspace = true }

[dev-dependencies]
tracing = { workspace = true }
72 changes: 72 additions & 0 deletions crates/is_default_derive_macro/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Copyright (c) Contributors to the SPK project.
// SPDX-License-Identifier: Apache-2.0
// https://github.com/spkenv/spk

extern crate proc_macro;

use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, Data, DeriveInput, Fields};

#[proc_macro_derive(IsDefault)]
pub fn derive_is_default(input: TokenStream) -> TokenStream {
// Parse the input tokens into a syntax tree
let input = parse_macro_input!(input as DeriveInput);

// Get the name of the struct
let name = input.ident;

// Generate the trait implementation based on the struct's data (fields)
let expanded = match input.data {
Data::Struct(data_struct) => {
match data_struct.fields {
Fields::Named(fields_named) => {
// Generate code that calls `IsDefault::is_default` on each field
let field_checks = fields_named.named.iter().map(|field| {
let field_name = &field.ident;
quote! {
spk_schema_foundation::IsDefault::is_default(&self.#field_name)
}
});

quote! {
impl spk_schema_foundation::IsDefault for #name {
fn is_default(&self) -> bool {
true #(&& #field_checks)*
}
}
}
}
Fields::Unnamed(fields_unnamed) => {
let field_checks = fields_unnamed.unnamed.iter().enumerate().map(|(i, _)| {
let index = syn::Index::from(i);
quote! {
spk_schema_foundation::IsDefault::is_default(&self.#index)
}
});

quote! {
impl spk_schema_foundation::IsDefault for #name {
fn is_default(&self) -> bool {
true #(&& #field_checks)*
}
}
}
}
Fields::Unit => {
quote! {
impl spk_schema_foundation::IsDefault for #name {
fn is_default(&self) -> bool {
true
}
}
}
}
}
}
_ => panic!("IsDefault can only be derived for structs"),
};

// Return the generated code
TokenStream::from(expanded)
}
34 changes: 34 additions & 0 deletions crates/spk-cli/cmd-build/src/cmd_build_test/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use spk_schema::foundation::option_map;
use spk_schema::ident::version_ident;
use spk_schema::ident_component::Component;
use spk_schema::option_map::HOST_OPTIONS;
use spk_schema::RuntimeEnvironment;
use spk_storage::fixtures::*;

use super::Build;
Expand Down Expand Up @@ -728,3 +729,36 @@ build:
);
}
}

#[rstest]
#[tokio::test]
async fn test_package_with_environment_ops_preserves_ops_in_recipe(tmpdir: tempfile::TempDir) {
let rt = spfs_runtime().await;

build_package!(
tmpdir,
"env-ops.spk.yaml",
br#"
api: v0/package
pkg: env-ops/1.0.0
build:
script:
- true
install:
environment:
- set: FOO
value: bar
"#
);

let recipe = rt
.tmprepo
.read_recipe(&version_ident!("env-ops/1.0.0"))
.await
.unwrap();

assert!(
!recipe.runtime_environment().is_empty(),
"should have environment ops"
);
}
1 change: 1 addition & 0 deletions crates/spk-schema/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ format_serde_error = { version = "0.3", default-features = false, features = [
] }
ignore = "0.4.18"
indexmap = { workspace = true }
is_default_derive_macro = { workspace = true }
itertools = { workspace = true }
nom = { workspace = true }
regex = { workspace = true }
Expand Down
8 changes: 8 additions & 0 deletions crates/spk-schema/crates/foundation/src/is_default.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Copyright (c) Contributors to the SPK project.
// SPDX-License-Identifier: Apache-2.0
// https://github.com/spkenv/spk

pub trait IsDefault {
/// Returns true if the value equivalent to the default value.
fn is_default(&self) -> bool;
}
2 changes: 2 additions & 0 deletions crates/spk-schema/crates/foundation/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ mod from_yaml;
pub mod ident_build;
pub mod ident_component;
pub mod ident_ops;
mod is_default;
pub mod name;
pub mod option_map;
pub mod spec_ops;
Expand All @@ -17,3 +18,4 @@ pub mod version_range;

pub use fixtures::*;
pub use from_yaml::{FromYaml, SerdeYamlError};
pub use is_default::IsDefault;
14 changes: 8 additions & 6 deletions crates/spk-schema/crates/foundation/src/version/compat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use serde::{Deserialize, Serialize};

use super::{Error, Result, Version, VERSION_SEP};
use crate::name::PkgNameBuf;
use crate::version;
use crate::{version, IsDefault};

#[cfg(test)]
#[path = "./compat_test.rs"]
Expand Down Expand Up @@ -324,11 +324,6 @@ impl FromStr for Compat {
}

impl Compat {
// True if this is the default compatibility specification
pub fn is_default(&self) -> bool {
self == &Self::default()
}

/// Create a compat rule set with two parts
pub fn double(first: CompatRuleSet, second: CompatRuleSet) -> Self {
Compat {
Expand Down Expand Up @@ -467,6 +462,13 @@ impl Compat {
}
}

impl IsDefault for Compat {
// True if this is the default compatibility specification
fn is_default(&self) -> bool {
self == &Self::default()
}
}

/// Parse a string as a compatibility specifier.
pub fn parse_compat<S: AsRef<str>>(compat: S) -> super::Result<Compat> {
Compat::from_str(compat.as_ref())
Expand Down
13 changes: 7 additions & 6 deletions crates/spk-schema/crates/ident/src/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use spk_schema_foundation::version_range::{
RestrictMode,
VersionFilter,
};
use spk_schema_foundation::IsDefault;

use super::AnyIdent;
use crate::{BuildIdent, Error, RangeIdent, Result, Satisfy, VersionIdent};
Expand All @@ -45,8 +46,8 @@ pub enum PreReleasePolicy {
IncludeAll,
}

impl PreReleasePolicy {
pub fn is_default(&self) -> bool {
impl IsDefault for PreReleasePolicy {
fn is_default(&self) -> bool {
matches!(self, &PreReleasePolicy::ExcludeAll)
}
}
Expand All @@ -73,8 +74,8 @@ pub enum InclusionPolicy {
IfAlreadyPresent,
}

impl InclusionPolicy {
pub fn is_default(&self) -> bool {
impl IsDefault for InclusionPolicy {
fn is_default(&self) -> bool {
matches!(self, &InclusionPolicy::Always)
}
}
Expand All @@ -101,9 +102,9 @@ pub enum PinPolicy {
IfPresentInBuildEnv,
}

impl PinPolicy {
impl IsDefault for PinPolicy {
#[inline]
pub fn is_default(&self) -> bool {
fn is_default(&self) -> bool {
self == &PinPolicy::default()
}
}
Expand Down
21 changes: 13 additions & 8 deletions crates/spk-schema/src/build_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use spk_schema_foundation::ident_build::BuildId;
use spk_schema_foundation::name::PkgName;
use spk_schema_foundation::option_map::{OptionMap, Stringified, HOST_OPTIONS};
use spk_schema_foundation::version::Compat;
use spk_schema_foundation::IsDefault;
use strum::Display;

use super::{v0, Opt, ValidationSpec};
Expand Down Expand Up @@ -51,10 +52,6 @@ pub enum AutoHostVars {
}

impl AutoHostVars {
pub fn is_default(&self) -> bool {
self == &Self::default()
}

fn names_added(&self) -> HashSet<&OptName> {
let names = match self {
AutoHostVars::Distro => DISTRO_ADDS,
Expand Down Expand Up @@ -128,6 +125,12 @@ impl AutoHostVars {
}
}

impl IsDefault for AutoHostVars {
fn is_default(&self) -> bool {
self == &Self::default()
}
}

/// A set of structured inputs used to build a package.
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
pub struct BuildSpec {
Expand Down Expand Up @@ -161,10 +164,6 @@ impl Default for BuildSpec {
}

impl BuildSpec {
pub fn is_default(&self) -> bool {
self == &Self::default()
}

/// Returns this build's options, plus any additional ones needed
/// for building the given variant
pub fn opts_for_variant<V>(&self, variant: &V) -> Result<Vec<Opt>>
Expand Down Expand Up @@ -335,6 +334,12 @@ impl BuildSpec {
}
}

impl IsDefault for BuildSpec {
fn is_default(&self) -> bool {
self == &Self::default()
}
}

impl TryFrom<UncheckedBuildSpec> for BuildSpec {
type Error = crate::Error;

Expand Down
2 changes: 1 addition & 1 deletion crates/spk-schema/src/build_spec_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// https://github.com/spkenv/spk

use rstest::rstest;
use spk_schema_foundation::{option_map, pkg_name, FromYaml};
use spk_schema_foundation::{option_map, pkg_name, FromYaml, IsDefault};

use super::{AutoHostVars, BuildSpec};
use crate::build_spec::UncheckedBuildSpec;
Expand Down
5 changes: 3 additions & 2 deletions crates/spk-schema/src/component_spec_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use std::collections::{BTreeSet, HashMap, HashSet};

use serde::{Deserialize, Serialize};
use spk_schema_foundation::IsDefault;

use super::ComponentSpec;
use crate::foundation::ident_component::Component;
Expand All @@ -19,8 +20,8 @@ mod component_spec_list_test;
#[serde(transparent)]
pub struct ComponentSpecList(Vec<ComponentSpec>);

impl ComponentSpecList {
pub fn is_default(&self) -> bool {
impl IsDefault for ComponentSpecList {
fn is_default(&self) -> bool {
self == &Self::default()
}
}
Expand Down
7 changes: 7 additions & 0 deletions crates/spk-schema/src/embedded_packages_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use serde::{Deserialize, Serialize};
use spk_schema_foundation::ident_build::EmbeddedSource;
use spk_schema_foundation::IsDefault;
use spk_schema_ident::AnyIdent;

use super::{BuildSpec, InstallSpec, Spec};
Expand All @@ -18,6 +19,12 @@ mod embedded_packages_list_test;
#[serde(transparent)]
pub struct EmbeddedPackagesList(Vec<Spec>);

impl IsDefault for EmbeddedPackagesList {
fn is_default(&self) -> bool {
self.is_empty()
}
}

impl std::ops::Deref for EmbeddedPackagesList {
type Target = Vec<Spec>;
fn deref(&self) -> &Self::Target {
Expand Down
Loading

0 comments on commit 662e4fa

Please sign in to comment.