Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions crates/openjd-model/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,25 @@ impl ValidationErrors {
self.errors.len()
}

/// Append every error in `other`, rewriting its path through `remap`.
///
/// Used when validation runs against a synthesized structure (a
/// desugared SimpleAction) whose node paths do not exist in the authored
/// template: the checks run into a scratch `ValidationErrors` rooted at
/// the synthesized node, and `remap` translates each relative path onto
/// the field the author actually wrote before the errors join the real
/// collection. Messages and structured detail are carried unchanged.
pub(crate) fn extend_remapped(
&mut self,
other: ValidationErrors,
remap: impl Fn(&[PathElement]) -> Vec<PathElement>,
) {
for mut err in other.errors {
err.path = remap(&err.path);
self.errors.push(err);
}
}

pub fn into_result(self, model_name: &str) -> Result<(), ModelError> {
if self.errors.is_empty() {
Ok(())
Expand Down
50 changes: 39 additions & 11 deletions crates/openjd-model/src/job/create_job/instantiate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,15 @@ pub(super) fn instantiate_step(
}
}

let script_template = st.resolve_syntax_sugar()?.or_else(|| st.script.clone());
let script_template = st.resolve_syntax_sugar();
let script = script_template.as_ref().map(convert_step_script);
// When the script came from a SimpleAction (§8), diagnostics on the
// desugared form must point at the field the author wrote.
let sugar_kind = if st.script.is_none() {
st.simple_actions().next().map(|(kind, _)| kind)
} else {
None
};

// Check symbol table for the step script's carried-forward
// (session/task-scope) format strings: `step_symtab`'s concrete
Expand Down Expand Up @@ -112,21 +119,42 @@ pub(super) fn instantiate_step(
// `data` — against the check symbol table, where job parameters are
// bound to real values. A violation template validation could only
// lower-bound is decidable here: fail at submission, not on every
// worker.
// worker. These are exactly the checks pass 8 applies — to the same
// desugared form for a SimpleAction step, with the same path remap
// back onto the authored field.
if let (Some(s), Some(cst)) = (&script_template, &check_symtab) {
let mut check_errors = ValidationErrors::default();
let script_path = [
let step_path = [
PathElement::Field("steps".to_string()),
PathElement::Index(step_index),
PathElement::Field("script".to_string()),
];
crate::template::validate_v2023_09::format_strings::check_carried_forward_step_script(
s,
cst,
ctx,
&script_path,
&mut check_errors,
);
match sugar_kind {
Some(kind) => {
let mut scratch = ValidationErrors::default();
crate::template::validate_v2023_09::format_strings::check_carried_forward_step_script(
s,
cst,
ctx,
&[],
&mut scratch,
);
let sa_path = path_field(&step_path, kind.field_name());
check_errors.extend_remapped(scratch, |rel| {
let mut p = sa_path.clone();
p.extend(kind.remap_desugared_path(rel));
p
});
}
None => {
crate::template::validate_v2023_09::format_strings::check_carried_forward_step_script(
s,
cst,
ctx,
&path_field(&step_path, "script"),
&mut check_errors,
);
}
}
check_errors.into_result("JobTemplate")?;
}

Expand Down
2 changes: 1 addition & 1 deletion crates/openjd-model/src/template/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ pub use expr_parameters::{
ListStringItemConstraints,
};
// step
pub use step::{SimpleAction, StepDependency, StepScript, StepTemplate};
pub use step::{SimpleAction, SimpleActionKind, StepDependency, StepScript, StepTemplate};
// environment
pub use environment::{EmbeddedFile, Environment, EnvironmentScript};
// actions
Expand Down
Loading
Loading