1use std::path::Path;
2
3pub fn install_pre_commit_hook() -> anyhow::Result<()> {
4 let git_dir = Path::new(".git");
5 if !git_dir.exists() {
6 anyhow::bail!("No `.git` directory found — are you in a git repository?");
7 }
8
9 let hooks_dir = git_dir.join("hooks");
10 if !hooks_dir.exists() {
11 std::fs::create_dir_all(&hooks_dir)?;
12 }
13
14 let hook_path = hooks_dir.join("pre-commit");
15
16 if hook_path.exists() {
17 let existing = std::fs::read_to_string(&hook_path)?;
18 if existing.contains("react-auditor") {
19 eprintln!(
20 "react-auditor pre-commit hook already installed at {}",
21 hook_path.display()
22 );
23 return Ok(());
24 }
25 eprintln!(
26 "A pre-commit hook already exists at {}. Appending react-auditor check.",
27 hook_path.display()
28 );
29 }
30
31 let hook_content = r#"#!/bin/sh
32# react-auditor pre-commit hook — scan staged JS/TS/React files
33FILES=$(git diff --cached --name-only --diff-filter=ACM -- '*.js' '*.jsx' '*.ts' '*.tsx')
34if [ -n "$FILES" ]; then
35 echo "$FILES" | xargs react-auditor --max-warnings 0
36 if [ $? -ne 0 ]; then
37 echo "react-auditor: fix violations before committing"
38 exit 1
39 fi
40fi
41"#;
42
43 std::fs::write(&hook_path, hook_content)?;
44
45 #[cfg(unix)]
46 {
47 use std::os::unix::fs::PermissionsExt;
48 std::fs::set_permissions(&hook_path, std::fs::Permissions::from_mode(0o755))?;
49 }
50
51 eprintln!(
52 "installed react-auditor pre-commit hook at {}",
53 hook_path.display()
54 );
55 Ok(())
56}