stanhope/write_script.rs
1//! *Write various kinds of script files* to files in a Process folder, based on the "Command" lines in that process's EBML file.
2//!
3//! General workflow, most of which occurs outside of this module:
4//! * User composes a process in an EBML file, with one or more "Command" lines
5//! * A call to stanhope to "scriptify" a process invokes the **read_ebml** module to collect the Command lines
6//! * Functions in this module know how to write scripts to the filesystem in various languages
7//!
8//! NOTE: this module doesn't help the user compose their "Command" lines in proper syntax, nor do any of these functions convert "Command" lines from one language to another. As far as these functions are concerned, it is assumed that "Command" line text is already in proper syntax for the script file type selected when running stanhope to *scriptify*.
9use std::{
10 fs::{OpenOptions},
11 io::{Write},
12};
13
14// ▄▄▄▄▄▄▄▄▄▄▄ ▄ ▄ ▄▄ ▄ ▄▄▄▄▄▄▄▄▄▄▄
15// ▐░░░░░░░░░░░▌▐░▌ ▐░▌▐░░▌ ▐░▌▐░░░░░░░░░░░▌
16// ▐░█▀▀▀▀▀▀▀▀▀ ▐░▌ ▐░▌▐░▌░▌ ▐░▌▐░█▀▀▀▀▀▀▀▀▀
17// ▐░▌ ▐░▌ ▐░▌▐░▌▐░▌ ▐░▌▐░▌
18// ▐░█▄▄▄▄▄▄▄▄▄ ▐░▌ ▐░▌▐░▌ ▐░▌ ▐░▌▐░▌
19// ▐░░░░░░░░░░░▌▐░▌ ▐░▌▐░▌ ▐░▌ ▐░▌▐░▌
20// ▐░█▀▀▀▀▀▀▀▀▀ ▐░▌ ▐░▌▐░▌ ▐░▌ ▐░▌▐░▌
21// ▐░▌ ▐░▌ ▐░▌▐░▌ ▐░▌▐░▌▐░▌
22// ▐░▌ ▐░█▄▄▄▄▄▄▄█░▌▐░▌ ▐░▐░▌▐░█▄▄▄▄▄▄▄▄▄
23// ▐░▌ ▐░░░░░░░░░░░▌▐░▌ ▐░░▌▐░░░░░░░░░░░▌
24// ▀ ▀▀▀▀▀▀▀▀▀▀▀ ▀ ▀▀ ▀▀▀▀▀▀▀▀▀▀▀
25
26/// Apply Born-Again SHell (BASH) formatting to the Command lines in a process
27/// * Comments are applied with lines starting with the "#" character
28/// * Shebang appears as the first line
29/// * Fairly safe assumption for *NIX systems: /bin/bash exists in client filesystem
30/// * "echo" used to output to stdout
31/// * "read -p" used to wait for operator to proceed (if "wait")
32///
33/// *This function is used for "bash" and "applescript" SCRIPT-FORMAT options
34pub fn bash_file_from_commands(c:Vec<(String,String)>, pnum:&String, wait:&String, suffix:&String) -> Vec<String> {
35 let mut script_header:Vec<String> = vec![];
36 script_header.push("#!/bin/bash".to_string());
37 script_header.push(("# ".to_owned() + pnum + suffix).to_string());
38 script_header.push(("# Automatically generated by stanhope, from ".to_owned() + pnum + ".ebml").to_string());
39 for (cmd,stp) in c {
40 script_header.push("".to_string());
41 script_header.push("# ".to_string() + &stp);
42 script_header.push("echo ".to_string() + &stp);
43 script_header.push(cmd);
44 match wait.as_str() {
45 "true" | "1" => {
46 script_header.push("read -p \"Press Enter to continue...\"".to_string());
47 },
48 _ => (),
49 };
50 }
51 script_header
52}
53
54/// Apply PowerShell formatting to the Command lines in a process
55/// * Comments are applied with lines starting with the "#" character
56/// * "Write-Host" used to output to stdout
57/// * "Read-Host" used to wait for operator to proceed (if "wait")
58///
59/// *This function is used for the "powershell" SCRIPT-FORMAT option
60pub fn powershell_file_from_commands(c:Vec<(String,String)>, pnum:&String, wait:&String, suffix:&String) -> Vec<String> {
61 let mut script_header:Vec<String> = vec![];
62 script_header.push(("# ".to_owned() + pnum + suffix).to_string());
63 script_header.push(("# Automatically generated by stanhope, from ".to_owned() + pnum + ".ebml").to_string());
64 for (cmd,stp) in c {
65 script_header.push("".to_string());
66 script_header.push("# ".to_string() + &stp);
67 script_header.push("Write-Host \"".to_string() + &stp + "\"");
68 script_header.push(cmd);
69 match wait.as_str() {
70 "true" | "1" => {
71 script_header.push("Write-Host \"Press Enter to continue...\"".to_string());
72 script_header.push("Read-Host | Out-Null # Pauses the script until Enter is pressed".to_string());
73 script_header.push("Write-Host \"Continuing script execution.\"".to_string());
74 },
75 _ => (),
76 };
77 }
78 script_header
79}
80
81/// Apply Python3 formatting to the Command lines in a process
82/// * Comments are applied with lines starting with the "#" character
83/// * Shebang appears as the first line
84/// * Important: assumes Python3 installed on client
85/// * "print" used to output to stdout, which is specific to Python3 and will not work on Python 2
86///
87/// *This function is used for the "python" SCRIPT-FORMAT option
88pub fn python_file_from_commands(c:Vec<(String,String)>, pnum:&String, wait:&String, suffix:&String) -> Vec<String> {
89 let mut script_header:Vec<String> = vec![];
90 script_header.push("#!/usr/bin/env python3".to_string());
91 script_header.push(("# ".to_owned() + pnum + suffix).to_string());
92 script_header.push(("# Automatically generated by stanhope, from ".to_owned() + pnum + ".ebml").to_string());
93 for (cmd,stp) in c {
94 script_header.push("".to_string());
95 script_header.push("# ".to_string() + &stp);
96 script_header.push("print(\"".to_string() + &stp + "\")");
97 script_header.push(cmd);
98 match wait.as_str() {
99 "true" | "1" => {
100 script_header.push("input(\"Press Enter to continue...\")".to_string());
101 },
102 _ => (),
103 };
104 }
105 script_header
106}
107
108/// Write all script lines to a file in the Process's folder.
109///
110/// If the file already exists, write over it. ("truncate")
111pub fn write_script(s:Vec<String>, pnum:&String, suffix:&String) {
112
113 // Assumption: every process has its own folder, and that folder is named the PROCESS NUMBER
114 let path = "./".to_string() + pnum;
115 let path_to_file = path.to_string() + "/" + pnum + suffix;
116
117 /*
118 // Scream out to stdout whether or not the file and/or path already exist
119 if verbose {
120 println!("{} file already exists: {}", &path_to_file, Path::new(&path_to_file).exists());
121 println!("Path to the script file will be: {}",path_to_file);
122 }
123 */
124
125 // Open the file to write
126 let mut file = OpenOptions::new()
127 .read(true)
128 .write(true)
129 .create(true)
130 .truncate(true)
131 .open(&path_to_file)
132 .expect("Could not open the file!");
133
134 for line in s {
135 file.write((line + "\n").as_bytes()).expect("Could not write template line into new file!");
136 }
137
138 println!("You will need to make the script file executable if it isn't already. For example, you might need to run:\nchmod +x {}",&path_to_file);
139
140}
141
142
143// ▄▄▄▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄▄▄▄
144// ▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌
145// ▀▀▀▀█░█▀▀▀▀ ▐░█▀▀▀▀▀▀▀▀▀ ▐░█▀▀▀▀▀▀▀▀▀ ▀▀▀▀█░█▀▀▀▀
146// ▐░▌ ▐░▌ ▐░▌ ▐░▌
147// ▐░▌ ▐░█▄▄▄▄▄▄▄▄▄ ▐░█▄▄▄▄▄▄▄▄▄ ▐░▌
148// ▐░▌ ▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌ ▐░▌
149// ▐░▌ ▐░█▀▀▀▀▀▀▀▀▀ ▀▀▀▀▀▀▀▀▀█░▌ ▐░▌
150// ▐░▌ ▐░▌ ▐░▌ ▐░▌
151// ▐░▌ ▐░█▄▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄▄█░▌ ▐░▌
152// ▐░▌ ▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌ ▐░▌
153// ▀ ▀▀▀▀▀▀▀▀▀▀▀ ▀▀▀▀▀▀▀▀▀▀▀ ▀
154
155#[cfg(test)]
156mod tests {
157
158 //use super::*;
159
160
161}