all repos

mugit @ fc51f8d

🐮 git server that your cow will love

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

Oleksandr Smirnov Oleksandr Smirnov
olexsmir@gmail.com
cli: add a way to change HEAD of repo, 3 months ago
1
package cli
2
3
import (
4
	"context"
5
	"fmt"
6
	"log/slog"
7
	"os"
8
	"strings"
9
10
	securejoin "github.com/cyphar/filepath-securejoin"
11
	"github.com/urfave/cli/v3"
12
	"olexsmir.xyz/mugit/internal/git"
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 := securejoin.SecureJoin(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
	if err = git.Init(path); err != nil {
31
		return err
32
	}
33
34
	repo, err := git.Open(path, "")
35
	if err != nil {
36
		return fmt.Errorf("failed to open repo: %w", err)
37
	}
38
39
	if err := repo.SetPrivate(cmd.Bool("private")); err != nil {
40
		return fmt.Errorf("failed to set private status: %w", err)
41
	}
42
43
	mirrorURL := cmd.String("mirror")
44
	if mirrorURL != "" {
45
		if !strings.HasPrefix(mirrorURL, "http") {
46
			return fmt.Errorf("only http and https remotes are supported")
47
		}
48
		if err := repo.SetMirrorRemote(mirrorURL); err != nil {
49
			return fmt.Errorf("failed to set mirror remote: %w", err)
50
		}
51
	}
52
53
	return nil
54
}
55
56
func (c *Cli) repoDescriptionAction(ctx context.Context, cmd *cli.Command) error {
57
	name, err := c.getRepoNameArg(cmd)
58
	if name == "" {
59
		return err
60
	}
61
62
	repo, err := c.openRepo(name)
63
	if err != nil {
64
		return fmt.Errorf("failed to open repo: %w", err)
65
	}
66
67
	newDesc := cmd.Args().Get(0)
68
	if newDesc != "" {
69
		if err = repo.SetDescription(newDesc); err != nil {
70
			return fmt.Errorf("failed to set description: %w", err)
71
		}
72
	}
73
74
	desc, err := repo.Description()
75
	if err != nil {
76
		return fmt.Errorf("failed to get description: %w", err)
77
	}
78
79
	slog.Info("changed repo description", "repo", name, "new_description", desc)
80
	return nil
81
}
82
83
func (c *Cli) repoPrivateAction(ctx context.Context, cmd *cli.Command) error {
84
	name, err := c.getRepoNameArg(cmd)
85
	if name == "" {
86
		return err
87
	}
88
89
	repo, err := c.openRepo(name)
90
	if err != nil {
91
		return fmt.Errorf("failed to open repo: %w", err)
92
	}
93
94
	isPrivate, err := repo.IsPrivate()
95
	if err != nil {
96
		return fmt.Errorf("failed to get private status: %w", err)
97
	}
98
99
	newStatus := !isPrivate
100
	if err := repo.SetPrivate(newStatus); err != nil {
101
		return fmt.Errorf("failed to set private status: %w", err)
102
	}
103
104
	slog.Info("new repo private status", "repo", name, "is_private", newStatus)
105
	return nil
106
}
107
108
func (c *Cli) repoCheckoutAction(ctx context.Context, cmd *cli.Command) error {
109
	name, err := c.getRepoNameArg(cmd)
110
	if name == "" {
111
		return err
112
	}
113
114
	repo, err := c.openRepo(name)
115
	if err != nil {
116
		return fmt.Errorf("failed to open repo: %w", err)
117
	}
118
119
	branch := cmd.Args().Get(0)
120
	slog.Info("chaining repo head", "repo", name, "branch", branch)
121
	err = repo.Checkout(branch)
122
	return err
123
}
124
125
func (c *Cli) getRepoNameArg(cmd *cli.Command) (string, error) {
126
	name := cmd.StringArg("name")
127
	if name == "" {
128
		return "", fmt.Errorf("no name provided")
129
	}
130
	name = strings.TrimRight(name, ".git") + ".git"
131
	return name, nil
132
}