1 use anyhow::{anyhow, Result};
2 use clap::Parser;
3 use console::style;
4 use smbpndk_cli::cli::CommandResult;
5 use smbpndk_cli::{
6 account::process_account,
7 cli::{Cli, Commands},
8 project::process_project,
9 };
10 use std::{
11 fs::{create_dir_all, OpenOptions},
12 path::PathBuf,
13 str::FromStr,
14 };
15 use tracing::subscriber::set_global_default;
16 use tracing_bunyan_formatter::{BunyanFormattingLayer, JsonStorageLayer};
17 use tracing_subscriber::{filter::LevelFilter, prelude::*, EnvFilter};
18
19 fn setup_logging(level: Option<EnvFilter>) -> Result<()> {
20 // Log in the current directory
21 let log_path = match home::home_dir() {
22 Some(path) => {
23 create_dir_all(path.join(".smb"))?;
24 let log_path = [path.to_str().unwrap(), "/.smb/smbpndk-cli.log"].join("");
25 // Create the file if it doesn't exist
26 let _file = OpenOptions::new()
27 .create(true)
28 .write(true)
29 .open(&log_path)?;
30
31 PathBuf::from(log_path)
32 }
33 None => {
34 return Err(anyhow!("Could not find home directory."));
35 }
36 };
37
38 let file = OpenOptions::new()
39 .create(true)
40 .write(true)
41 .open(log_path)
42 .unwrap();
43
44 let env_filter = if let Some(filter) = level {
45 filter
46 } else {
47 EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("trace"))
48 };
49
50 let formatting_layer = BunyanFormattingLayer::new("smb".into(), file);
51 let level_filter = LevelFilter::from_str(&env_filter.to_string())?;
52
53 let subscriber = tracing_subscriber::registry()
54 .with(formatting_layer.with_filter(level_filter))
55 .with(JsonStorageLayer);
56
57 set_global_default(subscriber).expect("Failed to set global default subscriber");
58
59 Ok(())
60 }
61
62 #[tokio::main]
63 async fn main() {
64 match run().await {
65 Ok(result) => {
66 let mut spinner = result.spinner;
67 spinner.stop_and_persist(&result.symbol, result.msg);
68 std::process::exit(1);
69 }
70 Err(e) => {
71 println!(
72 "\n{} {}",
73 style("✘".to_string()).for_stderr().red(),
74 style(e).red()
75 );
76 std::process::exit(1);
77 }
78 }
79 }
80
81 async fn run() -> Result<CommandResult> {
82 let cli = Cli::parse();
83
84 let log_level_error: Result<CommandResult> = Err(anyhow!(
85 "Invalid log level: {:?}.\n Valid levels are: trace, debug, info, warn, and error.",
86 cli.log_level
87 ));
88
89 if let Some(user_filter) = cli.log_level {
90 let filter = match EnvFilter::from_str(&user_filter) {
91 Ok(filter) => filter,
92 Err(_) => return log_level_error,
93 };
94 setup_logging(Some(filter))?;
95 } else {
96 setup_logging(None)?;
97 }
98
99 match cli.command {
100 Commands::Account { command } => process_account(command).await,
101 Commands::Project { command } => process_project(command).await,
102 //Commands::Oten { command } => process_auth_app(command).await,
103 }
104 }