From 1433a72ee25e6b793ead7b75bf583759c9eb67d7 Mon Sep 17 00:00:00 2001 From: Rose Hogenson Date: Mon, 24 Aug 2026 22:48:30 -0700 Subject: Fix hook and add self installer --- git-shell-commands.go | 72 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 69 insertions(+), 3 deletions(-) diff --git a/git-shell-commands.go b/git-shell-commands.go index f78f195..2311713 100644 --- a/git-shell-commands.go +++ b/git-shell-commands.go @@ -5,6 +5,7 @@ import ( "errors" "flag" "fmt" + "io" "io/fs" "os" "os/exec" @@ -39,9 +40,16 @@ func createRepo(name string) error { return err } hook := filepath.Join(dir, "hooks/post-update") - hookSample := hook + ".sample" - fmt.Fprintf(os.Stderr, "mv %s %s\n", hookSample, hook) - if err := os.Rename(hookSample, hook); err != nil { + fmt.Fprintf(os.Stderr, "echo exec git update-server-info > %s && chmod +x %[1]s\n", hook) + f, err := os.OpenFile(hook, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0755) + if err != nil { + return err + } + defer f.Close() + if _, err := io.WriteString(f, "exec git update-server-info\n"); err != nil { + return err + } + if err := f.Close(); err != nil { return err } return nil @@ -123,6 +131,62 @@ Delete the git repo named REPO. return nil } +func installFile(srcPath, dstPath string) error { + fmt.Fprintf(os.Stderr, "cp %s %s && chmod +x %[2]s\n", srcPath, dstPath) + src, err := os.Open(srcPath) + if err != nil { + return err + } + defer src.Close() + dst, err := os.OpenFile(dstPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0755) + if err != nil { + return err + } + defer dst.Close() + if _, err := io.Copy(dst, src); err != nil { + return err + } + if err := dst.Close(); err != nil { + return err + } + return nil +} + +func install() error { + const dir = "/nezuko/code/git-shell-commands" + fmt.Fprintf(os.Stderr, "Install to %q? ", dir) + scanner := bufio.NewScanner(os.Stdin) + if !scanner.Scan() { + return fmt.Errorf("exiting") + } + response := strings.TrimSpace(scanner.Text()) + if !(response == "" || strings.EqualFold(response, "y") || strings.EqualFold(response, "yes")) { + return fmt.Errorf("exiting") + } + selfPath := os.Args[0] + if !strings.Contains(selfPath, "/") { + var err error + if selfPath, err = exec.LookPath(selfPath); err != nil { + return err + } + } + helpPath := filepath.Join(dir, "help") + if err := installFile(selfPath, helpPath); err != nil { + return err + } + for _, cmd := range []string{"create", "delete"} { + cmdPath := filepath.Join(dir, cmd) + fmt.Fprintf(os.Stderr, "ln -f %s %s\n", helpPath, cmdPath) + if err := os.Remove(cmdPath); err != nil && !errors.Is(err, os.ErrNotExist) { + return err + } + if err := os.Link(helpPath, cmdPath); err != nil { + return err + } + } + return nil +} + func help() { fmt.Printf(`Available commands: create create a new git repo @@ -138,6 +202,8 @@ func main() { err = create() case "delete": err = delete() + case "git-shell-commands": + err = install() default: help() } -- cgit v1.3.1