Skip to content

Commit

Permalink
Work in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
gpoblon committed Feb 25, 2020
1 parent 4d0db7f commit eda58a5
Show file tree
Hide file tree
Showing 16 changed files with 150 additions and 192 deletions.
5 changes: 3 additions & 2 deletions rudder-lang/README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ The compiler is very pedantic to avoid defining invalid states as much as possib

=== Required modules
- perl (script: *src/generate-lib*)
`cpan Config::IniFiles`
`cpan TOML::Parser`

=== Configuration
- *cfg.ini* to define the cfengine and ncf binaries paths
- *cfg.toml* to define the cfengine and ncf binaries paths, and the compilation, translation paths
(will require to install the `toml` library: `pip3 install toml`)
7 changes: 7 additions & 0 deletions rudder-lang/libs/cfg.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[default_paths]
ncf="/usr/share/ncf"
cfengine="/opt/rudder/bin/cf-promises"
compile_input="tests/test_files/rl/"
compile_output="tests/test_files/target/"
translate_input="tests/test_files/json/"
translate_output="tests/test_files/target/"
7 changes: 4 additions & 3 deletions rudder-lang/libs/generate-lib
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@ use warnings;
use strict;
use warnings;
use strict;
use Config::IniFiles;
use TOML::Parser;

my %resource = ();
my @state = ();
my @config_lines=();

my $cfg = Config::IniFiles->new( -file => "./cfg.ini" );
my $ncf_methods = $cfg->val( 'default_paths', 'ncf' ) . "/tree/30_generic_methods/*";
my $parser = TOML::Parser->new;
my $cfg = $parser->parse_file("./cfg.toml");

