cli/scriptengine/
rsscript.rs1#[cfg(test)]
7#[path = "rsscript_test.rs"]
8mod rsscript_test;
9
10use crate::command;
11use crate::error::CargoMakeError;
12use crate::installer::{cargo_plugin_installer, crate_installer};
13use crate::scriptengine::script_utils::create_persisted_script_file;
14use crate::types::{InstallCrateInfo, TestArg};
15
16#[derive(PartialEq, Debug)]
17enum ScriptRunner {
18 RustScript,
19 CargoScript,
20 CargoPlay,
21}
22
23fn get_script_runner() -> ScriptRunner {
24 let provider = envmnt::get_or("CARGO_MAKE_RUST_SCRIPT_PROVIDER", "rust-script");
25
26 match provider.as_str() {
27 "rust-script" => ScriptRunner::RustScript,
28 "cargo-script" => ScriptRunner::CargoScript,
29 "cargo-play" => ScriptRunner::CargoPlay,
30 _ => ScriptRunner::RustScript,
31 }
32}
33
34fn install_crate(provider: &ScriptRunner) -> Result<(), CargoMakeError> {
35 match provider {
37 ScriptRunner::RustScript => {
38 let info = InstallCrateInfo {
39 crate_name: "rust-script".to_string(),
40 rustup_component_name: None,
41 binary: "rust-script".to_string(),
42 test_arg: TestArg {
43 inner: vec!["--version".to_string()],
44 },
45 min_version: None,
46 version: None,
47 install_command: None,
48 force: None,
49 };
50
51 crate_installer::install(&None, &info, &None, false)?;
52 }
53 ScriptRunner::CargoScript => cargo_plugin_installer::install_crate(
54 &None,
55 Some("script"),
56 "cargo-script",
57 &None,
58 true,
59 &None,
60 &None,
61 &None,
62 )?,
63 ScriptRunner::CargoPlay => cargo_plugin_installer::install_crate(
64 &None,
65 Some("play"),
66 "cargo-play",
67 &None,
68 true,
69 &None,
70 &None,
71 &None,
72 )?,
73 };
74 Ok(())
75}
76
77fn create_rust_file(rust_script: &Vec<String>) -> Result<String, CargoMakeError> {
78 create_persisted_script_file(rust_script, "rs")
79}
80
81fn run_file(
82 file: &str,
83 runner_arguments: Option<Vec<String>>,
84 cli_arguments: &Vec<String>,
85 provider: &ScriptRunner,
86) -> Result<bool, CargoMakeError> {
87 let (use_cargo, command) = match provider {
88 ScriptRunner::RustScript => (false, "rust-script"),
89 ScriptRunner::CargoScript => (true, "script"),
90 ScriptRunner::CargoPlay => (true, "play"),
91 };
92
93 let mut args = vec![];
94 if use_cargo {
95 args.push(command.to_string());
96 }
97 if let Some(mut runner_args) = runner_arguments {
98 args.append(&mut runner_args);
99 }
100 args.push(file.to_string());
101 let mut cli_args = cli_arguments.clone();
102 args.append(&mut cli_args);
103
104 let exit_code = if use_cargo {
105 command::run_command("cargo", &Some(args), false)
106 } else {
107 command::run_command(command, &Some(args), false)
108 }?;
109 debug!("Executed rust code, exit code: {}", exit_code);
110
111 Ok(exit_code == 0)
112}
113
114pub(crate) fn execute(
115 rust_script: &Vec<String>,
116 runner_arguments: Option<Vec<String>>,
117 cli_arguments: &Vec<String>,
118 validate: bool,
119) -> Result<bool, CargoMakeError> {
120 let provider = get_script_runner();
121
122 install_crate(&provider)?;
123
124 let file = create_rust_file(rust_script)?;
125
126 let valid = run_file(&file, runner_arguments, &cli_arguments, &provider)?;
127
128 if validate && !valid {
129 error!("Unable to execute rust code.");
130 }
131
132 Ok(valid)
133}