Skip to content

Commit

Permalink
feat(core): deprecate an argument
Browse files Browse the repository at this point in the history
  • Loading branch information
Quentin Brosse committed Sep 8, 2020
1 parent 2bb6abf commit 03ccdd9
Show file tree
Hide file tree
Showing 20 changed files with 185 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ ARGS:
[additional-snapshots.{key}.organization-id] Organization ID that own the additional snapshot
[project] Project ID of the image
[public] True to create a public image
[organization-id] Organization ID to use. If none is passed will use default organization ID from the config
[organization-id] Organization ID to use. If none is passed the default organization ID will be used
[zone=fr-par-1] Zone to target. If none is passed will use default zone from the config (fr-par-1 | nl-ams-1)

FLAGS:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ ARGS:
[project-id] The project ID the IP is reserved in
[server] UUID of the server you want to attach the IP to
[tags.{index}] An array of keywords you want to tag this IP with
[organization-id] Organization ID to use. If none is passed will use default organization ID from the config
[organization-id] Organization ID to use. If none is passed the default organization ID will be used
[zone=fr-par-1] Zone to target. If none is passed will use default zone from the config (fr-par-1 | nl-ams-1)

FLAGS:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ ARGS:
[project]
[policy-mode] (optional | enforced)
[policy-type] (max_availability | low_latency)
[organization-id] Organization ID to use. If none is passed will use default organization ID from the config
[organization-id] Organization ID to use. If none is passed the default organization ID will be used
[zone=fr-par-1] Zone to target. If none is passed will use default zone from the config (fr-par-1 | nl-ams-1)

FLAGS:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ ARGS:
[stateful=true] Whether the security group is stateful or not
[inbound-default-policy=accept] Default policy for inbound rules (accept | drop)
[outbound-default-policy=accept] Default policy for outbound rules (accept | drop)
[organization-id] Organization ID to use. If none is passed will use default organization ID from the config
[organization-id] Organization ID to use. If none is passed the default organization ID will be used
[zone=fr-par-1] Zone to target. If none is passed will use default zone from the config (fr-par-1 | nl-ams-1)

FLAGS:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,12 @@ ARGS:
[placement-group-id] The placement group ID in witch the server has to be created
[bootscript-id] The bootscript ID to use, if empty the local boot will be used
[cloud-init] The cloud-init script to use
[organization-id] Organization ID to use. If none is passed will use default organization ID from the config
[project-id] Project ID to use. If none is passed the default project ID will be used
[zone=fr-par-1] Zone to target. If none is passed will use default zone from the config

DEPRECATED ARGS:
[organization-id] Please use project-id instead

FLAGS:
-h, --help help for create
-w, --wait wait until the server is ready
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ ARGS:
[name=<generated>] Name of the snapshot
volume-id UUID of the volume
[project]
[organization-id] Organization ID to use. If none is passed will use default organization ID from the config
[organization-id] Organization ID to use. If none is passed the default organization ID will be used
[zone=fr-par-1] Zone to target. If none is passed will use default zone from the config (fr-par-1 | nl-ams-1)

FLAGS:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ ARGS:
[base-volume]
[base-snapshot]
[project]
[organization-id] Organization ID to use. If none is passed will use default organization ID from the config
[organization-id] Organization ID to use. If none is passed the default organization ID will be used
[zone=fr-par-1] Zone to target. If none is passed will use default zone from the config (fr-par-1 | nl-ams-1)

