mod commands;
mod confirm;
mod context;
mod environments;
mod notifier;
mod test_utils;
mod usage_stats;
use anyhow::Context;
use clap::Parser;
use commands::activate::{ActivateArgs, activate};
use commands::browser::{BrowserArgs, browser};
use commands::env_info::{EnvInfoArgs, env_info};
use commands::kanban::{KanbanArgs, kanban};
use commands::ls::{LsArgs, ls};
use commands::mark::{MarkArgs, mark};
use commands::prep::{PrepArgs, prep};
use commands::rm::{RmArgs, rm};
use commands::run::{RunArgs, run};
use commands::run_gear;
use commands::run_gear::{ENV_FLAG, LONG_YES_FLAG, SHORT_YES_FLAG};
use commands::wrap::{WrapArgs, wrap};
use context::CommandContext;
use enwiro_daemon::ConfigurationValues;
use std::ffi::OsString;
use std::fs::create_dir;
use std::io::Write;
use std::path::Path;
#[derive(Parser)]
struct Cli {
#[arg(global = true, long)]
env: Option<String>,
#[command(subcommand)]
command: EnwiroCli,
}
#[derive(clap::Subcommand)]
enum EnwiroCli {
Activate(ActivateArgs),
#[command(hide = true)]
Browser(BrowserArgs),
Info(EnvInfoArgs),
Kanban(KanbanArgs),
Ls(LsArgs),
Mark(MarkArgs),
Prep(PrepArgs),
Rm(RmArgs),
Run(RunArgs),
Wrap(WrapArgs),
}
fn ensure_can_run<W: Write>(config: &CommandContext<W>) -> anyhow::Result<()> {
let environments_directory = Path::new(&config.config.workspaces_directory);
if !environments_directory.exists() {
create_dir(environments_directory).context(
"Workspace directory does not exist and could not be automatically created.",
)?;
}
Ok(())
}
fn is_dispatch_invocation(argv: &[OsString]) -> bool {
let mut pos = 1;
if argv.get(pos).and_then(|a| a.to_str()) == Some(ENV_FLAG) {
pos += 2;
}
if argv
.get(pos)
.and_then(|a| a.to_str())
.is_some_and(|s| s == SHORT_YES_FLAG || s == LONG_YES_FLAG)
{
pos += 1;
}
argv.get(pos)
.and_then(|a| a.to_str())
.is_some_and(|s| s.starts_with(':'))
}
fn main() -> anyhow::Result<()> {
let _guard = enwiro_sdk::init_logging("enwiro.log");
let cwd = std::env::current_dir().context("Could not determine current directory")?;
let config_json = enwiro_sdk::config::build_cookbook_config(&cwd, "enwiro", &[])
.context("Could not load configuration")?;
let config: ConfigurationValues =
serde_json::from_value(config_json).context("Could not deserialize configuration")?;
let argv: Vec<OsString> = std::env::args_os().collect();
if is_dispatch_invocation(&argv) {
return run_gear::dispatch(Path::new(&config.workspaces_directory), &argv[1..]);
}
let cli = Cli::parse();
let mut writer = std::io::stdout();
let mut context_object = CommandContext::new(config, &mut writer)?;
context_object.global_env = cli.env;
ensure_can_run(&context_object)?;
let result = match cli.command {
EnwiroCli::Activate(args) => activate(&mut context_object, args),
EnwiroCli::Browser(args) => browser(&mut context_object, args),
EnwiroCli::Info(args) => env_info(&mut context_object, args),
EnwiroCli::Kanban(args) => kanban(&mut context_object, args),
EnwiroCli::Ls(args) => {
let scope = args.scope();
let status_filter = args.status.clone();
ls(&mut context_object, scope, args.json, status_filter)
}
EnwiroCli::Mark(args) => mark(&mut context_object, args),
EnwiroCli::Prep(args) => prep(&mut context_object, args),
EnwiroCli::Rm(args) => rm(&mut context_object, args),
EnwiroCli::Run(args) => run(&mut context_object, args),
EnwiroCli::Wrap(args) => wrap(&mut context_object, args),
};
context_object
.writer
.write_all("\n".as_bytes())
.context("Could not write to output")?;
result
}