soft-serve

git clone git://git.lin.moe/fork/soft-serve.git

 1package jobs
 2
 3import (
 4	"context"
 5	"runtime"
 6
 7	"charm.land/log/v2"
 8	"github.com/charmbracelet/soft-serve/git"
 9	"github.com/charmbracelet/soft-serve/pkg/backend"
10	"github.com/charmbracelet/soft-serve/pkg/config"
11	"github.com/charmbracelet/soft-serve/pkg/proto"
12	"github.com/charmbracelet/soft-serve/pkg/sync"
13	"github.com/spf13/cobra"
14)
15
16
17
18func init() {
19	Register("git-gc", mirrorPull{})
20}
21
22type gitGC struct{}
23
24func (g gitGC) Spec(ctx context.Context) string {
25	cfg := config.FromContext(ctx)
26	if cfg.Jobs.GitGC != "" {
27		return cfg.Jobs.GitGC
28	}
29	return ""
30}
31
32func (g gitGC) Command() *cobra.Command {
33	cmd := &cobra.Command{
34		Use:   "git_gc [REPOSITORY]",
35		Short: "Cleanup unnecessary files and optimize the repository",
36		RunE:  g.Func,
37	}
38	return cmd
39}
40
41func (g gitGC) Func(cmd *cobra.Command, args []string) error {
42	var (
43		repos []proto.Repository
44		err   error
45	)
46
47	ctx := cmd.Context()
48	b := backend.FromContext(ctx)
49	logger := log.FromContext(ctx).WithPrefix("jobs.gitgc")
50
51	if len(args) != 0 {
52		repo, err := b.Repository(ctx, args[0])
53		if err != nil {
54			logger.Error("error getting repositorie", "repo", repo, "err", err)
55			return err
56		}
57		repos = []proto.Repository{}
58	} else {
59		repos, err = b.Repositories(ctx)
60		if err != nil {
61			logger.Error("error getting repositories", "err", err)
62			return err
63		}
64	}
65
66	wq := sync.NewWorkPool(ctx, runtime.GOMAXPROCS(0),
67		sync.WithWorkPoolLogger(logger.Errorf),
68	)
69
70	logger.Debug("cleaning repo garbage")
71	for _, repo := range repos {
72		r, err := repo.Open()
73		if err != nil {
74			logger.Error("error opening repository", "repo", repo.Name(), "err", err)
75			continue
76		}
77
78		name := repo.Name()
79		wq.Add(name, func() {
80			cmd := git.NewCommand("gc", "--auto").WithContext(ctx)
81			if _, err := cmd.RunInDir(r.Path); err != nil {
82				logger.Error("error running git remote update", "repo", name, "err", err)
83			}
84		})
85
86		// TODO: clean up lfs
87	}
88
89	return nil
90}