cli/scriptengine/
script_utils.rs

1//! # script_utils
2//!
3//! Helper functions for script invocations.
4//!
5
6#[cfg(test)]
7#[path = "script_utils_test.rs"]
8mod script_utils_test;
9
10use crate::error::CargoMakeError;
11use crate::io::create_text_file;
12use fsio::file::write_text_file;
13use fsio::path::as_path::AsPath;
14use sha2::{Digest, Sha256};
15use std::path::PathBuf;
16
17pub(crate) fn create_script_file(
18    script_text: &Vec<String>,
19    extension: &str,
20) -> Result<String, CargoMakeError> {
21    let text = script_text.join("\n");
22
23    create_text_file(&text, &extension)
24}
25
26pub(crate) fn create_persisted_script_file(
27    script_text: &Vec<String>,
28    extension: &str,
29) -> Result<String, CargoMakeError> {
30    match create_persisted_script_file_with_options(script_text, extension, None) {
31        Ok(value) => Ok(value),
32        Err(_) => {
33            let limit = envmnt::get_usize("CARGO_MAKE_SCRIPT_FILE_PATH_MAX_LENGTH", 130);
34            create_persisted_script_file_with_options(script_text, extension, Some(limit))
35        }
36    }
37}
38
39fn create_persisted_script_file_with_options(
40    script_text: &Vec<String>,
41    extension: &str,
42    filename_limit: Option<usize>,
43) -> Result<String, CargoMakeError> {
44    let text = script_text.join("\n");
45
46    let string_bytes = text.as_bytes();
47    let mut hasher = Sha256::new();
48    hasher.update(string_bytes);
49    let mut file_name = hex::encode(hasher.finalize());
50
51    let default_target_directory = envmnt::get_or("CARGO_MAKE_CRATE_TARGET_DIRECTORY", "target");
52    let directory = envmnt::get_or(
53        "CARGO_MAKE_CRATE_CUSTOM_TRIPLE_TARGET_DIRECTORY",
54        &default_target_directory,
55    );
56    let mut file_path_buf = PathBuf::new();
57    file_path_buf.push(&directory);
58    file_path_buf.push("_cargo_make_temp");
59    file_path_buf.push("persisted_scripts");
60    file_path_buf.push(&file_name);
61    file_path_buf.set_extension(extension);
62    let mut file_path_string: String = file_path_buf.to_string_lossy().into_owned();
63
64    if let Some(limit) = filename_limit {
65        if file_path_string.len() > limit {
66            let reduce_size = file_path_string.len() - limit;
67            if reduce_size < file_name.len() {
68                file_name = file_name[0..file_name.len() - reduce_size].to_string();
69
70                file_path_buf = PathBuf::new();
71                file_path_buf.push(&directory);
72                file_path_buf.push("_cargo_make_temp");
73                file_path_buf.push("persisted_scripts");
74                file_path_buf.push(file_name);
75                file_path_buf.set_extension(extension);
76                file_path_string = file_path_buf.to_string_lossy().into_owned();
77            }
78        }
79    }
80
81    let file_path = file_path_string.as_path();
82    if file_path.exists() {
83        Ok(file_path_string)
84    } else {
85        match write_text_file(&file_path_string, &text) {
86            Ok(_) => Ok(file_path_string),
87            Err(error) => {
88                error!("Unable to create file: {} {:#?}", &file_path_string, &error);
89                Err(error.into())
90            }
91        }
92    }
93}