diff --git a/cmd/root.go b/cmd/root.go index ba1e39e..0982ab4 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -13,6 +13,7 @@ import ( prCmd "github.com/tyrantkhan/bb/cmd/pr" repoCmd "github.com/tyrantkhan/bb/cmd/repo" searchCmd "github.com/tyrantkhan/bb/cmd/search" + workspaceCmd "github.com/tyrantkhan/bb/cmd/workspace" "github.com/tyrantkhan/bb/internal/cmdutil" "github.com/tyrantkhan/bb/internal/output" "github.com/tyrantkhan/bb/internal/update" @@ -119,6 +120,7 @@ func NewRootCommand() *cli.Command { prCmd.NewCmdPR(), pipelineCmd.NewCmdPipeline(), searchCmd.NewCmdSearch(), + workspaceCmd.NewCmdWorkspace(), { Name: "version", Aliases: []string{"v"}, diff --git a/cmd/workspace/members.go b/cmd/workspace/members.go new file mode 100644 index 0000000..4215158 --- /dev/null +++ b/cmd/workspace/members.go @@ -0,0 +1,58 @@ +package workspace + +import ( + "context" + "fmt" + + "github.com/tyrantkhan/bb/internal/api" + "github.com/tyrantkhan/bb/internal/cmdutil" + "github.com/tyrantkhan/bb/internal/models" + "github.com/tyrantkhan/bb/internal/output" + "github.com/urfave/cli/v3" +) + +func newCmdMembers() *cli.Command { + return &cli.Command{ + Name: "members", + Usage: "List members in a workspace", + Flags: []cli.Flag{ + cmdutil.WorkspaceFlag, + cmdutil.FormatFlag, + cmdutil.LimitFlag, + }, + Action: cmdutil.NoArgs(func(ctx context.Context, cmd *cli.Command) error { + f := cmdutil.GetFactory(ctx) + client, err := f.APIClient() + if err != nil { + return err + } + + workspace, err := cmdutil.ResolveWorkspace(ctx, cmd) + if err != nil { + return err + } + + limit := int(cmd.Int("limit")) + path := fmt.Sprintf("/2.0/workspaces/%s/members", workspace) + + members, err := api.Paginate[models.WorkspaceMembership](client, path, limit) + if err != nil { + return err + } + + format := cmdutil.GetFormat(ctx, cmd) + + headers := []string{"Display Name", "Nickname", "Account ID"} + rows := make([][]string, len(members)) + for i, m := range members { + rows[i] = []string{ + m.User.DisplayName, + m.User.Nickname, + m.User.AccountID, + } + } + + return output.Format(format, members, headers, rows) + }), + } +} diff --git a/cmd/workspace/workspace.go b/cmd/workspace/workspace.go new file mode 100644 index 0000000..9da9e4f --- /dev/null +++ b/cmd/workspace/workspace.go @@ -0,0 +1,18 @@ +package workspace + +import ( + "github.com/tyrantkhan/bb/internal/cmdutil" + "github.com/urfave/cli/v3" +) + +// NewCmdWorkspace returns the parent workspace command with its subcommands. +func NewCmdWorkspace() *cli.Command { + return &cli.Command{ + Name: "workspace", + Usage: "Manage workspaces", + CommandNotFound: cmdutil.CommandNotFound, + Commands: []*cli.Command{ + newCmdMembers(), + }, + } +} diff --git a/go.mod b/go.mod index 9db4ad7..61b9761 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/tyrantkhan/bb -go 1.26.1 +go 1.26.2 require ( charm.land/glamour/v2 v2.0.0-20260302162937-86f90cfe96d1 diff --git a/internal/models/workspace.go b/internal/models/workspace.go new file mode 100644 index 0000000..ce1eadf --- /dev/null +++ b/internal/models/workspace.go @@ -0,0 +1,7 @@ +package models + +// WorkspaceMembership represents a member's membership in a workspace. +type WorkspaceMembership struct { + User User `json:"user"` + Workspace Workspace `json:"workspace"` +}