Skip to content

Commit b2e7f58

Browse files
author
Nichol Yip
committed
Fix issue where EnvOpList was not properly deserialized and bypassed the multiple priority config check.
Signed-off-by: Nichol Yip <nyip@imageworks.com>
1 parent 77fbd44 commit b2e7f58

File tree

4 files changed

+53
-51
lines changed

4 files changed

+53
-51
lines changed

crates/spk-schema/src/environ.rs

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,9 +188,46 @@ impl EnvOp {
188188
}
189189
}
190190

191-
#[derive(Clone, Debug, Default, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
191+
#[derive(Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
192192
pub struct EnvOpList(Vec<EnvOp>);
193193

194+
impl<'de> Deserialize<'de> for EnvOpList {
195+
fn deserialize<D>(deserializer: D) -> std::result::Result<EnvOpList, D::Error>
196+
where
197+
D: serde::Deserializer<'de>,
198+
{
199+
struct EnvConfVisitor;
200+
201+
impl<'de> serde::de::Visitor<'de> for EnvConfVisitor {
202+
type Value = EnvOpList;
203+
204+
fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
205+
f.write_str("an environment configuration")
206+
}
207+
208+
fn visit_seq<A>(self, mut seq: A) -> std::result::Result<Self::Value, A::Error>
209+
where
210+
A: serde::de::SeqAccess<'de>,
211+
{
212+
let mut vec = EnvOpList::default();
213+
214+
while let Some(elem) = seq.next_element::<EnvOp>()? {
215+
if vec.iter().any(|x: &EnvOp| x.kind() == OpKind::Priority)
216+
&& elem.kind() == OpKind::Priority
217+
{
218+
return Err(serde::de::Error::custom(
219+
"Multiple priority config cannot be set.",
220+
));
221+
};
222+
vec.push(elem);
223+
}
224+
Ok(vec)
225+
}
226+
}
227+
deserializer.deserialize_seq(EnvConfVisitor)
228+
}
229+
}
230+
194231
impl IsDefault for EnvOpList {
195232
fn is_default(&self) -> bool {
196233
self.0.is_empty()

crates/spk-schema/src/install_spec.rs

Lines changed: 10 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,10 @@ use crate::foundation::option_map::OptionMap;
1717
use crate::{
1818
ComponentSpecList,
1919
EmbeddedPackagesList,
20-
EnvOp,
2120
EnvOpList,
2221
Lint,
2322
LintedItem,
2423
Lints,
25-
OpKind,
2624
Package,
2725
RequirementsList,
2826
Result,
@@ -38,6 +36,7 @@ mod install_spec_test;
3836
Clone,
3937
Debug,
4038
Default,
39+
Deserialize,
4140
Eq,
4241
Hash,
4342
is_default_derive_macro::IsDefault,
@@ -63,7 +62,6 @@ where
6362
D: Default,
6463
{
6564
fn lints(&mut self) -> Vec<Lint> {
66-
// self.lints.extend(std::mem::take(&mut self.environment.lints));
6765
std::mem::take(&mut self.lints)
6866
}
6967
}
@@ -81,7 +79,7 @@ where
8179
_phantom: PhantomData<D>,
8280
}
8381

84-
impl<D> From<InstallSpecVisitor<D>> for InstallSpec
82+
impl<D> From<InstallSpecVisitor<D>> for RawInstallSpec
8583
where
8684
D: Default,
8785
{
@@ -206,69 +204,35 @@ impl From<RawInstallSpec> for InstallSpec {
206204
}
207205
}
208206

209-
#[derive(Deserialize)]
210-
struct RawInstallSpec {
207+
/// A raw, unvalidated install spec.
208+
#[derive(Serialize, Default)]
209+
pub struct RawInstallSpec {
211210
#[serde(default)]
212211
requirements: RequirementsList,
213212
#[serde(default)]
214213
embedded: EmbeddedPackagesList,
215214
#[serde(default)]
216215
components: ComponentSpecList,
217-
#[serde(default, deserialize_with = "deserialize_env_conf")]
216+
#[serde(default)]
218217
environment: EnvOpList,
219218
}
220219

221-
impl<'de> Deserialize<'de> for InstallSpec {
220+
impl<'de> Deserialize<'de> for RawInstallSpec {
222221
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
223222
where
224223
D: serde::de::Deserializer<'de>,
225224
{
226-
deserializer.deserialize_map(InstallSpecVisitor::<InstallSpec>::default())
225+
deserializer.deserialize_map(InstallSpecVisitor::<RawInstallSpec>::default())
227226
}
228227
}
229228

230-
impl<'de> Deserialize<'de> for LintedItem<InstallSpec> {
229+
impl<'de> Deserialize<'de> for LintedItem<RawInstallSpec> {
231230
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
232231
where
233232
D: serde::de::Deserializer<'de>,
234233
{
235-
deserializer.deserialize_map(InstallSpecVisitor::<LintedItem<InstallSpec>>::default())
236-
}
237-
}
238-
239-
fn deserialize_env_conf<'de, D>(deserializer: D) -> std::result::Result<EnvOpList, D::Error>
240-
where
241-
D: serde::Deserializer<'de>,
242-
{
243-
struct EnvConfVisitor;
244-
245-
impl<'de> serde::de::Visitor<'de> for EnvConfVisitor {
246-
type Value = EnvOpList;
247-
248-
fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
249-
f.write_str("an environment configuration")
250-
}
251-
252-
fn visit_seq<A>(self, mut seq: A) -> std::result::Result<Self::Value, A::Error>
253-
where
254-
A: serde::de::SeqAccess<'de>,
255-
{
256-
let mut vec = EnvOpList::default();
257-
258-
while let Some(elem) = seq.next_element::<EnvOp>()? {
259-
if vec.iter().any(|x: &EnvOp| x.kind() == OpKind::Priority)
260-
&& elem.kind() == OpKind::Priority
261-
{
262-
return Err(serde::de::Error::custom(
263-
"Multiple priority config cannot be set.",
264-
));
265-
};
266-
vec.push(elem);
267-
}
268-
Ok(vec)
269-
}
234+
deserializer.deserialize_map(InstallSpecVisitor::<LintedItem<RawInstallSpec>>::default())
270235
}
271-
deserializer.deserialize_seq(EnvConfVisitor)
272236
}
273237

274238
impl<'de, D> serde::de::Visitor<'de> for InstallSpecVisitor<D>

crates/spk-schema/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ pub use environ::{
4646
};
4747
pub use error::{Error, Result};
4848
pub use input_variant::InputVariant;
49-
pub use install_spec::InstallSpec;
49+
pub use install_spec::{InstallSpec, RawInstallSpec};
5050
pub use lints::{Lint, LintedItem, Lints, UnknownKey};
5151
pub use option::{Inheritance, Opt};
5252
pub use package::{Package, PackageMut};

crates/spk-schema/src/v0/spec.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ use crate::{
6666
Opt,
6767
Package,
6868
PackageMut,
69+
RawInstallSpec,
6970
Recipe,
7071
RequirementsList,
7172
Result,
@@ -990,7 +991,7 @@ struct SpecVisitor<B, T> {
990991
sources: Option<Vec<LintedItem<SourceSpec>>>,
991992
build: Option<LintedItem<BuildSpec>>,
992993
tests: Option<Vec<LintedItem<TestSpec>>>,
993-
install: Option<LintedItem<InstallSpec>>,
994+
install: Option<LintedItem<RawInstallSpec>>,
994995
#[field_names_as_array(skip)]
995996
check_build_spec: bool,
996997
#[field_names_as_array(skip)]
@@ -1047,7 +1048,7 @@ where
10471048
.iter()
10481049
.map(|l| l.item.clone())
10491050
.collect_vec(),
1050-
install: value.install.take().unwrap_or_default().item,
1051+
install: value.install.take().unwrap_or_default().item.into(),
10511052
}
10521053
}
10531054
}
@@ -1143,7 +1144,7 @@ where
11431144
}
11441145
}
11451146
"tests" => self.tests = Some(map.next_value::<Vec<LintedItem<TestSpec>>>()?),
1146-
"install" => self.install = Some(map.next_value::<LintedItem<InstallSpec>>()?),
1147+
"install" => self.install = Some(map.next_value::<LintedItem<RawInstallSpec>>()?),
11471148
"api" => {
11481149
map.next_value::<serde::de::IgnoredAny>()?;
11491150
}

0 commit comments

Comments
 (0)