diff --git a/bin/core/imag/Cargo.toml b/bin/core/imag/Cargo.toml index c37f1f7a..6846d2b4 100644 --- a/bin/core/imag/Cargo.toml +++ b/bin/core/imag/Cargo.toml @@ -25,6 +25,8 @@ version = "2.0" walkdir = "0.1" clap = "2.*" log = "0.3" +toml = "0.4" +toml-query = "0.3" libimagrt = { version = "0.4.0", path = "../../../lib/core/libimagrt" } libimagerror = { version = "0.4.0", path = "../../../lib/core/libimagerror" } diff --git a/bin/core/imag/src/main.rs b/bin/core/imag/src/main.rs index b9e4ab45..f6ae33f1 100644 --- a/bin/core/imag/src/main.rs +++ b/bin/core/imag/src/main.rs @@ -21,6 +21,8 @@ extern crate clap; #[macro_use] extern crate version; #[macro_use] extern crate log; extern crate walkdir; +extern crate toml; +extern crate toml_query; extern crate libimagrt; extern crate libimagerror; @@ -30,9 +32,12 @@ use std::process::exit; use std::process::Command; use std::process::Stdio; use std::io::ErrorKind; +use std::collections::BTreeMap; use walkdir::WalkDir; use clap::{Arg, AppSettings, SubCommand}; +use toml::Value; +use toml_query::read::TomlValueReadExt; use libimagrt::runtime::Runtime; use libimagerror::trace::trace_error; @@ -176,6 +181,16 @@ fn main() { exit(0); } + let aliases = match fetch_aliases(&rt) { + Ok(aliases) => aliases, + Err(e) => { + println!("Error while fetching aliases from configuration file"); + debug!("Error = {:?}", e); + println!("Aborting"); + exit(1); + } + }; + // Matches any subcommand given match matches.subcommand() { (subcommand, Some(scmd)) => { @@ -187,6 +202,9 @@ fn main() { None => Vec::new() }; + let subcommand = String::from(subcommand); + let subcommand = aliases.get(&subcommand).cloned().unwrap_or(subcommand); + debug!("Calling 'imag-{}' with args: {:?}", subcommand, subcommand_args); // Create a Command, and pass it the gathered arguments @@ -232,3 +250,49 @@ fn main() { _ => {}, } } + +fn fetch_aliases(rt: &Runtime) -> Result, String> { + let cfg = try!(rt.config().ok_or_else(|| String::from("No configuration found"))); + let value = cfg + .config() + .read("imag.aliases") + .map_err(|_| String::from("Reading from config failed")); + + match try!(value) { + None => Ok(BTreeMap::new()), + Some(&Value::Table(ref tbl)) => { + let mut alias_mappings = BTreeMap::new(); + + for (k, v) in tbl { + match v { + &Value::String(ref alias) => { + alias_mappings.insert(alias.clone(), k.clone()); + }, + &Value::Array(ref aliases) => { + for alias in aliases { + match alias { + &Value::String(ref s) => { + alias_mappings.insert(s.clone(), k.clone()); + }, + _ => { + let e = format!("Not all values are a String in 'imag.aliases.{}'", k); + return Err(e); + } + } + } + }, + + _ => { + let msg = format!("Type Error: 'imag.aliases.{}' is not a table or string", k); + return Err(msg); + }, + } + } + + Ok(alias_mappings) + }, + + Some(_) => Err(String::from("Type Error: 'imag.aliases' is not a table")), + } +} + diff --git a/imagrc.toml b/imagrc.toml index 955f5238..0c6a90a7 100644 --- a/imagrc.toml +++ b/imagrc.toml @@ -1,6 +1,20 @@ # This is a example configuration file for the imag suite. # It is written in TOML +# The alias section +# +# In this section one can define aliases for imag subcommands. +# +# E.G: An alias `store = [ "s", "st" ]` allows the user to call `imag s` or +# `imag st` for calling `imag store`. +# +# The aliases have to be either a single string or an array of strings, where no +# string contains whitespace (thus, aliasing a "store-create" call to "sc" for +# example is not supported). +# +[imag.aliases] +store = [ "s", "st" ] + [imag.logging] level = "debug" destinations = [ "-" ]