Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

93 linesCodeBlameRaw
1//! The g1t command line.
2
3mod auth;
4mod chunk;
5mod cli;
6mod client;
7mod commands;
8mod config;
9mod context;
10mod credentials;
11mod error;
12mod git;
13mod image;
14mod jq;
15mod mapping;
16mod ops;
17mod ops_table;
18mod output;
19mod prompt;
20mod push;
21mod reference;
22mod registry;
23mod repo;
24
25use clap::{CommandFactory, FromArgMatches};
26use std::process::ExitCode;
27
28fn main() -> ExitCode {
29 let args: Vec<String> = std::env::args().collect();
30 let code = match run(args) {
31 Ok(()) => 0,
32 Err(error) => {
33 if !error.silent && !error.message.is_empty() {
34 eprintln!("g1t: {}", error.message.trim_end());
35 }
36 error.kind.code()
37 }
38 };
39 ExitCode::from(code)
40}
41
42fn run(args: Vec<String>) -> error::Result<()> {
43 let args = match commands::alias::expand(args)? {
44 commands::alias::Expanded::Args(args) => args,
45 commands::alias::Expanded::Ran(code) => {
46 return if code == 0 {
47 Ok(())
48 } else {
49 Err(error::Error::exit(error::Kind::Failed))
50 };
51 }
52 };
53 let matches = match cli::Cli::command().try_get_matches_from(&args) {
54 Ok(m) => m,
55 Err(e) => return clap_error(e),
56 };
57 let parsed = match cli::Cli::from_arg_matches(&matches) {
58 Ok(p) => p,
59 Err(e) => return clap_error(e),
60 };
61 commands::dispatch(parsed)
62}
63
64/// Help and the version go to stdout and succeed; a mistake is one line on
65/// stderr and exit code 2.
66fn clap_error(e: clap::Error) -> error::Result<()> {
67 use clap::error::ErrorKind;
68 match e.kind() {
69 ErrorKind::DisplayHelp | ErrorKind::DisplayVersion => {
70 let _ = e.print();
71 Ok(())
72 }
73 ErrorKind::DisplayHelpOnMissingArgumentOrSubcommand => {
74 let _ = e.print();
75 Err(error::Error::exit(error::Kind::Usage))
76 }
77 _ => {
78 let text = e.render().to_string();
79 let line = text
80 .lines()
81 .find(|l| !l.trim().is_empty())
82 .unwrap_or("")
83 .trim_start_matches("error: ")
84 .trim();
85 let tip = text
86 .lines()
87 .find(|l| l.trim_start().starts_with("tip:"))
88 .map(|l| format!(" ({})", l.trim().trim_start_matches("tip: ")))
89 .unwrap_or_default();
90 Err(error::Error::usage(format!("{line}{tip} See --help.")))
91 }
92 }
93}