pub const HOOK_MARKER: &str = "# quorum-managed-hook";
pub const PRE_COMMIT_TEMPLATE: &str = r##"#!/bin/sh
# quorum-managed-hook v1 (pre-commit)
# Generated by `quorum install --hook=pre-commit`. Modifying this file
# manually means subsequent `quorum install` invocations refuse to overwrite.
# Bypass for one commit: env QUORUM_SKIP=1 git commit ...
if [ "${QUORUM_SKIP:-0}" != "0" ]; then
echo "quorum: skipped (QUORUM_SKIP set)" >&2
exit 0
fi
if ! command -v quorum >/dev/null 2>&1; then
echo "quorum: binary not on PATH; skipping" >&2
exit 0
fi
quorum review --hook-mode=pre-commit
HOOK_EXIT=$?
# Default fail-open: only exit 1 (high-severity findings) blocks.
# QUORUM_HOOK_POLICY=fail-closed blocks on auth (exit 3) and tooling (exit 2).
# QUORUM_HOOK_POLICY=warn never blocks regardless of exit code.
if [ "${QUORUM_HOOK_POLICY:-fail-open}" = "warn" ]; then
exit 0
fi
if [ "$HOOK_EXIT" -eq 1 ]; then
echo "" >&2
echo "quorum: high-severity findings present; commit blocked." >&2
echo " run \`quorum review --tui\` to dismiss or \`quorum review\` for full output." >&2
echo " to bypass once: QUORUM_SKIP=1 git commit" >&2
exit 1
fi
if [ "${QUORUM_HOOK_POLICY:-fail-open}" = "fail-closed" ]; then
if [ "$HOOK_EXIT" -eq 2 ] || [ "$HOOK_EXIT" -eq 3 ]; then
echo "quorum: tooling or auth failure (exit $HOOK_EXIT); commit blocked (fail-closed)." >&2
exit 1
fi
fi
exit 0
"##;
pub const PRE_PUSH_TEMPLATE: &str = r##"#!/bin/sh
# quorum-managed-hook v1 (pre-push)
# Generated by `quorum install --hook=pre-push`. Modifying this file
# manually means subsequent `quorum install` invocations refuse to overwrite.
# Bypass for one push: env QUORUM_SKIP=1 git push ...
#
# Git provides each ref being pushed on stdin as:
# <local-ref> <local-sha> <remote-ref> <remote-sha>
# This hook forwards stdin to `quorum review --hook-mode=pre-push`, which
# computes the commit range per ref and diffs accordingly.
if [ "${QUORUM_SKIP:-0}" != "0" ]; then
echo "quorum: skipped (QUORUM_SKIP set)" >&2
exit 0
fi
if ! command -v quorum >/dev/null 2>&1; then
echo "quorum: binary not on PATH; skipping" >&2
exit 0
fi
quorum review --hook-mode=pre-push
HOOK_EXIT=$?
if [ "${QUORUM_HOOK_POLICY:-fail-open}" = "warn" ]; then
exit 0
fi
if [ "$HOOK_EXIT" -eq 1 ]; then
echo "" >&2
echo "quorum: high-severity findings present; push blocked." >&2
echo " run \`quorum review --tui\` to dismiss or \`quorum review\` for full output." >&2
echo " to bypass once: QUORUM_SKIP=1 git push" >&2
exit 1
fi
if [ "${QUORUM_HOOK_POLICY:-fail-open}" = "fail-closed" ]; then
if [ "$HOOK_EXIT" -eq 2 ] || [ "$HOOK_EXIT" -eq 3 ]; then
echo "quorum: tooling or auth failure (exit $HOOK_EXIT); push blocked (fail-closed)." >&2
exit 1
fi
fi
exit 0
"##;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn marker_present_in_first_five_lines_of_both_templates() {
for (name, body) in [
("pre-commit", PRE_COMMIT_TEMPLATE),
("pre-push", PRE_PUSH_TEMPLATE),
] {
let first_five = body.lines().take(5).collect::<Vec<_>>().join("\n");
assert!(
first_five.contains(HOOK_MARKER),
"{name} template must contain {HOOK_MARKER:?} in its first 5 lines"
);
}
}
#[test]
fn templates_start_with_posix_shebang() {
for (name, body) in [
("pre-commit", PRE_COMMIT_TEMPLATE),
("pre-push", PRE_PUSH_TEMPLATE),
] {
assert!(
body.starts_with("#!/bin/sh\n"),
"{name} template must start with #!/bin/sh"
);
}
}
#[test]
fn pre_commit_template_references_git_commit_bypass() {
assert!(PRE_COMMIT_TEMPLATE.contains("QUORUM_SKIP=1 git commit"));
assert!(PRE_COMMIT_TEMPLATE.contains("commit blocked"));
}
#[test]
fn pre_push_template_references_git_push_bypass() {
assert!(PRE_PUSH_TEMPLATE.contains("QUORUM_SKIP=1 git push"));
assert!(PRE_PUSH_TEMPLATE.contains("push blocked"));
}
#[test]
fn templates_invoke_correct_hook_mode() {
assert!(PRE_COMMIT_TEMPLATE.contains("quorum review --hook-mode=pre-commit"));
assert!(PRE_PUSH_TEMPLATE.contains("quorum review --hook-mode=pre-push"));
}
#[test]
fn templates_honor_quorum_hook_policy() {
for body in [PRE_COMMIT_TEMPLATE, PRE_PUSH_TEMPLATE] {
assert!(body.contains("QUORUM_HOOK_POLICY"));
assert!(body.contains("warn"));
assert!(body.contains("fail-closed"));
assert!(body.contains("fail-open"));
}
}
#[test]
fn templates_handle_quorum_skip_and_missing_binary() {
for body in [PRE_COMMIT_TEMPLATE, PRE_PUSH_TEMPLATE] {
assert!(body.contains("QUORUM_SKIP"));
assert!(body.contains("command -v quorum"));
assert!(body.contains("binary not on PATH"));
}
}
}