vole
Clone
Read only, no credentials:
https://rodent.software/vole.git
Write over SSH with a registered key:
git clone ssh://git@rodent.software:2222/vole.git
A free and open-source forge that lives in your Git repo.
refactor
c5902451905acdaa478f8476844ccd4a510d9ca9 · Keenan Nemetz · 17d ago · parent ec2aba4b
cmd/vole/hook.go +82
| @@ -0,0 +1,82 @@ | |||
| 1 | package main | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "errors" | ||
| 5 | "os" | ||
| 6 | "strconv" | ||
| 7 | |||
| 8 | "github.com/rodent-software/vole/core/lfs" | ||
| 9 | "github.com/rodent-software/vole/server/hook" | ||
| 10 | ) | ||
| 11 | |||
| 12 | // ---------- hook ---------- | ||
| 13 | |||
| 14 | // cmdHook runs inside a git push. It must never be optimistic: anything it | ||
| 15 | // cannot verify is a rejection. | ||
| 16 | func cmdHook(args []string) error { | ||
| 17 | if len(args) == 0 { | ||
| 18 | return errors.New("usage: vole hook pre-receive|post-receive") | ||
| 19 | } | ||
| 20 | dir := os.Getenv("GIT_DIR") | ||
| 21 | if dir == "" { | ||
| 22 | dir = "." | ||
| 23 | } | ||
| 24 | if args[0] == "post-receive" { | ||
| 25 | hook.PostReceive(hook.Config{ | ||
| 26 | RepoDir: dir, | ||
| 27 | Actor: os.Getenv("VOLE_ACTOR"), | ||
| 28 | ActorID: os.Getenv("VOLE_ACTOR_ID"), | ||
| 29 | AuditPath: os.Getenv("VOLE_AUDIT"), | ||
| 30 | SpoolDir: os.Getenv("VOLE_SPOOL"), | ||
| 31 | In: os.Stdin, | ||
| 32 | Out: os.Stderr, | ||
| 33 | }) | ||
| 34 | return nil | ||
| 35 | } | ||
| 36 | if args[0] != "pre-receive" { | ||
| 37 | return usagef("unknown hook %q", args[0]) | ||
| 38 | } | ||
| 39 | maxBlob := int64(0) | ||
| 40 | if v := os.Getenv("VOLE_MAX_BLOB"); v != "" { | ||
| 41 | if n, err := strconv.ParseInt(v, 10, 64); err == nil { | ||
| 42 | maxBlob = n | ||
| 43 | } | ||
| 44 | } | ||
| 45 | code := hook.PreReceive(hook.Config{ | ||
| 46 | RepoDir: dir, | ||
| 47 | Actor: os.Getenv("VOLE_ACTOR"), | ||
| 48 | ActorID: os.Getenv("VOLE_ACTOR_ID"), | ||
| 49 | MaxBlobBytes: maxBlob, | ||
| 50 | LFS: lfsFromEnv(), | ||
| 51 | LFSWarnBytes: envInt("VOLE_LFS_WARN"), | ||
| 52 | AuditPath: os.Getenv("VOLE_AUDIT"), | ||
| 53 | UsersDB: os.Getenv("VOLE_USERS_DB"), | ||
| 54 | RunsDB: os.Getenv("VOLE_RUNS_DB"), | ||
| 55 | In: os.Stdin, | ||
| 56 | Out: os.Stderr, | ||
| 57 | }) | ||
| 58 | if code != 0 { | ||
| 59 | os.Exit(code) | ||
| 60 | } | ||
| 61 | return nil | ||
| 62 | } | ||
| 63 | |||
| 64 | // lfsFromEnv opens the instance's LFS store for the hook. The hook is a | ||
| 65 | // short-lived process, so an existing store is referenced, never created: a push | ||
| 66 | // must not be the reason an empty store directory appears. | ||
| 67 | func lfsFromEnv() *lfs.Store { | ||
| 68 | dir := os.Getenv("VOLE_LFS_DIR") | ||
| 69 | if dir == "" { | ||
| 70 | return nil | ||
| 71 | } | ||
| 72 | return lfs.New(dir, envInt("VOLE_LFS_MAX")) | ||
| 73 | } | ||
| 74 | |||
| 75 | func envInt(key string) int64 { | ||
| 76 | if v := os.Getenv(key); v != "" { | ||
| 77 | if n, err := strconv.ParseInt(v, 10, 64); err == nil { | ||
| 78 | return n | ||
| 79 | } | ||
| 80 | } | ||
| 81 | return 0 | ||
| 82 | } | ||