mirror of
https://gitea.com/gitea/tea.git
synced 2026-09-10 07:26:33 -04:00
feat(teams): add members subcommands
Provide list, add, and remove operations for team members via
'tea teams members {list,create,delete}'. The members package reuses
the RequireTeamID helper exported by cmd/teams.
This commit is contained in:
parent
bcdd28f395
commit
c8f75c9975
|
|
@ -5,6 +5,7 @@ package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"gitea.dev/tea/cmd/teams"
|
"gitea.dev/tea/cmd/teams"
|
||||||
|
"gitea.dev/tea/cmd/teams/members"
|
||||||
"github.com/urfave/cli/v3"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -21,6 +22,7 @@ var CmdTeams = cli.Command{
|
||||||
&teams.CmdTeamsCreate,
|
&teams.CmdTeamsCreate,
|
||||||
&teams.CmdTeamsDelete,
|
&teams.CmdTeamsDelete,
|
||||||
&teams.CmdTeamsEdit,
|
&teams.CmdTeamsEdit,
|
||||||
|
&members.CmdTeamsMembers,
|
||||||
},
|
},
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
|
|
|
||||||
55
cmd/teams/members/create.go
Normal file
55
cmd/teams/members/create.go
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package members
|
||||||
|
|
||||||
|
import (
|
||||||
|
stdctx "context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"gitea.dev/tea/cmd/flags"
|
||||||
|
"gitea.dev/tea/cmd/teams"
|
||||||
|
"gitea.dev/tea/modules/context"
|
||||||
|
"github.com/urfave/cli/v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CmdTeamsMembersCreate adds a member to a team.
|
||||||
|
var CmdTeamsMembersCreate = cli.Command{
|
||||||
|
Name: "create",
|
||||||
|
Aliases: []string{"add", "c"},
|
||||||
|
Usage: "Add a member to a team",
|
||||||
|
Description: "Add a user to a team",
|
||||||
|
ArgsUsage: "<team-id> <username>",
|
||||||
|
Action: runTeamsMembersCreate,
|
||||||
|
Flags: flags.AllDefaultFlags,
|
||||||
|
}
|
||||||
|
|
||||||
|
func runTeamsMembersCreate(ctx stdctx.Context, cmd *cli.Command) error {
|
||||||
|
if cmd.Args().Len() < 2 {
|
||||||
|
return errors.New("team ID and username are required")
|
||||||
|
}
|
||||||
|
|
||||||
|
teamID, err := teams.RequireTeamID(cmd)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
username := cmd.Args().Get(1)
|
||||||
|
|
||||||
|
c, err := context.InitCommand(cmd)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
client := c.Login.Client()
|
||||||
|
|
||||||
|
team, _, err := client.Organizations.GetTeam(ctx, teamID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err = client.Organizations.AddTeamMember(ctx, teamID, username); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Printf("User '%s' added to team '%s' (ID: %d)\n", username, team.Name, team.ID)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
71
cmd/teams/members/delete.go
Normal file
71
cmd/teams/members/delete.go
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package members
|
||||||
|
|
||||||
|
import (
|
||||||
|
stdctx "context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"gitea.dev/tea/cmd/flags"
|
||||||
|
"gitea.dev/tea/cmd/teams"
|
||||||
|
"gitea.dev/tea/modules/context"
|
||||||
|
"github.com/urfave/cli/v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CmdTeamsMembersDelete removes a member from a team.
|
||||||
|
var CmdTeamsMembersDelete = cli.Command{
|
||||||
|
Name: "delete",
|
||||||
|
Aliases: []string{"rm", "remove"},
|
||||||
|
Usage: "Remove a member from a team",
|
||||||
|
Description: "Remove a user from a team",
|
||||||
|
ArgsUsage: "<team-id> <username>",
|
||||||
|
Action: runTeamsMembersDelete,
|
||||||
|
Flags: append([]cli.Flag{
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "confirm",
|
||||||
|
Aliases: []string{"y"},
|
||||||
|
Usage: "confirm removal without prompting",
|
||||||
|
},
|
||||||
|
}, flags.AllDefaultFlags...),
|
||||||
|
}
|
||||||
|
|
||||||
|
func runTeamsMembersDelete(ctx stdctx.Context, cmd *cli.Command) error {
|
||||||
|
if cmd.Args().Len() < 2 {
|
||||||
|
return errors.New("team ID and username are required")
|
||||||
|
}
|
||||||
|
|
||||||
|
teamID, err := teams.RequireTeamID(cmd)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
username := cmd.Args().Get(1)
|
||||||
|
|
||||||
|
c, err := context.InitCommand(cmd)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
client := c.Login.Client()
|
||||||
|
|
||||||
|
team, _, err := client.Organizations.GetTeam(ctx, teamID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !cmd.Bool("confirm") {
|
||||||
|
fmt.Printf("Are you sure you want to remove '%s' from team '%s' (ID: %d)? [y/N] ", username, team.Name, team.ID)
|
||||||
|
var response string
|
||||||
|
fmt.Scanln(&response)
|
||||||
|
if response != "y" && response != "Y" && response != "yes" {
|
||||||
|
fmt.Println("Removal canceled.")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err = client.Organizations.RemoveTeamMember(ctx, teamID, username); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Printf("User '%s' removed from team '%s' (ID: %d)\n", username, team.Name, team.ID)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
58
cmd/teams/members/list.go
Normal file
58
cmd/teams/members/list.go
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package members
|
||||||
|
|
||||||
|
import (
|
||||||
|
stdctx "context"
|
||||||
|
|
||||||
|
gitea "gitea.dev/sdk"
|
||||||
|
|
||||||
|
"gitea.dev/tea/cmd/flags"
|
||||||
|
"gitea.dev/tea/cmd/teams"
|
||||||
|
"gitea.dev/tea/modules/context"
|
||||||
|
"gitea.dev/tea/modules/print"
|
||||||
|
"github.com/urfave/cli/v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CmdTeamsMembersList lists all members of a team.
|
||||||
|
var CmdTeamsMembersList = cli.Command{
|
||||||
|
Name: "list",
|
||||||
|
Aliases: []string{"ls"},
|
||||||
|
Usage: "List team members",
|
||||||
|
Description: "List all members of a team",
|
||||||
|
ArgsUsage: "<team-id>",
|
||||||
|
Action: runTeamsMembersList,
|
||||||
|
Flags: append([]cli.Flag{
|
||||||
|
&flags.PaginationPageFlag,
|
||||||
|
&flags.PaginationLimitFlag,
|
||||||
|
}, flags.AllDefaultFlags...),
|
||||||
|
}
|
||||||
|
|
||||||
|
func runTeamsMembersList(ctx stdctx.Context, cmd *cli.Command) error {
|
||||||
|
teamID, err := teams.RequireTeamID(cmd)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
c, err := context.InitCommand(cmd)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
client := c.Login.Client()
|
||||||
|
|
||||||
|
team, _, err := client.Organizations.GetTeam(ctx, teamID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
members, _, err := client.Organizations.ListTeamMembers(ctx, teamID, gitea.ListTeamMembersOptions{
|
||||||
|
ListOptions: flags.GetListOptions(cmd),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
print.TeamMembersList(members, c.Output, team.Name)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
26
cmd/teams/members/members.go
Normal file
26
cmd/teams/members/members.go
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package members
|
||||||
|
|
||||||
|
import (
|
||||||
|
stdctx "context"
|
||||||
|
|
||||||
|
"github.com/urfave/cli/v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CmdTeamsMembers is the parent command for managing team membership.
|
||||||
|
var CmdTeamsMembers = cli.Command{
|
||||||
|
Name: "members",
|
||||||
|
Aliases: []string{"member"},
|
||||||
|
Usage: "Manage team members",
|
||||||
|
Description: "List, add, or remove team members",
|
||||||
|
Commands: []*cli.Command{
|
||||||
|
&CmdTeamsMembersList,
|
||||||
|
&CmdTeamsMembersCreate,
|
||||||
|
&CmdTeamsMembersDelete,
|
||||||
|
},
|
||||||
|
Action: func(ctx stdctx.Context, cmd *cli.Command) error {
|
||||||
|
return cli.ShowCommandHelp(ctx, cmd, "members")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
@ -68,3 +68,30 @@ func yesNo(b bool) string {
|
||||||
}
|
}
|
||||||
return "no"
|
return "no"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TeamMembersList prints a list of team members.
|
||||||
|
func TeamMembersList(members []*gitea.User, output, teamName string) {
|
||||||
|
if len(members) == 0 {
|
||||||
|
fmt.Printf("No members found in team '%s'\n", teamName)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
t := tableWithHeader(
|
||||||
|
"ID",
|
||||||
|
"Username",
|
||||||
|
"Full Name",
|
||||||
|
"Email",
|
||||||
|
)
|
||||||
|
|
||||||
|
for _, m := range members {
|
||||||
|
t.addRow(
|
||||||
|
strconv.FormatInt(m.ID, 10),
|
||||||
|
m.UserName,
|
||||||
|
m.FullName,
|
||||||
|
m.Email,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Members of team '%s':\n", teamName)
|
||||||
|
t.print(output)
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue