use clap::{Args, Parser, Subcommand};
use autorun::{StartupEntry, StartupScope};
#[derive(Parser, Debug)]
#[command(name = "autorun", version, about, long_about = None)]
pub struct Cli {
#[command(subcommand)]
pub command: Command,
}
#[derive(Subcommand, Debug)]
pub enum Command {
List(ListArgs),
Add(AddArgs),
Remove(RemoveArgs),
Check(CheckArgs),
}
#[derive(Args, Debug, Clone)]
pub struct ScopeArg {
#[arg(short, long)]
pub system: bool,
#[arg(short, long, conflicts_with = "system")]
pub all: bool,
}
impl ScopeArg {
pub fn to_scope(&self) -> Option<StartupScope> {
if self.system {
Some(StartupScope::LocalMachine)
} else {
Some(StartupScope::CurrentUser)
}
}
}
#[derive(Args, Debug)]
pub struct ListArgs {
#[command(flatten)]
pub scope: ScopeArg,
}
#[derive(Args, Debug)]
pub struct AddArgs {
pub name: String,
pub command: String,
#[arg(short, long)]
pub system: bool,
}
#[derive(Args, Debug)]
pub struct RemoveArgs {
pub name: String,
#[arg(short, long)]
pub system: bool,
}
#[derive(Args, Debug)]
pub struct CheckArgs {
pub name: String,
#[arg(short, long)]
pub system: bool,
}
pub fn run(cli: Cli) -> Result<(), String> {
match cli.command {
Command::List(args) => cmd_list(args),
Command::Add(args) => cmd_add(args),
Command::Remove(args) => cmd_remove(args),
Command::Check(args) => cmd_check(args),
}
}
fn cmd_list(args: ListArgs) -> Result<(), String> {
if args.scope.all {
let entries = autorun::list_all()?;
print_entries(&entries);
} else {
let scope = args.scope.to_scope().unwrap();
let entries = autorun::list(scope)?;
println!("Startup entries [{}] ({} total):", scope, entries.len());
print_entries(&entries);
}
Ok(())
}
fn cmd_add(args: AddArgs) -> Result<(), String> {
let scope = if args.system {
StartupScope::LocalMachine
} else {
StartupScope::CurrentUser
};
autorun::add(&args.name, &args.command, scope)?;
println!("Added startup entry '{}' [{}]", args.name, scope);
Ok(())
}
fn cmd_remove(args: RemoveArgs) -> Result<(), String> {
let scope = if args.system {
StartupScope::LocalMachine
} else {
StartupScope::CurrentUser
};
autorun::remove(&args.name, scope)?;
println!("Removed startup entry '{}' [{}]", args.name, scope);
Ok(())
}
fn cmd_check(args: CheckArgs) -> Result<(), String> {
let scope = if args.system {
StartupScope::LocalMachine
} else {
StartupScope::CurrentUser
};
let found = autorun::exists(&args.name, scope)?;
if found {
println!("Startup entry '{}' exists [{}]", args.name, scope);
} else {
println!("Startup entry '{}' does not exist [{}]", args.name, scope);
}
Ok(())
}
fn print_entries(entries: &[StartupEntry]) {
if entries.is_empty() {
println!("(none)");
return;
}
let max_name = entries.iter().map(|e| e.name.len()).max().unwrap_or(0);
for entry in entries {
println!(
" [{scope}] {name:<width$} {cmd}",
scope = entry.scope,
name = entry.name,
width = max_name,
cmd = entry.command,
);
}
}