main git-pr / contrib / dev / main.go
Eric Bower  ·  2026-02-25
  1package main
  2
  3import (
  4	"context"
  5	"flag"
  6	"fmt"
  7	"log/slog"
  8	"net/http"
  9	"os"
 10	"os/signal"
 11	"syscall"
 12	"time"
 13
 14	"github.com/picosh/patchbin"
 15	"github.com/picosh/patchbin/fixtures"
 16	"github.com/picosh/patchbin/util"
 17)
 18
 19func main() {
 20	cleanupFlag := flag.Bool("cleanup", true, "Clean up tmp dir after quitting (default: true)")
 21	flag.Parse()
 22
 23	opts := &slog.HandlerOptions{
 24		AddSource: true,
 25	}
 26	logger := slog.New(
 27		slog.NewTextHandler(os.Stdout, opts),
 28	)
 29
 30	dataDir := util.CreateTmpDir()
 31	defer func() {
 32		if *cleanupFlag {
 33			_ = os.RemoveAll(dataDir)
 34		}
 35	}()
 36
 37	adminKey, userKey := util.GenerateKeys()
 38	cfgPath := util.CreateCfgFile(dataDir, cfgTmpl, adminKey)
 39	patchbin.LoadConfigFile(cfgPath, logger)
 40	cfg := patchbin.NewGitCfg(logger)
 41
 42	ctx, cancel := context.WithCancel(context.Background())
 43	defer cancel()
 44	s := patchbin.GitSshServer(ctx, cfg)
 45	go func() {
 46		_ = s.ListenAndServe()
 47	}()
 48	time.Sleep(time.Millisecond * 100)
 49	w := patchbin.GitWebServer(cfg)
 50	addr := fmt.Sprintf("%s:%s", cfg.Host, cfg.WebPort)
 51	go func() {
 52		_ = http.ListenAndServe(addr, w)
 53	}()
 54
 55	// Hack to wait for startup
 56	time.Sleep(time.Millisecond * 100)
 57
 58	patch, err := fixtures.Fixtures.ReadFile("single.patch")
 59	if err != nil {
 60		panic(err)
 61	}
 62	otherPatch, err := fixtures.Fixtures.ReadFile("with-cover.patch")
 63	if err != nil {
 64		panic(err)
 65	}
 66	rd1, err := fixtures.Fixtures.ReadFile("a_b_reorder.patch")
 67	if err != nil {
 68		panic(err)
 69	}
 70	rd2, err := fixtures.Fixtures.ReadFile("a_c_changed_commit.patch")
 71	if err != nil {
 72		panic(err)
 73	}
 74
 75	// Opened patch (creator opens their own PR)
 76	userKey.MustCmd(patch, "pr create test")
 77	userKey.MustCmd(nil, "pr edit 1 Opened patch")
 78	userKey.MustCmd(nil, `pr open --comment "ready for review" 1`)
 79
 80	// Drafted patch (creator sets back to draft)
 81	userKey.MustCmd(patch, "pr create test")
 82	userKey.MustCmd(nil, "pr edit 2 Drafted patch")
 83	userKey.MustCmd(nil, `pr draft --comment "need more work" 2`)
 84
 85	// Opened then re-drafted by creator
 86	userKey.MustCmd(patch, "pr create test")
 87	userKey.MustCmd(nil, "pr edit 3 Opened then re-drafted")
 88	userKey.MustCmd(nil, `pr open 3`)
 89	userKey.MustCmd(nil, `pr draft --comment "Woops, didn't mean to submit yet" 3`)
 90
 91	// Patchset added by another user, creator opens
 92	userKey.MustCmd(patch, "pr create test")
 93	userKey.MustCmd(nil, "pr edit 5 Patchset from another user")
 94	adminKey.MustCmd(otherPatch, `pr add 5`)
 95	userKey.MustCmd(nil, `pr open --comment "updated with feedback" 5`)
 96
 97	// Patchset added by another user, creator drafts
 98	userKey.MustCmd(patch, "pr create test")
 99	userKey.MustCmd(nil, "pr edit 6 Patchset then drafted")
100	adminKey.MustCmd(otherPatch, `pr add 6`)
101	userKey.MustCmd(nil, `pr draft --comment "taking a step back on this" 6`)
102
103	// Range Diff
104	userKey.MustCmd(rd1, "pr create test")
105	userKey.MustCmd(nil, "pr edit 7 Range Diff")
106	userKey.MustCmd(rd2, "pr add 7")
107
108	fmt.Println("time to do some testing...")
109	ch := make(chan os.Signal, 1)
110	signal.Notify(ch, os.Interrupt, syscall.SIGTERM)
111	<-ch
112}
113
114// args: tmpdir, adminKey
115var cfgTmpl = `
116url = "localhost"
117data_dir = %q
118admins = [%q]
119time_format = "01/02/2006 15:04:05 07:00"`