1pub(crate) mod cargo_plugin_installer;
10pub(crate) mod crate_installer;
11pub(crate) mod crate_version_check;
12pub(crate) mod rustup_component_installer;
13
14#[cfg(test)]
15#[path = "mod_test.rs"]
16mod mod_test;
17
18use crate::error::CargoMakeError;
19use crate::scriptengine;
20use crate::types::{FlowInfo, FlowState, InstallCrate, Task};
21use std::cell::RefCell;
22use std::rc::Rc;
23
24fn get_cargo_plugin_info_from_command(task_config: &Task) -> Option<(String, String)> {
25 match task_config.command {
26 Some(ref command) => {
27 if command == "cargo" {
28 match task_config.args {
29 Some(ref args) => {
30 if args.len() > 0 && !args[0].starts_with("-") {
31 let mut crate_name = "cargo-".to_string();
33 crate_name = crate_name + &args[0];
34
35 Some((args[0].clone(), crate_name))
36 } else {
37 None
38 }
39 }
40 None => None,
41 }
42 } else {
43 None
44 }
45 }
46 None => None,
47 }
48}
49
50fn get_first_command_arg(task_config: &Task) -> Option<String> {
51 match task_config.args {
52 Some(ref args) => {
53 if args.is_empty() {
54 None
55 } else {
56 Some(args[0].to_string())
57 }
58 }
59 None => None,
60 }
61}
62
63pub(crate) fn install(
64 task_config: &Task,
65 flow_info: &FlowInfo,
66 flow_state: Rc<RefCell<FlowState>>,
67) -> Result<(), CargoMakeError> {
68 if let Some(disable_install) = flow_info.config.config.disable_install {
69 if disable_install {
70 return Ok(());
71 }
72 }
73
74 let validate = !task_config.should_ignore_errors();
75
76 let toolchain = task_config.toolchain.clone();
77
78 let mut install_crate = task_config.install_crate.clone();
79 if let Some(ref install_crate_value) = install_crate {
80 if let InstallCrate::Enabled(enabled) = install_crate_value {
81 if *enabled {
82 install_crate = None;
84 }
85 }
86 }
87
88 match install_crate {
89 Some(ref install_crate_info) => match install_crate_info {
90 InstallCrate::Enabled(_) => (),
91 InstallCrate::Value(ref crate_name) => {
92 let first_arg = get_first_command_arg(task_config);
93 match first_arg {
94 Some(ref cargo_command) => cargo_plugin_installer::install_crate(
95 &toolchain,
96 Some(cargo_command),
97 crate_name,
98 &task_config.install_crate_args,
99 validate,
100 &None,
101 &None,
102 &None,
103 ),
104 None => cargo_plugin_installer::install_crate(
105 &toolchain,
106 None,
107 crate_name,
108 &task_config.install_crate_args,
109 validate,
110 &None,
111 &None,
112 &Some(false), ),
114 }?;
115 }
116 InstallCrate::CargoPluginInfo(ref install_info) => {
117 let (cargo_command, crate_name) =
118 match get_cargo_plugin_info_from_command(&task_config) {
119 Some(cargo_plugin_info) => cargo_plugin_info,
120 None => match get_first_command_arg(task_config) {
121 Some(arg) => match install_info.crate_name {
122 Some(ref crate_name) => (arg, crate_name.to_string()),
123 None => {
124 error!("Missing crate name to invoke.");
125 return Err(CargoMakeError::NotFound(String::from(
126 "Missing crate name to invoke.",
127 )));
128 }
129 },
130 None => match install_info.crate_name {
131 Some(ref crate_name) => {
132 (crate_name.to_string(), crate_name.to_string())
133 }
134 None => {
135 error!("Missing cargo command to invoke.");
136 return Err(CargoMakeError::NotFound(String::from(
137 "Missing crate command to invoke.",
138 )));
139 }
140 },
141 },
142 };
143
144 cargo_plugin_installer::install_crate(
145 &toolchain,
146 Some(&cargo_command),
147 &crate_name,
148 &task_config.install_crate_args,
149 validate,
150 &install_info.min_version,
151 &install_info.install_command,
152 &install_info.force,
153 )?;
154 }
155 InstallCrate::CrateInfo(ref install_info) => crate_installer::install(
156 &toolchain,
157 install_info,
158 &task_config.install_crate_args,
159 validate,
160 )?,
161 InstallCrate::RustupComponentInfo(ref install_info) => {
162 rustup_component_installer::install(&toolchain, install_info, validate);
163 }
164 },
165 None => match task_config.install_script {
166 Some(ref script) => {
167 scriptengine::invoke_script_in_flow_context(
168 &script,
169 task_config.script_runner.clone(),
170 task_config.script_runner_args.clone(),
171 task_config.script_extension.clone(),
172 validate,
173 Some(flow_info),
174 Some(flow_state),
175 )?;
176 ()
177 }
178 None => match get_cargo_plugin_info_from_command(&task_config) {
179 Some((cargo_command, crate_name)) => {
180 cargo_plugin_installer::install_crate(
181 &toolchain,
182 Some(&cargo_command),
183 &crate_name,
184 &task_config.install_crate_args,
185 validate,
186 &None,
187 &None,
188 &None,
189 )?;
190 }
191 None => debug!("No installation script defined."),
192 },
193 },
194 };
195 Ok(())
196}