cli/installer/
crate_installer.rs1#[cfg(test)]
7#[path = "crate_installer_test.rs"]
8mod crate_installer_test;
9
10use crate::command;
11use crate::error::CargoMakeError;
12use crate::installer::crate_version_check;
13use crate::installer::{cargo_plugin_installer, rustup_component_installer};
14use crate::toolchain::wrap_command;
15use crate::types::{CommandSpec, InstallCrateInfo, InstallRustupComponentInfo, ToolchainSpecifier};
16
17fn invoke_rustup_install(toolchain: &Option<ToolchainSpecifier>, info: &InstallCrateInfo) -> bool {
18 match info.rustup_component_name {
19 Some(ref component) => {
20 let rustup_component_info = InstallRustupComponentInfo {
21 rustup_component_name: component.to_string(),
22 binary: Some(info.binary.clone()),
23 test_arg: Some(info.test_arg.clone()),
24 };
25 rustup_component_installer::invoke_rustup_install(&toolchain, &rustup_component_info)
26 }
27 None => false,
28 }
29}
30
31fn invoke_cargo_install(
32 toolchain: &Option<ToolchainSpecifier>,
33 info: &InstallCrateInfo,
34 args: &Option<Vec<String>>,
35 validate: bool,
36) -> Result<(), CargoMakeError> {
37 let (automatic_lock_version, version_option) = if info.min_version.is_some() {
38 (false, &info.min_version)
39 } else {
40 (info.version.is_some(), &info.version)
41 };
42
43 let remove_lock =
44 if automatic_lock_version && !envmnt::is("CARGO_MAKE_CRATE_INSTALLATION_LOCKED") {
45 envmnt::set_bool("CARGO_MAKE_CRATE_INSTALLATION_LOCKED", true);
46 true
47 } else {
48 false
49 };
50
51 let install_args = cargo_plugin_installer::get_install_crate_args(
52 &info.crate_name,
53 info.force.unwrap_or(true),
54 &args,
55 version_option,
56 &info.install_command,
57 );
58
59 let command_spec = match toolchain {
60 Some(ref toolchain_string) => wrap_command(toolchain_string, "cargo", &Some(install_args)),
61 None => CommandSpec {
62 command: "cargo".to_string(),
63 args: Some(install_args),
64 },
65 };
66
67 command::run_command(&command_spec.command, &command_spec.args, validate)?;
68
69 if remove_lock {
70 envmnt::remove("CARGO_MAKE_CRATE_INSTALLATION_LOCKED");
71 }
72
73 Ok(())
74}
75
76fn is_crate_only_info(info: &InstallCrateInfo) -> bool {
77 match info.rustup_component_name {
78 Some(_) => false,
79 None => true,
80 }
81}
82
83pub(crate) fn install(
84 toolchain: &Option<ToolchainSpecifier>,
85 info: &InstallCrateInfo,
86 args: &Option<Vec<String>>,
87 validate: bool,
88) -> Result<(), CargoMakeError> {
89 let installed =
90 rustup_component_installer::is_installed(&toolchain, &info.binary, &info.test_arg);
91 let crate_only_info = is_crate_only_info(&info);
92 let run_installation = if !installed {
93 true
94 } else if crate_only_info && toolchain.is_none() {
95 match info.min_version {
96 Some(ref version) => !crate_version_check::is_min_version_valid(
97 &info.crate_name,
98 version,
99 Some(&info.binary),
100 ),
101 None => match info.version {
102 Some(ref version) => !crate_version_check::is_version_valid(
103 &info.crate_name,
104 version,
105 Some(&info.binary),
106 ),
107 None => false,
108 },
109 }
110 } else {
111 false
112 };
113
114 if run_installation {
115 debug!("Crate: {} not installed.", &info.crate_name);
116
117 if !invoke_rustup_install(&toolchain, &info) {
118 invoke_cargo_install(&toolchain, &info, &args, validate)?;
119 }
120 }
121 Ok(())
122}