Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(cli): abstract command execution to utility functions #647

Merged
merged 5 commits into from
Jan 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
110 changes: 37 additions & 73 deletions codegen/src/tools.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

pub test_input: String,

pub test_output: Option<String>,
pub test_output: String,
}

#[derive(Debug, serde::Deserialize, schemars::JsonSchema, Clone)]
Expand All @@ -29,9 +29,6 @@
#[expect(unused)]
pub homepage: Option<String>,

/// Whether to ignore the output of the command execution
pub ignore_output: bool,

pub tests: Option<Vec<ToolCommandTest>>,
}

Expand Down Expand Up @@ -114,8 +111,6 @@

pub module_name: String,

pub fn_name: String,

pub code: String,

pub serde_rename: String,
Expand Down Expand Up @@ -155,29 +150,26 @@

let test_fn_name = format!("test_{module_name}_{language}_{id}",);

let test_output = test.test_output.as_ref().map_or_else(
|| "None".to_owned(),
|output| {
format!(
"Some(
{INDENT}{INDENT}{INDENT}r#\"{output}\"#
{INDENT}{INDENT}{INDENT}.to_owned(),
{INDENT}{INDENT})"
)
},
);
let test_output = &test.test_output;

Check warning on line 153 in codegen/src/tools.rs

View check run for this annotation

Codecov / codecov/patch

codegen/src/tools.rs#L153

Added line #L153 was not covered by tests

