1pub mod commands;
4pub mod output;
5
6pub use commands::{check, watch, wrap, init, config, hook};
7pub use output::{OutputFormatter, HumanFormatter, JsonFormatter, SarifFormatter};
8
9use oparry_core::Config;
10use std::path::PathBuf;
11
12#[derive(Debug, Clone)]
14pub struct CliContext {
15 pub config: Config,
17 pub work_dir: PathBuf,
19 pub verbose: bool,
21 pub quiet: bool,
23}
24
25impl CliContext {
26 pub fn new() -> anyhow::Result<Self> {
28 let config = Config::load()
29 .map_err(|e| anyhow::anyhow!("Failed to load config: {}", e))?;
30
31 let work_dir = std::env::current_dir()
32 .map_err(|e| anyhow::anyhow!("Failed to get work dir: {}", e))?;
33
34 Ok(Self {
35 config,
36 work_dir,
37 verbose: false,
38 quiet: false,
39 })
40 }
41
42 pub fn with_config_path(config_path: PathBuf) -> anyhow::Result<Self> {
44 let config = Config::from_file(&config_path)
45 .map_err(|e| anyhow::anyhow!("Failed to load config from {:?}: {}", config_path, e))?;
46
47 let work_dir = std::env::current_dir()
48 .map_err(|e| anyhow::anyhow!("Failed to get work dir: {}", e))?;
49
50 Ok(Self {
51 config,
52 work_dir,
53 verbose: false,
54 quiet: false,
55 })
56 }
57
58 pub fn with_verbose(mut self, verbose: bool) -> Self {
60 self.verbose = verbose;
61 self
62 }
63
64 pub fn with_quiet(mut self, quiet: bool) -> Self {
66 self.quiet = quiet;
67 self
68 }
69}
70
71impl Default for CliContext {
72 fn default() -> Self {
73 Self::new().unwrap_or_else(|e| {
74 eprintln!("Warning: Failed to initialize context: {}", e);
75 Self {
76 config: Config::default(),
77 work_dir: PathBuf::from("."),
78 verbose: false,
79 quiet: false,
80 }
81 })
82 }
83}