1use std::io::{stderr, stdout, Write};
4
5use clap::{command, Arg, ArgAction, ArgMatches, Command};
6use serde_json::json;
7
8use crate::config::Config;
9use crate::subcommands;
10
11pub fn get_clap_app() -> Command {
13 command!()
14 .arg(
15 Arg::new("verbose")
16 .short('v')
17 .long("verbose")
18 .action(ArgAction::SetTrue)
19 .global(true)
20 .help("Enable verbose mode."),
21 )
22 .arg(
23 Arg::new("json")
24 .short('j')
25 .long("json")
26 .action(ArgAction::SetTrue)
27 .global(true)
28 .help("Output subcommand results in JSON."),
29 )
30 .arg(
31 Arg::new("untracked")
32 .short('u')
33 .long("untracked")
34 .action(ArgAction::SetTrue)
35 .conflicts_with("nountracked")
36 .global(true)
37 .help("Show untracked files in output."),
38 )
39 .arg(
40 Arg::new("nountracked")
41 .short('t')
42 .long("nountracked")
43 .action(ArgAction::SetTrue)
44 .conflicts_with("untracked")
45 .global(true)
46 .help("Don't show untracked files in output."),
47 )
48 .subcommands(
49 subcommands::get_subcommands()
50 .iter()
51 .map(|(cmd, desc)| Command::new(*cmd).about(*desc)),
52 )
53}
54
55fn merge_args_with_config(config: &mut Config, matches: &ArgMatches) {
57 if matches.get_flag("verbose") {
58 config.verbose = true;
59 }
60 if matches.get_flag("untracked") {
61 config.show_untracked = true;
62 }
63 if matches.get_flag("nountracked") {
64 config.show_untracked = false;
65 }
66}
67
68pub fn run_from_command_line() -> i32 {
73 let clap_app = get_clap_app();
74 let matches = clap_app.get_matches();
75 let mut config = Config::new();
76 merge_args_with_config(&mut config, &matches);
77 let report = subcommands::run(matches.subcommand_name(), config);
78 let use_json = matches.get_flag("json");
79 match report {
80 Ok(rep) => {
81 if use_json {
82 rep.print_json(&mut stdout());
83 } else {
84 rep.print(&mut stdout());
85 }
86 0
87 }
88 Err(err) => {
89 if use_json {
90 let out = json!({
91 "error": true,
92 "message": format!("{}", err)
93 });
94 writeln!(&mut stderr(), "{:#}", out).unwrap();
95 } else {
96 writeln!(&mut stderr(), "{}", err).unwrap();
97 }
98 1
99 }
100 }
101}