/ sinks / sink-common / src / cli.rs
cli.rs
 1  use std::{fs, path::Path};
 2  
 3  use anstyle::{AnsiColor, Style};
 4  use apibara_observability::init_opentelemetry;
 5  use apibara_script::{Script, ScriptOptions};
 6  use clap::builder::Styles;
 7  use error_stack::{report, Result, ResultExt};
 8  use tokio_util::sync::CancellationToken;
 9  
10  use crate::{SinkError, SinkErrorReportExt, SinkErrorResultExt};
11  
12  pub fn load_script_from_path(path: &Path, options: ScriptOptions) -> Result<Script, SinkError> {
13      let path = path.to_string_lossy();
14      load_script(&path, options)
15  }
16  
17  /// Load a script from a file.
18  pub fn load_script(path: &str, options: ScriptOptions) -> Result<Script, SinkError> {
19      let Ok(_) = fs::metadata(path) else {
20          return Err(SinkError::load_script(&format!(
21              "script file not found: {}",
22              path
23          )));
24      };
25  
26      let current_dir = std::env::current_dir().load_script("failed to get current directory")?;
27  
28      let script = Script::from_file(path, current_dir, options).map_err(|err| {
29          report!(err).load_script(&format!("failed to load script at path: {}", path))
30      })?;
31  
32      Ok(script)
33  }
34  
35  /// Initialize opentelemetry and the sigint (ctrl-c) handler.
36  pub fn initialize_sink(ct: CancellationToken) -> Result<(), SinkError> {
37      init_opentelemetry()
38          .map_err(|err| report!(err).configuration("failed to initialize opentelemetry"))?;
39  
40      set_ctrlc_handler(ct).map_err(|err| report!(err).fatal("failed to setup ctrl-c handler"))?;
41  
42      Ok(())
43  }
44  
45  /// Connect the cancellation token to the ctrl-c handler.
46  pub fn set_ctrlc_handler(ct: CancellationToken) -> Result<(), ctrlc::Error> {
47      ctrlc::set_handler({
48          move || {
49              ct.cancel();
50          }
51      })
52      .attach_printable("failed to register ctrl-c handler")?;
53  
54      Ok(())
55  }
56  
57  /// A clap style for all Apibara CLI applications.
58  pub fn apibara_cli_style() -> Styles {
59      Styles::styled()
60          .header(Style::new().bold().fg_color(Some(AnsiColor::Yellow.into())))
61          .error(Style::new().bold().fg_color(Some(AnsiColor::Red.into())))
62          .usage(Style::new().bold().fg_color(Some(AnsiColor::Yellow.into())))
63          .literal(Style::new().fg_color(Some(AnsiColor::BrightCyan.into())))
64          .placeholder(Style::new())
65          .valid(Style::new().fg_color(Some(AnsiColor::BrightBlue.into())))
66          .invalid(
67              Style::new()
68                  .underline()
69                  .fg_color(Some(AnsiColor::Red.into())),
70          )
71  }