aboutsummaryrefslogtreecommitdiff
path: root/development/tools/cargo-workspace2/src/cli.rs
blob: afea9e224176b4c068a668d2639a71f7c9dd99c6 (plain)
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
//! Helpers and utilities to parse the CLI input

use std::env;

pub struct CmdSet {
    pub debug: bool,
    pub line: Vec<String>,
}

fn get_nth(idx: usize) -> Option<String> {
    env::args().nth(idx).as_ref().map(|s| s.to_owned()).clone()
}

/// Call this instead of env::args() - it handles !commands too
pub fn parse_env_args() -> CmdSet {
    let mut line: Vec<_> = env::args().collect();
    let mut debug = false;

    if line.len() == 1 {
        render_help(2);
    }

    find_bang_commands().into_iter().for_each(|(idx, bang)| {
        let maybe_next = line.iter().nth(idx + 1).as_ref().map(|s| s.to_owned());

        match bang.trim() {
            "!help" => match maybe_next {
                None => render_help(0),
                Some(cmd) => crate::ops::render_help(cmd.to_string()),
            },
            "!version" => render_version(),
            "!debug" => {
                debug = true;
                line.remove(idx);
            }
            bang => {
                if debug {
                    eprintln!("Unrecognised bang command: {}", bang);
                }

                line.remove(idx);
            }
        }
    });

    CmdSet { line, debug }
}

/// Get env::args() and look for any string with a `!` in front of it.
/// If it's not in the set of known bang commands, ignore it.
fn find_bang_commands() -> Vec<(usize, String)> {
    env::args()
        .enumerate()
        .filter_map(|(idx, s)| {
            if s.starts_with("!") {
                Some((idx, s))
            } else {
                None
            }
        })
        .collect()
}

pub(crate) fn render_help(code: i32) -> ! {
    eprintln!("cargo-ws v{}", env!("CARGO_PKG_VERSION"));
    eprintln!("An expression language and command executor for cargo workspaces.");
    eprintln!("Usage: cargo ws2 <QUERY LANG> <COMMAND> [COMMAND ARGS] [!debug]");
    eprintln!("       cargo ws2 [!version | !debug]");
    eprintln!("       cargo ws2 !help [COMMAND]");
    eprintln!("");
    
    crate::ops::list_commands();
    eprintln!("");
    
    eprintln!("Query language examples:\n");
    eprintln!(" - [ foo bar ]: select crates foo and bar");
    eprintln!(" - {{ foo < }}: select crates that depend on foo");
    eprintln!(" - {{ foo < bar &< }}: select crates that depend on foo AND bar");
    eprintln!(" - {{ foo < bar |< }}: select crates that depend on foo OR bar");
    eprintln!("\nIf you have any questions, or find bugs, please e-mail me: kookie@spacekookie.de");
    std::process::exit(code)
}

fn render_version() -> ! {
    eprintln!("cargo-ws v{}", env!("CARGO_PKG_VERSION"));
    eprintln!(
        "Build with: {}",
        include_str!(concat!(env!("OUT_DIR"), "/rustc.version"))
    );
    std::process::exit(0)
}