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.

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