aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x.dev-suite/hooked/applypatch-msg1
-rwxr-xr-x.dev-suite/hooked/applypatch-msg.py1
-rwxr-xr-x.dev-suite/hooked/commit-msg4
-rwxr-xr-x.dev-suite/hooked/commit-msg.py1
-rwxr-xr-x.dev-suite/hooked/post-applypatch1
-rwxr-xr-x.dev-suite/hooked/post-applypatch.py1
-rwxr-xr-x.dev-suite/hooked/post-checkout1
-rwxr-xr-x.dev-suite/hooked/post-checkout.py1
-rwxr-xr-x.dev-suite/hooked/post-commit1
-rwxr-xr-x.dev-suite/hooked/post-commit.py1
-rwxr-xr-x.dev-suite/hooked/post-merge1
-rwxr-xr-x.dev-suite/hooked/post-merge.py1
-rwxr-xr-x.dev-suite/hooked/post-receive2
-rwxr-xr-x.dev-suite/hooked/post-receive.py1
-rwxr-xr-x.dev-suite/hooked/post-rewrite1
-rwxr-xr-x.dev-suite/hooked/post-rewrite.py1
-rwxr-xr-x.dev-suite/hooked/post-update1
-rwxr-xr-x.dev-suite/hooked/post-update.py1
-rwxr-xr-x.dev-suite/hooked/pre-auto-gc1
-rwxr-xr-x.dev-suite/hooked/pre-auto-gc.py1
-rwxr-xr-x.dev-suite/hooked/pre-commit7
-rwxr-xr-x.dev-suite/hooked/pre-commit.py7
-rwxr-xr-x.dev-suite/hooked/pre-push1
-rwxr-xr-x.dev-suite/hooked/pre-push.py1
-rwxr-xr-x.dev-suite/hooked/pre-rebase1
-rwxr-xr-x.dev-suite/hooked/pre-rebase.py1
-rwxr-xr-x.dev-suite/hooked/pre-receive1
-rwxr-xr-x.dev-suite/hooked/pre-receive.py1
-rwxr-xr-x.dev-suite/hooked/prepare-commit-msg1
-rwxr-xr-x.dev-suite/hooked/prepare-commit-msg.py1
-rwxr-xr-x.dev-suite/hooked/push-to-checkout1
-rwxr-xr-x.dev-suite/hooked/push-to-checkout.py1
-rwxr-xr-x.dev-suite/hooked/sendemail-validate1
-rwxr-xr-x.dev-suite/hooked/sendemail-validate.py1
-rwxr-xr-x.dev-suite/hooked/update1
-rwxr-xr-x.dev-suite/hooked/update.py1
-rwxr-xr-x.dev-suite/hooked/wrapper/applypatch-msg.sh2
-rwxr-xr-x.dev-suite/hooked/wrapper/commit-msg.sh2
-rwxr-xr-x.dev-suite/hooked/wrapper/post-applypatch.sh2
-rwxr-xr-x.dev-suite/hooked/wrapper/post-checkout.sh2
-rwxr-xr-x.dev-suite/hooked/wrapper/post-commit.sh2
-rwxr-xr-x.dev-suite/hooked/wrapper/post-merge.sh2
-rwxr-xr-x.dev-suite/hooked/wrapper/post-receive.sh2
-rwxr-xr-x.dev-suite/hooked/wrapper/post-rewrite.sh2
-rwxr-xr-x.dev-suite/hooked/wrapper/post-update.sh2
-rwxr-xr-x.dev-suite/hooked/wrapper/pre-auto-gc.sh2
-rwxr-xr-x.dev-suite/hooked/wrapper/pre-commit.sh2
-rwxr-xr-x.dev-suite/hooked/wrapper/pre-push.sh2
-rwxr-xr-x.dev-suite/hooked/wrapper/pre-rebase.sh2
-rwxr-xr-x.dev-suite/hooked/wrapper/pre-receive.sh2
-rwxr-xr-x.dev-suite/hooked/wrapper/prepare-commit-msg.sh2
-rwxr-xr-x.dev-suite/hooked/wrapper/push-to-checkout.sh2
-rwxr-xr-x.dev-suite/hooked/wrapper/sendemail-validate.sh2
-rwxr-xr-x.dev-suite/hooked/wrapper/update.sh2
-rw-r--r--hooked/src/main.rs181
-rw-r--r--hooked/tests/init.rs66
56 files changed, 271 insertions, 64 deletions
diff --git a/.dev-suite/hooked/applypatch-msg b/.dev-suite/hooked/applypatch-msg
deleted file mode 100755
index efcbaec..0000000
--- a/.dev-suite/hooked/applypatch-msg
+++ /dev/null
@@ -1 +0,0 @@
-#! /bin/bash \ No newline at end of file
diff --git a/.dev-suite/hooked/applypatch-msg.py b/.dev-suite/hooked/applypatch-msg.py
new file mode 100755
index 0000000..5f7ce86
--- /dev/null
+++ b/.dev-suite/hooked/applypatch-msg.py
@@ -0,0 +1 @@
+#!/usr/bin/env python3 \ No newline at end of file
diff --git a/.dev-suite/hooked/commit-msg b/.dev-suite/hooked/commit-msg
deleted file mode 100755
index cc072bf..0000000
--- a/.dev-suite/hooked/commit-msg
+++ /dev/null
@@ -1,4 +0,0 @@
-#! /bin/bash
-
-# Check that the commit message is up to spec
-hooked-commit-msg $@
diff --git a/.dev-suite/hooked/commit-msg.py b/.dev-suite/hooked/commit-msg.py
new file mode 100755
index 0000000..5f7ce86
--- /dev/null
+++ b/.dev-suite/hooked/commit-msg.py
@@ -0,0 +1 @@
+#!/usr/bin/env python3 \ No newline at end of file
diff --git a/.dev-suite/hooked/post-applypatch b/.dev-suite/hooked/post-applypatch
deleted file mode 100755
index efcbaec..0000000
--- a/.dev-suite/hooked/post-applypatch
+++ /dev/null
@@ -1 +0,0 @@
-#! /bin/bash \ No newline at end of file
diff --git a/.dev-suite/hooked/post-applypatch.py b/.dev-suite/hooked/post-applypatch.py
new file mode 100755
index 0000000..5f7ce86
--- /dev/null
+++ b/.dev-suite/hooked/post-applypatch.py
@@ -0,0 +1 @@
+#!/usr/bin/env python3 \ No newline at end of file
diff --git a/.dev-suite/hooked/post-checkout b/.dev-suite/hooked/post-checkout
deleted file mode 100755
index efcbaec..0000000
--- a/.dev-suite/hooked/post-checkout
+++ /dev/null
@@ -1 +0,0 @@
-#! /bin/bash \ No newline at end of file
diff --git a/.dev-suite/hooked/post-checkout.py b/.dev-suite/hooked/post-checkout.py
new file mode 100755
index 0000000..5f7ce86
--- /dev/null
+++ b/.dev-suite/hooked/post-checkout.py
@@ -0,0 +1 @@
+#!/usr/bin/env python3 \ No newline at end of file
diff --git a/.dev-suite/hooked/post-commit b/.dev-suite/hooked/post-commit
deleted file mode 100755
index efcbaec..0000000
--- a/.dev-suite/hooked/post-commit
+++ /dev/null
@@ -1 +0,0 @@
-#! /bin/bash \ No newline at end of file
diff --git a/.dev-suite/hooked/post-commit.py b/.dev-suite/hooked/post-commit.py
new file mode 100755
index 0000000..5f7ce86
--- /dev/null
+++ b/.dev-suite/hooked/post-commit.py
@@ -0,0 +1 @@
+#!/usr/bin/env python3 \ No newline at end of file
diff --git a/.dev-suite/hooked/post-merge b/.dev-suite/hooked/post-merge
deleted file mode 100755
index efcbaec..0000000
--- a/.dev-suite/hooked/post-merge
+++ /dev/null
@@ -1 +0,0 @@
-#! /bin/bash \ No newline at end of file
diff --git a/.dev-suite/hooked/post-merge.py b/.dev-suite/hooked/post-merge.py
new file mode 100755
index 0000000..5f7ce86
--- /dev/null
+++ b/.dev-suite/hooked/post-merge.py
@@ -0,0 +1 @@
+#!/usr/bin/env python3 \ No newline at end of file
diff --git a/.dev-suite/hooked/post-receive b/.dev-suite/hooked/post-receive
deleted file mode 100755
index fb6b709..0000000
--- a/.dev-suite/hooked/post-receive
+++ /dev/null
@@ -1,2 +0,0 @@
-#! /bin/bash
-git push github --all --force
diff --git a/.dev-suite/hooked/post-receive.py b/.dev-suite/hooked/post-receive.py
new file mode 100755
index 0000000..5f7ce86
--- /dev/null
+++ b/.dev-suite/hooked/post-receive.py
@@ -0,0 +1 @@
+#!/usr/bin/env python3 \ No newline at end of file
diff --git a/.dev-suite/hooked/post-rewrite b/.dev-suite/hooked/post-rewrite
deleted file mode 100755
index efcbaec..0000000
--- a/.dev-suite/hooked/post-rewrite
+++ /dev/null
@@ -1 +0,0 @@
-#! /bin/bash \ No newline at end of file
diff --git a/.dev-suite/hooked/post-rewrite.py b/.dev-suite/hooked/post-rewrite.py
new file mode 100755
index 0000000..5f7ce86
--- /dev/null
+++ b/.dev-suite/hooked/post-rewrite.py
@@ -0,0 +1 @@
+#!/usr/bin/env python3 \ No newline at end of file
diff --git a/.dev-suite/hooked/post-update b/.dev-suite/hooked/post-update
deleted file mode 100755
index efcbaec..0000000
--- a/.dev-suite/hooked/post-update
+++ /dev/null
@@ -1 +0,0 @@
-#! /bin/bash \ No newline at end of file
diff --git a/.dev-suite/hooked/post-update.py b/.dev-suite/hooked/post-update.py
new file mode 100755
index 0000000..5f7ce86
--- /dev/null
+++ b/.dev-suite/hooked/post-update.py
@@ -0,0 +1 @@
+#!/usr/bin/env python3 \ No newline at end of file
diff --git a/.dev-suite/hooked/pre-auto-gc b/.dev-suite/hooked/pre-auto-gc
deleted file mode 100755
index efcbaec..0000000
--- a/.dev-suite/hooked/pre-auto-gc
+++ /dev/null
@@ -1 +0,0 @@
-#! /bin/bash \ No newline at end of file
diff --git a/.dev-suite/hooked/pre-auto-gc.py b/.dev-suite/hooked/pre-auto-gc.py
new file mode 100755
index 0000000..5f7ce86
--- /dev/null
+++ b/.dev-suite/hooked/pre-auto-gc.py
@@ -0,0 +1 @@
+#!/usr/bin/env python3 \ No newline at end of file
diff --git a/.dev-suite/hooked/pre-commit b/.dev-suite/hooked/pre-commit
deleted file mode 100755
index 4229848..0000000
--- a/.dev-suite/hooked/pre-commit
+++ /dev/null
@@ -1,7 +0,0 @@
-#! /bin/bash
-set -eu -o pipefail
-
-cargo build --all
-cargo test --all
-rustup run nightly cargo fmt --all -- --check
-cargo clippy --all --all-targets -- -W clippy::pedantic
diff --git a/.dev-suite/hooked/pre-commit.py b/.dev-suite/hooked/pre-commit.py
new file mode 100755
index 0000000..5ddbc42
--- /dev/null
+++ b/.dev-suite/hooked/pre-commit.py
@@ -0,0 +1,7 @@
+#!/usr/bin/env python3
+import subprocess
+
+subprocess.run("cargo build --all", shell=True, check=True)
+subprocess.run("cargo test --all -- --test-threads=1", shell=True, check=True)
+subprocess.run("rustup run nightly cargo fmt --all -- --check", shell=True, check=True)
+subprocess.run("cargo clippy --all --all-targets -- -W clippy::pedantic", shell=True, check=True)
diff --git a/.dev-suite/hooked/pre-push b/.dev-suite/hooked/pre-push
deleted file mode 100755
index efcbaec..0000000
--- a/.dev-suite/hooked/pre-push
+++ /dev/null
@@ -1 +0,0 @@
-#! /bin/bash \ No newline at end of file
diff --git a/.dev-suite/hooked/pre-push.py b/.dev-suite/hooked/pre-push.py
new file mode 100755
index 0000000..5f7ce86
--- /dev/null
+++ b/.dev-suite/hooked/pre-push.py
@@ -0,0 +1 @@
+#!/usr/bin/env python3 \ No newline at end of file
diff --git a/.dev-suite/hooked/pre-rebase b/.dev-suite/hooked/pre-rebase
deleted file mode 100755
index efcbaec..0000000
--- a/.dev-suite/hooked/pre-rebase
+++ /dev/null
@@ -1 +0,0 @@
-#! /bin/bash \ No newline at end of file
diff --git a/.dev-suite/hooked/pre-rebase.py b/.dev-suite/hooked/pre-rebase.py
new file mode 100755
index 0000000..5f7ce86
--- /dev/null
+++ b/.dev-suite/hooked/pre-rebase.py
@@ -0,0 +1 @@
+#!/usr/bin/env python3 \ No newline at end of file
diff --git a/.dev-suite/hooked/pre-receive b/.dev-suite/hooked/pre-receive
deleted file mode 100755
index efcbaec..0000000
--- a/.dev-suite/hooked/pre-receive
+++ /dev/null
@@ -1 +0,0 @@
-#! /bin/bash \ No newline at end of file
diff --git a/.dev-suite/hooked/pre-receive.py b/.dev-suite/hooked/pre-receive.py
new file mode 100755
index 0000000..5f7ce86
--- /dev/null
+++ b/.dev-suite/hooked/pre-receive.py
@@ -0,0 +1 @@
+#!/usr/bin/env python3 \ No newline at end of file
diff --git a/.dev-suite/hooked/prepare-commit-msg b/.dev-suite/hooked/prepare-commit-msg
deleted file mode 100755
index efcbaec..0000000
--- a/.dev-suite/hooked/prepare-commit-msg
+++ /dev/null
@@ -1 +0,0 @@
-#! /bin/bash \ No newline at end of file
diff --git a/.dev-suite/hooked/prepare-commit-msg.py b/.dev-suite/hooked/prepare-commit-msg.py
new file mode 100755
index 0000000..5f7ce86
--- /dev/null
+++ b/.dev-suite/hooked/prepare-commit-msg.py
@@ -0,0 +1 @@
+#!/usr/bin/env python3 \ No newline at end of file
diff --git a/.dev-suite/hooked/push-to-checkout b/.dev-suite/hooked/push-to-checkout
deleted file mode 100755
index efcbaec..0000000
--- a/.dev-suite/hooked/push-to-checkout
+++ /dev/null
@@ -1 +0,0 @@
-#! /bin/bash \ No newline at end of file
diff --git a/.dev-suite/hooked/push-to-checkout.py b/.dev-suite/hooked/push-to-checkout.py
new file mode 100755
index 0000000..5f7ce86
--- /dev/null
+++ b/.dev-suite/hooked/push-to-checkout.py
@@ -0,0 +1 @@
+#!/usr/bin/env python3 \ No newline at end of file
diff --git a/.dev-suite/hooked/sendemail-validate b/.dev-suite/hooked/sendemail-validate
deleted file mode 100755
index efcbaec..0000000
--- a/.dev-suite/hooked/sendemail-validate
+++ /dev/null
@@ -1 +0,0 @@
-#! /bin/bash \ No newline at end of file
diff --git a/.dev-suite/hooked/sendemail-validate.py b/.dev-suite/hooked/sendemail-validate.py
new file mode 100755
index 0000000..5f7ce86
--- /dev/null
+++ b/.dev-suite/hooked/sendemail-validate.py
@@ -0,0 +1 @@
+#!/usr/bin/env python3 \ No newline at end of file
diff --git a/.dev-suite/hooked/update b/.dev-suite/hooked/update
deleted file mode 100755
index efcbaec..0000000
--- a/.dev-suite/hooked/update
+++ /dev/null
@@ -1 +0,0 @@
-#! /bin/bash \ No newline at end of file
diff --git a/.dev-suite/hooked/update.py b/.dev-suite/hooked/update.py
new file mode 100755
index 0000000..5f7ce86
--- /dev/null
+++ b/.dev-suite/hooked/update.py
@@ -0,0 +1 @@
+#!/usr/bin/env python3 \ No newline at end of file
diff --git a/.dev-suite/hooked/wrapper/applypatch-msg.sh b/.dev-suite/hooked/wrapper/applypatch-msg.sh
new file mode 100755
index 0000000..9719401
--- /dev/null
+++ b/.dev-suite/hooked/wrapper/applypatch-msg.sh
@@ -0,0 +1,2 @@
+#!C:\Program Files\Git\bin\sh.exe
+py.exe .dev-suite/hooked/applypatch-msg.py
diff --git a/.dev-suite/hooked/wrapper/commit-msg.sh b/.dev-suite/hooked/wrapper/commit-msg.sh
new file mode 100755
index 0000000..b1a3623
--- /dev/null
+++ b/.dev-suite/hooked/wrapper/commit-msg.sh
@@ -0,0 +1,2 @@
+#!C:\Program Files\Git\bin\sh.exe
+py.exe .dev-suite/hooked/commit-msg.py
diff --git a/.dev-suite/hooked/wrapper/post-applypatch.sh b/.dev-suite/hooked/wrapper/post-applypatch.sh
new file mode 100755
index 0000000..741c689
--- /dev/null
+++ b/.dev-suite/hooked/wrapper/post-applypatch.sh
@@ -0,0 +1,2 @@
+#!C:\Program Files\Git\bin\sh.exe
+py.exe .dev-suite/hooked/post-applypatch.py
diff --git a/.dev-suite/hooked/wrapper/post-checkout.sh b/.dev-suite/hooked/wrapper/post-checkout.sh
new file mode 100755
index 0000000..a2b99fa
--- /dev/null
+++ b/.dev-suite/hooked/wrapper/post-checkout.sh
@@ -0,0 +1,2 @@
+#!C:\Program Files\Git\bin\sh.exe
+py.exe .dev-suite/hooked/post-checkout.py
diff --git a/.dev-suite/hooked/wrapper/post-commit.sh b/.dev-suite/hooked/wrapper/post-commit.sh
new file mode 100755
index 0000000..6e392a4
--- /dev/null
+++ b/.dev-suite/hooked/wrapper/post-commit.sh
@@ -0,0 +1,2 @@
+#!C:\Program Files\Git\bin\sh.exe
+py.exe .dev-suite/hooked/post-commit.py
diff --git a/.dev-suite/hooked/wrapper/post-merge.sh b/.dev-suite/hooked/wrapper/post-merge.sh
new file mode 100755
index 0000000..8a6eda9
--- /dev/null
+++ b/.dev-suite/hooked/wrapper/post-merge.sh
@@ -0,0 +1,2 @@
+#!C:\Program Files\Git\bin\sh.exe
+py.exe .dev-suite/hooked/post-merge.py
diff --git a/.dev-suite/hooked/wrapper/post-receive.sh b/.dev-suite/hooked/wrapper/post-receive.sh
new file mode 100755
index 0000000..c8b87f9
--- /dev/null
+++ b/.dev-suite/hooked/wrapper/post-receive.sh
@@ -0,0 +1,2 @@
+#!C:\Program Files\Git\bin\sh.exe
+py.exe .dev-suite/hooked/post-receive.py
diff --git a/.dev-suite/hooked/wrapper/post-rewrite.sh b/.dev-suite/hooked/wrapper/post-rewrite.sh
new file mode 100755
index 0000000..fb41a73
--- /dev/null
+++ b/.dev-suite/hooked/wrapper/post-rewrite.sh
@@ -0,0 +1,2 @@
+#!C:\Program Files\Git\bin\sh.exe
+py.exe .dev-suite/hooked/post-rewrite.py
diff --git a/.dev-suite/hooked/wrapper/post-update.sh b/.dev-suite/hooked/wrapper/post-update.sh
new file mode 100755
index 0000000..f9e816d
--- /dev/null
+++ b/.dev-suite/hooked/wrapper/post-update.sh
@@ -0,0 +1,2 @@
+#!C:\Program Files\Git\bin\sh.exe
+py.exe .dev-suite/hooked/post-update.py
diff --git a/.dev-suite/hooked/wrapper/pre-auto-gc.sh b/.dev-suite/hooked/wrapper/pre-auto-gc.sh
new file mode 100755
index 0000000..2e1400c
--- /dev/null
+++ b/.dev-suite/hooked/wrapper/pre-auto-gc.sh
@@ -0,0 +1,2 @@
+#!C:\Program Files\Git\bin\sh.exe
+py.exe .dev-suite/hooked/pre-auto-gc.py
diff --git a/.dev-suite/hooked/wrapper/pre-commit.sh b/.dev-suite/hooked/wrapper/pre-commit.sh
new file mode 100755
index 0000000..196c797
--- /dev/null
+++ b/.dev-suite/hooked/wrapper/pre-commit.sh
@@ -0,0 +1,2 @@
+#!C:\Program Files\Git\bin\sh.exe
+py.exe .dev-suite/hooked/pre-commit.py
diff --git a/.dev-suite/hooked/wrapper/pre-push.sh b/.dev-suite/hooked/wrapper/pre-push.sh
new file mode 100755
index 0000000..0d760d0
--- /dev/null
+++ b/.dev-suite/hooked/wrapper/pre-push.sh
@@ -0,0 +1,2 @@
+#!C:\Program Files\Git\bin\sh.exe
+py.exe .dev-suite/hooked/pre-push.py
diff --git a/.dev-suite/hooked/wrapper/pre-rebase.sh b/.dev-suite/hooked/wrapper/pre-rebase.sh
new file mode 100755
index 0000000..642be35
--- /dev/null
+++ b/.dev-suite/hooked/wrapper/pre-rebase.sh
@@ -0,0 +1,2 @@
+#!C:\Program Files\Git\bin\sh.exe
+py.exe .dev-suite/hooked/pre-rebase.py
diff --git a/.dev-suite/hooked/wrapper/pre-receive.sh b/.dev-suite/hooked/wrapper/pre-receive.sh
new file mode 100755
index 0000000..b33366f
--- /dev/null
+++ b/.dev-suite/hooked/wrapper/pre-receive.sh
@@ -0,0 +1,2 @@
+#!C:\Program Files\Git\bin\sh.exe
+py.exe .dev-suite/hooked/pre-receive.py
diff --git a/.dev-suite/hooked/wrapper/prepare-commit-msg.sh b/.dev-suite/hooked/wrapper/prepare-commit-msg.sh
new file mode 100755
index 0000000..e04c27b
--- /dev/null
+++ b/.dev-suite/hooked/wrapper/prepare-commit-msg.sh
@@ -0,0 +1,2 @@
+#!C:\Program Files\Git\bin\sh.exe
+py.exe .dev-suite/hooked/prepare-commit-msg.py
diff --git a/.dev-suite/hooked/wrapper/push-to-checkout.sh b/.dev-suite/hooked/wrapper/push-to-checkout.sh
new file mode 100755
index 0000000..47718bf
--- /dev/null
+++ b/.dev-suite/hooked/wrapper/push-to-checkout.sh
@@ -0,0 +1,2 @@
+#!C:\Program Files\Git\bin\sh.exe
+py.exe .dev-suite/hooked/push-to-checkout.py
diff --git a/.dev-suite/hooked/wrapper/sendemail-validate.sh b/.dev-suite/hooked/wrapper/sendemail-validate.sh
new file mode 100755
index 0000000..389deb1
--- /dev/null
+++ b/.dev-suite/hooked/wrapper/sendemail-validate.sh
@@ -0,0 +1,2 @@
+#!C:\Program Files\Git\bin\sh.exe
+py.exe .dev-suite/hooked/sendemail-validate.py
diff --git a/.dev-suite/hooked/wrapper/update.sh b/.dev-suite/hooked/wrapper/update.sh
new file mode 100755
index 0000000..0d42ffd
--- /dev/null
+++ b/.dev-suite/hooked/wrapper/update.sh
@@ -0,0 +1,2 @@
+#!C:\Program Files\Git\bin\sh.exe
+py.exe .dev-suite/hooked/update.py
diff --git a/hooked/src/main.rs b/hooked/src/main.rs
index 7e33499..1c8388e 100644
--- a/hooked/src/main.rs
+++ b/hooked/src/main.rs
@@ -1,8 +1,9 @@
//! git hook manager tool
-#[cfg(windows)]
-use anyhow::bail;
-use anyhow::Result;
+use anyhow::{
+ bail,
+ Result,
+};
use log::*;
use shared::find_root;
#[cfg(not(windows))]
@@ -16,6 +17,7 @@ use std::{
env,
fs,
io::Write,
+ path::Path,
};
const HOOKS: [&str; 18] = [
@@ -41,8 +43,21 @@ const HOOKS: [&str; 18] = [
#[derive(structopt::StructOpt)]
enum Args {
- /// Initialize the repo to use ticket
- Init,
+ /// Initialize the repo to use hooked
+ Init(Language),
+ /// Link pre existing hooks to your .git folder
+ Link,
+}
+
+/// Which language the repo should be initialized with for hooks
+#[derive(Clone, Copy, structopt::StructOpt)]
+enum Language {
+ /// Use Bash for your git hooks
+ Bash,
+ /// Use Python 3 for your git hooks
+ Python,
+ /// Use Ruby for your git hooks
+ Ruby,
}
#[paw::main]
@@ -52,60 +67,172 @@ fn main(args: Args) {
.map_or_else(|| env::set_var("RUST_LOG", "info"), drop);
pretty_env_logger::init();
if let Err(e) = match args {
- Args::Init => init(),
+ Args::Init(lang) => init(lang),
+ Args::Link => link(),
} {
error!("{}", e);
std::process::exit(1);
}
}
-fn init() -> Result<()> {
- #[cfg(windows)]
- bail!("Windows is currently unsupported!");
-
+fn init(lang: Language) -> Result<()> {
let root = find_root()?;
let git_hooks = &root.join(".git").join("hooks");
debug!("git_hooks base path: {}", git_hooks.display());
let root = root.join(".dev-suite").join("hooked");
debug!("root base path: {}", root.display());
- fs::create_dir_all(&root)?;
+ let wrapper_dir = &root.join("wrapper");
+ fs::create_dir_all(&wrapper_dir)?;
for hook in &HOOKS {
- let path = &root.join(hook);
+ let mut path = (&root).join(hook);
debug!("dev-suite hook path: {}", path.display());
let git_hook = &git_hooks.join(hook);
debug!("git_hook path: {}", git_hook.display());
+ let mut wrapper_hook = (&wrapper_dir).join(hook);
+ let _ = wrapper_hook.set_extension("sh");
+ let _ = match lang {
+ Language::Bash => path.set_extension("sh"),
+ Language::Python => path.set_extension("py"),
+ Language::Ruby => path.set_extension("rb"),
+ };
if path.exists() {
debug!("git hook {} already exists. Skipping creation.", hook);
} else {
debug!("Creating dev-suite hook.");
let mut file = fs::File::create(&path)?;
+ let mut wrapper = fs::File::create(&wrapper_hook)?;
trace!("File created.");
- let mut perms = file.metadata()?.permissions();
- debug!("Setting dev-suite hook to be executable.");
- perms.set_mode(0o755);
- file.set_permissions(perms)?;
- trace!("Permissions were set.");
- file.write_all(b"#! /bin/bash")?;
+ #[cfg(not(windows))]
+ {
+ let mut perms = file.metadata()?.permissions();
+ let mut wrapper_perms = wrapper.metadata()?.permissions();
+ debug!("Setting dev-suite hook to be executable.");
+ perms.set_mode(0o755);
+ wrapper_perms.set_mode(0o755);
+ file.set_permissions(perms)?;
+ wrapper.set_permissions(wrapper_perms)?;
+ trace!("Permissions were set.");
+ }
+ match lang {
+ Language::Bash => {
+ file.write_all(b"#!/usr/bin/env bash")?;
+ wrapper.write_all(
+ format!(
+ "#!C:\\Program Files\\Git\\bin\\sh.exe\n\
+ bash.exe .dev-suite/hooked/{}.sh\n",
+ hook
+ )
+ .as_bytes(),
+ )?;
+ }
+ Language::Python => {
+ file.write_all(b"#!/usr/bin/env python3")?;
+ wrapper.write_all(
+ format!(
+ "#!C:\\Program Files\\Git\\bin\\sh.exe\n\
+ py.exe .dev-suite/hooked/{}.py\n",
+ hook
+ )
+ .as_bytes(),
+ )?;
+ }
+ Language::Ruby => {
+ file.write_all(b"#!/usr/bin/env ruby")?;
+ wrapper.write_all(
+ format!(
+ "#!C:\\Program Files\\Git\\bin\\sh.exe\n\
+ ruby.exe .dev-suite/hooked/{}.rb\n",
+ hook
+ )
+ .as_bytes(),
+ )?;
+ }
+ }
debug!("Writing data to file.");
debug!("Created git hook {}.", hook);
}
- let path = path.canonicalize()?;
- if !git_hook.exists() {
- debug!("Symlinking git hook {}.", hook);
- #[cfg(not(windows))]
- symlink(&path, &git_hook)?;
- #[cfg(windows)]
- symlink_file(&path, &git_hook)?;
- trace!("Symlinked git hook {} to .dev-suite/hooked/{}.", hook, hook);
- }
+ #[cfg(not(windows))]
+ let link_path = path.canonicalize()?;
+ #[cfg(windows)]
+ let link_path = wrapper_hook.canonicalize()?;
+
+ inner_link(&link_path, &git_hook, hook)?;
}
info!(
"Created and symlinked tickets to .git/hooks from {}.",
root.display()
);
+ #[cfg(windows)]
+ {
+ warn!("Make sure to add the hooks into git with 'git add --chmod=+x .dev-suite\\hooked'");
+ warn!("If you don't they won't be set as executable on unix systems");
+ }
+
+ Ok(())
+}
+
+fn link() -> Result<()> {
+ let root = find_root()?;
+ let git_hooks = &root.join(".git").join("hooks");
+ debug!("git_hooks base path: {}", git_hooks.display());
+ let root = root.join(".dev-suite").join("hooked");
+ debug!("root base path: {}", root.display());
+
+ for hook in &HOOKS {
+ let path = {
+ #[cfg(windows)]
+ let mut path = root.join("wrapper").join(hook);
+ #[cfg(not(windows))]
+ let mut path = root.join(hook);
+ debug!("PATH: {}", path.display());
+ let mut path_python = path.clone();
+ let _ = path_python.set_extension("py");
+ let mut path_ruby = path.clone();
+ let _ = path_ruby.set_extension("rb");
+ let mut path_bash = path.clone();
+ let _ = path_bash.set_extension("sh");
+
+ if path_python.exists() {
+ path_python
+ } else if path_ruby.exists() {
+ path_ruby
+ } else if path_bash.exists() {
+ path_bash
+ } else {
+ let _ = path.set_extension("");
+ bail!(
+ "The path {} does not exist. Have you initialized the repo to use hooked?",
+ path.display()
+ );
+ }
+ };
+ let path = path.canonicalize()?;
+ debug!("dev-suite hook path: {}", path.display());
+ let git_hook = &git_hooks.join(hook);
+ debug!("git_hook path: {}", git_hook.display());
+ inner_link(&path, &git_hook, hook)?;
+ }
+
+ info!("Successfully symlinked all githooks to .git/hooks");
+ Ok(())
+}
+
+fn inner_link(path: &Path, git_hook: &Path, hook: &str) -> Result<()> {
+ if !git_hook.exists() {
+ debug!("Symlinking git hook {}.", hook);
+ #[cfg(not(windows))]
+ symlink(&path, &git_hook)?;
+ #[cfg(windows)]
+ symlink_file(&path, &git_hook)?;
+ debug!(
+ "Symlinked git hook {} to {}",
+ git_hook.display(),
+ path.display()
+ );
+ }
Ok(())
}
diff --git a/hooked/tests/init.rs b/hooked/tests/init.rs
index 65c4aab..9c68ff3 100644
--- a/hooked/tests/init.rs
+++ b/hooked/tests/init.rs
@@ -1,10 +1,10 @@
use assert_cmd::prelude::*;
use git2::Repository;
+#[cfg(not(windows))]
+use std::os::unix::fs::PermissionsExt;
use std::{
- env,
error::Error,
fs,
- os::unix::fs::PermissionsExt,
process::Command,
};
use tempfile::tempdir;
@@ -30,19 +30,36 @@ const HOOKS: [&str; 18] = [
"sendemail-validate",
];
-#[test]
-fn init() -> Result<(), Box<dyn Error>> {
+fn lang(lang: &str) -> Result<(), Box<dyn Error>> {
let dir = tempdir()?;
let _ = Repository::init(&dir)?;
- let mut cmd = Command::cargo_bin("hooked")?;
- env::set_current_dir(&dir)?;
- let _ = cmd.arg("init").assert().success();
+ let _ = Command::cargo_bin("hooked")?
+ .arg("init")
+ .arg(lang)
+ .current_dir(&dir)
+ .assert()
+ .success();
let git = &dir.path().join(".git").join("hooks");
let dev = &dir.path().join(".dev-suite").join("hooked");
for hook in &HOOKS {
let git_hook = git.join(hook);
- let dev_hook = dev.join(hook);
+ #[cfg(not(windows))]
+ let mut dev_hook = dev.join(hook);
+ #[cfg(windows)]
+ let mut dev_hook = dev.join("wrapper").join(hook);
+
+ #[cfg(not(windows))]
+ let _ = match lang {
+ "bash" => dev_hook.set_extension("sh"),
+ "python" => dev_hook.set_extension("py"),
+ "ruby" => dev_hook.set_extension("rb"),
+ _ => unreachable!(),
+ };
+
+ #[cfg(windows)]
+ let _ = dev_hook.set_extension("sh");
+
assert!(&git_hook.exists());
assert!(&dev_hook.exists());
assert!(fs::symlink_metadata(&git_hook)?.file_type().is_symlink());
@@ -54,8 +71,39 @@ fn init() -> Result<(), Box<dyn Error>> {
// numbers essentially, allowing us to test the actual value we wanted to
// test, and making this test work without special casing it if git ever
// changes.
+ #[cfg(not(windows))]
assert_eq!(dev_hook.metadata()?.permissions().mode() & 511, 0o755);
- }
+ let shebang = fs::read_to_string(&dev_hook)?
+ .lines()
+ .nth(0)
+ .ok_or_else(|| "File is empty and has no shebang line")?
+ .to_owned();
+
+ #[cfg(not(windows))]
+ match lang {
+ "bash" => assert_eq!(shebang, "#!/usr/bin/env bash"),
+ "python" => assert_eq!(shebang, "#!/usr/bin/env python3"),
+ "ruby" => assert_eq!(shebang, "#!/usr/bin/env ruby"),
+ _ => unreachable!(),
+ }
+ #[cfg(windows)]
+ assert_eq!(shebang, "#!C:\\Program Files\\Git\\bin\\sh.exe")
+ }
Ok(())
}
+
+#[test]
+fn init_bash() -> Result<(), Box<dyn Error>> {
+ lang("bash")
+}
+
+#[test]
+fn init_python() -> Result<(), Box<dyn Error>> {
+ lang("python")
+}
+
+#[test]
+fn init_ruby() -> Result<(), Box<dyn Error>> {
+ lang("ruby")
+}