all repos

mugit @ 6e946c7

🐮 git server that your cow will love

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

Oleksandr Smirnov Oleksandr Smirnov
olexsmir@gmail.com
ssh!: switch to sshd, 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
						},
87
					},
88
					{
89
						Name:   "description",
90
						Usage:  "get or set repo description",
91
						Action: c.repoDescriptionAction,
92
						Arguments: []cli.Argument{
93
							&cli.StringArg{Name: "name"},
94
						},
95
					},
96
					{
97
						Name:   "private",
98
						Usage:  "toggle private status of a repo",
99
						Action: c.repoPrivateAction,
100
						Arguments: []cli.Argument{
101
							&cli.StringArg{Name: "name"},
102
						},
103
					},
104
					{
105
						Name:   "set-head",
106
						Usage:  "switches repo's head to specified branch",
107
						Action: c.repoSetHeadAction,
108
						Arguments: []cli.Argument{
109
							&cli.StringArg{Name: "name"},
110
						},
111
					},
112
				},
113
			},
114
			{
115
				Name:        "shell",
116
				Description: "sshd things", // TODO: update me
117
				Action:      c.sshShellAction,
118
				Commands: []*cli.Command{
119
					{
120
						Name:   "keys",
121
						Action: c.sshAuthorizedKeysAction,
122
					},
123
				},
124
			},
125
		},
126
	}
127
	return cmd.Run(ctx, args)
128
}
129
130
func (c *Cli) openRepo(name string) (*git.Repo, error) {
131
	path, err := git.ResolvePath(c.cfg.Repo.Dir, name)
132
	if err != nil {
133
		return nil, err
134
	}
135
136
	repo, err := git.Open(path, "")
137
	if err != nil {
138
		return nil, fmt.Errorf("failed to open repo: %w", err)
139
	}
140
141
	return repo, nil
142
}