fix(graph): validate the whole max_concurrency template string
A string max_concurrency passed the load-time check whenever it merely
contained a {{...}} pair, so forms like "n={{k}}" or "{{ key }}" that
can never resolve at runtime were only caught after the map's inputs had
been computed. The check now requires the trimmed string to be exactly
one template reference, matching what interpolate_raw resolves as a pure
reference; padded forms like " {{budget}} " stay valid.
Also: the bash tool build-failure context names the source file instead
of the destination path, and the map-subgraph validator no longer
shadows its member id list with the resolved member nodes.
This commit is contained in:
3 files changed
+97
-13
No files matched your search
@@ -320,6 +320,16 @@ pub(super) fn template_root_keys(template: &str) -> Vec<String> {
|
||||
.collect()
|
||||
}
|
||||
|
||||
// Whether `s` is exactly one `{{key}}` reference and nothing else, after the
|
||||
// same trim `interpolate_raw` applies, so this accepts exactly the strings the
|
||||
// runtime resolves as a pure reference.
|
||||
pub(super) fn is_lone_template(s: &str) -> bool {
|
||||
let s = s.trim();
|
||||
TEMPLATE_VAR_RE
|
||||
.find(s)
|
||||
.is_ok_and(|m| m.is_some_and(|m| m.start() == 0 && m.end() == s.len()))
|
||||
}
|
||||
|
||||
fn value_to_string(value: &Value) -> String {
|
||||
match value {
|
||||
Value::String(s) => s.clone(),
|
||||
@@ -931,6 +941,38 @@ mod tests {
|
||||
assert_eq!(result, json!("v"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn is_lone_template_cases() {
|
||||
for accepted in [
|
||||
"{{budget}}",
|
||||
"{{cfg.limits[0]}}",
|
||||
" {{budget}} ",
|
||||
"\n{{k}}\t",
|
||||
] {
|
||||
assert!(
|
||||
is_lone_template(accepted),
|
||||
"{accepted:?} should be a lone template"
|
||||
);
|
||||
}
|
||||
for rejected in [
|
||||
"",
|
||||
"4",
|
||||
"{{}}",
|
||||
"{{ key }}",
|
||||
"n={{k}}",
|
||||
"{{k}}x",
|
||||
"{{a}} {{b",
|
||||
"{{a}}{{b}}",
|
||||
"{{a-b}}",
|
||||
"{{k",
|
||||
] {
|
||||
assert!(
|
||||
!is_lone_template(rejected),
|
||||
"{rejected:?} must not be a lone template"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interpolate_raw_inner_spaces_treated_as_mixed() {
|
||||
let manager = manager_with(&[("k", json!("v"))]);
|
||||
|
||||
Reference in new issue
Block a user