Skip to content

Commit c92bb00

Browse files
committed
Refactor to render exports when resolving queries and commit src/exports.rs
1 parent 745235f commit c92bb00

2 files changed

Lines changed: 108 additions & 19 deletions

File tree

src/exports.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
use std::collections::HashMap;
2+
3+
use anyhow::Result;
4+
5+
use crate::node::Node;
6+
use crate::Reclass;
7+
8+
#[derive(Debug, Default)]
9+
pub struct Exports<'a> {
10+
pub(crate) exports: HashMap<String, Node>,
11+
pub(crate) reclass: Option<&'a Reclass>,
12+
}
13+
14+
impl<'a> Exports<'a> {
15+
// TODO(sg): ensure that we do proper ref lookups when rendering exports
16+
pub(crate) fn new(r: &'a Reclass) -> Result<Self> {
17+
let mut exports = HashMap::new();
18+
for n in r.nodes.keys() {
19+
let node = Node::parse(r, n)?;
20+
assert_eq!(n, &node.meta.name);
21+
exports.insert(n.clone(), node);
22+
}
23+
Ok(Self {
24+
exports,
25+
reclass: Some(r),
26+
})
27+
}
28+
}

src/invqueries/mod.rs

Lines changed: 80 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,11 @@ impl Query {
167167
if let Some(var) = &self.var {
168168
let o = Item::Obj(var.clone());
169169
let mut r = Mapping::new();
170-
for (n, n_exports) in &exports.exports {
170+
for (n, node) in &exports.exports {
171+
let m = node
172+
.merged(exports.reclass.unwrap())
173+
.map_err(|e| anyhow!("while rendering exports for {n}: {e}"))?;
174+
let n_exports = m.get_exports();
171175
let nv = o
172176
.value(n_exports, self.ignore_errors)
173177
.map_err(|e| anyhow!("while evaluating export value for {n}: {e}"))?;
@@ -191,8 +195,11 @@ impl Query {
191195
} else {
192196
let mut r = vec![];
193197
if let Some(e) = self.expr.as_ref() {
194-
for (n, n_exports) in &exports.exports {
195-
if e.evaluate(n_exports, self.ignore_errors)? {
198+
for (n, node) in &exports.exports {
199+
let m = node
200+
.merged(exports.reclass.unwrap())
201+
.map_err(|e| anyhow!("while rendering exports for {n}: {e}"))?;
202+
if e.evaluate(m.get_exports(), self.ignore_errors)? {
196203
r.push(n.clone().into());
197204
}
198205
}
@@ -204,22 +211,52 @@ impl Query {
204211

205212
#[cfg(test)]
206213
mod invqueries_test {
214+
use std::path::PathBuf;
215+
207216
use super::Query;
208217
use crate::exports::Exports;
218+
use crate::node::Node;
209219
use crate::types::{Mapping, Value};
220+
use crate::{NodeInfoMeta, Reclass};
221+
222+
fn make_node(name: &str, contents: &str) -> Node {
223+
let mut npath = PathBuf::new();
224+
npath.set_file_name(format!("{name}.yml"));
225+
Node::from_str(
226+
NodeInfoMeta::new(
227+
name,
228+
name,
229+
&format!("tmp://{name}"),
230+
npath.clone(),
231+
npath,
232+
"base",
233+
),
234+
None,
235+
contents,
236+
)
237+
.unwrap()
238+
}
210239

211240
#[test]
212241
fn test_resolve_simple_1() {
213242
let qstr = " exports:foo ";
214243
let q = Query::parse(qstr).unwrap();
215244
let mut exports = Exports::default();
245+
let r = Reclass::new("./tests/inventory", "nodes", "classes", false).unwrap();
246+
println!("{:?}", r.nodes);
247+
exports.reclass = Some(&r);
216248
let mut expected = Mapping::new();
217249
for n in ["n1", "n2", "n3"] {
218-
let mut m = Mapping::new();
219-
m.insert("foo".into(), "bar".into()).unwrap();
220-
exports.exports.insert(n.into(), m);
250+
let node = make_node(
251+
n,
252+
r#"
253+
exports:
254+
foo: bar
255+
"#,
256+
);
257+
exports.exports.insert(n.into(), node);
221258
expected
222-
.insert(n.into(), Value::String("bar".to_owned()))
259+
.insert(n.into(), Value::Literal("bar".to_owned()))
223260
.unwrap();
224261
}
225262
let v = q.resolve(&exports).unwrap();
@@ -232,12 +269,20 @@ mod invqueries_test {
232269
let qstr = " +IgnoreErrors exports:n1 ";
233270
let q = Query::parse(qstr).unwrap();
234271
let mut exports = Exports::default();
272+
let r = Reclass::new("./tests/inventory", "nodes", "classes", false).unwrap();
273+
exports.reclass = Some(&r);
235274
let mut expected = Mapping::new();
236275
for n in ["n1", "n2", "n3"] {
237-
let mut m = Mapping::new();
238-
m.insert(n.into(), Value::Literal("bar".to_owned()))
239-
.unwrap();
240-
exports.exports.insert(n.into(), m);
276+
let node = make_node(
277+
n,
278+
&format!(
279+
r#"
280+
exports:
281+
{n}: bar
282+
"#
283+
),
284+
);
285+
exports.exports.insert(n.into(), node);
241286
if n == "n1" {
242287
expected
243288
.insert(n.into(), Value::Literal("bar".to_owned()))
@@ -254,11 +299,19 @@ mod invqueries_test {
254299
let qstr = " exports:n1 ";
255300
let q = Query::parse(qstr).unwrap();
256301
let mut exports = Exports::default();
302+
let r = Reclass::new("./tests/inventory", "nodes", "classes", false).unwrap();
303+
exports.reclass = Some(&r);
257304
for n in ["n1", "n2", "n3"] {
258-
let mut m = Mapping::new();
259-
m.insert(n.into(), Value::Literal("bar".to_owned()))
260-
.unwrap();
261-
exports.exports.insert(n.into(), m);
305+
let node = make_node(
306+
n,
307+
&format!(
308+
r#"
309+
exports:
310+
{n}: bar
311+
"#
312+
),
313+
);
314+
exports.exports.insert(n.into(), node);
262315
}
263316
let v = q.resolve(&exports);
264317
assert!(v.is_err());
@@ -269,12 +322,20 @@ mod invqueries_test {
269322
let qstr = " exports:foo if exports:foo != n3 ";
270323
let q = Query::parse(qstr).unwrap();
271324
let mut exports = Exports::default();
325+
let r = Reclass::new("./tests/inventory", "nodes", "classes", false).unwrap();
326+
exports.reclass = Some(&r);
272327
let mut expected = Mapping::new();
273328
for n in ["n1", "n2", "n3"] {
274-
let mut m = Mapping::new();
275-
m.insert("foo".into(), Value::Literal(n.to_owned()))
276-
.unwrap();
277-
exports.exports.insert(n.into(), m);
329+
let node = make_node(
330+
n,
331+
&format!(
332+
r#"
333+
exports:
334+
foo: {n}
335+
"#
336+
),
337+
);
338+
exports.exports.insert(n.into(), node);
278339
if n != "n3" {
279340
expected
280341
.insert(n.into(), Value::Literal(n.to_owned()))

0 commit comments

Comments
 (0)