diff options
author | Runxi Yu <me@runxiyu.org> | 2025-02-18 10:00:23 +0800 |
---|---|---|
committer | Runxi Yu <me@runxiyu.org> | 2025-02-18 10:00:23 +0800 |
commit | 729dbeaaa968a6636026c78a2a0092c347f8e6d3 (patch) | |
tree | 25525d6ee53a0f83bbdb2e6dbb9c2a5b14e9afc7 | |
parent | main.go: Remove stale UNIX domain sockets (diff) | |
download | forge-729dbeaaa968a6636026c78a2a0092c347f8e6d3.tar.gz forge-729dbeaaa968a6636026c78a2a0092c347f8e6d3.tar.zst forge-729dbeaaa968a6636026c78a2a0092c347f8e6d3.zip |
git_hooks_handle: Allow anonymous pushes to contrib/
-rw-r--r-- | git_hooks_handle.go | 76 |
1 files changed, 74 insertions, 2 deletions
diff --git a/git_hooks_handle.go b/git_hooks_handle.go index e9b163a..f8fb5bd 100644 --- a/git_hooks_handle.go +++ b/git_hooks_handle.go @@ -9,6 +9,7 @@ import ( "net" "os" "path/filepath" + "strings" "syscall" ) @@ -84,8 +85,63 @@ func hooks_handle_connection(conn net.Conn) { if pack_to_hook.direct_access { conn.Write([]byte{0}) } else { - conn.Write([]byte{1}) - fmt.Fprintln(conn, "Non-maintainer push access not implemented yet") + ref_ok := make(map[string]uint8) + // 0 for ok + // 1 for rejection due to not a contrib branch + // 2 for rejection due to not being a new branch + + for { + line, err := stdin.ReadString('\n') + if errors.Is(err, io.EOF) { + break + } + line = line[:len(line)-1] + + old_oid, rest, found := strings.Cut(line, " ") + if !found { + conn.Write([]byte{1}) + fmt.Fprintln(conn, "Invalid pre-receive line:", line) + break + } + + new_oid, ref_name, found := strings.Cut(rest, " ") + if !found { + conn.Write([]byte{1}) + fmt.Fprintln(conn, "Invalid pre-receive line:", line) + break + } + + _ = new_oid + + if strings.HasPrefix(ref_name, "refs/heads/contrib/") { + if all_zero_num_string(old_oid) { + ref_ok[ref_name] = 0 + } else { + ref_ok[ref_name] = 2 + } + } else { + ref_ok[ref_name] = 1 + } + } + + if or_all_in_map(ref_ok) == 0 { + conn.Write([]byte{0}) + fmt.Fprintln(conn, "Stuff") + } else { + conn.Write([]byte{1}) + for ref, status := range ref_ok { + switch status { + case 0: + fmt.Fprintln(conn, "Acceptable", ref) + case 1: + fmt.Fprintln(conn, "Not in the contrib/ namespace", ref) + case 2: + fmt.Fprintln(conn, "Branch already exists", ref) + default: + panic("Invalid branch status") + } + } + } } default: conn.Write([]byte{1}) @@ -117,3 +173,19 @@ func get_ucred(conn net.Conn) (*syscall.Ucred, error) { } return ucred, nil } + +func all_zero_num_string(s string) bool { + for _, r := range s { + if r != '0' { + return false + } + } + return true +} + +func or_all_in_map[K comparable, V uint8 | uint16 | uint32 | uint64](m map[K]V) (result V) { + for _, value := range m { + result |= value + } + return +} |