You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Parse the single positional with util.ParseProjectPathTargetWithDefaultOrganization(ctx, args[0], ...). This helper is added as part of this issue's implementation in internal/cmd/util/scope.go (mirrors the pattern from #247: a thin new wrapper that splits [ORGANIZATION/]PROJECT/PATH into 3 strings; PATH may itself contain /).
No existing helper supports the 3-segment form.
6
--description is optional. Mirrors az pipelines folder create --description.
7
Non-interactive: no confirmation prompt.
Create is not destructive.
8
Plain output: print Created folder <PROJECT>/<PATH> to stdout on success.
Mirrors internal/cmd/repo/create/create.go.
9
JSON output: pass the raw *build.Folder from CreateFolder directly to opts.exporter.Write. No view struct.
The SDK type is the API surface; expose every field.
10
Table output: N/A.
Create commands print a single confirmation line, not a table.
11
Uses vendored build.Client.CreateFolder.
Vendor verified at vendor/.../v7/build/client.go:584.
No go mod tidy / go mod vendor / scripts/generate_mocks.sh work.
Command Signature
varcreateCmd=&cobra.Command{
Use: "create [ORGANIZATION/]PROJECT/PATH",
Aliases: []string{"c", "cr"},
Short: "Create a folder.",
Long: `Create a build definition folder at PATH under PROJECT.Mirrors 'az pipelines folder create'. PATH is the full path(e.g. "External/CI"). Azure DevOps stores folder paths with '/'.`,
Args: cobra.ExactArgs(1),
RunE: func(cmd*cobra.Command, args []string) error {
returnrunCreate(cmd.Context(), opts, args[0])
},
}
Flags
Flag
Type
Default
Required
Description
--description
string
""
no
Description of the folder.
--organization
string
$AZDO_ORGANIZATION or default config
no
Azure DevOps organization. Omit to use the default.
--project
string
""
no
Project name or ID. Omit to use the project from the positional target.
Also add util.AddJSONFlags(cmd, &opts.exporter, ...) registering every field of *build.Folder: createdBy, createdOn, description, lastChangedBy, lastChangedDate, path, project.
JSON Output Contract
Pass the raw *build.Folder returned by CreateFolder to opts.exporter.Write. No view struct.
The vendored SDK enforces args.Folder != nil, args.Project != "", args.Path != nil — will return ArgumentNilError / ArgumentNilOrEmptyError if any are missing. No extra validation needed in our wrapper.
Reference Existing Patterns
internal/cmd/pipelines/variablegroup/delete/delete.go:34 — closest sibling for the [ORGANIZATION/]PROJECT/TARGET Use syntax and util.ParseProjectTargetWithDefaultOrganization (with a project-only target; this issue adds the path variant).
internal/cmd/repo/create/create.go — closest sibling for the non-destructive create pattern (no confirmation, single-line success message, pass-through JSON).
internal/cmd/util/scope.go — the new ParseProjectPathTargetWithDefaultOrganization wrapper is added as part of this issue's implementation, parallel to the wrapper added in feat: Implement azdo pipelines agent show command #247 (ParsePoolAgentTargetWithDefaultOrganization).
Sub-issue of #262. Hardened spec — do not re-derive decisions.
Command Description
Create a new build definition folder at
PATHunderPROJECT. Mirrorsaz pipelines folder create.Locked Decisions
Use: "create [ORGANIZATION/]PROJECT/PATH".variable-group delete'sUse: "delete [ORGANIZATION/]PROJECT/GROUP"(internal/cmd/pipelines/variablegroup/delete/delete.go:34).Aliases: []string{"c", "cr"}.cobra.ExactArgs(1).util.ParseProjectPathTargetWithDefaultOrganization(ctx, args[0], ...). This helper is added as part of this issue's implementation ininternal/cmd/util/scope.go(mirrors the pattern from #247: a thin new wrapper that splits[ORGANIZATION/]PROJECT/PATHinto 3 strings; PATH may itself contain/).--descriptionis optional. Mirrorsaz pipelines folder create --description.Created folder <PROJECT>/<PATH>to stdout on success.internal/cmd/repo/create/create.go.*build.FolderfromCreateFolderdirectly toopts.exporter.Write. No view struct.build.Client.CreateFolder.vendor/.../v7/build/client.go:584.internal/mocks/build_client_mock.go:182-193already mocksCreateFolder.go mod tidy/go mod vendor/scripts/generate_mocks.shwork.Command Signature
Flags
--descriptionstring""--organizationstring$AZDO_ORGANIZATIONor default config--projectstring""Also add
util.AddJSONFlags(cmd, &opts.exporter, ...)registering every field of*build.Folder:createdBy,createdOn,description,lastChangedBy,lastChangedDate,path,project.JSON Output Contract
Pass the raw
*build.Folderreturned byCreateFoldertoopts.exporter.Write. No view struct.JSON fields exposed (matching SDK struct tags):
createdBy,createdOn,description,lastChangedBy,lastChangedDate,path,project.Table Output Contract
N/A. On success, print one line to stdout:
where
<PATH>is the path returned by the SDK (the SDK normalizes the separator to/).Command Wiring
internal/cmd/pipelines/folder/create/create.gowithpackage create, factoryfunc NewCmd(ctx util.CmdContext) *cobra.Command.import "github.com/tmeckel/azdo-cli/internal/cmd/pipelines/folder/create"tointernal/cmd/pipelines/folder/folder.go.folder.gowithcmd.AddCommand(create.NewCmd(ctx)).API Surface
Vendored SDK call (from
vendor/.../v7/build/client.go:584):The vendored SDK enforces
args.Folder != nil,args.Project != "",args.Path != nil— will returnArgumentNilError/ArgumentNilOrEmptyErrorif any are missing. No extra validation needed in our wrapper.Reference Existing Patterns
internal/cmd/pipelines/variablegroup/delete/delete.go:34— closest sibling for the[ORGANIZATION/]PROJECT/TARGETUse syntax andutil.ParseProjectTargetWithDefaultOrganization(with a project-only target; this issue adds the path variant).internal/cmd/repo/create/create.go— closest sibling for the non-destructive create pattern (no confirmation, single-line success message, pass-through JSON).internal/cmd/util/scope.go— the newParseProjectPathTargetWithDefaultOrganizationwrapper is added as part of this issue's implementation, parallel to the wrapper added in feat: Implementazdo pipelines agent showcommand #247 (ParsePoolAgentTargetWithDefaultOrganization).TDD Test Plan
TestNewCmd_createUse == "create [ORGANIZATION/]PROJECT/PATH",Aliases == ["c", "cr"],Args == cobra.ExactArgs(1).Test_runCreate_success_noDescriptionCreateFolderreturns*build.Folder{Path: ptr("MyProject/Foo")}. Run viaRunE.Created folder MyProject/Footo stdout.Test_runCreate_success_withDescriptionDescription: ptr("hello").MyProject/Foo.Test_runCreate_APIErrorerrors.New("boom").Test_runCreate_JSON--jsonflag set, exporter captures output.*build.FolderwithPath == ptr("MyProject/Foo").Test_runCreate_missingPathazdo pipelines folder createwith no args.Test_runCreate_defaultOrganization--organizationflag, default config returns"myOrg"."myOrg"via the factory.References
vendor/.../v7/build/client.go:584(CreateFolder),:615(CreateFolderArgs).vendor/.../v7/build/models.go:1401(Folder).internal/mocks/build_client_mock.go:182-193(CreateFolder).internal/azdo/factory.go:61—ClientFactory().Build(ctx, organization).a906531b-d2da-4f55-bda7-f3e676cc50d9, API version7.1-preview.2).internal/cmd/pipelines/variablegroup/delete/delete.go:34(project-scope + path-target Use syntax).internal/cmd/repo/create/create.go(non-destructive create, no confirmation, pass-through JSON).