Skip to content

Commit

Permalink
Work in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
gpoblon committed Nov 18, 2020
1 parent 808ea7e commit 907900d
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 34 deletions.
15 changes: 10 additions & 5 deletions rudder-lang/src/generator/dsc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,12 @@ impl DSC {
// let prefix = &self.var_prefixes[var.fragment()];
// // TODO there may still be some conflicts with var or enum containing '_'
// format!("{}_{}_{}", prefix, e.fragment(), item.fragment())
format!("{}_{}", var.fragment(), item.fragment())
// format!("{}_{}", var.fragment(), item.fragment())
format!(
r#"{}_${{report_data.canonified_directive_id}}_{}"#,
var.fragment(),
item.fragment()
)
}
}
EnumExpressionPart::RangeCompare(_var, _e, _item1, _item2) => unimplemented!(), // TODO
Expand Down Expand Up @@ -412,8 +417,8 @@ impl Generator for DSC {

// get parameters, default params are hardcoded for now
let mut formatted_parameters: Vec<String> = vec![
"[Parameter(Mandatory=$True)]\n [String] $ReportId".to_owned(),
"[Parameter(Mandatory=$True)]\n [String] $TechniqueName".to_owned(),
"[Parameter(Mandatory=$True)]\n [String]$ReportId".to_owned(),
"[Parameter(Mandatory=$True)]\n [String]$TechniqueName".to_owned(),
];
// ad gm parameters
formatted_parameters.extend(
Expand All @@ -423,7 +428,7 @@ impl Generator for DSC {
.chain(state.parameters.iter())
.map(|p| {
format!(
"[Parameter(Mandatory=$True)]\n [{}] ${}",
"[Parameter(Mandatory=$True)]\n [{}]${}",
&self.format_param_type(&p.type_),
pascebab_case(p.name.fragment())
)
Expand All @@ -432,7 +437,7 @@ impl Generator for DSC {
);
// parameter is not mandatory (implicit)
// Switches should be put last
formatted_parameters.push("[Switch] $AuditOnly".to_owned());
formatted_parameters.push("[Switch]$AuditOnly".to_owned());

let fn_name = format!("{} {}", resource_name.fragment(), state_name.fragment(),);

Expand Down
15 changes: 9 additions & 6 deletions rudder-lang/src/generator/dsc/syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -429,11 +429,13 @@ impl Call {
.iter()
.map(|(attr_type, content)| {
let fmt_call = match (attr_type, &self.variable) {
(CallType::If(call), _) => format!(
"$Class = {}\nif (Evaluate-Class $Class $LocalClasses $SystemClasses) {{{}\n}}",
content.as_ref().unwrap(),
call
),
(CallType::If(call), _) => {
format!(
"$Class = {}\nif (Evaluate-Class $Class $LocalClasses $SystemClasses) {{{}\n}}",
content.as_ref().unwrap(),
call
)
},
(CallType::Else(call), _) => format!("else {{{}\n}}", call),
(_, Some(var)) => format!("{} = {}", var, content.as_ref().unwrap()),
(_, None) => content.as_ref().unwrap().to_owned()
Expand Down Expand Up @@ -577,9 +579,10 @@ impl Method {
"canonify(\"${{class_prefix}}_{}_{}_{}\")",
self.resource, self.state, self.class_parameter.value
);
let condition_format = method_call.format();
vec![
Call::new()
.if_condition(self.condition.clone(), method_call.format())
.if_condition(self.condition.clone(), condition_format)
.else_condition(&self.condition, na_report.format()),
// Call::method(Parameters::new()
// .class_parameter(self.class_parameter.clone())
Expand Down
14 changes: 14 additions & 0 deletions rudder-lang/src/ir/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,18 @@ impl<'src> StringObject<'src> {
Ok(StringObject { pos, data })
}

pub fn to_string(&self) -> String {
self.data
.iter()
.map(|x| match x {
PInterpolatedElement::Static(s) => s.clone(),
PInterpolatedElement::Variable(s) => format!("${{{}}}", s),
_ => "".into(),
})
.collect::<Vec<String>>()
.concat()
}

pub fn append(&mut self, other: StringObject<'src>) {
self.data.extend(other.data);
}
Expand All @@ -45,8 +57,10 @@ impl<'src> StringObject<'src> {
impl<'src> TryFrom<&StringObject<'src>> for String {
type Error = Error; // rudder-lang

// this should only be called on static variable. But should we ?
fn try_from(value: &StringObject<'src>) -> Result<Self> {
// variable should probably be translated too, keeping ${} wrapper
// for now it cannot because it prevents the compiler from turning an interpolated variable into a string
if value
.data
.iter()
Expand Down
10 changes: 2 additions & 8 deletions rudder-lang/src/technique.rs
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ impl Parameter {
}
}

// generic function that is used by rudderd from multiple places to retrieve parameters in various formats
// generic function that is used by rudder from multiple places to retrieve parameters in various formats
pub fn fetch_method_parameters<F, P>(ir: &IR2, s: &StateDeclaration, f: F) -> Vec<P>
where
F: Fn(&str, &str) -> P,
Expand Down Expand Up @@ -439,13 +439,7 @@ where
.iter()
.chain(s.state_params.iter())
.map(|p| match p {
Value::String(ref o) => {
if let Ok(value) = String::try_from(o) {
return value;
}
let method_name = format!("{}_{}", *s.resource, *s.state);
panic!("Expected string for '{}' parameter type", method_name)
}
Value::String(ref o) => return o.to_string(),
_ => unimplemented!(),
})
.collect::<Vec<String>>();
Expand Down
17 changes: 17 additions & 0 deletions rudder-lang/tests/techniques/condition_dyn/technique.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,23 @@
"category": "ncf_technioues",
"parameter": [],
"method_calls": [
{
"parameters": [
{
"name": "condition_prefix",
"value": "skip_item_${report_data.canonified_directive_id}",
"$errors": []
},
{
"name": "variable_name",
"value": "node.properties[skip][${report_data.directive_id}]",
"$errors": []
}
],
"class_context": "any",
"method_name": "condition_from_variable_existence",
"component": "condition_from_variable_existence"
},
{
"class_context": "any.(skip_item_${report_data.canonified_directive_id}_false)",
"component": "Command execution",
Expand Down
2 changes: 2 additions & 0 deletions rudder-lang/tests/techniques/condition_dyn/technique.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ function Condition-Dyn {
$local_classes = New-ClassContext
$resources_dir = $PSScriptRoot + "\resources"

$local_classes = Merge-ClassContext $local_classes $(Condition-From-Variable-Existence -Condition "skip_item_${report_data.canonified_directive_id}" -VariableName "node.properties[skip][${report_data.directive_id}]" -componentName "condition_from_variable_existence" -reportId $reportId -techniqueName $techniqueName -auditOnly:$auditOnly).get_item("classes")

$class = "any.(skip_item_${report_data.canonified_directive_id}_false)"
if (Evaluate-Class $class $local_classes $system_classes) {
$local_classes = Merge-ClassContext $local_classes $(Command-Execution -Command "pwd" -componentName "Command execution" -reportId $reportId -techniqueName $techniqueName -auditOnly:$auditOnly).get_item("classes")
Expand Down
43 changes: 28 additions & 15 deletions rudder-lang/tools/cfjson_tester
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,13 @@ def load_dsc(filename):
is_powershell_string = False
is_block_comment = False
purged_content = []
original = []
line_index = 0
for line in f:
purged_line = ""
original_line = ""
last_char=''
line_index += 1
for char in line:
if char == '#' and last_char == '<' and is_powershell_string is False:
is_block_comment = True
Expand All @@ -118,11 +122,21 @@ def load_dsc(filename):
break
elif char == "'" or char == '"':
is_powershell_string != is_powershell_string
purged_line += char
elif char == "{" and last_char == "$": # ie is interpolated within a string
is_powershell_string != is_powershell_string
elif char == "}" and last_char != "\\": # ie is interpolated within a string
is_powershell_string != is_powershell_string

if not is_powershell_string:
purged_line += char_cleaner(char)
else:
purged_line += char
original_line += char
last_char = char
# remove starting/ending whitespaces
purged_line = purged_line.strip()
if len(purged_line):
original.append({ 'content': original_line, 'line': line_index })
# TODO put this somewhere else, in a proper updated function
# split in two lines (diff)
condition = re.search('\$class = "any\.\((?P<condition>.+)\)"', purged_line)
Expand All @@ -131,30 +145,29 @@ def load_dsc(filename):
elif purged_line == "} else {":
purged_content.append("}")
purged_content.append("else {")
original.append({ 'content': purged_line, 'line': line_index }) # line added 2 times to compensate for the added line to purged_content
else:
purged_content.append(purged_line)
last_char = char
return purged_content
return (original, purged_content)

# casefold make the string entirely lowercase, spaces, '_' and '-' are removed
# casefold make the char is lowercase, spaces, '_' and '-' are removed
# since powershell rules are not restrictives, these differences does not matter
def line_cleaner(line):
return line.casefold().replace('-', '').replace('_', '').replace(' ', '')
def char_cleaner(char):
return char.casefold().replace('-', '').replace('_', '')

def get_diffs_dsc(original, generated):
def get_diffs_dsc(base_original, base_purged_content, generated_original, generated_purged_content):
diff = list()
for (index, original_line) in enumerate(original):
oline = line_cleaner(original_line)
gline = line_cleaner(generated[index])
if oline != gline \
and original_line.replace(" {", "-Technique {") != generated[index]:
diff.append({ "expected_token": original_line, "generated_token": generated[index] })
for (index, base_purged_line) in enumerate(base_purged_content):
if base_purged_line != generated_purged_content[index] \
and base_purged_line.replace(" {", "technique {") != generated_purged_content[index]:
diff.append({ "expected": base_original[index], "generated": generated_original[index] })
return diff

def compare_dsc(original_filename, generated_filename):
original = load_dsc(original_filename)
generated = load_dsc(generated_filename)
diff = get_diffs_dsc(original, generated)
(base_original, base_purged) = load_dsc(original_filename)
(generated_original, generated_purged) = load_dsc(generated_filename)
diff = get_diffs_dsc(base_original, base_purged, generated_original, generated_purged)
if diff and len(diff) != 0:
print_json("compare_dsc", generated_filename, diff)
exit(1)
Expand Down

0 comments on commit 907900d

Please sign in to comment.