Skip to content

Commit

Permalink
Merge pull request #1 from dottorblaster/implement-json-output
Browse files Browse the repository at this point in the history
Implement JSON output for better interoperability
  • Loading branch information
dottorblaster authored Dec 12, 2018
2 parents 9b975d4 + 73671a5 commit b36d873
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 25 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "siren"
version = "1.0.3"
version = "1.1.0"
authors = ["Alessio Biancalana <dottorblaster@gmail.com>"]
description = "Your friendly neighborhood monitoring CLI tool."
homepage = "https://github.com/dottorblaster/siren"
Expand Down
65 changes: 44 additions & 21 deletions src/execute.rs
Original file line number Diff line number Diff line change
@@ -1,54 +1,77 @@
extern crate ansi_term;
extern crate serde_json;

use parse_config::Task;
use task_output::SerializableOutput;
use task_output;
use std::sync::{Mutex, Arc};
use std::thread;
use std::process::Command;
use std::process::Output;

use self::ansi_term::Colour::{Red, Green, Yellow, Black};
use self::ansi_term::ANSIString;

fn task_success(task: Task, output: Output) {
let stdout = ANSIString::from(String::from_utf8(output.stdout).unwrap());
println!(
"{} {}\n{}\n",
Black.bold().on(Green).paint(" SUCCESS "),
Yellow.paint(format!("{}", task.name)),
stdout
);
fn task_success(task: Task, output: Output, json: bool) {
if json == false {
let stdout = ANSIString::from(String::from_utf8(output.stdout).unwrap());
println!(
"{} {}\n{}\n",
Black.bold().on(Green).paint(" SUCCESS "),
Yellow.paint(format!("{}", task.name)),
stdout
);
}
}

fn task_failure(task: Task, output: Output) {
let stderr = ANSIString::from(String::from_utf8(output.stderr).unwrap());
println!(
"{} {}\n{}\n",
Black.bold().on(Red).paint(" FAIL "),
Yellow.paint(format!("{}", task.name)),
stderr
);
fn task_failure(task: Task, output: Output, json: bool) {
if json == false {
let stderr = ANSIString::from(String::from_utf8(output.stderr).unwrap());
println!(
"{} {}\n{}\n",
Black.bold().on(Red).paint(" FAIL "),
Yellow.paint(format!("{}", task.name)),
stderr
);
}
}

fn print_json(outputs: Arc<Mutex<Vec<task_output::TaskOutput>>>, json: bool) {
if json == true {
let slice = &*outputs.lock().unwrap();
let serializable_output = SerializableOutput { tasks: slice.to_vec() };
println!("{}", serde_json::to_string(&serializable_output).unwrap());
}
}

pub fn run(tasks: Vec<Task>, cwd_path: String) -> bool {
pub fn run(tasks: Vec<Task>, cwd_path: String, json_output: bool) -> bool {
let outputs = Arc::new(Mutex::new(task_output::Tasks::with_capacity(tasks.len())));
let mut handles = Vec::with_capacity(tasks.len());
println!("\n");
for task in &tasks {
let (data, path) = (task.clone(), cwd_path.clone());
let outputs = Arc::clone(&outputs);
let child = thread::spawn(move || {
let local_task = data.clone();
let task_data = data.clone();
let mut iter = local_task.command.split_whitespace();
let output = Command::new(iter.nth(0).unwrap())
let mut list = outputs.lock().unwrap();
let command_output = Command::new(iter.nth(0).unwrap())
.args(iter)
.current_dir(path)
.output()
.expect("command failed");
match output.status.code() {
Some(0) => task_success(data, output),
Some(_) => task_failure(data, output),
let cloned_output = command_output.clone();
list.push(task_output::build_task_output(cloned_output, task_data));
match command_output.status.code() {
Some(0) => task_success(data, command_output, json_output),
Some(_) => task_failure(data, command_output, json_output),
None => println!("Process terminated by signal")
}
});
handles.push(child);
}
for handle in handles { handle.join().unwrap(); }
print_json(outputs, json_output);
true
}
12 changes: 10 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use clap::{Arg, App};

mod parse_config;
mod execute;
mod task_output;

fn parentpath(path: String) -> String {
let mut v: Vec<&str> = path.split("/").collect();
Expand All @@ -30,7 +31,7 @@ fn read_sirenfile(sirenfile_path: String) -> Result<String, IoError> {

fn main() {
let matches = App::new("Siren")
.version("1.0.3")
.version("1.1.0")
.author("Alessio Biancalana <dottorblaster@gmail.com>")
.about("Your tiny friendly rusty neighborhood monitoring CLI tool")
.arg(Arg::with_name("file")
Expand All @@ -39,9 +40,16 @@ fn main() {
.value_name("FILE")
.help("Sets a custom Sirenfile")
.takes_value(true))
.arg(Arg::with_name("json-output")
.short("j")
.long("json-output")
.value_name("JSON")
.help("Enable JSON output")
.takes_value(false))
.get_matches();

let sirenfile_path = matches.value_of("file").unwrap_or("./Sirenfile.json").to_owned();
let output_json = matches.is_present("json-output");

let configstring = match read_sirenfile(sirenfile_path) {
Ok(jsoncontent) => jsoncontent,
Expand All @@ -55,5 +63,5 @@ fn main() {
true => parentpath(matches.value_of("file").unwrap_or("./Sirenfile.json").to_owned()),
false => String::from(".")
};
execute::run(conf.tasks, cwd_path);
execute::run(conf.tasks, cwd_path, output_json);
}
31 changes: 31 additions & 0 deletions src/task_output.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
extern crate serde;
extern crate serde_json;

use parse_config::Task;
use std::process::Output;

#[derive(Serialize, Clone)]
pub struct TaskOutput {
pub outcome: String,
pub code: String,
pub name: String,
pub description: String,
pub command: String,
}

pub type Tasks = Vec<TaskOutput>;

#[derive(Serialize, Clone)]
pub struct SerializableOutput {
pub tasks: Vec<TaskOutput>,
}

pub fn build_task_output(output: Output, task: Task) -> TaskOutput {
TaskOutput {
outcome: String::from_utf8(output.stdout).unwrap(),
code: output.status.code().unwrap().to_string(),
name: task.name,
description: task.description,
command: task.command,
}
}

0 comments on commit b36d873

Please sign in to comment.