use anyhow::{Context, Error};
use bigml::resource;
use futures::executor::block_on;
use futures::FutureExt;
use std::{
env,
io::{self, Write},
process, result,
str::FromStr,
};
use tracing::debug;
use tracing_subscriber::{
fmt::{format::FmtSpan, Subscriber},
prelude::*,
EnvFilter,
};
pub type Result<T, E = Error> = result::Result<T, E>;
fn helper(
script_id: &str,
inputs: &[(String, String)],
outputs: &[String],
) -> Result<()> {
let bigml_username = env::var("BIGML_USERNAME")
.context("pass BIGML_USERNAME as an environment variable")?;
let bigml_api_key = env::var("BIGML_API_KEY")
.context("pass BIGML_API_KEY as an environment variable")?;
let client = bigml::Client::new(bigml_username, bigml_api_key)?;
let mut args = resource::execution::Args::default();
args.set_script(resource::Id::<resource::Script>::from_str(script_id)?);
for &(ref name, ref value) in inputs {
args.add_input(name.to_owned(), value)?;
}
for name in outputs {
args.add_output(name.to_owned());
}
let execution = block_on(client.create_and_wait(&args).boxed())?;
println!("{:#?}", execution);
Ok(())
}
fn usage() -> ! {
writeln!(
&mut io::stderr(),
"\
Usage: create_execution <SCRIPT_ID> <INPUT>=<VALUE>... --output=<NAME>..."
)
.expect("can't write to stderr, giving up");
process::exit(1);
}
fn main() {
let filter = EnvFilter::from_default_env();
Subscriber::builder()
.with_writer(std::io::stderr)
.with_span_events(FmtSpan::NEW | FmtSpan::CLOSE)
.with_env_filter(filter)
.finish()
.init();
let mut script_id = None;
let mut inputs = vec![];
let mut outputs = vec![];
let mut first = true;
for arg in env::args().skip(1) {
if first {
first = false;
debug!("script_id: {}", &arg);
script_id = Some(arg);
} else {
let chunks = arg.splitn(2, '=').collect::<Vec<_>>();
debug!("parsing: {} = {}", chunks[0], chunks[1]);
if chunks.len() == 2 {
if chunks[0] == "--output" {
outputs.push(chunks[1].to_owned());
} else {
inputs.push((chunks[0].to_owned(), chunks[1].to_owned()));
}
} else {
usage();
}
}
}
let script_id = match script_id {
Some(script_id) => script_id,
None => usage(),
};
if let Err(err) = helper(&script_id, &inputs, &outputs) {
eprint!("ERROR");
for e in err.chain() {
eprint!(": {}", e);
}
eprintln!();
eprintln!("{:?}", err.backtrace());
process::exit(1);
}
}