all repos

mugit @ 58c5b75

🐮 git server that your cow will love

mugit/internal/cli/repo.go (view raw)

Oleksandr Smirnov Oleksandr Smirnov
olexsmir@gmail.com
goimports -local 'olexsmir.xyz' -w ., 1 month ago
1
package cli
2
3
import (
4
	"context"
5
	"fmt"
6
	"log/slog"
7
	"os"
8
9
	"github.com/urfave/cli/v3"
10
11
	"olexsmir.xyz/mugit/internal/git"
12
	"olexsmir.xyz/mugit/internal/mirror"
13
)
14
15
func (c *Cli) repoNewAction(ctx context.Context, cmd *cli.Command) error {
16
	name, err := c.getRepoNameArg(cmd)
17
	if name == "" {
18
		return err
19
	}
20
21
	path, err := git.ResolvePath(c.cfg.Repo.Dir, name)
22
	if err != nil {
23
		return err
24
	}
25
26
	if _, err = os.Stat(path); err == nil {
27
		return fmt.Errorf("repository already exists: %s", name)
28
	}
29
30
	mirrorURL := cmd.String("mirror")
31
	if mirrorURL != "" {
32
		if merr := mirror.IsRemoteSupported(mirrorURL); merr != nil {
33
			return merr
34
		}
35
	}
36
37
	if err = git.Init(path); err != nil {
38
		return err
39
	}
40
41
	repo, err := git.Open(path, "")
42
	if err != nil {
43
		return fmt.Errorf("failed to open repo: %w", err)
44
	}
45
46
	if err := repo.SetPrivate(cmd.Bool("private")); err != nil {
47
		return fmt.Errorf("failed to set private status: %w", err)
48
	}
49
50
	if mirrorURL != "" {
51
		if err := repo.SetMirrorRemote(mirrorURL); err != nil {
52
			return fmt.Errorf("failed to set mirror remote: %w", err)
53
		}
54
55
		slog.Info("performing initial sync for mirror", "repo", name)
56
		if err := c.syncRepo(ctx, name); err != nil {
57
			return err
58
		}
59
		slog.Info("initial mirror sync completed", "repo", name)
60
	}
61
62
	desc := cmd.String("description")
63
	if desc != "" {
64
		if err := repo.SetDescription(desc); err != nil {
65
			return fmt.Errorf("failed to set description: %w", err)
66
		}
67
	}
68
69
	return nil
70
}
71
72
func (c *Cli) repoDescriptionAction(ctx context.Context, cmd *cli.Command) error {
73
	name, err := c.getRepoNameArg(cmd)
74
	if name == "" {
75
		return err
76
	}
77
78
	repo, err := c.openRepo(name)
79
	if err != nil {
80
		return fmt.Errorf("failed to open repo: %w", err)
81
	}
82
83
	newDesc := cmd.Args().Get(0)
84
	if newDesc != "" {
85
		if err = repo.SetDescription(newDesc); err != nil {
86
			return fmt.Errorf("failed to set description: %w", err)
87
		}
88
	}
89
90
	desc, err := repo.Description()
91
	if err != nil {
92
		return fmt.Errorf("failed to get description: %w", err)
93
	}
94
95
	slog.Info("changed repo description", "repo", name, "new_description", desc)
96
	return nil
97
}
98
99
func (c *Cli) repoPrivateAction(ctx context.Context, cmd *cli.Command) error {
100
	name, err := c.getRepoNameArg(cmd)
101
	if name == "" {
102
		return err
103
	}
104
105
	repo, err := c.openRepo(name)
106
	if err != nil {
107
		return fmt.Errorf("failed to open repo: %w", err)
108
	}
109
110
	isPrivate, err := repo.IsPrivate()
111
	if err != nil {
112
		return fmt.Errorf("failed to get private status: %w", err)
113
	}
114
115
	newStatus := !isPrivate
116
	if err := repo.SetPrivate(newStatus); err != nil {
117
		return fmt.Errorf("failed to set private status: %w", err)
118
	}
119
120
	slog.Info("new repo private status", "repo", name, "is_private", newStatus)
121
	return nil
122
}
123
124
func (c *Cli) repoDefaultAction(ctx context.Context, cmd *cli.Command) error {
125
	name, err := c.getRepoNameArg(cmd)
126
	if name == "" {
127
		return err
128
	}
129
130
	repo, err := c.openRepo(name)
131
	if err != nil {
132
		return fmt.Errorf("failed to open repo: %w", err)
133
	}
134
135
	branch := cmd.Args().Get(0)
136
	if err = repo.SetDefaultBranch(branch); err != nil {
137
		return err
138
	}
139
140
	slog.Info("changed repo head", "repo", name, "branch", branch)
141
	return err
142
}
143
144
func (c *Cli) repoSyncAction(ctx context.Context, cmd *cli.Command) error {
145
	name, err := c.getRepoNameArg(cmd)
146
	if name == "" {
147
		return err
148
	}
149
150
	repo, err := c.openRepo(name)
151
	if err != nil {
152
		return fmt.Errorf("failed to open repo: %w", err)
153
	}
154
155
	isMirror, err := repo.IsMirror()
156
	if err != nil {
157
		return fmt.Errorf("failed to check mirror status: %w", err)
158
	}
159
	if !isMirror {
160
		return fmt.Errorf("repository is not a mirror: %s", name)
161
	}
162
163
	if err := c.syncRepo(ctx, name); err != nil {
164
		return err
165
	}
166
167
	slog.Info("mirror sync triggered", "repo", name)
168
	return nil
169
}
170
171
func (c *Cli) getRepoNameArg(cmd *cli.Command) (string, error) {
172
	name := cmd.StringArg("name")
173
	if name == "" {
174
		return "", fmt.Errorf("no name provided")
175
	}
176
	return git.ResolveName(name), nil
177
}
178
179
func (c *Cli) syncRepo(ctx context.Context, name string) error {
180
	worker := mirror.NewWorker(c.cfg)
181
	if err := worker.SyncRepo(ctx, name); err != nil {
182
		return fmt.Errorf("failed to sync mirror: %w", err)
183
	}
184
	return nil
185
}