Install a single hook. Returns Ok(true) if newly installed, Ok(false) if already present.
(path: &Path, _name: &str)
| 139 | |
| 140 | /// Install a single hook. Returns Ok(true) if newly installed, Ok(false) if already present. |
| 141 | fn install_single_hook(path: &Path, _name: &str) -> Result<bool, std::io::Error> { |
| 142 | let existing = if path.exists() { |
| 143 | fs::read_to_string(path)? |
| 144 | } else { |
| 145 | String::new() |
| 146 | }; |
| 147 | |
| 148 | // Already installed? |
| 149 | if existing.contains(MARKER_BEGIN) { |
| 150 | return Ok(false); |
| 151 | } |
| 152 | |
| 153 | // Build the section to append (body depends on which hook this is). |
| 154 | let section = format!( |
| 155 | "\n{}\n{}\n{}\n", |
| 156 | MARKER_BEGIN, |
| 157 | body_for_hook(_name), |
| 158 | MARKER_END |
| 159 | ); |
| 160 | |
| 161 | let new_content = if existing.is_empty() { |
| 162 | format!("#!/bin/sh\n{}", section) |
| 163 | } else { |
| 164 | format!("{}{}", existing.trim_end(), section) |
| 165 | }; |
| 166 | |
| 167 | fs::write(path, &new_content)?; |
| 168 | |
| 169 | // Make executable (unix only) |
| 170 | #[cfg(unix)] |
| 171 | { |
| 172 | use std::os::unix::fs::PermissionsExt; |
| 173 | let mut perms = fs::metadata(path)?.permissions(); |
| 174 | perms.set_mode(0o755); |
| 175 | fs::set_permissions(path, perms)?; |
| 176 | } |
| 177 | |
| 178 | Ok(true) |
| 179 | } |
| 180 | |
| 181 | /// Remove Atomic sections from all hooks. |
| 182 | fn uninstall_hooks() -> CliResult<()> { |