all repos

mugit @ f70e150377a19db58e4348197a9bf08f23c07a4f

🐮 git server that your cow will love

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

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