FLAGS:
Expand Down
32 changes: 2 additions & 30 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -59,36 +59,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200601141019-df9902c66d0d h1:5643F4Bm9aFFz482Zju0EW/oP+XA7j+pRWWL6kVcjkQ=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200601141019-df9902c66d0d/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200603093029-edb933d7c8d4 h1:zJe5/C/RVqDc2GYekjEhFI0e6mrBqotu85LyjBHWhhA=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200603093029-edb933d7c8d4/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200608155405-2c0edbf44628 h1:7sBvEdHVZ+IkOAVh6rizkyQOnCz4xQ5V/qMXqtKF36I=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200608155405-2c0edbf44628/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200610085115-f7eab704fcbe h1:sDuQ3A081/brDcQr5AFz8JwX9Od1v8w3sW/L/g25UfY=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200610085115-f7eab704fcbe/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200622145638-4884584cccc2 h1:Pbot5MmWbvw0K2HqVjcJo3+J7l6vGbB852f7CNeKfyQ=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200622145638-4884584cccc2/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200622150328-6c000c76bc65 h1:QhG9tN5aUb20f6W8ecoH9XZwa4+0sg6ovBZrYKkp7C0=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200622150328-6c000c76bc65/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200624111939-0a4e128e532e h1:Ef+KTOg0kjZe14rHHoC7VOjiZBrxvuViVGaga7/BLM8=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200624111939-0a4e128e532e/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200707130522-abc4aeb2a4e6 h1:mCYMQVdy3ciDx7jtDnRuxTk9IUB525PhZYkCTjMWQUI=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200707130522-abc4aeb2a4e6/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200710161155-10382899255f h1:FHSh2peVlKEecLqHX/8uevrWqeua68LbVBOzIhC0HBw=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200710161155-10382899255f/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200713125201-82e19f805d12 h1:JqiinsAqmg65byKaTYomB48jf/7bOq9zs+5TprjnKvI=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200713125201-82e19f805d12/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200715091506-c51118fe6906 h1:Nspt1o8HahZ8BwgaxQUUQeqCOr3ojt/5f2gFH8gI/wo=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200715091506-c51118fe6906/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200717161204-1542ce02b602 h1:Yd8SJyi0yLMSXSwjH/iyliBPyySdwt/+n/ea1YoulZ4=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200717161204-1542ce02b602/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200810155502-64702d7341d2 h1:HzsSvXy7L36098vVrNS331FIum7XDKNLvExwkl3yT+I=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200810155502-64702d7341d2/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200818160321-42f4b6772b5c h1:5R916mdrgsgkZZQAeJxuUtciIv0yoX0UUTtBXsfOgJE=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200818160321-42f4b6772b5c/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200907085655-d6f50c14b691 h1:VvsH7nT47XoQwNKJCcNKTKPY8ennOzCtwSSQk1HFHH0=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200907085655-d6f50c14b691/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200828151447-c88def765356 h1:cL3Kx+H/cVgS8Fhkk0nR2GC5v2NyhNrI8VF9coACJ5Y=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6.0.20200828151447-c88def765356/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8=
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
Expand Down
22 changes: 21 additions & 1 deletion internal/core/arg_specs.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ type ArgSpec struct {

// Only one argument of the same OneOfGroup could be specified
OneOfGroup string

// Deprecated is used to flag an argument as deprecated.
Deprecated bool
}

func (a *ArgSpec) Prefix() string {
Expand Down Expand Up @@ -161,10 +164,27 @@ func OrganizationIDArgSpec() *ArgSpec {
}
}

func OrganizationIDDeprecatedArgSpec() *ArgSpec {
return &ArgSpec{
Name: "organization-id",
Short: "Please use project-id instead",
ValidateFunc: ValidateOrganizationID(),
Deprecated: true,
}
}

func OrganizationArgSpec() *ArgSpec {
return &ArgSpec{
Name: "organization",
Short: "Organization ID to use. If none is passed will use default organization ID from the config",
Short: "Organization ID to use. If none is passed the default organization ID will be used",
ValidateFunc: ValidateOrganizationID(),
}
}

