use std::env::current_dir;
use std::fs::{create_dir_all, File};
use std::io::{Read, Write};
use std::path::PathBuf;
use std::process::exit;
use clap::{crate_authors, crate_description, crate_version, App, AppSettings, Arg, SubCommand};
use spandex::config::Config;
use spandex::{build, Error};
macro_rules! unwrap {
($e: expr, $error: expr) => {
match $e {
Some(e) => e,
None => return Err($error),
}
};
}
fn main() {
if let Err(e) = run() {
eprintln!("{}", e);
exit(1);
}
}
fn run() -> Result<(), Error> {
let mut app = App::new("SpanDeX")
.bin_name("spandex")
.version(crate_version!())
.author(crate_authors!("\n"))
.about(crate_description!())
.setting(AppSettings::ColoredHelp)
.subcommand(
SubCommand::with_name("init")
.about("Creates a new default SpanDeX project")
.arg(Arg::with_name("TITLE").required(false)),
)
.subcommand(SubCommand::with_name("build").about("Builds the SpanDeX project"));
let matches = app.clone().get_matches();
if let Some(init) = matches.subcommand_matches("init") {
let mut current_dir =
PathBuf::from(unwrap!(current_dir().ok(), Error::CannotReadCurrentDir));
let current_dir_name = current_dir.clone();
let current_dir_name = unwrap!(current_dir_name.file_name(), Error::CannotReadCurrentDir);
let current_dir_name = unwrap!(current_dir_name.to_str(), Error::CannotReadCurrentDir);
let title = match init.value_of("TITLE") {
Some(title) => {
current_dir.push(title);
title
}
None => current_dir_name,
};
create_dir_all(¤t_dir).ok();
let config = Config::with_title(title);
let toml = toml::to_string(&config).expect("Failed to generate toml");
current_dir.push("spandex.toml");
let mut file = File::create(¤t_dir)?;
file.write(toml.as_bytes())?;
current_dir.pop();
current_dir.push("main.dex");
let mut file = File::create(¤t_dir)?;
file.write("# Hello world".as_bytes())?;
} else if let Some(_) = matches.subcommand_matches("build") {
let mut current_dir =
PathBuf::from(unwrap!(current_dir().ok(), Error::CannotReadCurrentDir));
let config_path = loop {
current_dir.push("spandex.toml");
if current_dir.is_file() {
break current_dir;
} else {
current_dir.pop();
if !current_dir.pop() {
return Err(Error::NoConfigFile);
}
}
};
let mut file = File::open(&config_path)?;
let mut content = String::new();
file.read_to_string(&mut content)?;
let config: Config = toml::from_str(&content).expect("Failed to parse toml");
build(&config)?;
} else {
app.print_help().ok();
println!();
}
Ok(())
}