Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/azdo.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Work seamlessly with Azure DevOps from the command line.
* [azdo project](./azdo_project.md)
* [azdo repo](./azdo_repo.md)
* [azdo service-endpoint](./azdo_service-endpoint.md)
* [azdo team](./azdo_team.md)

### Security commands

Expand Down
28 changes: 28 additions & 0 deletions docs/azdo_help_reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -1293,6 +1293,34 @@ Update a service endpoint.
--url string New service endpoint URL.
```

## `azdo team <command>`

Manage Azure DevOps teams.

Aliases

```
t
```

### `azdo team create [ORGANIZATION/]PROJECT [flags]`

Create a new team in a project.

```
--description string Description of the new team
-q, --jq expression Filter JSON output using a jq expression
--json fields[=*] Output JSON with the specified fields. Prefix a field with '-' to exclude it.
--name string Name of the new team (required)
-t, --template string Format JSON output using a Go template; see "azdo help formatting"
```

Aliases

```
c, cr, new, n, add, a
```



### See also
Expand Down
15 changes: 15 additions & 0 deletions docs/azdo_team.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
## Command `azdo team`

Manage Azure DevOps teams.

### Available commands

* [azdo team create](./azdo_team_create.md)

### ALIASES

- `t`

### See also

* [azdo](./azdo.md)
61 changes: 61 additions & 0 deletions docs/azdo_team_create.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
## Command `azdo team create`

```
azdo team create [ORGANIZATION/]PROJECT [flags]
```

Create a new team in the specified project. The --name flag is required.
The project argument is required; the organization falls back to the
configured default when omitted.


### Options


* `--description` `string`

Description of the new team

* `-q`, `--jq` `expression`

Filter JSON output using a jq expression

* `--json` `fields`

Output JSON with the specified fields. Prefix a field with &#39;-&#39; to exclude it.

* `--name` `string`

Name of the new team (required)

* `-t`, `--template` `string`

Format JSON output using a Go template; see &#34;azdo help formatting&#34;


### ALIASES

- `c`
- `cr`
- `new`
- `n`
- `add`
- `a`

### JSON Fields

`description`, `id`, `identity`, `identityUrl`, `name`, `projectId`, `projectName`, `url`

### Examples

```bash
# Create a team in the default organization
azdo team create Fabrikam --name "Fabrikam Engineering"

# Create a team with a description
azdo team create MyOrg/Fabrikam --name "My Team" --description "Owns the web app"
```

### See also

* [azdo team](./azdo_team.md)
2 changes: 2 additions & 0 deletions internal/cmd/root/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/tmeckel/azdo-cli/internal/cmd/repo"
"github.com/tmeckel/azdo-cli/internal/cmd/security"
"github.com/tmeckel/azdo-cli/internal/cmd/serviceendpoint"
"github.com/tmeckel/azdo-cli/internal/cmd/team"
"github.com/tmeckel/azdo-cli/internal/cmd/util"
versionCmd "github.com/tmeckel/azdo-cli/internal/cmd/version"
"github.com/tmeckel/azdo-cli/internal/validation"
Expand Down Expand Up @@ -97,6 +98,7 @@ func NewCmdRoot(ctx util.CmdContext, version, buildDate string) (*cobra.Command,
cmd.AddCommand(serviceendpoint.NewCmd(ctx))
cmd.AddCommand(boards.NewCmd(ctx))
cmd.AddCommand(pipelines.NewCmd(ctx))
cmd.AddCommand(team.NewCmd(ctx))

// Help topics
var referenceCmd *cobra.Command
Expand Down
121 changes: 121 additions & 0 deletions internal/cmd/team/create/create.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package create

import (
"fmt"

"github.com/MakeNowJust/heredoc/v2"
"github.com/google/uuid"
"github.com/microsoft/azure-devops-go-api/azuredevops/v7/core"
"github.com/spf13/cobra"
"github.com/tmeckel/azdo-cli/internal/cmd/util"
"github.com/tmeckel/azdo-cli/internal/types"
)

type createOptions struct {
scopeArg string
name string
description string
exporter util.Exporter
}

func NewCmd(ctx util.CmdContext) *cobra.Command {
opts := &createOptions{}

cmd := &cobra.Command{
Use: "create [ORGANIZATION/]PROJECT",
Short: "Create a new team in a project.",
Long: heredoc.Doc(`
Create a new team in the specified project. The --name flag is required.
The project argument is required; the organization falls back to the
configured default when omitted.
`),
Example: heredoc.Doc(`
# Create a team in the default organization
azdo team create Fabrikam --name "Fabrikam Engineering"

# Create a team with a description
azdo team create MyOrg/Fabrikam --name "My Team" --description "Owns the web app"
`),
Aliases: []string{
"c",
"cr",
"new",
"n",
"add",
"a",
},
Args: util.ExactArgs(1, "project argument required"),
RunE: func(cmd *cobra.Command, args []string) error {
opts.scopeArg = args[0]
return runCreate(ctx, opts)
},
}

cmd.Flags().StringVar(&opts.name, "name", "", "Name of the new team (required)")
cmd.Flags().StringVar(&opts.description, "description", "", "Description of the new team")
_ = cmd.MarkFlagRequired("name")

util.AddJSONFlags(cmd, &opts.exporter, []string{
"id", "name", "description", "url",
"identity", "identityUrl", "projectId", "projectName",
})

return cmd
}

func runCreate(ctx util.CmdContext, opts *createOptions) error {
ios, err := ctx.IOStreams()
if err != nil {
return err
}

ios.StartProgressIndicator()
defer ios.StopProgressIndicator()

scope, err := util.ParseProjectScope(ctx, opts.scopeArg)
if err != nil {
return util.FlagErrorWrap(err)
}

client, err := ctx.ClientFactory().Core(ctx.Context(), scope.Organization)
if err != nil {
return fmt.Errorf("failed to create Core client: %w", err)
}

team := &core.WebApiTeam{
Name: types.ToPtr(opts.name),
Description: types.ToPtr(opts.description),
}

created, err := client.CreateTeam(ctx.Context(), core.CreateTeamArgs{
Team: team,
ProjectId: &scope.Project,
})
if err != nil {
return fmt.Errorf("failed to create team: %w", err)
}

ios.StopProgressIndicator()

if opts.exporter != nil {
return opts.exporter.Write(ios, created)
}

return renderTeam(ctx, created)
}

func renderTeam(ctx util.CmdContext, team *core.WebApiTeam) error {
tp, err := ctx.Printer("list")
if err != nil {
return err
}
tp.AddColumns("ID", "NAME", "DESCRIPTION", "PROJECT", "URL")
tp.EndRow()
tp.AddField(types.GetValue(team.Id, uuid.UUID{}).String())
tp.AddField(types.GetValue(team.Name, ""))
tp.AddField(types.GetValue(team.Description, ""))
tp.AddField(types.GetValue(team.ProjectName, ""))
tp.AddField(types.GetValue(team.Url, ""))
tp.EndRow()
return tp.Render()
}
Loading
Loading