1package repo
2
3import (
4 "strings"
5
6 "github.com/charmbracelet/log"
7 "github.com/charmbracelet/soft-serve/cmd"
8 "github.com/charmbracelet/soft-serve/git"
9 "github.com/charmbracelet/soft-serve/pkg/access"
10 "github.com/charmbracelet/soft-serve/pkg/backend"
11 "github.com/charmbracelet/soft-serve/pkg/proto"
12 "github.com/charmbracelet/soft-serve/pkg/webhook"
13 "github.com/spf13/cobra"
14)
15
16func tagCommand() *cobra.Command {
17 cmd := &cobra.Command{
18 Use: "tag",
19 Short: "Manage repository tags",
20 }
21
22 cmd.AddCommand(
23 tagListCommand(),
24 tagDeleteCommand(),
25 )
26
27 return cmd
28}
29
30func tagListCommand() *cobra.Command {
31 cmd := &cobra.Command{
32 Use: "list REPOSITORY",
33 Aliases: []string{"ls"},
34 Short: "List repository tags",
35 Args: cobra.ExactArgs(1),
36 RunE: func(co *cobra.Command, args []string) error {
37 ctx := co.Context()
38 be := backend.FromContext(ctx)
39 rn := strings.TrimSuffix(args[0], ".git")
40 rr, err := be.Repository(ctx, rn)
41 if err != nil {
42 return err
43 }
44
45 if !cmd.CheckUserHasAccess(co, rr.Name(), access.ReadOnlyAccess) {
46 return proto.ErrUnauthorized
47 }
48
49 r, err := rr.Open()
50 if err != nil {
51 return err
52 }
53
54 tags, _ := r.Tags()
55 for _, t := range tags {
56 co.Println(t)
57 }
58
59 return nil
60 },
61 }
62
63 return cmd
64}
65
66func tagDeleteCommand() *cobra.Command {
67 cmd := &cobra.Command{
68 Use: "delete REPOSITORY TAG",
69 Aliases: []string{"remove", "rm", "del"},
70 Short: "Delete a tag",
71 Args: cobra.ExactArgs(2),
72 RunE: func(co *cobra.Command, args []string) error {
73 ctx := co.Context()
74 be := backend.FromContext(ctx)
75 rn := strings.TrimSuffix(args[0], ".git")
76 rr, err := be.Repository(ctx, rn)
77 if err != nil {
78 return err
79 }
80
81 if !cmd.CheckUserHasAccess(co, rr.Name(), access.ReadWriteAccess) {
82 return proto.ErrUnauthorized
83 }
84
85 r, err := rr.Open()
86 if err != nil {
87 log.Errorf("failed to open repo: %s", err)
88 return err
89 }
90
91 tag := args[1]
92 tags, _ := r.Tags()
93 var exists bool
94 for _, t := range tags {
95 if tag == t {
96 exists = true
97 break
98 }
99 }
100
101 if !exists {
102 log.Errorf("failed to get tag: tag %s does not exist", tag)
103 return git.ErrReferenceNotExist
104 }
105
106 tagCommit, err := r.TagCommit(tag)
107 if err != nil {
108 log.Errorf("failed to get tag commit: %s", err)
109 return err
110 }
111
112 if err := r.DeleteTag(tag); err != nil {
113 log.Errorf("failed to delete tag: %s", err)
114 return err
115 }
116
117 wh, err := webhook.NewBranchTagEvent(ctx, proto.UserFromContext(ctx), rr, git.RefsTags+tag, tagCommit.ID.String(), git.ZeroID)
118 if err != nil {
119 log.Error("failed to create branch_tag webhook", "err", err)
120 return err
121 }
122
123 return webhook.SendEvent(ctx, wh)
124 },
125 }
126
127 return cmd
128}