use anyhow::Result;
use clap::{CommandFactory, Parser};
use clap_complete::Shell;
use console::style;
use std::path::PathBuf;
mod config;
mod init;
mod prompts;
mod remote;
mod templates;
#[cfg(feature = "tui")]
mod tui;
#[derive(Parser)]
#[command(name = "fledge", version, about = "Get your projects ready to fly.")]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(clap::Subcommand)]
enum Commands {
Init {
name: String,
#[arg(short, long)]
template: Option<String>,
#[arg(short, long, default_value = ".")]
output: PathBuf,
#[arg(long)]
no_git: bool,
#[arg(long)]
no_install: bool,
#[arg(long)]
refresh: bool,
#[arg(long)]
dry_run: bool,
#[arg(short, long)]
yes: bool,
},
List,
Completions {
#[arg(value_enum)]
shell: Shell,
},
#[cfg(feature = "tui")]
Tui {
#[arg(short, long, default_value = ".")]
output: PathBuf,
#[arg(long)]
no_git: bool,
},
}
fn main() {
if let Err(e) = run() {
eprintln!("{} {:#}", style("error:").red().bold(), e);
std::process::exit(1);
}
}
fn run() -> Result<()> {
let cli = Cli::parse();
match cli.command {
Commands::Init {
name,
template,
output,
no_git,
no_install,
refresh,
dry_run,
yes,
} => {
init::run(init::InitOptions {
name,
template,
output,
no_git,
no_install,
refresh,
dry_run,
yes,
})?;
}
Commands::List => {
list_templates()?;
}
Commands::Completions { shell } => {
clap_complete::generate(shell, &mut Cli::command(), "fledge", &mut std::io::stdout());
}
#[cfg(feature = "tui")]
Commands::Tui { output, no_git } => {
tui::run(output, no_git)?;
}
}
Ok(())
}
fn list_templates() -> Result<()> {
let config = config::Config::load()?;
let extra_paths = config.extra_template_paths();
let token = config.github_token();
let available = templates::discover_templates_with_repos(
&extra_paths,
config.template_repos(),
token.as_deref(),
)?;
if available.is_empty() {
println!("No templates found.");
return Ok(());
}
println!("{}", style("Available templates:").bold());
for t in &available {
println!(
" {:<14} {}",
style(&t.name).green(),
style(&t.description).dim()
);
}
Ok(())
}