use anyhow::Result;
use clap::{Parser, Subcommand};
mod commands;
mod nix;
use crate::commands::{
activate, add, command, completions, direnv, env,
export::{self, ExportType},
hook::{self, HookShell},
init, list, lock, profiles, remove, search, show, update,
};
#[derive(Parser)]
#[command(name = "flk")]
#[command(author = "AEduardo-dev")]
#[command(version)]
#[command(about = "A CLI tool for managing flake.nix devShell environments", long_about = None)]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
Init {
#[arg(short, long)]
template: Option<String>,
#[arg(short, long)]
force: bool,
},
Search {
query: String,
#[arg(short, long, default_value_t = 10)]
limit: usize,
},
DeepSearch {
package: String,
},
List {
#[arg(short = 'p', long)]
profile: Option<String>,
},
Show {},
Add {
package: String,
#[arg(short, long)]
version: Option<String>,
#[arg(short = 'p', long)]
profile: Option<String>,
},
Remove {
package: String,
#[arg(short = 'p', long)]
profile: Option<String>,
},
Update {
packages: Vec<String>,
#[arg(short, long)]
show: bool,
},
Command {
#[command(subcommand)]
action: CommandAction,
#[arg(short = 'p', long)]
profile: Option<String>,
},
Env {
#[command(subcommand)]
action: EnvAction,
#[arg(short = 'p', long)]
profile: Option<String>,
},
Lock {
#[command(subcommand)]
action: LockAction,
},
Completions {
#[arg(long)]
install: bool,
#[arg(value_enum)]
shell: Option<clap_complete::shells::Shell>,
},
Activate {
#[arg(short = 'p', long)]
profile: Option<String>,
},
Export {
#[arg(short, long)]
format: ExportType,
#[arg(short = 'p', long)]
profile: Option<String>,
},
Direnv {
#[command(subcommand)]
action: DirenvAction,
},
Hook {
#[arg(value_enum)]
shell: HookShell,
},
Profile {
#[command(subcommand)]
action: ProfileAction,
},
}
#[derive(Subcommand)]
enum CommandAction {
Add {
name: String,
#[arg(trailing_var_arg = true, allow_hyphen_values = true)]
command: Vec<String>,
#[arg(short, long)]
file: Option<String>,
},
Remove {
name: String,
},
List,
}
#[derive(Subcommand)]
enum EnvAction {
Add {
name: String,
value: String,
},
Remove {
name: String,
},
List,
}
#[derive(Subcommand)]
enum LockAction {
Show,
History,
Restore {
backup: String,
},
}
#[derive(Subcommand)]
enum DirenvAction {
Init,
Attach,
Detach,
}
#[derive(Subcommand)]
enum ProfileAction {
Add {
name: String,
#[arg(short, long)]
template: Option<String>,
#[arg(short, long)]
force: bool,
},
Remove {
name: String,
},
List,
SetDefault {
profile: String,
},
}
fn main() -> Result<()> {
let cli = Cli::parse();
match cli.command {
Commands::Init { template, force } => {
init::run(template, force)?;
}
Commands::Search { query, limit } => {
search::run_search(&query, limit)?;
}
Commands::DeepSearch { package } => {
search::run_deep_search(&package)?;
}
Commands::List { profile } => {
list::run_list(profile)?;
}
Commands::Show {} => {
show::run_show()?;
}
Commands::Add {
package,
version,
profile,
} => {
add::run_add(&package, version, profile)?;
}
Commands::Remove { package, profile } => {
remove::run_remove(&package, profile)?;
}
Commands::Update { packages, show } => {
update::run_update(packages, show)?;
}
Commands::Command { action, profile } => match action {
CommandAction::Add {
name,
command,
file,
} => {
let cmd = command.join(" ");
command::run_add(&name, &cmd, file, profile)?;
}
CommandAction::Remove { name } => {
command::run_remove(&name, profile)?;
}
CommandAction::List => {
command::list(profile)?;
}
},
Commands::Env { action, profile } => match action {
EnvAction::Add { name, value } => {
env::add(&name, &value, profile)?;
}
EnvAction::Remove { name } => {
env::remove(&name, profile)?;
}
EnvAction::List => {
env::list(profile)?;
}
},
Commands::Lock { action } => match action {
LockAction::Show => {
lock::show()?;
}
LockAction::History => {
lock::history()?;
}
LockAction::Restore { backup } => {
lock::restore(&backup)?;
}
},
Commands::Completions { install, shell } => {
completions::handle_completions(install, shell)?;
}
Commands::Activate { profile } => {
activate::run_activate(profile)?;
}
Commands::Export { format, profile } => {
export::run_export(&format, profile)?;
}
Commands::Direnv { action } => match action {
DirenvAction::Init => {
direnv::direnv_init()?;
}
DirenvAction::Attach => {
direnv::direnv_attach()?;
}
DirenvAction::Detach => {
direnv::direnv_detach()?;
}
},
Commands::Hook { shell } => {
hook::run_hook(shell)?;
}
Commands::Profile { action } => match action {
ProfileAction::Add {
name,
template,
force,
} => {
profiles::run_add(name, template, force)?;
}
ProfileAction::Remove { name } => {
profiles::run_remove(name)?;
}
ProfileAction::List => {
profiles::run_list()?;
}
ProfileAction::SetDefault { profile } => {
profiles::run_set_default(profile)?;
}
},
}
Ok(())
}