all repos

mugit @ da1546430020daf5b14c456278e45471dff4d259

🐮 git server that your cow will love

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

Oleksandr Smirnov Oleksandr Smirnov
olexsmir@gmail.com
mirror: sync on mirror repo creation, 2 months ago
1
package cli
2
3
import (
4
	"context"
5
	"fmt"
6
7
	"github.com/urfave/cli/v3"
8
	"olexsmir.xyz/mugit/internal/config"
9
	"olexsmir.xyz/mugit/internal/git"
10
	"olexsmir.xyz/mugit/internal/ssh"
11
)
12
13
type Cli struct {
14
	cfg     *config.Config
15
	ssh     *ssh.Shell
16
	version string
17
}
18
19
func New(version string) *Cli {
20
	return &Cli{
21
		version: version,
22
	}
23
}
24
25
func (c *Cli) Run(ctx context.Context, args []string) error {
26
	cmd := &cli.Command{
27
		Name:                  "mugit",
28
		Usage:                 "a frontend for git repos",
29
		Version:               c.version,
30
		EnableShellCompletion: true,
31
		Flags: []cli.Flag{
32
			&cli.StringFlag{
33
				Name:    "config",
34
				Aliases: []string{"c"},
35
				Usage:   "path to config file",
36
			},
37
		},
38
		Before: func(ctx context.Context, cmd *cli.Command) (context.Context, error) {
39
			loadedCfg, err := config.Load(
40
				config.PathOrDefault(cmd.String("config")))
41
			if err != nil {
42
				return ctx, err
43
			}
44
			c.cfg = loadedCfg
45
46
			if c.cfg.SSH.Enable {
47
				shell, err := ssh.NewShell(c.cfg)
48
				if err != nil {
49
					return ctx, err
50
				}
51
				c.ssh = shell
52
			}
53
54
			return ctx, nil
55
		},
56
		Commands: []*cli.Command{
57
			{
58
				Name:   "serve",
59
				Usage:  "starts the server",
60
				Action: c.serveAction,
61
			},
62
			{
63
				Name: "repo",
64
				Commands: []*cli.Command{
65
					{
66
						Name:   "new",
67
						Usage:  "create new repo",
68
						Action: c.repoNewAction,
69
						Arguments: []cli.Argument{
70
							&cli.StringArg{Name: "name"},
71
						},
72
						Flags: []cli.Flag{
73
							&cli.StringFlag{
74
								Name:  "mirror",
75
								Usage: "remote URL(only http/https) to mirror from",
76
							},
77
							&cli.StringFlag{
78
								Name:    "description",
79
								Usage:   "set repo description",
80
								Aliases: []string{"desc"},
81
							},
82
							&cli.BoolFlag{
83
								Name:  "private",
84
								Usage: "make the repository private",
85
							},
86
							&cli.StringFlag{
87
								Name:  "default",
88
								Usage: "set default branch",
89
							},
90
						},
91
					},
92
					{
93
						Name:   "description",
94
						Usage:  "get or set repo description",
95
						Action: c.repoDescriptionAction,
96
						Arguments: []cli.Argument{
97
							&cli.StringArg{Name: "name"},
98
						},
99
					},
100
					{
101
						Name:   "private",
102
						Usage:  "toggle private status of a repo",
103
						Action: c.repoPrivateAction,
104
						Arguments: []cli.Argument{
105
							&cli.StringArg{Name: "name"},
106
						},
107
					},
108
					{
109
						Name:   "set-default",
110
						Usage:  "switch repo's default branch",
111
						Action: c.repoDefaultAction,
112
						Arguments: []cli.Argument{
113
							&cli.StringArg{Name: "name"},
114
						},
115
					},
116
					{
117
						Name:   "sync",
118
						Usage:  "trigger sync for a mirror repository",
119
						Action: c.repoSyncAction,
120
						Arguments: []cli.Argument{
121
							&cli.StringArg{Name: "name"},
122
						},
123
					},
124
				},
125
			},
126
			{
127
				Name:        "shell",
128
				Description: "sshd things", // TODO: update me
129
				Action:      c.sshShellAction,
130
				Commands: []*cli.Command{
131
					{
132
						Name:   "keys",
133
						Action: c.sshAuthorizedKeysAction,
134
					},
135
				},
136
			},
137
		},
138
	}
139
	return cmd.Run(ctx, args)
140
}
141
142
func (c *Cli) openRepo(name string) (*git.Repo, error) {
143
	path, err := git.ResolvePath(c.cfg.Repo.Dir, name)
144
	if err != nil {
145
		return nil, err
146
	}
147
148
	repo, err := git.Open(path, "")
149
	if err != nil {
150
		return nil, fmt.Errorf("failed to open repo: %w", err)
151
	}
152
153
	return repo, nil
154
}