1package repo
2
3import (
4 "github.com/charmbracelet/soft-serve/cmd"
5 "github.com/charmbracelet/soft-serve/pkg/access"
6 "github.com/charmbracelet/soft-serve/pkg/backend"
7 "github.com/charmbracelet/soft-serve/pkg/proto"
8 "github.com/spf13/cobra"
9)
10
11func collabCommand() *cobra.Command {
12 cmd := &cobra.Command{
13 Use: "collab",
14 Aliases: []string{"collabs", "collaborator", "collaborators"},
15 Short: "Manage collaborators",
16 }
17
18 cmd.AddCommand(
19 collabAddCommand(),
20 collabRemoveCommand(),
21 collabListCommand(),
22 )
23
24 return cmd
25}
26
27func collabAddCommand() *cobra.Command {
28 cmd := &cobra.Command{
29 Use: "add REPOSITORY USERNAME [LEVEL]",
30 Short: "Add a collaborator to a repo",
31 Long: "Add a collaborator to a repo. LEVEL can be one of: no-access, read-only, read-write, or admin-access. Defaults to read-write.",
32 Args: cobra.RangeArgs(2, 3),
33 RunE: func(c *cobra.Command, args []string) error {
34 ctx := c.Context()
35 be := backend.FromContext(ctx)
36 repo := args[0]
37 rr, err := be.Repository(ctx, repo)
38 if err != nil {
39 return err
40 }
41
42 if !cmd.CheckUserHasAccess(c, rr.Name(), access.ReadWriteAccess) {
43 return proto.ErrUnauthorized
44 }
45
46 username := args[1]
47 level := access.ReadWriteAccess
48 if len(args) > 2 {
49 level = access.ParseAccessLevel(args[2])
50 if level < 0 {
51 return access.ErrInvalidAccessLevel
52 }
53 }
54
55 return be.AddCollaborator(ctx, repo, username, level)
56 },
57 }
58
59 return cmd
60}
61
62func collabRemoveCommand() *cobra.Command {
63 cmd := &cobra.Command{
64 Use: "remove REPOSITORY USERNAME",
65 Args: cobra.ExactArgs(2),
66 Short: "Remove a collaborator from a repo",
67 RunE: func(c *cobra.Command, args []string) error {
68 ctx := c.Context()
69 be := backend.FromContext(ctx)
70 repo := args[0]
71 rr, err := be.Repository(ctx, repo)
72 if err != nil {
73 return err
74 }
75
76 if !cmd.CheckUserHasAccess(c, rr.Name(), access.ReadWriteAccess) {
77 return proto.ErrUnauthorized
78 }
79
80 username := args[1]
81
82 return be.RemoveCollaborator(ctx, repo, username)
83 },
84 }
85
86 return cmd
87}
88
89func collabListCommand() *cobra.Command {
90 cmd := &cobra.Command{
91 Use: "list REPOSITORY",
92 Short: "List collaborators for a repo",
93 Args: cobra.ExactArgs(1),
94 RunE: func(co *cobra.Command, args []string) error {
95 ctx := co.Context()
96 be := backend.FromContext(ctx)
97 repo := args[0]
98 rr, err := be.Repository(ctx, repo)
99 if err != nil {
100 return err
101 }
102
103 if !cmd.CheckUserHasAccess(co, rr.Name(), access.ReadWriteAccess) {
104 return proto.ErrUnauthorized
105 }
106
107 collabs, err := be.Collaborators(ctx, repo)
108 if err != nil {
109 return err
110 }
111
112 for _, c := range collabs {
113 co.Println(c)
114 }
115
116 return nil
117 },
118 }
119
120 return cmd
121}