Skip to content

feat: Implement azdo pipelines queue list command #249

Description

@tmeckel

Sub-issue of #240. Hardened spec — do not re-derive decisions. Mirrors internal/cmd/pipelines/variablegroup/list/list.go (the modern list pattern with JSON view struct + table printer).

Command Description

List the agent queues in a project. The command fetches the matching queues via the Agent Queues REST 7.1 endpoint and renders them as a default table (with optional JSON export). All output passes through ctx.Printer("list") for the table and opts.exporter.Write(ios, view) for JSON.

GET https://dev.azure.com/{organization}/{project}/_apis/distributedtask/queues?queueName={filter}&api-version=7.1

Locked Decisions (do not re-derive)

# Decision Rationale
1 Use the vendored SDK taskagent.Client.GetAgentQueues (not raw HTTP). Mock already generated at internal/mocks/taskagent_client_mock.go:471-480. Consistent with the other taskagent subgroup siblings.
2 Queues are project-scoped: positional [ORGANIZATION/]PROJECT parsed with util.ParseProjectScope from internal/cmd/util/scope.go:138. The function returns a *util.Path with Organization (defaults resolved from ctx.Config().Authentication().GetDefaultOrganization()) and Project populated; Targets is not used (the command has no target beyond the project). Queues belong to a project. Same parser as work-item list (#136), work-item create (#203), and the pipelines build family.
2.5 cobra.ExactArgs(1, "project argument required")args[0] is the full scope. Combined with the ParseProjectScope parser, the resulting shape is azdo pipelines queue list [ORGANIZATION/]PROJECT, NOT [ORGANIZATION/]PROJECT/TARGET. Mirrors the project-scope precedent; no target segment exists for this command.
3 Optional filter --name (string) maps to GetAgentQueuesArgs.QueueName. Mirrors Azure CLI filter.
4 Default output is a table. JSON output via --json passes a dedicated view struct []queueJSON to opts.exporter.Write. The view struct flattens Pool (name only) and ProjectId (string). Mirrors pipelines/variablegroup/list/list.go.
5 JSON view struct fields: id, name, pool (name), projectId (string), createdBy (flattened). Symmetric with boards/list siblings.
6 --max-items (int, default 0 = no cap) — if positive, truncate the result slice client-side. Mirrors pipelines/variablegroup/list --max-items.
7 Aliases: ls, l. Project convention.
8 No new SDK client, no new helper, no new package beyond internal/cmd/pipelines/queue/list. Reuse SDK call from the vendored taskagent package. Mandate: minimal code.
9 Mock for GetAgentQueues is already generated at internal/mocks/taskagent_client_mock.go:471-480. Do not regenerate. Verified.

Command Signature

azdo pipelines queue list [ORGANIZATION/]PROJECT
  [--name NAME]                  (optional string filter)
  [--max-items MAX]              (int, default 0 = no cap)
  [--json ...]                   (JSON output: --json / --jq / --template)

Aliases: ls, l.

Positional structure (parser: util.ParseProjectScope at internal/cmd/util/scope.go:138)

The parser expects 1 or 2 /-separated segments in the single positional. The resulting *util.Path has the following fields after a successful parse:

Field Value Notes
*Path.Organization string Required. Resolved from the first segment, or from ctx.Config().Authentication().GetDefaultOrganization() when the segment is omitted.
*Path.Project string Required. Resolved from the second segment when 2 segments are given, or from the single segment when only 1 is given.
*Path.Targets []string{} Always empty. The command has no positional target beyond the project; queue filtering is done server-side via --name and client-side via --max-items.

Segment-count table

Input Result
"" (no positional) Error"accepts 1 arg(s), received 0" (cobra-level). The parser itself accepts the empty input as a project-less scope, but cobra.ExactArgs(1) rejects the call before parsing.
"Fabrikam" Organization = default org, Project = "Fabrikam".
"myorg/Fabrikam" Organization = "myorg", Project = "Fabrikam".
"a/b/c" Error"invalid input \"a/b/c\": expected 1-2 segments, got 3".

cobra.Args validator

cobra.ExactArgs(1, "project argument required"). The RunE handler assigns args[0] to opts.scopeArg, then run() calls util.ParseProjectScope(ctx, opts.scopeArg) to obtain the *util.Path.

Flags

Flag Type Default Required Maps to Description
--name string "" no GetAgentQueuesArgs.QueueName Optional name filter on the queue. Empty string → no name filter.
--max-items int 0 no (client-side cap) Maximum number of queues to return. 0 = no cap; truncates the slice after the SDK call.
--json / --jq / --template no util.AddJSONFlags JSON output. --json id,name,poolName filters fields; --template @file accepts a Go-template file.

JSON Output Contract

type queueJSON struct {
    ID        *int    `json:"id,omitempty"`
    Name      *string `json:"name,omitempty"`
    PoolName  *string `json:"poolName,omitempty"`
    ProjectID *string `json:"projectId,omitempty"`
}

Table Output Contract

Default columns: ID, NAME, POOL, PROJECT (matches the pipelines queue show table from #245).

Command Wiring

  • Package path: internal/cmd/pipelines/queue/list
  • Files:
    • list.goNewCmd(ctx util.CmdContext) *cobra.Command + listOptions + runList
    • list_test.go — table-driven gomock tests
  • Update internal/cmd/pipelines/queue/queue.go to add listcmd "github.com/tmeckel/azdo-cli/internal/cmd/pipelines/queue/list" and cmd.AddCommand(listcmd.NewCmd(ctx)). Update the Example block.
  • Higher-level parents must already remain wired: pipelinesqueuelist.

API Surface

Reuse the already-vendored client. No new SDK clients required.

  • taskagent.Client.GetAgentQueuesAgent Queues - List (REST 7.1)
  • taskagent.GetAgentQueuesArgs struct: {Project *string, QueueName *string, ActionFilter *TaskAgentQueueActionFilter}.

Mock for GetAgentQueues is already generated at internal/mocks/taskagent_client_mock.go:471-480. No mock regeneration needed.

Reference Existing Patterns

  • internal/cmd/pipelines/variablegroup/list/list.goprimary list reference (modern list pattern with JSON view struct, table printer, --max-items cap).
  • internal/cmd/pipelines/queue/show/show.go (sibling under feat: Implement azdo pipelines queue show command #245) — closest sibling; copy the table columns and the queueJSON view struct shape.
  • internal/cmd/boards/workitem/list/list_test.go:765-844setupFakeDeps / stub* fixture.
  • internal/mocks/taskagent_client_mock.go:471-480 — mock for GetAgentQueues (already generated, do not regenerate).
  • internal/azdo/factory.go:133-139ClientFactory().TaskAgent(...) accessor (reuse).
  • internal/cmd/util/scope.go:138util.ParseProjectScope (common project-scope parser, also used by feat: Implement azdo boards work-item list command #136, feat: Implement azdo boards work-item create command #203, and the pipelines build family).

References

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions