Skip to content

Commit

Permalink
update err for input mismatch
Browse files Browse the repository at this point in the history
  • Loading branch information
bartvanbenthem committed Jul 4, 2023
1 parent 2806154 commit 9fca2d8
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 36 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ handlebars = "4.3.7"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
clap = "2.33"
serde_yaml = "0.8"
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# manifestgen-rs
CLI tool for generating configuration manifests.
CLI tool for generating configuration manifests. Both JSON and YAML are valid input types that can be converted from template to manifest.

# usage manual
```bash
Expand Down Expand Up @@ -27,10 +27,16 @@ OPTIONS:
# read variables from stdin and write manifest to a file
cat project/example-var.json | ./target/debug/manifestgen -t project/targets.tmpl -o project/config.yaml

# read variables from a file and write manifest to stdout
# read JSON variables from a file and write manifest to stdout
./target/debug/manifestgen -v project/example-var.json -t project/targets.tmpl

# read variables from stdin and write manifest to stdout
# read YAML variables from a file and write manifest to stdout
./target/debug/manifestgen -v project/example-var.yaml -t project/targets.tmpl

# read JSON variables from stdin and write manifest to stdout
cat project/example-var.json | ./target/debug/manifestgen --template project/targets.tmpl

# read YAML variables from stdin and write manifest to stdout
cat project/example-var.yaml | ./target/debug/manifestgen --template project/targets.tmpl

```
4 changes: 2 additions & 2 deletions project/example-var.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"policy_name": "test-policy",
"pool_name": "poc-pool"
"policy_name": "test-policy-json-input",
"pool_name": "poc-pool-json-input"
}
4 changes: 2 additions & 2 deletions project/example-var.yaml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
policy_name: test-policy
pool_name: poc-pool
policy_name: test-policy-yaml-input
pool_name: poc-pool-yaml-input
1 change: 1 addition & 0 deletions project/invalid-input
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dfgyyrtyhdhfgh
4 changes: 3 additions & 1 deletion run.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#!/bin/bash
cargo test
cargo build

# run example to stdout
cat project/example-var.json | ./target/debug/manifestgen --template project/targets.tmpl
#cat project/example-var.yaml | ./target/debug/manifestgen --template project/targets.tmpl
#cat project/example-var.yaml | ./target/debug/manifestgen --template project/targets.tmpl
#cat project/invalid-input | ./target/debug/manifestgen --template project/targets.tmpl
101 changes: 73 additions & 28 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use std::collections::BTreeMap;
use std::fs;
use serde::{Deserialize, Serialize};
use serde_json;
use serde_json::{Value};
use serde_yaml;
use std::env;
use std::error::Error;
use std::io::{self, Read, Write};
use std::process;

use handlebars::Handlebars;
use clap::{App, Arg};
Expand All @@ -19,33 +21,21 @@ struct Config {
variables_file: String,
}


fn main() -> Result<(), Box<dyn Error>> {
// Get command-line arguments
let config = get_args().unwrap();

// initialize KeyValuePair type
let key_value_pairs: KeyValuePairs;

if config.variables_file.is_empty() {
// Process the JSON value trough stdin
let mut input = String::new();
io::stdin().read_to_string(&mut input)?;
key_value_pairs = serde_json::from_str(&input)?;
} else {
// Read JSON file
let json_content = fs::read_to_string(config.variables_file)?;
key_value_pairs = serde_json::from_str(&json_content)?;
}

// Load template file
let template_content = fs::read_to_string(config.template_file)?;

// Initialize the templating engine
let mut handlebars = Handlebars::new();
handlebars.register_template_string("template", &template_content)?;
let input_type_result = parse_input_type(&config);
let input_type = match input_type_result {
Ok(input_type) => input_type,
Err(_) => {
eprintln!("No valid JSON or YAML input type, restart the Manifestgen with valid input!");
process::exit(1)
},
};

// Render the template
let rendered_template = handlebars.render("template", &key_value_pairs.0)?;
let rendered_template = render_config(&input_type, &config)?;

// write to disk or stdout based on the provided output param
if let Err(err) = manifest_writer(&config.output_file, &rendered_template) {
Expand Down Expand Up @@ -93,6 +83,66 @@ fn get_args() -> Result<Config, Box<dyn Error>> {
})
}

fn parse_input_type(config: &Config) -> Result<KeyValuePairs, Box<dyn Error>> {
// initialize KeyValuePair type
let key_value_pairs: KeyValuePairs;

if config.variables_file.is_empty() {
// Process the JSON value trough stdin
let mut input = String::new();
io::stdin().read_to_string(&mut input)?;
if is_valid_json(&input) {
key_value_pairs = serde_json::from_str(&input)?;
} else if is_valid_yaml(&input){
key_value_pairs = serde_yaml::from_str(&input)?;
} else {
panic!("No valid JSON or YAML input type!")
}
} else {
// Read JSON file
let var_file = fs::read_to_string(&config.variables_file)?;
if is_valid_json(&var_file) {
key_value_pairs = serde_json::from_str(&var_file)?;
} else if is_valid_yaml(&var_file){
key_value_pairs = serde_yaml::from_str(&var_file)?;
} else {
panic!("No valid JSON or YAML input type!")
}
}

Ok(key_value_pairs)

}

fn is_valid_json(input: &str) -> bool {
match serde_json::from_str::<Value>(input) {
Ok(_) => true,
Err(_) => false,
}
}

fn is_valid_yaml(input: &str) -> bool {
match serde_yaml::from_str::<Value>(input) {
Ok(_) => true,
Err(_) => false,
}
}

// --------------------------------------------------
fn render_config(key_value_pairs: &KeyValuePairs, config: &Config) -> Result<String, Box<dyn Error>> {
// Load template file
let template_content = fs::read_to_string(&config.template_file)?;

// Initialize the templating engine
let mut handlebars = Handlebars::new();
handlebars.register_template_string("template", &template_content)?;

// Render the template
let rendered_template = handlebars.render("template", &key_value_pairs.0)?;

Ok(rendered_template)
}

// --------------------------------------------------
fn manifest_writer(output: &String, template: &String) -> Result<(), Box<dyn Error>> {
if output.is_empty() {
Expand All @@ -115,11 +165,6 @@ fn manifest_writer(output: &String, template: &String) -> Result<(), Box<dyn Err
Ok(())
}

//fn yaml_to_json(cfg: &Config) -> Result<(), Box<dyn Error>> {
//
// Ok(())
//}

// --------------------------------------------------
fn print_current_dir() {
if let Ok(current_dir) = env::current_dir() {
Expand Down

0 comments on commit 9fca2d8

Please sign in to comment.