mod config;
mod pull;
mod push;
#[cfg(test)]
mod testutil;
mod types;
mod util;
use clap::{Args, Parser, Subcommand, ValueEnum};
use worktrunk::styling::eprintln;
use types::StageMode;
const STAGING_HELP: &str = r#"## Staging
Controls what to stage before the wip checkpoint commit:
| Value | Behavior |
|---------|------------------------------------------------------------------------|
| all | Stage everything: untracked files + unstaged tracked changes (default) |
| tracked | Stage tracked changes only (like `git add -u`) |
| none | Stage nothing, commit only what's already in the index |
Configure the default in worktrunk's user or project config:
```toml
[wip]
stage = "tracked"
```"#;
#[derive(Parser)]
#[command(name = "wt-wip", version, args_conflicts_with_subcommands = true)]
struct Cli {
#[command(subcommand)]
command: Option<Command>,
#[command(flatten)]
push: PushArgs,
}
#[derive(Subcommand)]
enum Command {
#[command(after_long_help = STAGING_HELP)]
Push(PushArgs),
Pull {
#[arg(long, value_enum, default_value_t = Format::Text, help_heading = "Automation")]
format: Format,
},
}
#[derive(Args)]
struct PushArgs {
#[arg(long, value_enum)]
stage: Option<StageMode>,
#[arg(short = 'm', long)]
message: Option<String>,
#[arg(long, value_enum, default_value_t = Format::Text, help_heading = "Automation")]
format: Format,
}
#[derive(Clone, Copy, PartialEq, Eq, ValueEnum)]
enum Format {
Text,
Json,
}
fn run_push(args: PushArgs) -> anyhow::Result<()> {
let result = push::push(args.stage, args.message)?;
if args.format == Format::Json {
println!("{}", serde_json::to_string(&result)?);
}
Ok(())
}
fn main() {
let cli = Cli::parse();
let result = match cli.command {
Some(Command::Push(args)) => run_push(args),
Some(Command::Pull { format }) => pull::pull().and_then(|r| {
if format == Format::Json {
println!("{}", serde_json::to_string(&r)?);
}
Ok(())
}),
None => run_push(cli.push),
};
if let Err(err) = result {
eprintln!("{}", worktrunk::styling::error_message(format!("{err:#}")));
std::process::exit(1);
}
}