diff --git a/CHANGELOG.md b/CHANGELOG.md index 0884171967..c56de7d253 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -79,6 +79,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * `jj git fetch` and `jj git push` will now use the single defined remote even if it is not named "origin". +* `jj` with no subcommand now invokes `jj log` with the default options, instead + of showing help. + ### Fixed bugs * Modify/delete conflicts now include context lines diff --git a/src/commands/mod.rs b/src/commands/mod.rs index e13a540c36..2584507030 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -325,7 +325,7 @@ struct ShowArgs { struct StatusArgs {} /// Show commit history -#[derive(clap::Args, Clone, Debug)] +#[derive(clap::Args, Clone, Debug, Default)] struct LogArgs { /// Which revisions to show. Defaults to the `ui.default-revset` setting, /// or `@ | (remote_branches() | tags()).. | ((remote_branches() | @@ -3474,9 +3474,7 @@ fn cmd_sparse(ui: &mut Ui, command: &CommandHelper, args: &SparseArgs) -> Result pub fn default_app() -> Command { let app: Command = Commands::augment_subcommands(Args::command()); - app.arg_required_else_help(true) - .subcommand_required(true) - .version(env!("JJ_VERSION")) + app.version(env!("JJ_VERSION")) } pub fn run_command( @@ -3484,47 +3482,55 @@ pub fn run_command( command_helper: &CommandHelper, matches: &ArgMatches, ) -> Result<(), CommandError> { - let derived_subcommands: Commands = Commands::from_arg_matches(matches).unwrap(); + let derived_subcommands: Option = Commands::from_arg_matches(matches).ok(); match &derived_subcommands { - Commands::Version(sub_args) => cmd_version(ui, command_helper, sub_args), - Commands::Init(sub_args) => cmd_init(ui, command_helper, sub_args), - Commands::Config(sub_args) => cmd_config(ui, command_helper, sub_args), - Commands::Checkout(sub_args) => cmd_checkout(ui, command_helper, sub_args), - Commands::Untrack(sub_args) => cmd_untrack(ui, command_helper, sub_args), - Commands::Files(sub_args) => cmd_files(ui, command_helper, sub_args), - Commands::Cat(sub_args) => cmd_cat(ui, command_helper, sub_args), - Commands::Diff(sub_args) => cmd_diff(ui, command_helper, sub_args), - Commands::Show(sub_args) => cmd_show(ui, command_helper, sub_args), - Commands::Status(sub_args) => cmd_status(ui, command_helper, sub_args), - Commands::Log(sub_args) => cmd_log(ui, command_helper, sub_args), - Commands::Interdiff(sub_args) => cmd_interdiff(ui, command_helper, sub_args), - Commands::Obslog(sub_args) => cmd_obslog(ui, command_helper, sub_args), - Commands::Describe(sub_args) => cmd_describe(ui, command_helper, sub_args), - Commands::Commit(sub_args) => cmd_commit(ui, command_helper, sub_args), - Commands::Duplicate(sub_args) => cmd_duplicate(ui, command_helper, sub_args), - Commands::Abandon(sub_args) => cmd_abandon(ui, command_helper, sub_args), - Commands::Edit(sub_args) => cmd_edit(ui, command_helper, sub_args), - Commands::New(sub_args) => cmd_new(ui, command_helper, sub_args), - Commands::Move(sub_args) => cmd_move(ui, command_helper, sub_args), - Commands::Squash(sub_args) => cmd_squash(ui, command_helper, sub_args), - Commands::Unsquash(sub_args) => cmd_unsquash(ui, command_helper, sub_args), - Commands::Restore(sub_args) => cmd_restore(ui, command_helper, sub_args), - Commands::Diffedit(sub_args) => cmd_diffedit(ui, command_helper, sub_args), - Commands::Split(sub_args) => cmd_split(ui, command_helper, sub_args), - Commands::Merge(sub_args) => cmd_merge(ui, command_helper, sub_args), - Commands::Rebase(sub_args) => cmd_rebase(ui, command_helper, sub_args), - Commands::Backout(sub_args) => cmd_backout(ui, command_helper, sub_args), - Commands::Resolve(sub_args) => cmd_resolve(ui, command_helper, sub_args), - Commands::Branch(sub_args) => branch::cmd_branch(ui, command_helper, sub_args), - Commands::Undo(sub_args) => operation::cmd_op_undo(ui, command_helper, sub_args), - Commands::Operation(sub_args) => operation::cmd_operation(ui, command_helper, sub_args), - Commands::Workspace(sub_args) => cmd_workspace(ui, command_helper, sub_args), - Commands::Sparse(sub_args) => cmd_sparse(ui, command_helper, sub_args), - Commands::Git(sub_args) => git::cmd_git(ui, command_helper, sub_args), - Commands::Util(sub_args) => cmd_util(ui, command_helper, sub_args), + Some(Commands::Version(sub_args)) => cmd_version(ui, command_helper, sub_args), + Some(Commands::Init(sub_args)) => cmd_init(ui, command_helper, sub_args), + Some(Commands::Config(sub_args)) => cmd_config(ui, command_helper, sub_args), + Some(Commands::Checkout(sub_args)) => cmd_checkout(ui, command_helper, sub_args), + Some(Commands::Untrack(sub_args)) => cmd_untrack(ui, command_helper, sub_args), + Some(Commands::Files(sub_args)) => cmd_files(ui, command_helper, sub_args), + Some(Commands::Cat(sub_args)) => cmd_cat(ui, command_helper, sub_args), + Some(Commands::Diff(sub_args)) => cmd_diff(ui, command_helper, sub_args), + Some(Commands::Show(sub_args)) => cmd_show(ui, command_helper, sub_args), + Some(Commands::Status(sub_args)) => cmd_status(ui, command_helper, sub_args), + Some(Commands::Log(sub_args)) => cmd_log(ui, command_helper, sub_args), + Some(Commands::Interdiff(sub_args)) => cmd_interdiff(ui, command_helper, sub_args), + Some(Commands::Obslog(sub_args)) => cmd_obslog(ui, command_helper, sub_args), + Some(Commands::Describe(sub_args)) => cmd_describe(ui, command_helper, sub_args), + Some(Commands::Commit(sub_args)) => cmd_commit(ui, command_helper, sub_args), + Some(Commands::Duplicate(sub_args)) => cmd_duplicate(ui, command_helper, sub_args), + Some(Commands::Abandon(sub_args)) => cmd_abandon(ui, command_helper, sub_args), + Some(Commands::Edit(sub_args)) => cmd_edit(ui, command_helper, sub_args), + Some(Commands::New(sub_args)) => cmd_new(ui, command_helper, sub_args), + Some(Commands::Move(sub_args)) => cmd_move(ui, command_helper, sub_args), + Some(Commands::Squash(sub_args)) => cmd_squash(ui, command_helper, sub_args), + Some(Commands::Unsquash(sub_args)) => cmd_unsquash(ui, command_helper, sub_args), + Some(Commands::Restore(sub_args)) => cmd_restore(ui, command_helper, sub_args), + Some(Commands::Diffedit(sub_args)) => cmd_diffedit(ui, command_helper, sub_args), + Some(Commands::Split(sub_args)) => cmd_split(ui, command_helper, sub_args), + Some(Commands::Merge(sub_args)) => cmd_merge(ui, command_helper, sub_args), + Some(Commands::Rebase(sub_args)) => cmd_rebase(ui, command_helper, sub_args), + Some(Commands::Backout(sub_args)) => cmd_backout(ui, command_helper, sub_args), + Some(Commands::Resolve(sub_args)) => cmd_resolve(ui, command_helper, sub_args), + Some(Commands::Branch(sub_args)) => branch::cmd_branch(ui, command_helper, sub_args), + Some(Commands::Undo(sub_args)) => operation::cmd_op_undo(ui, command_helper, sub_args), + Some(Commands::Operation(sub_args)) => { + operation::cmd_operation(ui, command_helper, sub_args) + } + Some(Commands::Workspace(sub_args)) => cmd_workspace(ui, command_helper, sub_args), + Some(Commands::Sparse(sub_args)) => cmd_sparse(ui, command_helper, sub_args), + Some(Commands::Git(sub_args)) => git::cmd_git(ui, command_helper, sub_args), + Some(Commands::Util(sub_args)) => cmd_util(ui, command_helper, sub_args), #[cfg(feature = "bench")] - Commands::Bench(sub_args) => bench::cmd_bench(ui, command_helper, sub_args), - Commands::Debug(sub_args) => cmd_debug(ui, command_helper, sub_args), + Some(Commands::Bench(sub_args)) => bench::cmd_bench(ui, command_helper, sub_args), + Some(Commands::Debug(sub_args)) => cmd_debug(ui, command_helper, sub_args), + None => { + let sub_args = LogArgs { + ..Default::default() + }; + cmd_log(ui, command_helper, &sub_args) + } } } diff --git a/src/diff_util.rs b/src/diff_util.rs index 55e3991e60..b61916418b 100644 --- a/src/diff_util.rs +++ b/src/diff_util.rs @@ -32,7 +32,7 @@ use jujutsu_lib::{conflicts, diff, files, rewrite, tree}; use crate::cli_util::{CommandError, WorkspaceCommandHelper}; use crate::formatter::Formatter; -#[derive(clap::Args, Clone, Debug)] +#[derive(clap::Args, Clone, Debug, Default)] #[command(group(clap::ArgGroup::new("short-format").args(&["summary", "types"])))] #[command(group(clap::ArgGroup::new("long-format").args(&["git", "color_words"])))] pub struct DiffFormatArgs { diff --git a/tests/test_alias.rs b/tests/test_alias.rs index 546dc64c15..86bdac4030 100644 --- a/tests/test_alias.rs +++ b/tests/test_alias.rs @@ -69,7 +69,7 @@ fn test_alias_bad_name() { insta::assert_snapshot!(stderr, @r###" error: unrecognized subcommand 'foo.' - Usage: jj [OPTIONS] + Usage: jj [OPTIONS] [COMMAND] For more information, try '--help'. "###); @@ -86,7 +86,7 @@ fn test_alias_calls_unknown_command() { insta::assert_snapshot!(stderr, @r###" error: unrecognized subcommand 'nonexistent' - Usage: jj [OPTIONS] + Usage: jj [OPTIONS] [COMMAND] For more information, try '--help'. "###); @@ -123,7 +123,7 @@ fn test_alias_calls_help() { To get started, see the tutorial at https://github.com/martinvonz/jj/blob/main/docs/tutorial.md. - Usage: jj [OPTIONS] + Usage: jj [OPTIONS] [COMMAND] "###); } diff --git a/tests/test_global_opts.rs b/tests/test_global_opts.rs index fca8012696..a79aacdc4b 100644 --- a/tests/test_global_opts.rs +++ b/tests/test_global_opts.rs @@ -47,23 +47,11 @@ fn test_non_utf8_arg() { #[test] fn test_no_subcommand() { let test_env = TestEnvironment::default(); + test_env.jj_cmd_success(test_env.env_root(), &["init", "repo", "--git"]); + let repo_path = test_env.env_root().join("repo"); - let stderr = test_env.jj_cmd_cli_error(test_env.env_root(), &[]); - insta::assert_snapshot!(stderr.lines().next().unwrap(), @"Jujutsu (An experimental VCS)"); - - let stderr = test_env.jj_cmd_cli_error(test_env.env_root(), &["-R."]); - insta::assert_snapshot!(stderr.lines().next().unwrap(), @"error: 'jj' requires a subcommand but one was not provided"); - - let stdout = test_env.jj_cmd_success(test_env.env_root(), &["--version"]); - let sanitized = stdout.replace(|c: char| c.is_ascii_hexdigit(), "?"); - assert!( - sanitized == "jj ?.?.?\n" - || sanitized == "jj ?.?.?-????????????????????????????????????????\n", - "{sanitized}" - ); - - let stdout = test_env.jj_cmd_success(test_env.env_root(), &["--help"]); - insta::assert_snapshot!(stdout.lines().next().unwrap(), @"Jujutsu (An experimental VCS)"); + let stdout = test_env.jj_cmd_success(&repo_path, &[]); + assert_eq!(stdout, test_env.jj_cmd_success(&repo_path, &["log"])); } #[test]