Skip to content

Commit

Permalink
Work in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
gpoblon committed Mar 16, 2021
1 parent e0ab8a1 commit 521e75b
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 75 deletions.
79 changes: 32 additions & 47 deletions rudder-lang/src/generator/cfengine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,30 +142,30 @@ impl CFEngine {
st: &Statement,
in_class: String,
) -> Result<Vec<Promise>> {
// get variables to try to get the proper parameter value
let mut variables: HashMap<&Token, &VariableDef> = HashMap::new();
for st_from_list in &state_def.statements {
// variables declared after the current statemnt are not defined at this point
if st_from_list == st {
break;
} else if let Statement::VariableDefinition(v) = st_from_list {
variables.insert(&v.name, v);
}
}
variables.extend(res_def.variable_definitions.get());
variables.extend(&gc.variable_definitions);

match st {
Statement::ConditionVariableDefinition(var) => {
let component = match var.metadata.get("component") {
Some(TomlValue::String(s)) => s.to_owned(),
_ => "any".to_string(),
};

// get variables to try to get the proper parameter value
let mut variables: HashMap<&Token, &VariableDef> = HashMap::new();
for st_from_list in &state_def.statements {
// variables declared after the current statemnt are not defined at this point
if st_from_list == st {
break;
} else if let Statement::VariableDefinition(v) = st_from_list {
variables.insert(&v.name, v);
}
}
variables.extend(res_def.variable_definitions.get());
variables.extend(&gc.variable_definitions);

// TODO setup mode and output var by calling ... bundle
let parameters =
fetch_method_parameters(gc, &var.to_method(), |_name, value, _metadatas| {
self.value_to_string(value, Some(&variables), true)
self.value_to_string(value, &variables, true)
})
.into_iter()
.collect::<Result<Vec<String>>>()?;
Expand All @@ -177,7 +177,7 @@ impl CFEngine {
let class_param = var
.resource_params
.get(class_param_index)
.and_then(|p| self.value_to_string(&p, Some(&variables), false).ok())
.and_then(|p| self.value_to_string(&p, &variables, false).ok())
.unwrap_or_else(|| "".to_string());

Ok(Method::new()
Expand All @@ -199,25 +199,12 @@ impl CFEngine {
_ => "any".to_string(),
};

// get variables to try to get the proper parameter value
let mut variables: HashMap<&Token, &VariableDef> = HashMap::new();
for st_from_list in &state_def.statements {
// variables declared after the current statemnt are not defined at this point
if st_from_list == st {
break;
} else if let Statement::VariableDefinition(v) = st_from_list {
variables.insert(&v.name, v);
}
}
variables.extend(res_def.variable_definitions.get());
variables.extend(&gc.variable_definitions);

// TODO setup mode and output var by calling ... bundle
let parameters = sd
.resource_params
.iter()
.chain(sd.state_params.iter())
.map(|x| self.value_to_string(x, Some(&variables), true))
.map(|x| self.value_to_string(x, &variables, true))
.collect::<Result<Vec<String>>>()?;

let method_name = &format!("{}-{}", sd.resource.fragment(), sd.state.fragment());
Expand All @@ -229,7 +216,7 @@ impl CFEngine {
let class_param = sd
.resource_params
.get(class_param_index)
.and_then(|p| self.value_to_string(&p, Some(&variables), false).ok())
.and_then(|p| self.value_to_string(&p, &variables, false).ok())
.unwrap_or_else(|| "".to_string());

Ok(Method::new()
Expand Down Expand Up @@ -272,15 +259,15 @@ impl CFEngine {
None,
vec![
quoted("policy_fail"),
self.value_to_string(msg, None, true)?,
self.value_to_string(msg, &variables, true)?,
],
)]),
Statement::LogDebug(msg) => Ok(vec![Promise::usebundle(
"log_rudder_mode",
None,
vec![
quoted("log_debug"),
self.value_to_string(msg, None, true)?,
self.value_to_string(msg, &variables, true)?,
quoted("None"),
// TODO: unique class prefix
quoted("log_debug"),
Expand All @@ -291,7 +278,7 @@ impl CFEngine {
None,
vec![
quoted("log_info"),
self.value_to_string(msg, None, true)?,
self.value_to_string(msg, &variables, true)?,
quoted("None"),
// TODO: unique class prefix
quoted("log_info"),
Expand All @@ -302,7 +289,7 @@ impl CFEngine {
None,
vec![
quoted("log_warn"),
self.value_to_string(msg, None, true)?,
self.value_to_string(msg, &variables, true)?,
quoted("None"),
// TODO: unique class prefix
quoted("log_warn"),
Expand Down Expand Up @@ -331,7 +318,7 @@ impl CFEngine {
fn value_to_string(
&self,
value: &Value,
variables: Option<&HashMap<&Token, &VariableDef>>,
variables: &HashMap<&Token, &VariableDef>,
string_delim: bool,
) -> Result<String> {
let delim = if string_delim { "\"" } else { "" };
Expand Down Expand Up @@ -372,7 +359,7 @@ impl CFEngine {
Value::EnumExpression(_e) => unimplemented!(),
Value::List(l) => format!(
"[ {} ]",
map_strings_results(l.iter(), |x| self.value_to_string(x, None, true), ",")?
map_strings_results(l.iter(), |x| self.value_to_string(x, variables, true), ",")?
),
Value::Struct(s) => format!(
"{{ {} }}",
Expand All @@ -381,22 +368,20 @@ impl CFEngine {
|(x, y)| Ok(format!(
r#""{}":{}"#,
x,
self.value_to_string(y, None, true)?
self.value_to_string(y, variables, true)?
)),
","
)?
),
Value::Variable(v) => {
if let Some(variables) = variables {
if let Some(var) = variables.get(v).and_then(|var_def| {
var_def
.value
.first_value()
.and_then(|v| self.value_to_string(v, Some(variables), string_delim))
.ok()
}) {
return Ok(var);
}
if let Some(var) = variables.get(v).and_then(|var_def| {
var_def
.value
.first_value()
.and_then(|v| self.value_to_string(v, variables, string_delim))
.ok()
}) {
return Ok(var);
}
warn!(
"The variable {} isn't recognized by rudderc, so we can't guarantee it will be defined when evaluated",
Expand Down
82 changes: 65 additions & 17 deletions rudder-lang/src/generator/dsc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ use crate::{
pascal_case, Call, Function, Method, Parameter, ParameterType, Parameters, Policy,
},
generator::Format,
ir::{context::Type, enums::EnumExpressionPart, ir2::IR2, resource::*, value::*},
ir::{
context::Type, enums::EnumExpressionPart, ir2::IR2, resource::*, value::*,
variable::VariableDef,
},
parser::*,
technique::fetch_method_parameters,
};
Expand Down Expand Up @@ -174,13 +177,29 @@ impl DSC {
fn format_statement(
&mut self,
gc: &IR2,
res_def: &ResourceDef,
state_def: &StateDef,
st: &Statement,
condition_content: String,
) -> Result<Vec<Call>> {
// get variables to try to get the proper parameter value
let mut variables: HashMap<&Token, &VariableDef> = HashMap::new();
for st_from_list in &state_def.statements {
// variables declared after the current statemnt are not defined at this point
if st_from_list == st {
break;
} else if let Statement::VariableDefinition(v) = st_from_list {
variables.insert(&v.name, v);
}
}
variables.extend(res_def.variable_definitions.get());
variables.extend(&gc.variable_definitions);

match st {
Statement::ConditionVariableDefinition(var) => {
let state_decl = var.to_method();
let method_name = &format!("{}-{}", var.resource.fragment(), var.state.fragment());

let mut parameters =
fetch_method_parameters(gc, &state_decl, |name, value, parameter_metadatas| {
let content_type = parameter_metadatas
Expand All @@ -189,7 +208,7 @@ impl DSC {
.and_then(|type_str| ParameterType::from_str(type_str).ok())
.unwrap_or(ParameterType::default());
let string_value = &self
.value_to_string(value, false)
.value_to_string(value, &variables, false)
.expect("Value is not formatted correctly");
Parameter::method_parameter(name, string_value, content_type)
});
Expand Down Expand Up @@ -228,6 +247,7 @@ impl DSC {
}

let method_name = &format!("{}-{}", sd.resource.fragment(), sd.state.fragment());

let mut parameters =
fetch_method_parameters(gc, sd, |name, value, parameter_metadatas| {
let content_type = parameter_metadatas
Expand All @@ -236,7 +256,7 @@ impl DSC {
.and_then(|type_str| ParameterType::from_str(type_str).ok())
.unwrap_or(ParameterType::default());
let string_value = &self
.value_to_string(value, false)
.value_to_string(value, &variables, false)
.expect("Value is not formatted correctly");
Parameter::method_parameter(name, string_value, content_type)
});
Expand Down Expand Up @@ -282,20 +302,26 @@ impl DSC {
for (case, vst) in vec {
let case_exp = self.format_case_expr(gc, &case.expression)?;
for st in vst {
res.append(&mut self.format_statement(gc, st, case_exp.clone())?);
res.append(&mut self.format_statement(
gc,
res_def,
state_def,
st,
case_exp.clone(),
)?);
}
}
Ok(res)
}
Statement::Fail(msg) => Ok(vec![Call::abort(
Parameters::new()
.message("policy_fail")
.message(&self.value_to_string(msg, true)?), //self.parameter_to_dsc(msg, "Fail")?,
.message(&self.value_to_string(msg, &variables, true)?),
)]),
Statement::LogDebug(msg) => Ok(vec![Call::log(
Parameters::new()
.message("log_debug")
.message(&self.value_to_string(msg, true)?)
.message(&self.value_to_string(msg, &variables, true)?)
//self.parameter_to_dsc(msg, "Log")?,
.message("None")
// TODO: unique class prefix
Expand All @@ -304,15 +330,15 @@ impl DSC {
Statement::LogInfo(msg) => Ok(vec![Call::log(
Parameters::new()
.message("log_info")
.message(&self.value_to_string(msg, true)?)
.message(&self.value_to_string(msg, &variables, true)?)
.message("None")
// TODO: unique class prefix
.message("log_info"),
)]),
Statement::LogWarn(msg) => Ok(vec![Call::log(
Parameters::new()
.message("log_warn")
.message(&self.value_to_string(msg, true)?)
.message(&self.value_to_string(msg, &variables, true)?)
.message("None")
// TODO: unique class prefix
.message("log_warn"),
Expand All @@ -336,7 +362,12 @@ impl DSC {
}
}

fn value_to_string(&self, value: &Value, string_delim: bool) -> Result<String> {
fn value_to_string(
&self,
value: &Value,
variables: &HashMap<&Token, &VariableDef>,
string_delim: bool,
) -> Result<String> {
let delim = if string_delim { "\"" } else { "" };
Ok(match value {
Value::String(s) => format!("{}{}{}", delim, String::try_from(s)?, delim),
Expand All @@ -346,17 +377,36 @@ impl DSC {
Value::EnumExpression(_) => unimplemented!(),
Value::List(l) => format!(
"[ {} ]",
map_strings_results(l.iter(), |x| self.value_to_string(x, true), ",")?
map_strings_results(l.iter(), |x| self.value_to_string(x, variables, true), ",")?
),
Value::Struct(s) => format!(
"{{ {} }}",
map_strings_results(
s.iter(),
|(x, y)| Ok(format!(r#""{}":{}"#, x, self.value_to_string(y, true)?)),
|(x, y)| Ok(format!(
r#""{}":{}"#,
x,
self.value_to_string(y, variables, true)?
)),
","
)?
),
Value::Variable(_) => unimplemented!(),
Value::Variable(v) => {
if let Some(var) = variables.get(v).and_then(|var_def| {
var_def
.value
.first_value()
.and_then(|v| self.value_to_string(v, variables, string_delim))
.ok()
}) {
return Ok(var);
}
warn!(
"The variable {} isn't recognized by rudderc, so we can't guarantee it will be defined when evaluated",
v.fragment()
);
format!("{}${{{}}}{}", delim, v.fragment(), delim)
}
})
}

Expand Down Expand Up @@ -438,11 +488,9 @@ impl Generator for DSC {
Call::variable("$ResourcesDir", "$PSScriptRoot + \"\\resources\""),
]);

for methods in state
.statements
.iter()
.flat_map(|statement| self.format_statement(gc, statement, "any".to_string()))
{
for methods in state.statements.iter().flat_map(|statement| {
self.format_statement(gc, resource, state, statement, "any".to_string())
}) {
function.push_scope(methods);
}

Expand Down
4 changes: 2 additions & 2 deletions rudder-lang/src/io/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ mod backtrace;
pub use self::backtrace::Backtrace;

use super::logs::*;
use crate::{command::*, error::Result};
use crate::{command::*, error::Result, generator::Format};
use colored::Colorize;
use lazy_static::lazy_static;
use regex::Regex;
Expand Down Expand Up @@ -200,7 +200,7 @@ impl LogOutput {
if let (Some(dest), Some(new_content)) = (&file.destination, &file.content) {
if let Some(content) = filemap.get_mut(dest) {
*content = format!("{}\n\n{}", content, new_content);
} else {
} else if file.format != Format::JSON {
filemap.insert(dest, format!("# generated by rudderc\n{}", new_content));
}
file.content = None;
Expand Down
Loading

0 comments on commit 521e75b

Please sign in to comment.