Files
jj-cz/src/cli/mod.rs
T

128 lines
3.5 KiB
Rust
Raw Permalink Normal View History

use clap::Parser;
/// Interactive conventional commit tool for Jujutsu
///
/// Guides you through creating a properly formatted conventional commit message
/// and applies it to the current change in your Jujutsu repository.
#[derive(Debug, Parser)]
#[command(
name = "jj-cz",
version = concat!(env!("CARGO_PKG_VERSION"), " (jj-lib ", env!("JJ_LIB_VERSION") ,")"),
about = "Interactive conventional commit tool for Jujutsu",
long_about = "Guides you through creating a properly formatted conventional \
commit message and applies it to the current change in your \
Jujutsu repository.\n\n\
This tool requires an interactive terminal (TTY)."
)]
2026-04-05 23:02:14 +02:00
pub struct Cli {
/// The revision(s) whose description to edit (default: @)
#[arg(value_name = "REVSETS")]
revsets: Vec<String>,
2026-06-07 12:37:18 +02:00
/// Create a new child revision after editing the description
#[arg(short, long)]
new: bool,
2026-04-05 23:02:14 +02:00
}
impl Cli {
/// Returns the revsets to operate on, defaulting to `["@"]` if none provided
pub fn revsets(&self) -> Vec<&str> {
if self.revsets.is_empty() {
vec!["@"]
} else {
self.revsets.iter().map(|s| s.as_str()).collect()
}
}
2026-06-07 12:37:18 +02:00
pub fn create_new(&self) -> bool {
self.new
}
pub fn validate(&self) -> Result<(), jj_cz::Error> {
if self.new && self.revsets().len() > 1 {
Err(jj_cz::Error::NewFlagWithMultipleRevisions)
} else {
Ok(())
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use clap::Parser;
#[test]
fn revsets_defaults_to_at() {
let cli = Cli::parse_from(["jj-cz"]);
assert_eq!(cli.revsets(), vec!["@"]);
}
#[test]
fn revsets_returns_provided_values() {
let cli = Cli::parse_from(["jj-cz", "abc", "def"]);
let revsets = cli.revsets();
assert_eq!(revsets, vec!["abc", "def"]);
}
#[test]
fn revsets_single_revset() {
let cli = Cli::parse_from(["jj-cz", "xyz"]);
assert_eq!(cli.revsets(), vec!["xyz"]);
}
#[test]
fn create_new_returns_false_by_default() {
let cli = Cli::parse_from(["jj-cz"]);
assert!(!cli.create_new());
}
#[test]
fn create_new_returns_true_with_flag() {
let cli = Cli::parse_from(["jj-cz", "--new"]);
assert!(cli.create_new());
}
#[test]
fn create_new_returns_true_with_short_flag() {
let cli = Cli::parse_from(["jj-cz", "-n"]);
assert!(cli.create_new());
}
#[test]
fn validate_ok_with_no_args() {
let cli = Cli::parse_from(["jj-cz"]);
assert!(cli.validate().is_ok());
}
#[test]
fn validate_ok_with_new_and_single_revset() {
let cli = Cli::parse_from(["jj-cz", "--new", "@"]);
assert!(cli.validate().is_ok());
}
#[test]
fn validate_ok_with_multiple_revsets_no_new() {
let cli = Cli::parse_from(["jj-cz", "abc", "def"]);
assert!(cli.validate().is_ok());
}
#[test]
fn validate_err_with_new_and_multiple_revsets() {
let cli = Cli::parse_from(["jj-cz", "--new", "abc", "def"]);
let result = cli.validate();
assert!(result.is_err());
assert!(matches!(
result.unwrap_err(),
jj_cz::Error::NewFlagWithMultipleRevisions
));
}
#[test]
fn cli_derives_debug() {
let cli = Cli::parse_from(["jj-cz", "--new", "@"]);
let debug = format!("{:?}", cli);
assert!(debug.contains("Cli"));
}
2026-04-05 23:02:14 +02:00
}