fix: sudo not intalled on runners
This commit is contained in:
parent
371e08c21b
commit
cccf08a414
9 changed files with 140 additions and 44 deletions
|
@ -1,4 +1,4 @@
|
|||
use std::{fs, path::PathBuf, str::FromStr};
|
||||
use std::{collections::VecDeque, fs, path::PathBuf, str::FromStr};
|
||||
|
||||
use parking_lot::RwLock;
|
||||
|
||||
|
@ -151,38 +151,31 @@ impl Command for ExecFile {
|
|||
.build()
|
||||
})?;
|
||||
if file_path.extension().is_some() && file_path.extension().unwrap() != "zensh" {
|
||||
return Err(ZenyxError::builder(ZenyxErrorKind::CommandParsing)
|
||||
Err(ZenyxError::builder(ZenyxErrorKind::CommandParsing)
|
||||
.with_message("Selected file was not a zensh file")
|
||||
.build());
|
||||
.build())
|
||||
} else {
|
||||
let zscript = fs::read_to_string(file_path).map_err(|e| {
|
||||
ZenyxError::builder(ZenyxErrorKind::Io)
|
||||
.with_message("Failed to read file")
|
||||
.with_source(e)
|
||||
.build()
|
||||
})?;
|
||||
let mut script_output = String::new();
|
||||
if let Ok(commands_to_execute) = eval(zscript) {
|
||||
for (cmd_name, cmd_args) in commands_to_execute {
|
||||
match COMMAND_MANAGER.read().execute(&cmd_name, cmd_args) {
|
||||
Ok(output) => script_output.push_str(&output),
|
||||
Err(e) => {
|
||||
return Err(ZenyxError::builder(
|
||||
ZenyxErrorKind::CommandExecution,
|
||||
)
|
||||
.with_message(format!(
|
||||
"Error executing command '{}' in script: {}",
|
||||
cmd_name, e
|
||||
))
|
||||
.build());
|
||||
match self.evaluate_script_heap_based(file_path) {
|
||||
Ok(commands_to_execute) => {
|
||||
for (cmd_name, cmd_args) in commands_to_execute {
|
||||
match COMMAND_MANAGER.read().execute(&cmd_name, cmd_args) {
|
||||
Ok(output) => script_output.push_str(&output),
|
||||
Err(e) => {
|
||||
return Err(ZenyxError::builder(
|
||||
ZenyxErrorKind::CommandExecution,
|
||||
)
|
||||
.with_message(format!(
|
||||
"Error executing command '{}' in script: {}",
|
||||
cmd_name, e
|
||||
))
|
||||
.build());
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(script_output)
|
||||
}
|
||||
return Ok(script_output);
|
||||
} else {
|
||||
return Err(ZenyxError::builder(ZenyxErrorKind::CommandExecution)
|
||||
.with_message("Failed to evaluate script")
|
||||
.build());
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -213,6 +206,102 @@ impl Command for ExecFile {
|
|||
}
|
||||
}
|
||||
|
||||
impl ExecFile {
|
||||
const MAX_RECURSION_DEPTH: usize = 100; // Increased for heap-based approach
|
||||
|
||||
fn evaluate_script_heap_based(
|
||||
&self,
|
||||
initial_file_path: PathBuf,
|
||||
) -> Result<Vec<(String, Option<Vec<String>>)>, ZenyxError> {
|
||||
let mut command_queue: VecDeque<(PathBuf, usize)> = VecDeque::new();
|
||||
let mut collected_commands = Vec::new();
|
||||
command_queue.push_back((initial_file_path, 0));
|
||||
|
||||
while let Some((current_file_path, current_depth)) = command_queue.pop_front() {
|
||||
if current_depth > Self::MAX_RECURSION_DEPTH {
|
||||
return Err(ZenyxError::builder(ZenyxErrorKind::CommandExecution)
|
||||
.with_message(format!(
|
||||
"Recursion limit of {} exceeded while executing script.",
|
||||
Self::MAX_RECURSION_DEPTH
|
||||
))
|
||||
.build());
|
||||
}
|
||||
|
||||
let zscript_result = fs::read_to_string(¤t_file_path).map_err(|e| {
|
||||
ZenyxError::builder(ZenyxErrorKind::Io)
|
||||
.with_message(format!("Failed to read file: {}", current_file_path.display()))
|
||||
.with_source(e)
|
||||
.build()
|
||||
});
|
||||
|
||||
match zscript_result {
|
||||
Ok(zscript) => {
|
||||
let commands: Vec<&str> = zscript.split(|c| c == ';' || c == '\n').collect();
|
||||
for command_str in commands {
|
||||
let command_str = command_str.trim();
|
||||
if command_str.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let tokens = tokenize(command_str);
|
||||
if tokens.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let cmd_name = &tokens[0];
|
||||
let args: Option<Vec<String>> = if tokens.len() > 1 {
|
||||
Some(tokens[1..].iter().map(|s| s.to_string()).collect())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
if cmd_name.to_lowercase() == "exec" {
|
||||
if let Some(ref file_args) = args {
|
||||
if let Some(nested_file_path_str) = file_args.first() {
|
||||
let nested_file_path =
|
||||
PathBuf::from_str(nested_file_path_str).map_err(|e| {
|
||||
ZenyxError::builder(ZenyxErrorKind::CommandParsing)
|
||||
.with_message("Invalid file path in nested exec command")
|
||||
.with_source(e)
|
||||
.build()
|
||||
})?;
|
||||
if nested_file_path.extension().is_some()
|
||||
&& nested_file_path.extension().unwrap() != "zensh"
|
||||
{
|
||||
return Err(ZenyxError::builder(
|
||||
ZenyxErrorKind::CommandParsing,
|
||||
)
|
||||
.with_message("Nested exec file was not a zensh file")
|
||||
.build());
|
||||
}
|
||||
command_queue.push_back((nested_file_path, current_depth + 1));
|
||||
} else {
|
||||
return Err(ZenyxError::builder(
|
||||
ZenyxErrorKind::CommandParsing,
|
||||
)
|
||||
.with_message("Not enough arguments for nested exec command")
|
||||
.build());
|
||||
}
|
||||
} else {
|
||||
return Err(ZenyxError::builder(
|
||||
ZenyxErrorKind::CommandParsing,
|
||||
)
|
||||
.with_message("Not enough arguments for nested exec command")
|
||||
.build());
|
||||
}
|
||||
} else {
|
||||
collected_commands.push((cmd_name.to_owned(), args));
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(collected_commands)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct CounterCommand {
|
||||
counter: RwLock<u32>,
|
||||
|
@ -318,4 +407,4 @@ fn eval(input: String) -> Result<Vec<(String, Option<Vec<String>>)>, ZenyxError>
|
|||
evaluted.push((cmd_name.to_owned(), args));
|
||||
}
|
||||
Ok(evaluted)
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue