1mod abandon;
16mod absorb;
17#[cfg(feature = "bench")]
18mod bench;
19mod bisect;
20mod bookmark;
21mod commit;
22mod config;
23mod debug;
24mod describe;
25mod diff;
26mod diffedit;
27mod duplicate;
28mod edit;
29mod evolog;
30mod file;
31mod fix;
32#[cfg(feature = "git")]
33mod gerrit;
34#[cfg(feature = "git")]
35mod git;
36mod help;
37mod interdiff;
38mod log;
39mod metaedit;
40mod new;
41mod next;
42mod operation;
43mod parallelize;
44mod prev;
45mod rebase;
46mod redo;
47mod resolve;
48mod restore;
49mod revert;
50mod root;
51mod run;
52mod show;
53mod sign;
54mod simplify_parents;
55mod sparse;
56mod split;
57mod squash;
58mod status;
59mod tag;
60mod undo;
61mod unsign;
62mod util;
63mod version;
64mod workspace;
65
66use std::fmt::Debug;
67
68use clap::CommandFactory as _;
69use clap::FromArgMatches as _;
70use clap::Subcommand as _;
71use clap::builder::Styles;
72use clap::builder::styling::AnsiColor;
73use clap_complete::engine::SubcommandCandidates;
74use tracing::instrument;
75
76use crate::cli_util::Args;
77use crate::cli_util::CommandHelper;
78use crate::command_error::CommandError;
79use crate::complete;
80use crate::ui::Ui;
81
82const STYLES: Styles = Styles::styled()
83 .header(AnsiColor::Yellow.on_default().bold())
84 .usage(AnsiColor::Yellow.on_default().bold())
85 .literal(AnsiColor::Green.on_default().bold())
86 .placeholder(AnsiColor::Green.on_default());
87
88#[derive(clap::Parser, Clone, Debug)]
89#[command(styles = STYLES)]
90#[command(disable_help_subcommand = true)]
91#[command(after_long_help = help::show_keyword_hint_after_help())]
92#[command(add = SubcommandCandidates::new(complete::aliases))]
93enum Command {
94 Abandon(abandon::AbandonArgs),
95 Absorb(absorb::AbsorbArgs),
96 #[cfg(feature = "bench")]
97 #[command(subcommand)]
98 Bench(bench::BenchCommand),
99 #[command(subcommand)]
100 Bisect(bisect::BisectCommand),
101 #[command(subcommand)]
102 Bookmark(bookmark::BookmarkCommand),
103 Commit(commit::CommitArgs),
104 #[command(subcommand)]
105 Config(config::ConfigCommand),
106 #[command(subcommand)]
107 Debug(debug::DebugCommand),
108 Describe(describe::DescribeArgs),
109 Diff(diff::DiffArgs),
110 Diffedit(diffedit::DiffeditArgs),
111 Duplicate(duplicate::DuplicateArgs),
112 Edit(edit::EditArgs),
113 #[command(alias = "obslog", visible_alias = "evolution-log")]
114 Evolog(evolog::EvologArgs),
115 #[command(subcommand)]
116 File(file::FileCommand),
117 Fix(fix::FixArgs),
118 #[cfg(feature = "git")]
119 #[command(subcommand)]
120 Gerrit(gerrit::GerritCommand),
121 #[cfg(feature = "git")]
122 #[command(subcommand)]
123 Git(git::GitCommand),
124 Help(help::HelpArgs),
125 Interdiff(interdiff::InterdiffArgs),
126 Log(log::LogArgs),
127 Metaedit(metaedit::MetaeditArgs),
128 New(new::NewArgs),
129 Next(next::NextArgs),
130 #[command(subcommand)]
131 #[command(visible_alias = "op")]
132 Operation(operation::OperationCommand),
133 Parallelize(parallelize::ParallelizeArgs),
134 Prev(prev::PrevArgs),
135 Rebase(rebase::RebaseArgs),
136 Redo(redo::RedoArgs),
137 Resolve(resolve::ResolveArgs),
138 Restore(restore::RestoreArgs),
139 Revert(revert::RevertArgs),
140 Root(root::RootArgs),
141 #[command(hide = true)]
142 Run(run::RunArgs),
144 Show(show::ShowArgs),
145 Sign(sign::SignArgs),
146 SimplifyParents(simplify_parents::SimplifyParentsArgs),
147 #[command(subcommand)]
148 Sparse(sparse::SparseCommand),
149 Split(split::SplitArgs),
150 Squash(squash::SquashArgs),
151 Status(status::StatusArgs),
152 #[command(subcommand)]
153 Tag(tag::TagCommand),
154 Undo(undo::UndoArgs),
155 Unsign(unsign::UnsignArgs),
156 #[command(subcommand)]
157 Util(util::UtilCommand),
158 Version(version::VersionArgs),
159 #[command(subcommand)]
160 Workspace(workspace::WorkspaceCommand),
161}
162
163pub fn default_app() -> clap::Command {
164 Command::augment_subcommands(Args::command())
165}
166
167#[instrument(skip_all)]
168pub fn run_command(ui: &mut Ui, command_helper: &CommandHelper) -> Result<(), CommandError> {
169 let subcommand = Command::from_arg_matches(command_helper.matches()).unwrap();
170 match &subcommand {
171 Command::Abandon(args) => abandon::cmd_abandon(ui, command_helper, args),
172 Command::Absorb(args) => absorb::cmd_absorb(ui, command_helper, args),
173 #[cfg(feature = "bench")]
174 Command::Bench(args) => bench::cmd_bench(ui, command_helper, args),
175 Command::Bisect(args) => bisect::cmd_bisect(ui, command_helper, args),
176 Command::Bookmark(args) => bookmark::cmd_bookmark(ui, command_helper, args),
177 Command::Commit(args) => commit::cmd_commit(ui, command_helper, args),
178 Command::Config(args) => config::cmd_config(ui, command_helper, args),
179 Command::Debug(args) => debug::cmd_debug(ui, command_helper, args),
180 Command::Describe(args) => describe::cmd_describe(ui, command_helper, args),
181 Command::Diff(args) => diff::cmd_diff(ui, command_helper, args),
182 Command::Diffedit(args) => diffedit::cmd_diffedit(ui, command_helper, args),
183 Command::Duplicate(args) => duplicate::cmd_duplicate(ui, command_helper, args),
184 Command::Edit(args) => edit::cmd_edit(ui, command_helper, args),
185 Command::Evolog(args) => evolog::cmd_evolog(ui, command_helper, args),
186 Command::File(args) => file::cmd_file(ui, command_helper, args),
187 Command::Fix(args) => fix::cmd_fix(ui, command_helper, args),
188 #[cfg(feature = "git")]
189 Command::Gerrit(sub_args) => gerrit::cmd_gerrit(ui, command_helper, sub_args),
190 #[cfg(feature = "git")]
191 Command::Git(args) => git::cmd_git(ui, command_helper, args),
192 Command::Help(args) => help::cmd_help(ui, command_helper, args),
193 Command::Interdiff(args) => interdiff::cmd_interdiff(ui, command_helper, args),
194 Command::Log(args) => log::cmd_log(ui, command_helper, args),
195 Command::Metaedit(args) => metaedit::cmd_metaedit(ui, command_helper, args),
196 Command::New(args) => new::cmd_new(ui, command_helper, args),
197 Command::Next(args) => next::cmd_next(ui, command_helper, args),
198 Command::Operation(args) => operation::cmd_operation(ui, command_helper, args),
199 Command::Parallelize(args) => parallelize::cmd_parallelize(ui, command_helper, args),
200 Command::Prev(args) => prev::cmd_prev(ui, command_helper, args),
201 Command::Rebase(args) => rebase::cmd_rebase(ui, command_helper, args),
202 Command::Redo(args) => redo::cmd_redo(ui, command_helper, args),
203 Command::Resolve(args) => resolve::cmd_resolve(ui, command_helper, args),
204 Command::Restore(args) => restore::cmd_restore(ui, command_helper, args),
205 Command::Revert(args) => revert::cmd_revert(ui, command_helper, args),
206 Command::Root(args) => root::cmd_root(ui, command_helper, args),
207 Command::Run(args) => run::cmd_run(ui, command_helper, args),
208 Command::SimplifyParents(args) => {
209 simplify_parents::cmd_simplify_parents(ui, command_helper, args)
210 }
211 Command::Show(args) => show::cmd_show(ui, command_helper, args),
212 Command::Sign(args) => sign::cmd_sign(ui, command_helper, args),
213 Command::Sparse(args) => sparse::cmd_sparse(ui, command_helper, args),
214 Command::Split(args) => split::cmd_split(ui, command_helper, args),
215 Command::Squash(args) => squash::cmd_squash(ui, command_helper, args),
216 Command::Status(args) => status::cmd_status(ui, command_helper, args),
217 Command::Tag(args) => tag::cmd_tag(ui, command_helper, args),
218 Command::Undo(args) => undo::cmd_undo(ui, command_helper, args),
219 Command::Unsign(args) => unsign::cmd_unsign(ui, command_helper, args),
220 Command::Util(args) => util::cmd_util(ui, command_helper, args),
221 Command::Version(args) => version::cmd_version(ui, command_helper, args),
222 Command::Workspace(args) => workspace::cmd_workspace(ui, command_helper, args),
223 }
224}
225
226pub(crate) fn renamed_cmd<Args>(
228 old_name: &'static str,
229 new_name: &'static str,
230 cmd: impl Fn(&mut Ui, &CommandHelper, &Args) -> Result<(), CommandError>,
231) -> impl Fn(&mut Ui, &CommandHelper, &Args) -> Result<(), CommandError> {
232 move |ui: &mut Ui, command: &CommandHelper, args: &Args| -> Result<(), CommandError> {
233 writeln!(
234 ui.warning_default(),
235 "`jj {old_name}` is deprecated; use `jj {new_name}` instead, which is equivalent"
236 )?;
237 writeln!(
238 ui.warning_default(),
239 "`jj {old_name}` will be removed in a future version, and this will be a hard error"
240 )?;
241 cmd(ui, command, args)
242 }
243}
244
245#[cfg(test)]
246mod tests {
247 use super::*;
248
249 #[test]
250 fn verify_app() {
251 default_app().debug_assert();
252 }
253}