sagiegurari / cargo-make
1
//! # cargo_plugin_installer
2
//!
3
//! Installs cargo plugins automatically if needed.
4
//!
5

6
#[cfg(test)]
7
#[path = "./cargo_plugin_installer_test.rs"]
8
mod cargo_plugin_installer_test;
9

10
use crate::command;
11
use crate::installer::crate_version_check;
12
use crate::toolchain::wrap_command;
13
use envmnt;
14
use std::process::Command;
15

16 8
fn is_crate_installed(toolchain: &Option<String>, crate_name: &str) -> bool {
17 8
    debug!("Getting list of installed cargo commands.");
18

19 0
    let mut command_struct = match toolchain {
20 8
        Some(ref toolchain_string) => {
21 4
            let command_spec = wrap_command(toolchain_string, "cargo", &None);
22 4
            let mut cmd = Command::new(command_spec.command);
23

24 4
            let args_vec = command_spec.args.unwrap();
25 4
            for arg in args_vec.iter() {
26 4
                cmd.arg(arg);
27
            }
28

29 4
            cmd
30 4
        }
31 8
        None => Command::new("cargo"),
32
    };
33

34 8
    let result = command_struct.arg("--list").output();
35

36 8
    match result {
37 8
        Ok(output) => {
38 8
            let mut found = false;
39

40 8
            let exit_code = command::get_exit_code(Ok(output.status), false);
41 8
            command::validate_exit_code(exit_code);
42

43 8
            let stdout = String::from_utf8_lossy(&output.stdout);
44 8
            let lines: Vec<&str> = stdout.split(' ').collect();
45 8
            for mut line in lines {
46 8
                line = line.trim();
47

48 8
                debug!("Checking: {}", &line);
49

50 8
                if line.contains(crate_name) && crate_name.contains(line) {
51 8
                    found = true;
52 8
                    debug!("Found installed crate.");
53

54 6
                    break;
55
                }
56 8
            }
57

58 8
            found
59 8
        }
60 2
        Err(error) => {
61 0
            error!(
62 0
                "Unable to check if crate is installed: {} {:#?}",
63 0
                crate_name, &error
64
            );
65 0
            false
66 0
        }
67 0
    }
68 8
}
69

70 8
fn should_skip_crate_name(args: &Option<Vec<String>>) -> bool {
71 8
    match *args {
72 8
        Some(ref args_vec) => args_vec.contains(&"--git".to_string()),
73 8
        None => false,
74
    }
75 8
}
76

77 8
pub(crate) fn get_install_crate_args(
78
    crate_name: &str,
79
    force: bool,
80
    args: &Option<Vec<String>>,
81
    min_version: &Option<String>,
82
) -> Vec<String> {
83 8
    let mut install_args = vec!["install".to_string()];
84

85 8
    if force {
86 8
        install_args.push("--force".to_string());
87
    }
88

89 8
    match *args {
90 8
        Some(ref args_vec) => {
91 8
            for arg in args_vec.iter() {
92 8
                install_args.push(arg.to_string());
93
            }
94
        }
95 8
        None => debug!("No crate installation args defined."),
96
    };
97

98 8
    let skip_crate_name = should_skip_crate_name(&args);
99 8
    if !skip_crate_name {
100
        // add locked flags
101 8
        if let Some(version) = min_version {
102 2
            if envmnt::is("CARGO_MAKE_CRATE_INSTALLATION_LOCKED") {
103 2
                install_args.push("--locked".to_string());
104 2
                install_args.push("--version".to_string());
105 2
                install_args.push(version.to_string());
106
            }
107
        }
108

109 8
        install_args.push(crate_name.to_string());
110
    }
111

112 2
    install_args
113 8
}
114

115 8
pub(crate) fn install_crate(
116
    toolchain: &Option<String>,
117
    cargo_command: &str,
118
    crate_name: &str,
119
    args: &Option<Vec<String>>,
120
    validate: bool,
121
    min_version: &Option<String>,
122
) {
123 8
    let installed = is_crate_installed(&toolchain, cargo_command);
124 8
    let mut force = false;
125 8
    let run_installation = if !installed {
126 8
        true
127 8
    } else if toolchain.is_none() {
128 8
        match *min_version {
129 8
            Some(ref version) => {
130 2
                if crate_version_check::is_min_version_valid(&crate_name, version) {
131 2
                    false
132
                } else {
133 0
                    force = true;
134 0
                    true
135
                }
136
            }
137 8
            None => false,
138
        }
139
    } else {
140 0
        false
141
    };
142

143 8
    if run_installation {
144 8
        let install_args = get_install_crate_args(crate_name, force, args, &min_version);
145

146 0
        match toolchain {
147 8
            Some(ref toolchain_string) => {
148 0
                let command_spec = wrap_command(&toolchain_string, "cargo", &Some(install_args));
149 0
                command::run_command(&command_spec.command, &command_spec.args, validate)
150 0
            }
151 8
            None => command::run_command("cargo", &Some(install_args), validate),
152
        };
153 0
    }
154 8
}

Read our documentation on viewing source code .

Loading