Skip to main content

driven/cli/
mod.rs

1//! CLI Command Handlers
2//!
3//! Individual command implementations for the driven CLI.
4
5mod analyze;
6mod benchmark;
7mod cache;
8mod command_capture;
9mod convert;
10mod hook;
11mod init;
12mod module;
13mod sign;
14mod steer;
15mod strategy;
16mod strategy_receipt;
17mod sync;
18mod template;
19mod validate;
20
21pub use analyze::AnalyzeCommand;
22pub use benchmark::{BenchmarkCommand, BenchmarkResults};
23pub use cache::{CacheCommand, CacheStats};
24pub use convert::ConvertCommand;
25pub use hook::{HookCommand, HookInfo, TriggerResult, print_hook_details, print_hooks_table};
26pub use init::InitCommand;
27pub use module::{
28    InstallResult, ModuleCommand, ModuleDetails, ModuleInfo, UninstallResult, UpdateResult,
29    print_module_details, print_modules_table,
30};
31pub use sign::{SignCommand, generate_keypair};
32pub use steer::{SteerCommand, SteeringInfo, print_steering_details, print_steering_table};
33pub use strategy::{StrategyClaimOutput, StrategyCommand, StrategyStateOptions};
34pub use strategy_receipt::StrategyReceiptExecutionOptions;
35pub use sync::SyncCommand;
36pub use template::TemplateCommand;
37pub use validate::ValidateCommand;
38
39use crate::Result;
40use std::path::Path;
41
42/// Common options for all commands
43#[derive(Debug, Clone)]
44pub struct CommonOptions {
45    /// Project root path
46    pub project_root: std::path::PathBuf,
47    /// Verbosity level (0-3)
48    pub verbosity: u8,
49    /// Enable color output
50    pub color: bool,
51}
52
53impl Default for CommonOptions {
54    fn default() -> Self {
55        Self {
56            project_root: std::env::current_dir().unwrap_or_default(),
57            verbosity: 1,
58            color: true,
59        }
60    }
61}
62
63/// Print a success message
64pub fn print_success(msg: &str) {
65    use console::style;
66    println!("{} {}", style("✓").green().bold(), msg);
67}
68
69/// Print an error message
70pub fn print_error(msg: &str) {
71    use console::style;
72    eprintln!("{} {}", style("✗").red().bold(), msg);
73}
74
75/// Print a warning message
76pub fn print_warning(msg: &str) {
77    use console::style;
78    println!("{} {}", style("!").yellow().bold(), msg);
79}
80
81/// Print an info message
82pub fn print_info(msg: &str) {
83    use console::style;
84    println!("{} {}", style("ℹ").blue(), msg);
85}
86
87/// Create a progress bar
88pub fn create_progress_bar(len: u64, message: &str) -> indicatif::ProgressBar {
89    use indicatif::{ProgressBar, ProgressStyle};
90
91    let pb = ProgressBar::new(len);
92    pb.set_style(
93        ProgressStyle::default_bar()
94            .template("{spinner:.green} [{elapsed_precise}] [{bar:40.cyan/blue}] {pos}/{len} {msg}")
95            .unwrap()
96            .progress_chars("#>-"),
97    );
98    pb.set_message(message.to_string());
99    pb
100}
101
102/// Create a spinner
103pub fn create_spinner(message: &str) -> indicatif::ProgressBar {
104    use indicatif::{ProgressBar, ProgressStyle};
105
106    let pb = ProgressBar::new_spinner();
107    pb.set_style(
108        ProgressStyle::default_spinner()
109            .template("{spinner:.green} {msg}")
110            .unwrap(),
111    );
112    pb.set_message(message.to_string());
113    pb.enable_steady_tick(std::time::Duration::from_millis(100));
114    pb
115}
116
117/// Resolve project root
118pub fn resolve_project_root(path: Option<&Path>) -> Result<std::path::PathBuf> {
119    match path {
120        Some(p) => Ok(p.to_path_buf()),
121        None => std::env::current_dir().map_err(|e| {
122            crate::DrivenError::Config(format!("Failed to get current directory: {}", e))
123        }),
124    }
125}