From e39837edc50c4aeaeae7efa5156f31fafcdbd845 Mon Sep 17 00:00:00 2001 From: Antoine Grondin Date: Tue, 5 Nov 2024 15:14:40 +0900 Subject: [PATCH] move the version math to the `version` command --- main.go | 495 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 245 insertions(+), 250 deletions(-) diff --git a/main.go b/main.go index b5e51c5..1fb15c8 100644 --- a/main.go +++ b/main.go @@ -178,256 +178,6 @@ func newApp() *cli.App { app.Commands = append(app.Commands, cli.Command{ Name: "get", Subcommands: cli.Commands{ - { - Name: "version", - Subcommands: cli.Commands{ - { - Name: "to-json", - Flags: []cli.Flag{ - cli.StringFlag{Name: flagVersion}, - cli.IntFlag{Name: flagVersionMajor}, - cli.IntFlag{Name: flagVersionMinor}, - cli.IntFlag{Name: flagVersionPatch}, - cli.StringSliceFlag{Name: flagVersionPrereleases}, - cli.StringFlag{Name: flagVersionBuild}, - }, - Action: func(cctx *cli.Context) error { - version, err := parseVersion(cctx) - if err != nil { - return fmt.Errorf("parsing version flag: %w", err) - } - if err := json.NewEncoder(os.Stdout).Encode(version); err != nil { - return fmt.Errorf("encoding to stdout: %w", err) - } - return nil - }, - }, - { - Name: "from-json", - Action: func(cctx *cli.Context) error { - input := new(typesv1.Version) - if err := json.NewDecoder(os.Stdin).Decode(input); err != nil { - return fmt.Errorf("decoding version from stdin: %w", err) - } - sv, err := input.AsSemver() - if err != nil { - return fmt.Errorf("converting to semver: %v", err) - } - _, err = os.Stdout.WriteString(sv.String()) - return err - }, - }, - { - Name: "math", - Usage: " []", - Description: "Operate on versions as JSON on stdin.\n" + - "`` can be one of `major`, `minor`, `patch`\n" + - "`` can be one of `add`, `sub` or `set`\n" + - "`` is an integer value, relevant depending on \n", - Action: func(cctx *cli.Context) error { - - lhs := cctx.Args().Get(0) - operator := cctx.Args().Get(1) - rhs := cctx.Args().Get(2) - parseInt32RHS := func() (int32, error) { - if rhs == "" { - return 0, fmt.Errorf(" can't be empty") - } - v, err := strconv.ParseInt(rhs, 10, 32) - if err != nil { - return 0, fmt.Errorf("invalid argument for : %w", err) - } - return int32(v), nil - } - parseStringRHS := func() (string, error) { - return rhs, nil - } - parseStringSliceRHS := func() ([]string, error) { - return strings.Split(rhs, ","), nil - } - - var ( - load func(*typesv1.Version) any - store func(*typesv1.Version, any) - operatorFn func(any) (any, error) - makeInt32Operator = func(fn func(int32) int32) func(any) (any, error) { - return func(arg any) (any, error) { - a, ok := arg.(int32) - if !ok { - return nil, fmt.Errorf(" is not an int") - } - return fn(a), nil - } - } - makeStringSliceOperator = func(fn func([]string) []string) func(any) (any, error) { - return func(arg any) (any, error) { - a, ok := arg.([]string) - if !ok { - return nil, fmt.Errorf(" is not a slice of string") - } - return fn(a), nil - } - } - makeStringOperator = func(fn func(string) string) func(any) (any, error) { - return func(arg any) (any, error) { - a, ok := arg.(string) - if !ok { - return nil, fmt.Errorf(" is not a slice of string") - } - return fn(a), nil - } - } - operatorType string - ) - switch lhs { - default: - log.Printf("unsupported : %q", lhs) - return cli.ShowSubcommandHelp(cctx) - case "": - log.Printf("no specified") - return cli.ShowSubcommandHelp(cctx) - case "major": - load = func(version *typesv1.Version) any { return version.Major } - store = func(version *typesv1.Version, v any) { version.Major = v.(int32) } - operatorType = "int32" - case "minor": - load = func(version *typesv1.Version) any { return version.Minor } - store = func(version *typesv1.Version, v any) { version.Minor = v.(int32) } - operatorType = "int32" - case "patch": - load = func(version *typesv1.Version) any { return version.Patch } - store = func(version *typesv1.Version, v any) { version.Patch = v.(int32) } - operatorType = "int32" - case "pre": - load = func(version *typesv1.Version) any { return version.Prereleases } - store = func(version *typesv1.Version, v any) { version.Prereleases = v.([]string) } - operatorType = "[]string" - case "build": - load = func(version *typesv1.Version) any { return version.Build } - store = func(version *typesv1.Version, v any) { version.Build = v.(string) } - operatorType = "string" - } - switch operator { - default: - log.Printf("unsupported : %q", operator) - return cli.ShowSubcommandHelp(cctx) - case "": - log.Printf("no specified") - return cli.ShowSubcommandHelp(cctx) - case "add": - switch operatorType { - case "int32": - rhsv, err := parseInt32RHS() - if err != nil { - log.Printf("invalid for `add`: %v", err) - return cli.ShowSubcommandHelp(cctx) - } - operatorFn = makeInt32Operator(func(lhsv int32) int32 { - return lhsv + rhsv - }) - case "[]string": - rhsv, err := parseStringRHS() - if err != nil { - log.Printf("invalid for `add`: %v", err) - return cli.ShowSubcommandHelp(cctx) - } - operatorFn = makeStringSliceOperator(func(lhsv []string) []string { - return append(lhsv, rhsv) - }) - case "string": - rhsv, err := parseStringRHS() - if err != nil { - log.Printf("invalid for `add`: %v", err) - return cli.ShowSubcommandHelp(cctx) - } - operatorFn = makeStringOperator(func(lhsv string) string { - return lhsv + rhsv - }) - } - - case "sub": - switch operatorType { - case "int32": - rhsv, err := parseInt32RHS() - if err != nil { - log.Printf("invalid for `sub`: %v", err) - return cli.ShowSubcommandHelp(cctx) - } - operatorFn = makeInt32Operator(func(lhsv int32) int32 { - return lhsv - rhsv - }) - case "[]string": - rhsv, err := parseStringRHS() - if err != nil { - log.Printf("invalid for `sub`: %v", err) - return cli.ShowSubcommandHelp(cctx) - } - operatorFn = makeStringSliceOperator(func(lhsv []string) []string { - return slices.DeleteFunc(lhsv, func(v string) bool { - return v == rhsv - }) - }) - case "string": - rhsv, err := parseStringRHS() - if err != nil { - log.Printf("invalid for `sub`: %v", err) - return cli.ShowSubcommandHelp(cctx) - } - operatorFn = makeStringOperator(func(lhsv string) string { - return strings.ReplaceAll(lhsv, rhsv, "") - }) - } - case "set": - switch operatorType { - case "int32": - rhsv, err := parseInt32RHS() - if err != nil { - log.Printf("invalid for `set`: %v", err) - return cli.ShowSubcommandHelp(cctx) - } - operatorFn = makeInt32Operator(func(_ int32) int32 { - return rhsv - }) - case "[]string": - rhsv, err := parseStringSliceRHS() - if err != nil { - log.Printf("invalid for `set`: %v", err) - return cli.ShowSubcommandHelp(cctx) - } - operatorFn = makeStringSliceOperator(func(_ []string) []string { - return rhsv - }) - case "string": - rhsv, err := parseStringRHS() - if err != nil { - log.Printf("invalid for `set`: %v", err) - return cli.ShowSubcommandHelp(cctx) - } - operatorFn = makeStringOperator(func(_ string) string { - return rhsv - }) - } - } - - input := new(typesv1.Version) - if err := json.NewDecoder(os.Stdin).Decode(input); err != nil { - return fmt.Errorf("decoding version from stdin: %w", err) - } - - out, err := operatorFn(load(input)) - if err != nil { - return fmt.Errorf("performing operation: %v", err) - } - store(input, out) - - if err := json.NewEncoder(os.Stdout).Encode(input); err != nil { - return fmt.Errorf("encoding result to stdout: %v", err) - } - return nil - }, - }, - }, - }, { Name: "next-update", Flags: []cli.Flag{ @@ -869,6 +619,251 @@ func newApp() *cli.App { return selfupdate.UpgradeInPlace(ctx, "apictl", os.Stdout, os.Stderr, os.Stdin) }, }, + { + Name: "to-json", + Flags: []cli.Flag{ + cli.StringFlag{Name: flagVersion}, + cli.IntFlag{Name: flagVersionMajor}, + cli.IntFlag{Name: flagVersionMinor}, + cli.IntFlag{Name: flagVersionPatch}, + cli.StringSliceFlag{Name: flagVersionPrereleases}, + cli.StringFlag{Name: flagVersionBuild}, + }, + Action: func(cctx *cli.Context) error { + version, err := parseVersion(cctx) + if err != nil { + return fmt.Errorf("parsing version flag: %w", err) + } + if err := json.NewEncoder(os.Stdout).Encode(version); err != nil { + return fmt.Errorf("encoding to stdout: %w", err) + } + return nil + }, + }, + { + Name: "from-json", + Action: func(cctx *cli.Context) error { + input := new(typesv1.Version) + if err := json.NewDecoder(os.Stdin).Decode(input); err != nil { + return fmt.Errorf("decoding version from stdin: %w", err) + } + sv, err := input.AsSemver() + if err != nil { + return fmt.Errorf("converting to semver: %v", err) + } + _, err = os.Stdout.WriteString(sv.String()) + return err + }, + }, + { + Name: "math", + Usage: " []", + Description: "Operate on versions as JSON on stdin.\n" + + "`` can be one of `major`, `minor`, `patch`\n" + + "`` can be one of `add`, `sub` or `set`\n" + + "`` is an integer value, relevant depending on \n", + Action: func(cctx *cli.Context) error { + + lhs := cctx.Args().Get(0) + operator := cctx.Args().Get(1) + rhs := cctx.Args().Get(2) + parseInt32RHS := func() (int32, error) { + if rhs == "" { + return 0, fmt.Errorf(" can't be empty") + } + v, err := strconv.ParseInt(rhs, 10, 32) + if err != nil { + return 0, fmt.Errorf("invalid argument for : %w", err) + } + return int32(v), nil + } + parseStringRHS := func() (string, error) { + return rhs, nil + } + parseStringSliceRHS := func() ([]string, error) { + return strings.Split(rhs, ","), nil + } + + var ( + load func(*typesv1.Version) any + store func(*typesv1.Version, any) + operatorFn func(any) (any, error) + makeInt32Operator = func(fn func(int32) int32) func(any) (any, error) { + return func(arg any) (any, error) { + a, ok := arg.(int32) + if !ok { + return nil, fmt.Errorf(" is not an int") + } + return fn(a), nil + } + } + makeStringSliceOperator = func(fn func([]string) []string) func(any) (any, error) { + return func(arg any) (any, error) { + a, ok := arg.([]string) + if !ok { + return nil, fmt.Errorf(" is not a slice of string") + } + return fn(a), nil + } + } + makeStringOperator = func(fn func(string) string) func(any) (any, error) { + return func(arg any) (any, error) { + a, ok := arg.(string) + if !ok { + return nil, fmt.Errorf(" is not a slice of string") + } + return fn(a), nil + } + } + operatorType string + ) + switch lhs { + default: + log.Printf("unsupported : %q", lhs) + return cli.ShowSubcommandHelp(cctx) + case "": + log.Printf("no specified") + return cli.ShowSubcommandHelp(cctx) + case "major": + load = func(version *typesv1.Version) any { return version.Major } + store = func(version *typesv1.Version, v any) { version.Major = v.(int32) } + operatorType = "int32" + case "minor": + load = func(version *typesv1.Version) any { return version.Minor } + store = func(version *typesv1.Version, v any) { version.Minor = v.(int32) } + operatorType = "int32" + case "patch": + load = func(version *typesv1.Version) any { return version.Patch } + store = func(version *typesv1.Version, v any) { version.Patch = v.(int32) } + operatorType = "int32" + case "pre": + load = func(version *typesv1.Version) any { return version.Prereleases } + store = func(version *typesv1.Version, v any) { version.Prereleases = v.([]string) } + operatorType = "[]string" + case "build": + load = func(version *typesv1.Version) any { return version.Build } + store = func(version *typesv1.Version, v any) { version.Build = v.(string) } + operatorType = "string" + } + switch operator { + default: + log.Printf("unsupported : %q", operator) + return cli.ShowSubcommandHelp(cctx) + case "": + log.Printf("no specified") + return cli.ShowSubcommandHelp(cctx) + case "add": + switch operatorType { + case "int32": + rhsv, err := parseInt32RHS() + if err != nil { + log.Printf("invalid for `add`: %v", err) + return cli.ShowSubcommandHelp(cctx) + } + operatorFn = makeInt32Operator(func(lhsv int32) int32 { + return lhsv + rhsv + }) + case "[]string": + rhsv, err := parseStringRHS() + if err != nil { + log.Printf("invalid for `add`: %v", err) + return cli.ShowSubcommandHelp(cctx) + } + operatorFn = makeStringSliceOperator(func(lhsv []string) []string { + return append(lhsv, rhsv) + }) + case "string": + rhsv, err := parseStringRHS() + if err != nil { + log.Printf("invalid for `add`: %v", err) + return cli.ShowSubcommandHelp(cctx) + } + operatorFn = makeStringOperator(func(lhsv string) string { + return lhsv + rhsv + }) + } + + case "sub": + switch operatorType { + case "int32": + rhsv, err := parseInt32RHS() + if err != nil { + log.Printf("invalid for `sub`: %v", err) + return cli.ShowSubcommandHelp(cctx) + } + operatorFn = makeInt32Operator(func(lhsv int32) int32 { + return lhsv - rhsv + }) + case "[]string": + rhsv, err := parseStringRHS() + if err != nil { + log.Printf("invalid for `sub`: %v", err) + return cli.ShowSubcommandHelp(cctx) + } + operatorFn = makeStringSliceOperator(func(lhsv []string) []string { + return slices.DeleteFunc(lhsv, func(v string) bool { + return v == rhsv + }) + }) + case "string": + rhsv, err := parseStringRHS() + if err != nil { + log.Printf("invalid for `sub`: %v", err) + return cli.ShowSubcommandHelp(cctx) + } + operatorFn = makeStringOperator(func(lhsv string) string { + return strings.ReplaceAll(lhsv, rhsv, "") + }) + } + case "set": + switch operatorType { + case "int32": + rhsv, err := parseInt32RHS() + if err != nil { + log.Printf("invalid for `set`: %v", err) + return cli.ShowSubcommandHelp(cctx) + } + operatorFn = makeInt32Operator(func(_ int32) int32 { + return rhsv + }) + case "[]string": + rhsv, err := parseStringSliceRHS() + if err != nil { + log.Printf("invalid for `set`: %v", err) + return cli.ShowSubcommandHelp(cctx) + } + operatorFn = makeStringSliceOperator(func(_ []string) []string { + return rhsv + }) + case "string": + rhsv, err := parseStringRHS() + if err != nil { + log.Printf("invalid for `set`: %v", err) + return cli.ShowSubcommandHelp(cctx) + } + operatorFn = makeStringOperator(func(_ string) string { + return rhsv + }) + } + } + + input := new(typesv1.Version) + if err := json.NewDecoder(os.Stdin).Decode(input); err != nil { + return fmt.Errorf("decoding version from stdin: %w", err) + } + + out, err := operatorFn(load(input)) + if err != nil { + return fmt.Errorf("performing operation: %v", err) + } + store(input, out) + + if err := json.NewEncoder(os.Stdout).Encode(input); err != nil { + return fmt.Errorf("encoding result to stdout: %v", err) + } + return nil + }, + }, }, })