use godwit::{glyph::Glyph, *};
use log::{debug, error, info};
use simplelog::*;
use std::path::PathBuf;
use structopt::{clap::Shell, StructOpt};
#[derive(Debug, StructOpt)]
#[structopt(
name = "Godwit",
about = "An all-in-one organizational project management utility."
)]
struct CliArgs {
#[structopt(short, long, global = true, conflicts_with = "verbose")]
quiet: bool,
#[structopt(
short,
long,
global = true,
conflicts_with = "quiet",
parse(from_occurrences)
)]
verbose: u64,
#[structopt(
short,
long = "org",
global = true,
// required_unless = "glyph",
// conflicts_with = "glyph"
)]
organization: Option<String>,
#[structopt(
short,
long,
global = true,
// required_unless = "glyph",
// conflicts_with = "glyph"
)]
project: Option<String>,
#[structopt(subcommand)]
operation: Option<OpsEnum>,
}
#[derive(Debug, StructOpt)]
#[structopt(about = "Operation selection")]
enum OpsEnum {
Init {
target: Option<PathBuf>,
#[structopt(long)]
headless: bool,
#[structopt(long)]
refresh: bool,
},
Switch {
#[structopt(required_unless_all = &["project", "organization"], conflicts_with_all = &["project", "organization"])]
glyph: Option<Glyph>,
#[structopt(long)]
default: bool,
},
Add {
#[structopt(required_unless_all = &["project", "organization"], conflicts_with_all = &["project", "organization"])]
glyph: Option<Glyph>,
location: PathBuf,
#[structopt(short, long)]
existing: bool,
#[structopt(long)]
active: bool,
#[structopt(long)]
default: bool,
},
Remove {
#[structopt(required_unless_all = &["project", "organization"], conflicts_with_all = &["project", "organization"])]
glyph: Option<Glyph>,
},
Status,
}
fn get_log_level(quiet: bool, verbosity: u64) -> LevelFilter {
if quiet {
return LevelFilter::Off;
} else if verbosity == 0 || verbosity == 1 {
return LevelFilter::Warn;
} else if verbosity == 2 {
return LevelFilter::Info;
} else if verbosity == 3 {
return LevelFilter::Debug;
} else {
return LevelFilter::Trace;
}
}
fn main() {
CliArgs::clap().gen_completions(env!("CARGO_PKG_NAME"), Shell::Bash, "completions");
CliArgs::clap().gen_completions(env!("CARGO_PKG_NAME"), Shell::Fish, "completions");
CliArgs::clap().gen_completions(env!("CARGO_PKG_NAME"), Shell::PowerShell, "completions");
CliArgs::clap().gen_completions(env!("CARGO_PKG_NAME"), Shell::Zsh, "completions");
let args = CliArgs::from_args();
let (organization, project) = (args.organization, args.project);
let (verbose, verbosity, quiet) = (args.verbose > 0, args.verbose, args.quiet);
CombinedLogger::init(vec![TermLogger::new(
get_log_level(quiet, verbosity),
Config::default(),
TerminalMode::Mixed,
)
.unwrap()])
.unwrap();
match args.operation {
Some(OpsEnum::Init {
target,
headless,
refresh,
}) => {
debug!("Entered init operation.");
match core::init(target, headless, refresh) {
Ok(_) => {
debug!("Init operation passed.");
info!("Looks like we're good to go!");
}
Err(e) => {
debug!("Init operation failed.\n{}", e);
error!(
"Error occured while completing setup for Godwit directories.\n{}",
e
);
}
}
}
Some(OpsEnum::Add {
existing,
glyph,
location,
active,
default,
}) => {
debug!("Entered add operation.");
let glyph = glyph.unwrap_or_else(|| glyph::Glyph {
tag: organization.unwrap_or_default(),
id: project.unwrap_or_default(),
});
debug!("Adding {}", &glyph);
match core::add(glyph, location, existing, active, default) {
Ok(_) => {
debug!("Add operation passed.");
}
Err(e) => {
debug!("Add operation failed.\n{}", e);
error!("Error occured while adding new state.\n{}", e);
}
}
}
Some(OpsEnum::Remove { glyph }) => {
debug!("Entered remove operation.");
let glyph = glyph.unwrap_or_else(|| glyph::Glyph {
tag: organization.unwrap_or_default(),
id: project.unwrap_or_default(),
});
debug!("Removing {}", glyph);
match core::remove(glyph) {
Ok(_) => {
debug!("Remove operation passed.");
}
Err(e) => {
debug!("Remove operation failed.\n{}", e);
error!("Error occured while removing state.\n{}", e);
}
}
}
Some(OpsEnum::Switch { glyph, default }) => {
debug!("Entered switch operation.");
let glyph = glyph.unwrap_or_else(|| glyph::Glyph {
tag: organization.unwrap_or_default(),
id: project.unwrap_or_default(),
});
debug!("Switching to {}", glyph);
match core::switch(glyph, default) {
Ok(_) => {
debug!("Switch operation passed.");
}
Err(e) => {
debug!("Switch operation failed.\n{}", e);
error!("Error occured while switching projects.\n{}", e);
}
}
}
Some(OpsEnum::Status) => {
match core::list() {
Ok(state_list) => {
debug!("Status operation passed.");
iohandler::printer::print_state_graph(state_list, verbose)
.map_err(|e| error!("{:?}", e))
.ok();
}
Err(e) => {
debug!("Status operation failed.\n{}", e);
error!("Error occured while listing projects.\n{}", e);
}
};
}
None => {
match core::runsplash() {
Ok(_) => {
debug!("Returned successfully.");
info!("Godwit exited with success");
}
Err(e) => {
debug!("An exception was thrown.\n{}", e);
error!("Godwit threw an exception.\n{}", e);
}
};
}
}
}