all repos

mugit @ 3adee8f591b6b7ee8756e6634f8a40209672fc59

🐮 git server that your cow will love

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package cli

import (
	"context"
	"fmt"

	securejoin "github.com/cyphar/filepath-securejoin"
	"github.com/urfave/cli/v3"
	"olexsmir.xyz/mugit/internal/config"
	"olexsmir.xyz/mugit/internal/git"
)

type Cli struct {
	cfg     *config.Config
	version string
}

func New(version string) *Cli {
	return &Cli{
		version: version,
	}
}

func (c *Cli) Run(ctx context.Context, args []string) error {
	cmd := &cli.Command{
		Name:                  "mugit",
		Usage:                 "a frontend for git repos",
		Version:               c.version,
		EnableShellCompletion: true,
		Flags: []cli.Flag{
			&cli.StringFlag{
				Name:    "config",
				Aliases: []string{"c"},
				Usage:   "path to config file",
			},
		},
		Before: func(ctx context.Context, cmd *cli.Command) (context.Context, error) {
			loadedCfg, err := config.Load(
				config.PathOrDefault(cmd.String("config")))
			if err != nil {
				return ctx, err
			}
			c.cfg = loadedCfg
			return ctx, nil
		},
		Commands: []*cli.Command{
			{
				Name:   "serve",
				Usage:  "starts the server",
				Action: c.serveAction,
			},
			{
				Name: "repo",
				Commands: []*cli.Command{
					{
						Name:   "new",
						Usage:  "create new repo",
						Action: c.repoNewAction,
						Arguments: []cli.Argument{
							&cli.StringArg{Name: "name"},
						},
						Flags: []cli.Flag{
							&cli.StringFlag{
								Name:  "mirror",
								Usage: "remote URL(only http/https) to mirror from",
							},
							&cli.BoolFlag{
								Name:  "private",
								Usage: "make the repository private",
							},
						},
					},
					{
						Name:   "description",
						Usage:  "get or set repo description",
						Action: c.repoDescriptionAction,
						Arguments: []cli.Argument{
							&cli.StringArg{Name: "name"},
						},
					},
					{
						Name:   "private",
						Usage:  "toggle private status of a repo",
						Action: c.repoPrivateAction,
						Arguments: []cli.Argument{
							&cli.StringArg{Name: "name"},
						},
					},
				},
			},
		},
	}
	return cmd.Run(ctx, args)
}

func (c *Cli) openRepo(name string) (*git.Repo, error) {
	path, err := securejoin.SecureJoin(c.cfg.Repo.Dir, name)
	if err != nil {
		return nil, err
	}

	repo, err := git.Open(path, "")
	if err != nil {
		return nil, fmt.Errorf("failed to open repo: %w", err)
	}

	return repo, nil
}