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
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
use anyhow::Result;

use super::super::cmd;
use super::super::model;
use super::super::model::Color;
use super::super::query;

/// Main entry point for the "garden exec" command
/// Parameters:
/// - options: `garden::model::CommandOptions`

pub fn main(app: &mut model::ApplicationContext) -> Result<()> {
    let mut query: Vec<String> = Vec::new();
    parse_args(&mut app.options, &mut query);

    let verbose = app.options.verbose;
    let config = app.get_root_config_mut();
    inspect(config, verbose, &query)
}

/// Parse "inspect" arguments.
fn parse_args(options: &mut model::CommandOptions, query: &mut Vec<String>) {
    let mut ap = argparse::ArgumentParser::new();
    ap.set_description("garden inspect - query tree status");

    ap.refer(query).add_argument(
        "query",
        argparse::List,
        "gardens/groups/trees to exec (tree queries)",
    );

    options.args.insert(0, "garden inspect".into());
    cmd::parse_args(ap, options.args.to_vec());

    if query.is_empty() {
        query.push(".".into());
    }

    if options.is_debug("inspect") {
        debug!("query: {:?}", query);
    }
}

/// Execute a command over every tree in the evaluated tree query.
pub fn inspect(config: &mut model::Configuration, verbose: bool, queries: &[String]) -> Result<()> {
    for query in queries {
        // Resolve the tree query into a vector of tree contexts.
        let contexts = query::resolve_trees(config, query);
        // Loop over each context and inspect the tree.
        for context in &contexts {
            let tree = &config.trees[context.tree];
            let path = tree.path_as_ref()?;
            // Sparse gardens/missing trees are ok -> skip these entries.
            if !std::path::PathBuf::from(&path).exists() {
                if verbose {
                    println!(
                        "{} {}  {}",
                        Color::red("-").dimmed(),
                        Color::red(tree.get_name()),
                        Color::red(&path).dimmed()
                    );
                } else {
                    println!(
                        "{} {}",
                        Color::red("-").dimmed(),
                        Color::red(tree.get_name())
                    );
                }
                continue;
            }

            if tree.is_symlink {
                if verbose {
                    println!(
                        "{} {}  {} {} {}",
                        Color::green("+"),
                        Color::green(tree.get_name()).bold(),
                        Color::green(&path),
                        Color::yellow("->").bold(),
                        Color::blue(&tree.symlink_as_ref()?).bold()
                    );
                } else {
                    println!(
                        "{} {} {} {}",
                        Color::green("+"),
                        Color::green(tree.get_name()).bold(),
                        Color::yellow("->").bold(),
                        Color::blue(tree.symlink_as_ref()?).bold()
                    );
                }
            } else if verbose {
                println!(
                    "{} {}  {}",
                    Color::green("+"),
                    Color::green(tree.get_name()).bold(),
                    Color::green(&path)
                );
            } else {
                println!(
                    "{} {}",
                    Color::green("+"),
                    Color::green(tree.get_name()).bold()
                );
            }
        }
    }

    Ok(())
}