1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
pub(crate) mod commands;
pub(crate) mod config;
pub(crate) mod state;
pub(crate) mod store;
pub(crate) mod utils;
use anyhow::Result;
use clap::Parser;
use commands::update::version_notice;
#[cfg(feature = "update")]
use commands::Commands::Update;
use commands::{handle_command, Commands};
use config::{ARCH, PLATFORM, VERSION};
use state::{State, StateOptions};
#[derive(Debug, Parser)]
#[clap(
name = "hop",
about = "🐇 Interact with Hop via command line",
version,
author
)]
pub struct CLI {
#[clap(subcommand)]
pub commands: Commands,
#[clap(
short,
long,
help = "Namespace or ID of the project to use",
global = true
)]
pub project: Option<String>,
#[clap(short = 'D', long, help = "Enable debug mode", global = true)]
pub debug: bool,
}
pub async fn run() -> Result<()> {
let cli = CLI::parse();
utils::set_hook();
utils::logs(cli.debug);
log::debug!("Hop-CLI v{VERSION} build for {ARCH}-{PLATFORM}");
utils::sudo::fix().await?;
let state = State::new(StateOptions {
override_project: std::env::var("PROJECT_ID").ok().or(cli.project),
override_token: std::env::var("TOKEN").ok(),
})
.await?;
match cli.commands {
#[cfg(feature = "update")]
Update(_) => None,
_ if cfg!(debug_assertions) || state.is_ci => None,
_ => version_notice(state.ctx.clone()).await.ok(),
};
if let Err(error) = handle_command(cli.commands, state).await {
log::error!("{error}");
std::process::exit(1);
}
utils::clean_term();
Ok(())
}
#[cfg(test)]
mod tests {
#[test]
fn test_cli() {
use clap::CommandFactory;
use super::*;
CLI::command().debug_assert();
}
}