let test_code = format!(
"{INDENT}#[test_with::executable({bin})]
{INDENT}fn {test_fn_name}() {{
{INDENT}{INDENT}let input = r#\"{input}\"#;
{INDENT}{INDENT}let output = {test_output};

{INDENT}{INDENT}let output = r#\"{test_output}\"#;

Check warning on line 161 in codegen/src/tools.rs

View check run for this annotation

Codecov / codecov/patch

codegen/src/tools.rs#L159-L161

Added lines #L159 - L161 were not covered by tests
{INDENT}{INDENT}let file_ext = crate::fttype::get_file_extension(\"{language}\");

Check warning on line 163 in codegen/src/tools.rs

View check run for this annotation

Codecov / codecov/patch

codegen/src/tools.rs#L163

Added line #L163 was not covered by tests
{INDENT}{INDENT}let snippet =
{INDENT}{INDENT}{INDENT}crate::execution::setup_snippet(input, &file_ext).expect(\"it to create a snippet file\");
{INDENT}{INDENT}let result = crate::tools::{module_name}::run(snippet.path(), 0)
{INDENT}{INDENT}{INDENT}.expect(\"it to be successful\")
{INDENT}{INDENT}{INDENT}.1;

{INDENT}{INDENT}let result =
{INDENT}{INDENT}{INDENT}crate::execution::run_tools(&super::COMMANDS, snippet.path(), super::set_args, 0)
{INDENT}{INDENT}{INDENT}{INDENT}.expect(\"it to be successful\")
{INDENT}{INDENT}{INDENT}{INDENT}.1
{INDENT}{INDENT}{INDENT}{INDENT}.expect(\"it to be some\");

Check warning on line 172 in codegen/src/tools.rs

View check run for this annotation

Codecov / codecov/patch

codegen/src/tools.rs#L166-L172

Added lines #L166 - L172 were not covered by tests
{INDENT}{INDENT}assert_eq!(result, output);
{INDENT}}}",
bin = if self.packages.npm.is_some() {
Expand All @@ -196,15 +188,9 @@
fn generate(&self) -> Vec<GeneratedCommand> {
let mut all_commands = Vec::new();

let map_execution_result_whitespace = format!("\n{INDENT}{INDENT}{INDENT}");

for (cmd, options) in &self.commands {
let command_name = self.get_command_name(cmd);

let set_args_fn_name = format!("set_{command_name}_args");

let run_fn_name = "run".to_string();

let mut command_types: Vec<String> = Vec::new();
{
if self.packages.npm.is_some() {
Expand All @@ -225,8 +211,8 @@
// TODO: generate if statements instead of array
let command_arr = if command_types.len() > 1 {
format!(
"\n{INDENT}{INDENT}{},\n{INDENT}",
command_types.join(format!(",\n{INDENT}{INDENT}").as_str())
"\n{INDENT}{},\n",
command_types.join(format!(",\n{INDENT}").as_str())

Check warning on line 215 in codegen/src/tools.rs

View check run for this annotation

Codecov / codecov/patch

codegen/src/tools.rs#L214-L215

Added lines #L214 - L215 were not covered by tests
)
} else {
command_types.join(", ")
Expand Down Expand Up @@ -279,51 +265,22 @@
format!("\n{}\n", tests.join("\n\n"))
};

let map_execution_result = if options.ignore_output {
".map(|value| (value.0, None))"
} else {
""
};

let execution_result_whitespace = if map_execution_result.is_empty() {
" "
} else {
map_execution_result_whitespace.as_str()
};
let command_type_count = command_types.len();

Check warning on line 268 in codegen/src/tools.rs

View check run for this annotation

Codecov / codecov/patch

codegen/src/tools.rs#L268

Added line #L268 was not covered by tests

let code = format!(
"{GENERATED_FILE_COMMENT}
use std::process::Command;

use crate::{{error::MdsfError, execution::execute_command, runners::CommandType}};
use crate::runners::CommandType;

Check warning on line 272 in codegen/src/tools.rs

View check run for this annotation

Codecov / codecov/patch

codegen/src/tools.rs#L272

Added line #L272 was not covered by tests

#[inline]
fn {set_args_fn_name}(mut cmd: Command, file_path: &std::path::Path) -> Command {{
pub fn set_args(
{INDENT}mut cmd: std::process::Command,
{INDENT}file_path: &std::path::Path,
) -> std::process::Command {{

Check warning on line 278 in codegen/src/tools.rs

View check run for this annotation

Codecov / codecov/patch

codegen/src/tools.rs#L275-L278

Added lines #L275 - L278 were not covered by tests
{string_args}
{INDENT}cmd
}}

#[inline]
pub fn {run_fn_name}(file_path: &std::path::Path, timeout: u64) -> Result<(bool, Option<String>), MdsfError> {{
{INDENT}let commands = [{command_arr}];

{INDENT}for (index, cmd) in commands.iter().enumerate() {{
{INDENT}{INDENT}let cmd = {set_args_fn_name}(cmd.build(), file_path);
{INDENT}{INDENT}let execution_result ={execution_result_whitespace}execute_command(cmd, file_path, timeout){map_execution_result};

{INDENT}{INDENT}if index == commands.len() - 1 {{
{INDENT}{INDENT}{INDENT}return execution_result;
{INDENT}{INDENT}}}

{INDENT}{INDENT}if let Ok(r) = execution_result {{
{INDENT}{INDENT}{INDENT}if !r.0 {{
{INDENT}{INDENT}{INDENT}{INDENT}return Ok(r);
{INDENT}{INDENT}{INDENT}}}
{INDENT}{INDENT}}}
{INDENT}}}

{INDENT}Ok((true, None))
}}
pub const COMMANDS: [CommandType; {command_type_count}] = [{command_arr}];

Check warning on line 283 in codegen/src/tools.rs

View check run for this annotation

Codecov / codecov/patch

codegen/src/tools.rs#L283

Added line #L283 was not covered by tests

#[cfg(test)]
mod test_{module_name} {{{tests}}}
Expand All @@ -333,7 +290,6 @@
all_commands.push(GeneratedCommand {
enum_value: command_name.to_case(Case::Pascal),
module_name,
fn_name: run_fn_name,
code,
serde_rename: format!(
"{}{}{}",
Expand Down Expand Up @@ -404,19 +360,22 @@
)?;

files.insert(command.module_name.clone());

let enum_value = &command.enum_value;
let module_name = &command.module_name;

Check warning on line 366 in codegen/src/tools.rs

View check run for this annotation

Codecov / codecov/patch

codegen/src/tools.rs#L363-L366

Added lines #L363 - L366 were not covered by tests
enum_values.insert(format!(
"{INDENT}#[serde(rename = \"{rename}\")]
{INDENT}/// `{bin} {args}`
{INDENT}{enum_name},",
{INDENT}{enum_value},",

Check warning on line 370 in codegen/src/tools.rs

View check run for this annotation

Codecov / codecov/patch

codegen/src/tools.rs#L370

Added line #L370 was not covered by tests
rename = command.serde_rename,
enum_name = command.enum_value,
bin = plugin.binary,
args = command.args.join(" ")
));

Check warning on line 375 in codegen/src/tools.rs

View check run for this annotation

Codecov / codecov/patch

codegen/src/tools.rs#L375

Added line #L375 was not covered by tests
format_snippet_values.insert(format!(
"{INDENT}{INDENT}{INDENT}Self::{} => {}::{}(snippet_path, timeout),",
command.enum_value, command.module_name, command.fn_name
));
"{INDENT}{INDENT}{INDENT}Self::{enum_value} => (&{module_name}::COMMANDS, {module_name}::set_args),"
));

Check warning on line 378 in codegen/src/tools.rs

View check run for this annotation

Codecov / codecov/patch

codegen/src/tools.rs#L377-L378

Added lines #L377 - L378 were not covered by tests

as_ref_values.insert(format!(
"{INDENT}{INDENT}{INDENT}Self::{} => \"{}\",",
Expand Down Expand Up @@ -461,9 +420,14 @@
{INDENT}{INDENT}snippet_path: &std::path::Path,
{INDENT}{INDENT}timeout: u64,
{INDENT}) -> Result<(bool, Option<String>), crate::error::MdsfError> {{
{INDENT}{INDENT}match self {{
{INDENT}{INDENT}let (commands, set_args_fn): (
{INDENT}{INDENT}{INDENT}&[crate::runners::CommandType],
{INDENT}{INDENT}{INDENT}fn(std::process::Command, &std::path::Path) -> std::process::Command,
{INDENT}{INDENT}) = match self {{

Check warning on line 426 in codegen/src/tools.rs

View check run for this annotation

Codecov / codecov/patch

codegen/src/tools.rs#L423-L426

Added lines #L423 - L426 were not covered by tests
{}
{INDENT}{INDENT}}}
{INDENT}{INDENT}}};

{INDENT}{INDENT}crate::execution::run_tools(commands, snippet_path, set_args_fn, timeout)

Check warning on line 430 in codegen/src/tools.rs

View check run for this annotation

Codecov / codecov/patch

codegen/src/tools.rs#L428-L430

Added lines #L428 - L430 were not covered by tests
{INDENT}}}
}}

Expand Down
2 changes: 0 additions & 2 deletions mdsf/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,6 @@ impl MdsfConfig {
// TODO: reduce the amount of cloning

if !self.language_aliases.is_empty() {
println!("has alias");

let mut seen_languages: std::collections::HashMap<String, String> =
std::collections::HashMap::new();

Expand Down
31 changes: 30 additions & 1 deletion mdsf/src/execution/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
config::MdsfConfig,
error::MdsfError,
fttype::get_file_extension,
runners::CommandType,
terminal::{
print_binary_not_in_path, print_error_formatting, print_formatter_info,
print_formatter_time,
Expand Down Expand Up @@ -129,7 +130,9 @@
}
}

handle_post_execution(spawn_command(cmd, timeout), snippet_path)
let output = spawn_command(cmd, timeout);

handle_post_execution(output, snippet_path)
}

#[inline]
Expand Down Expand Up @@ -286,3 +289,29 @@
}
}
}

#[inline]
pub fn run_tools(
commands: &[CommandType],
file_path: &std::path::Path,
set_args_fn: fn(std::process::Command, &std::path::Path) -> std::process::Command,
timeout: u64,
) -> Result<(bool, Option<String>), MdsfError> {
for (index, cmd) in commands.iter().enumerate() {
let cmd = set_args_fn(cmd.build(), file_path);

let execution_result = execute_command(cmd, file_path, timeout);

if index == commands.len() - 1 {
return execution_result;
}

if let Ok(r) = execution_result {
if !r.0 {
return Ok(r);
}
}

Check warning on line 313 in mdsf/src/execution/mod.rs

View check run for this annotation

Codecov / codecov/patch

mdsf/src/execution/mod.rs#L313

Added line #L313 was not covered by tests
}

Ok((true, None))

Check warning on line 316 in mdsf/src/execution/mod.rs

View check run for this annotation

Codecov / codecov/patch

mdsf/src/execution/mod.rs#L316

Added line #L316 was not covered by tests
}
1 change: 1 addition & 0 deletions mdsf/src/runners/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ fn setup_php_vender_bin_command(binary_name: &str) -> std::process::Command {
setup_command_from_path("./vendor/bin/", binary_name)
}

#[derive(Debug)]
pub enum CommandType {
BinaryPath(&'static str, &'static str),
Direct(&'static str),
Expand Down
56 changes: 25 additions & 31 deletions mdsf/src/tools/actionlint.rs
Original file line number Diff line number Diff line change
@@ -1,43 +1,23 @@
///
/// THIS FILE IS GENERATED USING CODE - DO NOT EDIT MANUALLY
///
use std::process::Command;

use crate::{error::MdsfError, execution::execute_command, runners::CommandType};
use crate::runners::CommandType;

#[inline]
fn set_actionlint_args(mut cmd: Command, file_path: &std::path::Path) -> Command {
pub fn set_args(
mut cmd: std::process::Command,
file_path: &std::path::Path,
) -> std::process::Command {
cmd.arg(file_path);
cmd
}

#[inline]
pub fn run(file_path: &std::path::Path, timeout: u64) -> Result<(bool, Option<String>), MdsfError> {
let commands = [CommandType::Direct("actionlint")];

for (index, cmd) in commands.iter().enumerate() {
let cmd = set_actionlint_args(cmd.build(), file_path);
let execution_result =
execute_command(cmd, file_path, timeout).map(|value| (value.0, None));

if index == commands.len() - 1 {
return execution_result;
}

if let Ok(r) = execution_result {
if !r.0 {
return Ok(r);
}
}
}

Ok((true, None))
}
pub const COMMANDS: [CommandType; 1] = [CommandType::Direct("actionlint")];

#[cfg(test)]
mod test_actionlint {
#[test_with::executable(actionlint)]
fn test_actionlint_yaml_e8ea2c4c1494f1e5() {
fn test_actionlint_yaml_da8378e9384e0b1f() {
let input = r#"name: action
on: push
jobs:
Expand All @@ -46,13 +26,27 @@ jobs:
steps:
- run: mdsf format .
"#;
let output = None;

let output = r#"name: action
on: push
jobs:
format:
runs-on: ubuntu-latest
steps:
- run: mdsf format .
"#;

let file_ext = crate::fttype::get_file_extension("yaml");

let snippet =
crate::execution::setup_snippet(input, &file_ext).expect("it to create a snippet file");
let result = crate::tools::actionlint::run(snippet.path(), 0)
.expect("it to be successful")
.1;

let result =
crate::execution::run_tools(&super::COMMANDS, snippet.path(), super::set_args, 0)
.expect("it to be successful")
.1
.expect("it to be some");

assert_eq!(result, output);
}
}
Loading
Loading