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.

g1t.sh
95 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 commands::dispatch(parsed)
64}
65
66/// Help and the version go to stdout and succeed; a mistake is one line on
67/// stderr and exit code 2.
68fn clap_error(e: clap::Error) -> error::Result<()> {
69 use clap::error::ErrorKind;
70 match e.kind() {
71 ErrorKind::DisplayHelp | ErrorKind::DisplayVersion => {
72 let _ = e.print();
73 Ok(())
74 }
75 ErrorKind::DisplayHelpOnMissingArgumentOrSubcommand => {
76 let _ = e.print();
77 Err(error::Error::exit(error::Kind::Usage))
78 }
79 _ => {
80 let text = e.render().to_string();
81 let line = text
82 .lines()
83 .find(|l| !l.trim().is_empty())
84 .unwrap_or("")
85 .trim_start_matches("error: ")
86 .trim();
87 let tip = text
88 .lines()
89 .find(|l| l.trim_start().starts_with("tip:"))
90 .map(|l| format!(" ({})", l.trim().trim_start_matches("tip: ")))
91 .unwrap_or_default();
92 Err(error::Error::usage(format!("{line}{tip} See --help.")))
93 }
94 }
95}