Repository: swellaby/rusty-hook (rust)

Issue:
Allow multiple commands for a given Git hook
## Description

I started using `rusty-hook` recently. I have everything configured now, but I can't execute multiple commands for a given Git hook, for instance:

```toml
[hooks]
pre-commit = "cargo fmt -- --check"
pre-push = [
  "cargo test --all",
  "cargo build --release"
]

[logging]
verbose = true
```

That's what I'm trying to achieve, but the configuration file is invalid. Is it possible to allow multiple actions/commands when a given Git hook is triggered?

## Value

Sometimes we would like to do several actions/things when a Git hook is triggered. Currently that's not possible, or at least in the way I would expect it to work. I can join the commands I guess, but it would be clear to accept an array and execute them.

Pull request:
Allow multiple commands issue 112
## Changes
<!-- Summary of changes included in this PR -->
- [x]  Allow multiple commands for a given Git hook
- [x] Write tests

## Related Issues
<!-- List any related/impacted issues -->
- Closes #112 


Patch:
diff --git a/src/config.rs b/src/config.rs
index 5c1309c..86b57b3 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -155,9 +155,18 @@ pub fn get_log_setting(config_contents: &str) -> bool {
 pub fn get_hook_script(config_contents: &str, hook_name: &str) -> Result<String, String> {
     match get_table_key_value_from_config(config_contents, "hooks", hook_name) {
         Err(err) => Err(err),
-        Ok(value) => match value.as_str() {
-            Some(script) => Ok(String::from(script)),
-            None => Err(String::from("Invalid hook config")),
+        Ok(value) => match value {
+            Value::String(script) => Ok(script),
+            Value::Array(val) => Ok(val
+                .iter()
+                .map(|v| v.as_str())
+                .collect::<Option<Vec<_>>>()
+                .ok_or(format!(
+                    "Invalid hook config for {}. An element in the array is not a string",
+                    hook_name
+                ))?
+                .join(" && ")),
+            _ => Err(String::from("Invalid hook config")),
         },
     }
 }


Test patch:
diff --git a/src/config_test.rs b/src/config_test.rs
index 12233b2..6925ccc 100644
--- a/src/config_test.rs
+++ b/src/config_test.rs
@@ -268,4 +268,33 @@ mod get_hook_script_tests {
         let result = get_hook_script(contents, "pre-commit");
         assert_eq!(result.unwrap(), "cargo test");
     }
+
+    #[test]
+    fn returns_result_when_value_array() {
+        let contents = r#"[hooks]
+            pre-commit = [
+                "cargo test",
+                "cargo fmt"
+            ]
+        "#;
+        let result = get_hook_script(contents, "pre-commit");
+        assert_eq!(result.unwrap(), "cargo test && cargo fmt");
+    }
+
+    #[test]
+    fn returns_error_when_wrong_value_array() {
+        let contents = r#"[hooks]
+            pre-commit = [
+                "cargo test",
+                8
+            ]
+        "#;
+        let result = get_hook_script(contents, "pre-commit");
+        assert_eq!(
+            result,
+            Err(String::from(
+                "Invalid hook config for pre-commit. An element in the array is not a string"
+            ))
+        );
+    }
 }