my $ncf_methods = $cfg->{default_paths}->{ncf} . "/tree/30_generic_methods/*";
foreach my $file (glob $ncf_methods) {
# file exclusion
next if $file=~ /\/_/;
Expand Down
22 changes: 11 additions & 11 deletions rudder-lang/libs/stdlib.rl
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
@format=0


resource http(p0)
resource environment(p0)
resource service(p0)
resource sharedfile(p0)
resource user(p0)
resource group(p0)
resource permissions(p0)
resource variable(p0,p1)
resource monitoring(p0)
resource http(p0)
resource command(p0)
resource group(p0)
resource schedule(p0)
resource file(p0)
resource user(p0)
resource directory(p0)
resource kernel_module(p0)
resource package(p0)
resource monitoring(p0)
resource file(p0)
resource variable(p0,p1)
resource service(p0)
resource sharedfile(p0)
resource environment(p0)
resource schedule(p0)
resource condition(p0)
resource kernel_module(p0)

command state execution(){}
command state execution_once(p1,p2,p3){}
Expand Down
101 changes: 0 additions & 101 deletions rudder-lang/libs/tmp.rl

This file was deleted.

2 changes: 1 addition & 1 deletion rudder-lang/libs/translate_config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -175,4 +175,4 @@ variable_string_default = { class_prefix="variable_string_default", class_parame
variable_string_from_command = { class_prefix="variable_string_from_command", class_parameter_id = 1 }
variable_string_from_file = { class_prefix="variable_string_from_file", class_parameter_id = 1 }
variable_string_from_math_expression = { class_prefix="variable_string_from_math_expression", class_parameter_id = 1 }
variable_string_match = { class_prefix="variable_string_match", class_parameter_id = 0 }
variable_string_match = { class_prefix="variable_string_match", class_parameter_id = 0 }
50 changes: 23 additions & 27 deletions rudder-lang/src/bin/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use log::*;
use std::path::PathBuf;
use structopt::StructOpt;

use rudderc::{compile::compile_file, logger, translate::translate_file};
use rudderc::{ compile::compile_file, file_paths, logger, translate::translate_file };

///! Principle:
///! 1- rl -> PAST::add_file() -> PAST
Expand All @@ -32,6 +32,13 @@ use rudderc::{compile::compile_file, logger, translate::translate_file};
// - arguments non ordonnés pour les resources et les states ?
// - usage des alias: pour les children, pour les (in)compatibilités, pour le générateur?

// Next steps:
//
//

// TODO a state S on an object A depending on a condition on an object B is invalid if A is a descendant of B
// TODO except if S is the "absent" state

/// Usage example (long / short version):
/// cargo run -- --compile --input tests/compile/s_basic.rl --output tests/target/s_basic.rl --log-level debug --json-log-fmt
/// cargo run -- -c -i tests/compile/s_basic.rl -o tests/target/s_basic.rl -l debug -j
Expand All @@ -47,7 +54,7 @@ use rudderc::{compile::compile_file, logger, translate::translate_file};
#[derive(Debug, StructOpt)]
#[structopt(rename_all = "kebab-case")]
struct Opt {
/// use default path for input/output file or directory and concat the path (filename)
/// use default directory for input/output with the specified filename
#[structopt(long, short)]
default: Option<PathBuf>,
/// Output file or directory
Expand Down Expand Up @@ -79,33 +86,28 @@ fn main() {
// easy option parsing
let opt = Opt::from_args();

let mut input = PathBuf::new();
let mut output = PathBuf::new();
if let Some(input_path) = opt.input {
input = input_path;
}
if let Some(output_path) = opt.output {
output = output_path;
}
// if opt.default.is_some() {
// unimplemented!();
// } else if opt.input.is_none() || opt.output.is_none() {
// error!("No path specified");
// return ;
// }

let exec_action = if opt.compile { "compile" } else { "translate" };
// compile should be the default case, so if none of compile / translate is passed -> compile
let is_compile_default = if !opt.translate { true } else { false };
let exec_action = if is_compile_default { "compile" } else { "translate" };

logger::set(
opt.log_level,
opt.json_log_fmt,
&input,
&output,
&exec_action,
);

// if input / output file are not set, panic seems ok since nothing else can be done,
// including printing the output closure properly
let (input, output) = file_paths::get(exec_action, &opt.default, &opt.input, &opt.output).unwrap();
println!("input = {:?}, output = {:?}", input, output);
let result;
if opt.translate {
if is_compile_default {
result = compile_file(&input, &output, is_compile_default);
match &result {
Err(e) => error!("{}", e),
Ok(_) => info!("{} {}", "Compilation".bright_green(), "OK".bright_cyan()),
}
} else {
result = translate_file(&input, &output);
match &result {
Err(e) => error!("{}", e),
Expand All @@ -115,12 +117,6 @@ fn main() {
"OK".bright_cyan()
),
}
} else {
result = compile_file(&input, &output, opt.compile);
match &result {
Err(e) => error!("{}", e),
Ok(_) => info!("{} {}", "Compilation".bright_green(), "OK".bright_cyan()),
}
}

logger::print_output_closure(
Expand Down
79 changes: 79 additions & 0 deletions rudder-lang/src/file_paths.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@

// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2019-2020 Normation SAS

use std::path::PathBuf;

use crate::error::*;

/// get explicit input. If none, get default path + filename. If none, error
fn get_input(exec_action: &str, paths: &toml::Value, opt_default: &Option<PathBuf>, opt_input: &Option<PathBuf>) -> Result<PathBuf> {
Ok(match opt_input {
Some(input) => input.to_path_buf(),
None => match paths.get(format!("{}_input", exec_action)) {
None => return Err(Error::User("There should either be an explicit or default input path".to_owned())),
Some(path) => {
let filename = match opt_default {
Some(filename) => filename,
None => return Err(Error::User("Could not determine output path without input or default defined".to_owned())),
};
PathBuf::from(path.as_str().unwrap()).join(filename)
}
}
})
}

/// get explicit output. If no explicit output get default path + filename. I none, use input path (and update extension). If none worked, error
fn get_output(exec_action: &str, paths: &toml::Value, opt_default: &Option<PathBuf>, opt_input: &Option<PathBuf>, opt_output: &Option<PathBuf>) -> Result<PathBuf> {
Ok(match opt_output {
Some(output) => output.to_path_buf(),
None => {
let path = match opt_default {
Some(filename) => match paths.get(format!("{}_output", exec_action)) {
Some(default_path) => PathBuf::from(default_path.as_str().unwrap()).join(&filename),
// if no default, try to get input path
None => match get_input(exec_action, paths, opt_default, opt_input) {
Ok(input) => input,
Err(_) => return Err(Error::User("Could not determine output path without ouput default or input defined".to_owned())),
},
},
// if no default, try to get input path
None => match get_input(exec_action, paths, opt_default, opt_input) {
Ok(input) => input,
Err(_) => return Err(Error::User("Could not determine output path without ouput default or input defined".to_owned())),
}
};
if exec_action == "compile" {
path.with_extension("rl.cf")
} else {
path.with_extension("json.rl")
}
}
})
}

/// get the correct input and output paths based on parameters
/// Input priority is input > default
/// Output prority is output > default > input
pub fn get(exec_action: &str, opt_default: &Option<PathBuf>, opt_input: &Option<PathBuf>, opt_output: &Option<PathBuf>) -> Result<(PathBuf, PathBuf)> {
// Ease of read closure
let err_gen = |e: &str| Err(Error::User(format!("{}", e)));

let config_filename = "libs/cfg.toml";
let config: toml::Value = match std::fs::read_to_string(config_filename) {
Err(_) => return err_gen("Could not read toml config file"),
Ok(config_data) => match toml::from_str(&config_data) {
Ok(config) => config,
Err(_) => return err_gen("Could not parse (probably faulty) toml config file"),
}
};
let paths = match config.get("default_paths") {
None => return err_gen("No default_path section in toml config file"),
Some(m) => m
};

Ok((
get_input(exec_action, paths, opt_default, opt_input)?,
get_output(exec_action, paths, opt_default, opt_input, opt_output)?,
))
}
4 changes: 3 additions & 1 deletion rudder-lang/src/generators/cfengine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@ impl Generator for CFEngine {
let file_to_create = match file {
Some(filepath) => {
let input_filename = Path::new(sn.file()).file_name();
// println!("filepath = {:?}, /// input_filename = {:?}", filepath.file_name(), input_filename);
if filepath.file_name() != input_filename {
continue;
}
Expand Down Expand Up @@ -413,8 +414,9 @@ impl Generator for CFEngine {
}
}
for (name, content) in files.iter() {
println!("name = {}", name);
let mut file =
File::create(format!("{}.cf", name)).expect("Could not create output file");
File::create(name).expect("Could not create output file");
file.write_all(content.as_bytes())
.expect("Could not write content into output file");
}
Expand Down
1 change: 1 addition & 0 deletions rudder-lang/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ mod ast;
pub mod compile;
mod generators;
pub mod logger;
pub mod file_paths;
mod parser;
pub mod translate;
pub mod generate_oslib;
Loading

0 comments on commit eda58a5

Please sign in to comment.