func ProjectIDArgSpec() *ArgSpec {
return &ArgSpec{
Name: "project-id",
Short: "Project ID to use. If none is passed the default project ID will be used",
ValidateFunc: ValidateProjectID(),
}
}
5 changes: 5 additions & 0 deletions internal/core/autocomplete.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,11 @@ func BuildAutoCompleteTree(commands *Commands) *AutoCompleteNode {

// We consider ArgSpecs as leaf in the autocomplete tree.
for _, argSpec := range cmd.ArgSpecs {
if argSpec.Deprecated {
// Do not autocomplete deprecated arguments.
continue
}

if argSpec.Positional {
node.Children[positionalValueNodeID] = NewAutoCompleteArgNode(cmd, argSpec)
continue
Expand Down
11 changes: 9 additions & 2 deletions internal/core/cobra_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,11 @@ func (b *cobraBuilder) hydrateCobra(cobraCmd *cobra.Command, cmd *Command) {
}

if cmd.ArgsType != nil {
cobraCmd.Annotations["UsageArgs"] = buildUsageArgs(b.ctx, cmd)
cobraCmd.Annotations["UsageArgs"] = buildUsageArgs(b.ctx, cmd, false)
}

if cmd.ArgSpecs != nil {
cobraCmd.Annotations["UsageDeprecatedArgs"] = buildUsageArgs(b.ctx, cmd, true)
}

if cmd.Examples != nil {
Expand Down Expand Up @@ -139,7 +143,10 @@ EXAMPLES:
{{.Annotations.Examples}}{{end}}{{if .Annotations.UsageArgs}}
ARGS:
{{.Annotations.UsageArgs}}{{end}}{{if .HasAvailableSubCommands}}
{{.Annotations.UsageArgs}}{{end}}{{if .Annotations.UsageDeprecatedArgs}}
DEPRECATED ARGS:
{{.Annotations.UsageDeprecatedArgs}}{{end}}{{if .HasAvailableSubCommands}}
AVAILABLE COMMANDS:{{range .Commands}}{{if (or .IsAvailableCommand (eq .Name "help"))}}
{{rpad .Name .NamePadding }} {{if .Short}}{{.Short}}{{end}}{{end}}{{end}}{{end}}{{if .HasAvailableLocalFlags}}
Expand Down
13 changes: 11 additions & 2 deletions internal/core/cobra_usage_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,21 @@ const (
)

// buildUsageArgs builds usage args string.
// If deprecated is true, true only deprecated argSpecs will be considered.
// This string will be used by cobra usage template.
func buildUsageArgs(ctx context.Context, cmd *Command) string {
func buildUsageArgs(ctx context.Context, cmd *Command, deprecated bool) string {
var argsBuffer bytes.Buffer
tw := tabwriter.NewWriter(&argsBuffer, 0, 0, 3, ' ', 0)

err := _buildUsageArgs(ctx, tw, cmd.ArgSpecs)
// Filter deprecated argSpecs.
argSpecs := ArgSpecs(nil)
for _, argSpec := range cmd.ArgSpecs {
if argSpec.Deprecated == deprecated {
argSpecs = append(argSpecs, argSpec)
}
}

err := _buildUsageArgs(ctx, tw, argSpecs)
if err != nil {
// TODO: decide how to handle this error
err = fmt.Errorf("building %v: %v", cmd.getPath(), err)
Expand Down
2 changes: 1 addition & 1 deletion internal/core/cobra_usage_builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ func Test_buildUsageArgs(t *testing.T) {
Short: "Additional volume name",
},
},
})
}, false)

assert.Equal(t, want, got)
}
6 changes: 4 additions & 2 deletions internal/core/cobra_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ func run(ctx context.Context, cobraCmd *cobra.Command, cmd *Command, rawArgs []s
if cmd.ValidateFunc != nil {
validateFunc = cmd.ValidateFunc
}
err = validateFunc(cmd, cmdArgs, rawArgs)
err = validateFunc(ctx, cmd, cmdArgs, rawArgs)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -190,7 +190,9 @@ func handleUnmarshalErrors(cmd *Command, unmarshalErr *args.UnmarshalArgError) e
case *args.UnknownArgError, *args.InvalidArgNameError:
argNames := []string(nil)
for _, argSpec := range cmd.ArgSpecs {
argNames = append(argNames, argSpec.Name)
if !argSpec.Deprecated {
argNames = append(argNames, argSpec.Name)
}
}

return &CliError{
Expand Down
9 changes: 9 additions & 0 deletions internal/core/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,15 @@ func GetOrganizationIDFromContext(ctx context.Context) (organizationID string) {
return organizationID
}

func GetProjectIDFromContext(ctx context.Context) (projectID string) {
client := ExtractClient(ctx)
projectID, exists := client.GetDefaultProjectID()
if !exists {
panic("no default project ID found")
}
return projectID
}

func ExtractClient(ctx context.Context) *scw.Client {
return extractMeta(ctx).Client
}
Expand Down
37 changes: 35 additions & 2 deletions internal/core/validate.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package core

import (
"context"
"fmt"
"reflect"
"strconv"
Expand All @@ -14,14 +15,14 @@ import (

// CommandValidateFunc validates en entire command.
// Used in core.cobraRun().
type CommandValidateFunc func(cmd *Command, cmdArgs interface{}, rawArgs args.RawArgs) error
type CommandValidateFunc func(ctx context.Context, cmd *Command, cmdArgs interface{}, rawArgs args.RawArgs) error

// ArgSpecValidateFunc validates one argument of a command.
type ArgSpecValidateFunc func(argSpec *ArgSpec, value interface{}) error

// DefaultCommandValidateFunc is the default validation function for commands.
func DefaultCommandValidateFunc() CommandValidateFunc {
return func(cmd *Command, cmdArgs interface{}, rawArgs args.RawArgs) error {
return func(ctx context.Context, cmd *Command, cmdArgs interface{}, rawArgs args.RawArgs) error {
err := validateArgValues(cmd, cmdArgs)
if err != nil {
return err
Expand All @@ -34,6 +35,8 @@ func DefaultCommandValidateFunc() CommandValidateFunc {
if err != nil {
return err
}

validateDeprecated(ctx, cmd)
return nil
}
}
Expand Down Expand Up @@ -109,6 +112,15 @@ func validateNoConflict(cmd *Command, rawArgs args.RawArgs) error {
return nil
}

func validateDeprecated(ctx context.Context, cmd *Command) {
for _, argSpec := range cmd.ArgSpecs {
if argSpec.Deprecated {
helpCmd := cmd.GetCommandLine(extractMeta(ctx).BinaryName) + " --help"
ExtractLogger(ctx).Warningf("The argument '%s' is deprecated, more info with: %s\n", argSpec.Name, helpCmd)
}
}
}

// DefaultArgSpecValidateFunc validates a value passed for an ArgSpec
// Uses ArgSpec.EnumValues
func DefaultArgSpecValidateFunc() ArgSpecValidateFunc {
Expand Down Expand Up @@ -179,3 +191,24 @@ func ValidateOrganizationID() ArgSpecValidateFunc {
return nil
}
}

// ValidateProjectID validates a non-required project ID.
// By default, for most command, the project ID is not required.
// In that case, we allow the empty-string value "".
func ValidateProjectID() ArgSpecValidateFunc {
return func(argSpec *ArgSpec, valueI interface{}) error {
value, isStr := valueI.(string)
valuePtr, isPtr := valueI.(*string)
if !isStr && isPtr && valuePtr != nil {
value = *valuePtr
}

if value == "" && !argSpec.Required {
return nil
}
if !validation.IsProjectID(value) {
return InvalidProjectIDError(value)
}
return nil
}
}
33 changes: 30 additions & 3 deletions internal/core/validate_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package core

import (
"context"
"fmt"
"testing"

Expand Down Expand Up @@ -37,7 +38,7 @@ func Test_DefaultCommandValidateFunc(t *testing.T) {

run := func(testCase TestCase) func(t *testing.T) {
return func(t *testing.T) {
err := DefaultCommandValidateFunc()(testCase.command, testCase.parsedArguments, testCase.rawArgs)
err := DefaultCommandValidateFunc()(context.Background(), testCase.command, testCase.parsedArguments, testCase.rawArgs)
assert.Equal(t, fmt.Errorf("arg validation called"), err)
}
}
Expand Down Expand Up @@ -194,14 +195,14 @@ func Test_DefaultCommandRequiredFunc(t *testing.T) {

runOK := func(testCase TestCase) func(t *testing.T) {
return func(t *testing.T) {
err := DefaultCommandValidateFunc()(testCase.command, testCase.parsedArguments, testCase.rawArgs)
err := DefaultCommandValidateFunc()(context.Background(), testCase.command, testCase.parsedArguments, testCase.rawArgs)
assert.Equal(t, nil, err)
}
}

runErr := func(testCase TestCase, argName string) func(t *testing.T) {
return func(t *testing.T) {
err := DefaultCommandValidateFunc()(testCase.command, testCase.parsedArguments, testCase.rawArgs)
err := DefaultCommandValidateFunc()(context.Background(), testCase.command, testCase.parsedArguments, testCase.rawArgs)
assert.Equal(t, MissingRequiredArgumentError(argName), err)
}
}
Expand Down Expand Up @@ -343,3 +344,29 @@ func Test_ValidateNoConflict(t *testing.T) {
arg2: "all-ssh-keys",
}))
}

func Test_ValidateDeprecated(t *testing.T) {
type TestCase struct {
command *Command
rawArgs args.RawArgs
arg1 string
arg2 string
}

t.Run("Deprecated", func(t *testing.T) {
testCase := TestCase{
command: &Command{
ArgSpecs: ArgSpecs{
{
Name: "a",
Deprecated: true,
},
},
},
rawArgs: []string{"a=yo"},
}
err := validateNoConflict(testCase.command, testCase.rawArgs)
assert.Equal(t, nil, err)
})

}
Loading

0 comments on commit 03ccdd9

Please sign in to comment.