repos / git-pr

a self-hosted git collaboration server
git clone https://github.com/picosh/git-pr.git

git-pr / cmd / git-pr
Eric Bower  ·  2026-02-24

main.go

 1package main
 2
 3import (
 4	"context"
 5	"flag"
 6	"fmt"
 7	"log/slog"
 8	"net/http"
 9	"os"
10	"os/signal"
11	"syscall"
12
13	git "github.com/picosh/git-pr"
14)
15
16func main() {
17	fpath := flag.String("config", "git-pr.toml", "configuration toml file")
18	flag.Parse()
19	opts := &slog.HandlerOptions{
20		AddSource: true,
21	}
22	logger := slog.New(
23		slog.NewTextHandler(os.Stdout, opts),
24	)
25	git.LoadConfigFile(*fpath, logger)
26	cfg := git.NewGitCfg(logger)
27
28	// Web Server
29	addr := fmt.Sprintf("%s:%s", cfg.Host, cfg.WebPort)
30	web := git.GitWebServer(cfg)
31	cfg.Logger.Info("starting web server", "addr", addr)
32	go func() {
33		if err := http.ListenAndServe(addr, web); err != nil {
34			cfg.Logger.Error("listen", "err", err)
35		}
36	}()
37
38	ctx, cancel := context.WithCancel(context.Background())
39	defer cancel()
40	// SSH Server
41	ssh := git.GitSshServer(ctx, cfg)
42
43	done := make(chan os.Signal, 1)
44	signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
45	logger.Info("starting SSH server", "addr", ssh.Config.ListenAddr)
46	go func() {
47		if err := ssh.ListenAndServe(); err != nil {
48			logger.Error("serve", "err", err.Error())
49			os.Exit(1)
50		}
51	}()
52
53	exit := func() {
54		logger.Info("stopping ssh server")
55		cancel()
56	}
57
58	<-done
59	exit()
60}