diff --git a/internal/cmd/customers.go b/internal/cmd/customers.go index 63f6953..64d728c 100644 --- a/internal/cmd/customers.go +++ b/internal/cmd/customers.go @@ -101,6 +101,7 @@ func newCustomersCreateCommand() *cobra.Command { } addInputSourceFlags(cmd, &file, &payload, "customer") inline.register(cmd) + inline.registerSlug(cmd) return cmd } @@ -168,6 +169,12 @@ type customerInputFlags struct { func (f *customerInputFlags) register(cmd *cobra.Command) { cmd.Flags().StringVar(&f.name, "name", "", "Customer name") cmd.Flags().StringVar(&f.externalCustomerID, "external-customer-id", "", "External customer ID") +} + +// registerSlug adds --slug to create only. The API never renames a customer: +// its update accepts the slug already in the path and refuses any other, so the +// flag could only restate the argument or be refused. +func (f *customerInputFlags) registerSlug(cmd *cobra.Command) { cmd.Flags().StringVar(&f.slug, "slug", "", "Customer slug") } diff --git a/internal/cmd/deployment_zones.go b/internal/cmd/deployment_zones.go index b77a09c..80bee94 100644 --- a/internal/cmd/deployment_zones.go +++ b/internal/cmd/deployment_zones.go @@ -101,6 +101,7 @@ func newDeploymentZonesCreateCommand() *cobra.Command { } addInputSourceFlags(cmd, &file, &payload, "deployment zone") inline.register(cmd) + inline.registerSlug(cmd) return cmd } @@ -175,6 +176,12 @@ func (f *deploymentZoneInputFlags) register(cmd *cobra.Command) { cmd.Flags().StringVar(&f.description, "description", "", "Deployment zone description") cmd.Flags().StringVar(&f.metadata, "metadata-json", "", "Deployment zone metadata as inline JSON or YAML object") cmd.Flags().StringVar(&f.releaseID, "release-id", "", "Release ID") +} + +// registerSlug adds --slug to create only. The API never renames a deployment zone: +// its update accepts the slug already in the path and refuses any other, so the +// flag could only restate the argument or be refused. +func (f *deploymentZoneInputFlags) registerSlug(cmd *cobra.Command) { cmd.Flags().StringVar(&f.slug, "slug", "", "Deployment zone slug") } diff --git a/internal/cmd/entitlement_groups.go b/internal/cmd/entitlement_groups.go index eb9770c..7a06930 100644 --- a/internal/cmd/entitlement_groups.go +++ b/internal/cmd/entitlement_groups.go @@ -104,6 +104,7 @@ func newEntitlementGroupsCreateCommand() *cobra.Command { } addInputSourceFlags(cmd, &file, &payload, "entitlement group") inline.register(cmd) + inline.registerSlug(cmd) return cmd } @@ -251,6 +252,12 @@ type entitlementGroupInputFlags struct { func (f *entitlementGroupInputFlags) register(cmd *cobra.Command) { cmd.Flags().StringVar(&f.name, "name", "", "Entitlement group name") cmd.Flags().StringVar(&f.description, "description", "", "Entitlement group description") +} + +// registerSlug adds --slug to create only. The API never renames an entitlement group: +// its update accepts the slug already in the path and refuses any other, so the +// flag could only restate the argument or be refused. +func (f *entitlementGroupInputFlags) registerSlug(cmd *cobra.Command) { cmd.Flags().StringVar(&f.slug, "slug", "", "Entitlement group slug") } diff --git a/internal/cmd/entitlements.go b/internal/cmd/entitlements.go index d41c820..3c67830 100644 --- a/internal/cmd/entitlements.go +++ b/internal/cmd/entitlements.go @@ -101,6 +101,7 @@ func newEntitlementsCreateCommand() *cobra.Command { } addInputSourceFlags(cmd, &file, &payload, "entitlement") inline.register(cmd) + inline.registerSlug(cmd) return cmd } @@ -175,6 +176,12 @@ func (f *entitlementInputFlags) register(cmd *cobra.Command) { cmd.Flags().StringVar(&f.kind, "type", "", "Entitlement type") cmd.Flags().StringVar(&f.aggregationMethod, "aggregation-method", "", "Entitlement aggregation method") cmd.Flags().StringArrayVar(&f.groupSlugs, "group-slug", nil, "Entitlement group slug, repeat for multiple values") +} + +// registerSlug adds --slug to create only. The API never renames an entitlement: +// its update accepts the slug already in the path and refuses any other, so the +// flag could only restate the argument or be refused. +func (f *entitlementInputFlags) registerSlug(cmd *cobra.Command) { cmd.Flags().StringVar(&f.slug, "slug", "", "Entitlement slug") } diff --git a/internal/cmd/exit_test.go b/internal/cmd/exit_test.go index 8e7f73a..5f77a23 100644 --- a/internal/cmd/exit_test.go +++ b/internal/cmd/exit_test.go @@ -105,6 +105,10 @@ func TestExitCodeForUsageMistakes(t *testing.T) { name: "unsupported config key", args: []string{"config", "set", "bogus", "value"}, }, + { + name: "a slug on the update of a resource the API never renames", + args: []string{"--base-url", "http://127.0.0.1:1", "entitlements", "update", "webhook", "--name", "webhook", "--slug", "webhooks"}, + }, { name: "destructive command with a non-interactive stdin and no --yes", args: []string{"--base-url", "http://127.0.0.1:1", "customers", "delete", "acme"}, diff --git a/internal/cmd/input_sources_test.go b/internal/cmd/input_sources_test.go index 0f3b36a..a2e581a 100644 --- a/internal/cmd/input_sources_test.go +++ b/internal/cmd/input_sources_test.go @@ -273,6 +273,40 @@ func TestInlineFlagsAreRecognisedByTheCommandThatRegistersThem(t *testing.T) { }) } +// TestSlugFlagIsOfferedOnlyWhereTheAPIActsOnIt pins --slug to the commands where a slug +// does something. Six resources are never renamed: their update accepts the slug already +// in the path and refuses any other. The SDK dropped the field on those updates, so +// "update webhook --slug webhooks" printed a success and left the slug alone. Components +// and instances do take a slug on update, so they keep the flag there. +func TestSlugFlagIsOfferedOnlyWhereTheAPIActsOnIt(t *testing.T) { + root := NewRootCommand() + + for path, want := range map[string]bool{ + "customers create": true, + "customers update": false, + "deployment-zones create": true, + "deployment-zones update": false, + "entitlement-groups create": true, + "entitlement-groups update": false, + "entitlements create": true, + "entitlements update": false, + "licenses create": true, + "licenses update": false, + "service-accounts create": true, + "service-accounts update": false, + "components update": true, + "instances update": true, + } { + cmd, _, err := root.Find(strings.Split(path, " ")) + if err != nil { + t.Fatalf("Find(%q) error = %v", path, err) + } + if got := cmd.Flags().Lookup("slug") != nil; got != want { + t.Errorf("%q offers --slug = %t, want %t", path, got, want) + } + } +} + // placeholderArgs supplies one throwaway value per positional argument in the command's // Use line, so that argument validation is satisfied and the run reaches the input check. func placeholderArgs(cmd *cobra.Command) []string { diff --git a/internal/cmd/licenses.go b/internal/cmd/licenses.go index deb59c3..01cf5a5 100644 --- a/internal/cmd/licenses.go +++ b/internal/cmd/licenses.go @@ -102,6 +102,7 @@ func newLicensesCreateCommand() *cobra.Command { } addInputSourceFlags(cmd, &file, &payload, "license") inline.register(cmd) + inline.registerSlug(cmd) return cmd } @@ -331,6 +332,12 @@ func (f *licenseInputFlags) register(cmd *cobra.Command) { cmd.Flags().StringVar(&f.version, "version", "", "License version") cmd.Flags().StringVar(&f.versionName, "version-name", "", "Human-readable license version name") cmd.Flags().BoolVar(&f.isDefault, "default", false, "Whether the license is the default") +} + +// registerSlug adds --slug to create only. The API never renames a license: +// its update accepts the slug already in the path and refuses any other, so the +// flag could only restate the argument or be refused. +func (f *licenseInputFlags) registerSlug(cmd *cobra.Command) { cmd.Flags().StringVar(&f.slug, "slug", "", "License slug") } diff --git a/internal/cmd/service_accounts.go b/internal/cmd/service_accounts.go index 404b2d8..1573bfe 100644 --- a/internal/cmd/service_accounts.go +++ b/internal/cmd/service_accounts.go @@ -101,6 +101,7 @@ func newServiceAccountsCreateCommand() *cobra.Command { } addInputSourceFlags(cmd, &file, &payload, "service account") inline.register(cmd) + inline.registerSlug(cmd) return cmd } @@ -238,6 +239,12 @@ type serviceAccountInputFlags struct { func (f *serviceAccountInputFlags) register(cmd *cobra.Command) { cmd.Flags().StringVar(&f.name, "name", "", "Service account name") +} + +// registerSlug adds --slug to create only. The API never renames a service account: +// its update accepts the slug already in the path and refuses any other, so the +// flag could only restate the argument or be refused. +func (f *serviceAccountInputFlags) registerSlug(cmd *cobra.Command) { cmd.Flags().StringVar(&f.slug, "slug", "", "Service account slug") }