fix(function): build bundled bash tools without writing back to the source tree
PR #24 follow-up 1. The bundled-tools test called the writing generate_bash_declarations on the repo's assets/functions/tools/*.sh, so cargo test could rewrite tracked files. Split the build+export step into a pure build_bash_tool so the test never touches the source tree.
This commit is contained in:
2 files changed
+17
-7
No files matched your search
+2
-1
@@ -3389,7 +3389,8 @@ mod tests {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let name = path.file_stem().unwrap().to_string_lossy().to_string();
|
let name = path.file_stem().unwrap().to_string_lossy().to_string();
|
||||||
let declarations = Functions::generate_declarations(&path)
|
let src = std::fs::read_to_string(&path).unwrap();
|
||||||
|
let (_, declarations) = bash::build_bash_tool(&src, &name)
|
||||||
.unwrap_or_else(|e| panic!("bundled tool '{name}' failed to parse: {e}"));
|
.unwrap_or_else(|e| panic!("bundled tool '{name}' failed to parse: {e}"));
|
||||||
assert!(
|
assert!(
|
||||||
!declarations.is_empty(),
|
!declarations.is_empty(),
|
||||||
|
|||||||
+15
-6
@@ -18,23 +18,32 @@ pub fn generate_bash_declarations(
|
|||||||
.with_context(|| format!("Failed to load script at '{tool_file:?}'"))?;
|
.with_context(|| format!("Failed to load script at '{tool_file:?}'"))?;
|
||||||
|
|
||||||
debug!("Building script at '{tool_file:?}'");
|
debug!("Building script at '{tool_file:?}'");
|
||||||
|
let (build_script, declarations) = build_bash_tool(&src, file_name)
|
||||||
|
.with_context(|| format!("Failed to build script at '{tools_file_path:?}'"))?;
|
||||||
|
function::write_file_atomic(tools_file_path, &build_script, Some(0o755))
|
||||||
|
.with_context(|| format!("Failed to write built script to '{tools_file_path:?}'"))?;
|
||||||
|
|
||||||
|
Ok(declarations)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Builds the argc script and derives its declarations without touching the
|
||||||
|
/// filesystem, so callers can inspect a tool source without rewriting it.
|
||||||
|
pub fn build_bash_tool(src: &str, file_name: &str) -> Result<(String, Vec<FunctionDeclaration>)> {
|
||||||
let build_script = argc::build(
|
let build_script = argc::build(
|
||||||
&src,
|
src,
|
||||||
"",
|
"",
|
||||||
env::var("TERM_WIDTH").ok().and_then(|v| v.parse().ok()),
|
env::var("TERM_WIDTH").ok().and_then(|v| v.parse().ok()),
|
||||||
)?;
|
)?;
|
||||||
let build_script = allow_empty_required_values(&build_script);
|
let build_script = allow_empty_required_values(&build_script);
|
||||||
function::write_file_atomic(tools_file_path, &build_script, Some(0o755))
|
|
||||||
.with_context(|| format!("Failed to write built script to '{tools_file_path:?}'"))?;
|
|
||||||
|
|
||||||
let command_value = argc::export(&build_script, file_name)
|
let command_value = argc::export(&build_script, file_name)
|
||||||
.with_context(|| format!("Failed to parse script at '{tool_file:?}'"))?;
|
.with_context(|| format!("Failed to parse script '{file_name}'"))?;
|
||||||
if command_value.subcommands.is_empty() {
|
if command_value.subcommands.is_empty() {
|
||||||
let function_declaration =
|
let function_declaration =
|
||||||
command_to_function_declaration(&command_value).ok_or_else(|| {
|
command_to_function_declaration(&command_value).ok_or_else(|| {
|
||||||
anyhow::format_err!("Tool definition missing or empty description: {file_name}")
|
anyhow::format_err!("Tool definition missing or empty description: {file_name}")
|
||||||
})?;
|
})?;
|
||||||
Ok(vec![function_declaration])
|
Ok((build_script, vec![function_declaration]))
|
||||||
} else {
|
} else {
|
||||||
let mut declarations = vec![];
|
let mut declarations = vec![];
|
||||||
for subcommand in &command_value.subcommands {
|
for subcommand in &command_value.subcommands {
|
||||||
@@ -54,7 +63,7 @@ pub fn generate_bash_declarations(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(declarations)
|
Ok((build_script, declarations))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user