44 lines · 1176 bytes
1 use std::{
2 env,
3 io::{self, Read},
4 process,
5 };
6 use walkdir::WalkDir;
7
8 fn dir_size_bytes(root: &str) -> io::Result<u64> {
9 let mut total: u64 = 0;
10 for entry in WalkDir::new(root).follow_links(false) {
11 let entry = entry.map_err(|e| io::Error::new(io::ErrorKind::Other, e.to_string()))?;
12 if entry.file_type().is_file() {
13 let md = entry.metadata()?;
14 total = total.saturating_add(md.len());
15 }
16 }
17 Ok(total)
18 }
19
20 fn main() {
21 // Consume stdin (pre-receive provides ref updates on stdin)
22 let mut _stdin = String::new();
23 let _ = io::stdin().read_to_string(&mut _stdin);
24
25 let max_bytes: u64 = env::var("MAX_REPO_BYTES")
26 .ok()
27 .and_then(|v| v.parse::<u64>().ok())
28 .unwrap_or(50 * 1024 * 1024);
29
30 let size = match dir_size_bytes(".") {
31 Ok(s) => s,
32 Err(e) => {
33 eprintln!("quota hook error: failed to compute repo size: {e}");
34 process::exit(1);
35 }
36 };
37
38 if size > max_bytes {
39 eprintln!("Rejected: repo exceeds quota ({} bytes > {} bytes).", size, max_bytes);
40 process::exit(1);
41 }
42
43 process::exit(0);
44 }