Compare commits

...

10 Commits

Author SHA1 Message Date
Bauke 0835a08981
Use snake_case for renaming enums. 2022-10-28 14:37:42 +02:00
Bauke 10c871d5c9
Add default pre_commit. 2022-10-28 14:09:17 +02:00
Bauke 1084bd08e2
Add default to on_failure. 2022-10-28 14:08:27 +02:00
Bauke bff78ccc21
Add a with-hooks test. 2022-10-28 14:06:03 +02:00
Bauke c47d0a1e6e
Implement Default for ExitAction. 2022-10-28 14:03:32 +02:00
Bauke 3f0f643a8a
Add a test for serializing and update snapshots. 2022-10-28 14:03:01 +02:00
Bauke 7a543409ba
Add the PreCommit hook struct. 2022-10-28 13:58:36 +02:00
Bauke 1eecfa7146
Add the ExitAction enum. 2022-10-28 13:35:34 +02:00
Bauke 4d62527e23
Add the Task struct. 2022-10-28 13:13:53 +02:00
Bauke 3846a62591
Project setup commit. 2022-10-28 12:23:05 +02:00
15 changed files with 709 additions and 0 deletions

432
Cargo.lock generated Normal file
View File

@ -0,0 +1,432 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "addr2line"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b"
dependencies = [
"gimli",
]
[[package]]
name = "adler"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "backtrace"
version = "0.3.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cab84319d616cfb654d03394f38ab7e6f0919e181b1b57e1fd15e7fb4077d9a7"
dependencies = [
"addr2line",
"cc",
"cfg-if",
"libc",
"miniz_oxide",
"object",
"rustc-demangle",
]
[[package]]
name = "cc"
version = "1.0.73"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "color-eyre"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a667583cca8c4f8436db8de46ea8233c42a7d9ae424a82d338f2e4675229204"
dependencies = [
"backtrace",
"color-spantrace",
"eyre",
"indenter",
"once_cell",
"owo-colors",
"tracing-error",
]
[[package]]
name = "color-spantrace"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ba75b3d9449ecdccb27ecbc479fdc0b87fa2dd43d2f8298f9bf0e59aacc8dce"
dependencies = [
"once_cell",
"owo-colors",
"tracing-core",
"tracing-error",
]
[[package]]
name = "console"
version = "0.15.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c050367d967ced717c04b65d8c619d863ef9292ce0c5760028655a2fb298718c"
dependencies = [
"encode_unicode",
"lazy_static",
"libc",
"terminal_size",
"winapi",
]
[[package]]
name = "encode_unicode"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
[[package]]
name = "eyre"
version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb"
dependencies = [
"indenter",
"once_cell",
]
[[package]]
name = "gimli"
version = "0.26.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d"
[[package]]
name = "hooked"
version = "0.1.0"
dependencies = [
"color-eyre",
"insta",
"serde",
"test-case",
"toml",
]
[[package]]
name = "indenter"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
[[package]]
name = "insta"
version = "1.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "581d4e3314cae4536e5d22ffd23189d4a374696c5ef733eadafae0ed273fd303"
dependencies = [
"console",
"lazy_static",
"linked-hash-map",
"similar",
"yaml-rust",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.137"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89"
[[package]]
name = "linked-hash-map"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
[[package]]
name = "memchr"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "miniz_oxide"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34"
dependencies = [
"adler",
]
[[package]]
name = "object"
version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53"
dependencies = [
"memchr",
]
[[package]]
name = "once_cell"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1"
[[package]]
name = "owo-colors"
version = "3.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f"
[[package]]
name = "pin-project-lite"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
[[package]]
name = "proc-macro-error"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [
"proc-macro-error-attr",
"proc-macro2",
"quote",
"syn",
"version_check",
]
[[package]]
name = "proc-macro-error-attr"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [
"proc-macro2",
"quote",
"version_check",
]
[[package]]
name = "proc-macro2"
version = "1.0.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rustc-demangle"
version = "0.1.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342"
[[package]]
name = "serde"
version = "1.0.147"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.147"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "sharded-slab"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31"
dependencies = [
"lazy_static",
]
[[package]]
name = "similar"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62ac7f900db32bf3fd12e0117dd3dc4da74bc52ebaac97f39668446d89694803"
[[package]]
name = "syn"
version = "1.0.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "terminal_size"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df"
dependencies = [
"libc",
"winapi",
]
[[package]]
name = "test-case"
version = "2.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21d6cf5a7dffb3f9dceec8e6b8ca528d9bd71d36c9f074defb548ce161f598c0"
dependencies = [
"test-case-macros",
]
[[package]]
name = "test-case-macros"
version = "2.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e45b7bf6e19353ddd832745c8fcf77a17a93171df7151187f26623f2b75b5b26"
dependencies = [
"cfg-if",
"proc-macro-error",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "thread_local"
version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180"
dependencies = [
"once_cell",
]
[[package]]
name = "toml"
version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7"
dependencies = [
"serde",
]
[[package]]
name = "tracing"
version = "0.1.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
dependencies = [
"cfg-if",
"pin-project-lite",
"tracing-core",
]
[[package]]
name = "tracing-core"
version = "0.1.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a"
dependencies = [
"once_cell",
"valuable",
]
[[package]]
name = "tracing-error"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e"
dependencies = [
"tracing",
"tracing-subscriber",
]
[[package]]
name = "tracing-subscriber"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70"
dependencies = [
"sharded-slab",
"thread_local",
"tracing-core",
]
[[package]]
name = "unicode-ident"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
[[package]]
name = "valuable"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "yaml-rust"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
dependencies = [
"linked-hash-map",
]

24
Cargo.toml Normal file
View File

@ -0,0 +1,24 @@
[package]
name = "hooked"
description = "Small Git hooks manager."
repository = "https://git.bauke.xyz/Holllo/hooked"
license = "AGPL-3.0-or-later"
version = "0.1.0"
authors = ["Holllo <helllo@holllo.org>"]
edition = "2021"
[lib]
name = "hooked"
path = "source/lib.rs"
[dependencies]
color-eyre = "0.6.2"
toml = "0.5.9"
[dependencies.serde]
features = ["derive"]
version = "1.0.147"
[dev-dependencies]
insta = "1.21.0"
test-case = "2.2.2"

View File

@ -0,0 +1,17 @@
//! Action to take on hook exit.
use serde::{Deserialize, Serialize};
/// Action to take on hook exit.
#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum ExitAction {
Continue,
Stop,
}
impl Default for ExitAction {
fn default() -> Self {
Self::Stop
}
}

21
source/config/general.rs Normal file
View File

@ -0,0 +1,21 @@
//! General configuration definitions.
use std::path::PathBuf;
use serde::{Deserialize, Serialize};
/// General Hooked configuration.
#[derive(Debug, Deserialize, Serialize)]
#[serde(default, deny_unknown_fields)]
pub struct General {
/// The directory to use for hooks.
pub directory: PathBuf,
}
impl Default for General {
fn default() -> Self {
Self {
directory: PathBuf::from("hooks"),
}
}
}

39
source/config/mod.rs Normal file
View File

@ -0,0 +1,39 @@
//! Configuration structs and logic.
use std::{fs::read_to_string, path::Path};
use {
color_eyre::Result,
serde::{Deserialize, Serialize},
};
mod exit_action;
mod general;
mod pre_commit;
mod task;
pub use exit_action::*;
pub use general::*;
pub use pre_commit::*;
pub use task::*;
/// The main Hooked configuration struct.
#[derive(Debug, Default, Deserialize, Serialize)]
#[serde(default, deny_unknown_fields)]
pub struct Config {
/// General Hooked configuration.
pub general: General,
/// Pre-commit hooks.
pub pre_commit: Vec<PreCommit>,
}
impl Config {
/// Read a file and parse it with [`toml`].
pub fn from_toml_file<P>(file: P) -> Result<Self>
where
P: AsRef<Path>,
{
toml::from_str(&read_to_string(file)?).map_err(Into::into)
}
}

View File

@ -0,0 +1,21 @@
//! Pre-commit hook definitions.
use serde::{Deserialize, Serialize};
use crate::{ExitAction, Task};
/// A pre-commit hook.
#[derive(Debug, Deserialize, Serialize)]
#[serde(deny_unknown_fields)]
pub struct PreCommit {
/// Display name for this hook.
pub name: Option<String>,
/// What to do when the hook exits with a non-zero status code.
#[serde(default)]
pub on_failure: ExitAction,
/// Task to perform when this hook is called.
#[serde(flatten)]
pub task: Task,
}

16
source/config/task.rs Normal file
View File

@ -0,0 +1,16 @@
//! Task to perform in hooks.
use std::path::PathBuf;
use serde::{Deserialize, Serialize};
/// Task to perform in hooks.
#[derive(Debug, Deserialize, Serialize)]
#[serde(deny_unknown_fields)]
pub struct Task {
/// Command to execute directly.
pub command: Option<String>,
/// Path to a script to execute.
pub script: Option<PathBuf>,
}

7
source/lib.rs Normal file
View File

@ -0,0 +1,7 @@
//! # Hooked
//!
//! > **Git hooks manager.**
mod config;
pub use config::*;

14
tests/parsing.rs Normal file
View File

@ -0,0 +1,14 @@
use std::path::PathBuf;
use {color_eyre::Result, hooked::Config};
use {insta::assert_debug_snapshot, test_case::test_case};
#[test_case("defaults" ; "defaults")]
#[test_case("with-hooks" ; "with-hooks")]
fn test_config_parsing(file_name: &str) -> Result<()> {
let file = PathBuf::from(format!("tests/parsing/{file_name}.toml"));
let config = Config::from_toml_file(file)?;
assert_debug_snapshot!(format!("{file_name}"), config);
Ok(())
}

View File

@ -0,0 +1 @@
[[pre_commit]]

View File

@ -0,0 +1,12 @@
[general]
directory = "hooked"
[[pre_commit]]
name = "Pre Commit 1"
command = "exit 0"
on_failure = "continue"
[[pre_commit]]
name = "Pre Commit 2"
script = "test.sh"
on_failure = "stop"

34
tests/serialize.rs Normal file
View File

@ -0,0 +1,34 @@
use {
hooked::{Config, ExitAction, PreCommit, Task},
toml::to_string_pretty,
};
use insta::assert_snapshot;
#[test]
fn test_serialize() {
let pre_commit_command = PreCommit {
name: Some("Command Test".to_string()),
on_failure: ExitAction::Continue,
task: Task {
command: Some("exit 0".to_string()),
script: None,
},
};
let pre_commit_script = PreCommit {
name: Some("Script Test".to_string()),
on_failure: ExitAction::Stop,
task: Task {
command: None,
script: Some("test.sh".into()),
},
};
let config = Config {
general: Default::default(),
pre_commit: vec![pre_commit_command, pre_commit_script],
};
assert_snapshot!("serialize", to_string_pretty(&config).unwrap());
}

View File

@ -0,0 +1,19 @@
---
source: tests/parsing.rs
expression: config
---
Config {
general: General {
directory: "hooks",
},
pre_commit: [
PreCommit {
name: None,
on_failure: Stop,
task: Task {
command: None,
script: None,
},
},
],
}

View File

@ -0,0 +1,35 @@
---
source: tests/parsing.rs
expression: config
---
Config {
general: General {
directory: "hooked",
},
pre_commit: [
PreCommit {
name: Some(
"Pre Commit 1",
),
on_failure: Continue,
task: Task {
command: Some(
"exit 0",
),
script: None,
},
},
PreCommit {
name: Some(
"Pre Commit 2",
),
on_failure: Stop,
task: Task {
command: None,
script: Some(
"test.sh",
),
},
},
],
}

View File

@ -0,0 +1,17 @@
---
source: tests/serialize.rs
expression: to_string_pretty(&config).unwrap()
---
[general]
directory = 'hooks'
[[pre_commit]]
name = 'Command Test'
on_failure = 'continue'
command = 'exit 0'
[[pre_commit]]
name = 'Script Test'
on_failure = 'stop'
script = 'test.sh'