Federated via graft
0

Configure Feed

Select the types of activity you want to include in your feed.

graft-source / cmd / sync / main.go
1.6 kB 77 lines
1// Command sync runs the Forgejo <-> Radicle sync daemon: on an interval, it 2// mirrors git content, issues and patches for every repo pair listed in the 3// config file, then sleeps until the next pass. 4package main 5 6import ( 7 "flag" 8 "log/slog" 9 "os" 10 "time" 11 12 "graft/internal/config" 13 "graft/internal/state" 14 "graft/internal/sync" 15) 16 17func main() { 18 configPath := flag.String("config", "/etc/graft/config.yaml", "path to config.yaml") 19 once := flag.Bool("once", false, "run a single pass and exit, instead of looping") 20 flag.Parse() 21 22 log := slog.New(slog.NewJSONHandler(os.Stdout, nil)) 23 24 cfg, err := config.Load(*configPath) 25 if err != nil { 26 log.Error("load config", "err", err) 27 os.Exit(1) 28 } 29 30 st, err := state.Open(cfg.StateDB) 31 if err != nil { 32 log.Error("open state db", "err", err) 33 os.Exit(1) 34 } 35 defer st.Close() 36 37 stateDir := cfg.StateDB 38 if idx := lastSlash(stateDir); idx >= 0 { 39 stateDir = stateDir[:idx] 40 } 41 42 syncers := make([]*sync.RepoSyncer, 0, len(cfg.Repos)) 43 for _, pair := range cfg.Repos { 44 rs, err := sync.New(pair, st, sync.WorkDirFor(stateDir, pair.Name)) 45 if err != nil { 46 log.Error("set up repo pair", "pair", pair.Name, "err", err) 47 os.Exit(1) 48 } 49 syncers = append(syncers, rs) 50 } 51 52 runAll := func() { 53 for _, rs := range syncers { 54 rs.Run(log) 55 } 56 } 57 58 runAll() 59 if *once { 60 return 61 } 62 63 ticker := time.NewTicker(cfg.SyncInterval) 64 defer ticker.Stop() 65 for range ticker.C { 66 runAll() 67 } 68} 69 70func lastSlash(s string) int { 71 for i := len(s) - 1; i >= 0; i-- { 72 if s[i] == '/' { 73 return i 74 } 75 } 76 return -1 77}