Skip to content

Commit

Permalink
chore: add support for perfsprint (#4070)
Browse files Browse the repository at this point in the history
  • Loading branch information
remyleone authored Aug 22, 2024
1 parent 41aa419 commit dd557be
Show file tree
Hide file tree
Showing 74 changed files with 226 additions and 188 deletions.
4 changes: 4 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ linters:
- nakedret # Finds naked returns in functions greater than a specified function length [fast: true, auto-fix: false]
- nolintlint # Reports ill-formed or insufficient nolint directives [fast: true, auto-fix: false]
- nosprintfhostport # Checks for misuse of Sprintf to construct a host with port in a URL. [fast: true, auto-fix: false]
- perfsprint # Checks that fmt.Sprintf can be replaced with a faster alternative. [fast: false, auto-fix: false]
- prealloc # Finds slice declarations that could potentially be pre-allocated [fast: true, auto-fix: false]
- predeclared # find code that shadows one of Go's predeclared identifiers [fast: true, auto-fix: false]
- promlinter # Check Prometheus metrics naming via promlint [fast: true, auto-fix: false]
Expand Down Expand Up @@ -102,6 +103,9 @@ issues:
exclude-dirs:
- internal/pkg

max-issues-per-linter: 0
max-same-issues: 0

exclude-rules:
- path: _test\.go
linters:
Expand Down
2 changes: 1 addition & 1 deletion internal/args/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ type CannotParseDateError struct {
}

func (e *CannotParseDateError) Error() string {
return fmt.Sprintf(`date parsing error: could not parse %s`, e.ArgValue)
return "date parsing error: could not parse " + e.ArgValue
}

type CannotParseBoolError struct {
Expand Down
5 changes: 3 additions & 2 deletions internal/args/unmarshal.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package args
// into CLI arguments represented as Go data.

import (
"errors"
"fmt"
"io"
"net"
Expand Down Expand Up @@ -32,7 +33,7 @@ var unmarshalFuncs = map[reflect.Type]UnmarshalFunc{
// Only support G, GB for now (case insensitive).
value = strings.ToLower(value)
if !strings.HasSuffix(value, "g") && !strings.HasSuffix(value, "gb") {
return fmt.Errorf("size must be defined using the G or GB unit")
return errors.New("size must be defined using the G or GB unit")
}

bytes, err := humanize.ParseBytes(value)
Expand Down Expand Up @@ -70,7 +71,7 @@ var unmarshalFuncs = map[reflect.Type]UnmarshalFunc{
}

if len(value) == 0 {
return fmt.Errorf("empty time given")
return errors.New("empty time given")
}

// Handle relative time
Expand Down
4 changes: 2 additions & 2 deletions internal/core/checks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package core_test

import (
"context"
"fmt"
"errors"
"path/filepath"
"reflect"
"strings"
Expand Down Expand Up @@ -35,7 +35,7 @@ func TestCheckAPIKey(t *testing.T) {
api := iam.NewAPI(ctx.Client)
accessKey, exists := ctx.Client.GetAccessKey()
if !exists {
return fmt.Errorf("missing access-key")
return errors.New("missing access-key")
}

apiKey, err := api.GetAPIKey(&iam.GetAPIKeyRequest{
Expand Down
2 changes: 1 addition & 1 deletion internal/core/cobra_usage_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ func buildExamples(binaryName string, cmd *Command) string {

for _, cmdExample := range cmd.Examples {
// Build title.
title := fmt.Sprintf(" %s", cmdExample.Short)
title := " " + cmdExample.Short
commandLine := cmdExample.GetCommandLine(binaryName, cmd)

commandLine = interactive.Indent(commandLine, 4)
Expand Down
10 changes: 5 additions & 5 deletions internal/core/cobra_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,15 @@ func cobraRun(ctx context.Context, cmd *Command) func(*cobra.Command, []string)
if exist {
otherArgs := rawArgs.Remove(positionalArgSpec.Name)
return &CliError{
Err: fmt.Errorf("a positional argument is required for this command"),
Err: errors.New("a positional argument is required for this command"),
Hint: positionalArgHint(meta.BinaryName, cmd, value, otherArgs, len(positionalArgs) > 0),
}
}

// If no positional arguments were provided, return an error
if len(positionalArgs) == 0 {
return &CliError{
Err: fmt.Errorf("a positional argument is required for this command"),
Err: errors.New("a positional argument is required for this command"),
Hint: positionalArgHint(meta.BinaryName, cmd, "<"+positionalArgSpec.Name+">", rawArgs, false),
}
}
Expand Down Expand Up @@ -209,7 +209,7 @@ func handleUnmarshalErrors(cmd *Command, unmarshalErr *args.UnmarshalArgError) e
switch e.Err.(type) {
case *args.CannotParseBoolError:
return &CliError{
Err: fmt.Errorf(""),
Err: errors.New(""),
Message: fmt.Sprintf("invalid value for '%s' argument: invalid boolean value", unmarshalErr.ArgName),
Hint: "Possible values: true, false",
}
Expand Down Expand Up @@ -237,7 +237,7 @@ Relative time error: %s

return &CliError{
Err: fmt.Errorf("invalid argument '%s': %s", unmarshalErr.ArgName, e.Error()),
Hint: fmt.Sprintf("Valid arguments are: %s", strings.Join(argNames, ", ")),
Hint: "Valid arguments are: " + strings.Join(argNames, ", "),
}
case *args.UnknownArgError:
argNames := []string(nil)
Expand All @@ -248,7 +248,7 @@ Relative time error: %s

return &CliError{
Err: fmt.Errorf("unknown argument '%s'", unmarshalErr.ArgName),
Hint: fmt.Sprintf("Valid arguments are: %s", strings.Join(argNames, ", ")),
Hint: "Valid arguments are: " + strings.Join(argNames, ", "),
}

default:
Expand Down
20 changes: 10 additions & 10 deletions internal/core/cobra_utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package core_test

import (
"context"
"fmt"
"errors"
"reflect"
"testing"
"time"
Expand Down Expand Up @@ -115,7 +115,7 @@ func Test_handleUnmarshalErrors(t *testing.T) {
Check: core.TestCheckCombine(
core.TestCheckExitCode(1),
core.TestCheckError(&core.CliError{
Err: fmt.Errorf("invalid argument 'name_id': arg name must only contain lowercase letters, numbers or dashes"),
Err: errors.New("invalid argument 'name_id': arg name must only contain lowercase letters, numbers or dashes"),
Hint: "Valid arguments are: name-id",
}),
),
Expand All @@ -127,7 +127,7 @@ func Test_handleUnmarshalErrors(t *testing.T) {
Check: core.TestCheckCombine(
core.TestCheckExitCode(1),
core.TestCheckError(&core.CliError{
Err: fmt.Errorf("invalid argument 'ubuntu_focal': arg name must only contain lowercase letters, numbers or dashes"),
Err: errors.New("invalid argument 'ubuntu_focal': arg name must only contain lowercase letters, numbers or dashes"),
Hint: "Valid arguments are: name-id",
}),
),
Expand All @@ -143,7 +143,7 @@ func Test_handleUnmarshalErrors(t *testing.T) {
Details: `Absolute time error: parsing time "+3R" as "2006-01-02T15:04:05Z07:00": cannot parse "+3R" as "2006"
Relative time error: unknown unit in duration: "R"
`,
Err: fmt.Errorf("date parsing error: +3R"),
Err: errors.New("date parsing error: +3R"),
Hint: "Run `scw help date` to learn more about date parsing",
}),
),
Expand Down Expand Up @@ -177,7 +177,7 @@ func Test_PositionalArg(t *testing.T) {
Check: core.TestCheckCombine(
core.TestCheckExitCode(1),
core.TestCheckError(&core.CliError{
Err: fmt.Errorf("a positional argument is required for this command"),
Err: errors.New("a positional argument is required for this command"),
Hint: "Try running: scw test positional <name-id>",
}),
),
Expand All @@ -189,7 +189,7 @@ func Test_PositionalArg(t *testing.T) {
Check: core.TestCheckCombine(
core.TestCheckExitCode(1),
core.TestCheckError(&core.CliError{
Err: fmt.Errorf("a positional argument is required for this command"),
Err: errors.New("a positional argument is required for this command"),
Hint: "Try running: scw test positional <name-id> tag=world",
}),
),
Expand All @@ -201,7 +201,7 @@ func Test_PositionalArg(t *testing.T) {
Check: core.TestCheckCombine(
core.TestCheckExitCode(1),
core.TestCheckError(&core.CliError{
Err: fmt.Errorf("a positional argument is required for this command"),
Err: errors.New("a positional argument is required for this command"),
Hint: "Try running: scw test positional plop tag=world",
}),
),
Expand All @@ -213,7 +213,7 @@ func Test_PositionalArg(t *testing.T) {
Check: core.TestCheckCombine(
core.TestCheckExitCode(1),
core.TestCheckError(&core.CliError{
Err: fmt.Errorf("a positional argument is required for this command"),
Err: errors.New("a positional argument is required for this command"),
Hint: "Try running: scw test positional plop tag=world",
}),
),
Expand All @@ -225,7 +225,7 @@ func Test_PositionalArg(t *testing.T) {
Check: core.TestCheckCombine(
core.TestCheckExitCode(1),
core.TestCheckError(&core.CliError{
Err: fmt.Errorf("a positional argument is required for this command"),
Err: errors.New("a positional argument is required for this command"),
Hint: "Try running: scw test positional plop",
}),
),
Expand Down Expand Up @@ -311,7 +311,7 @@ func Test_MultiPositionalArg(t *testing.T) {
Check: core.TestCheckCombine(
core.TestCheckExitCode(1),
core.TestCheckError(&core.CliError{
Err: fmt.Errorf("a positional argument is required for this command"),
Err: errors.New("a positional argument is required for this command"),
Hint: "Try running: scw test multi-positional <name-ids> tag=tag1",
}),
),
Expand Down
4 changes: 2 additions & 2 deletions internal/core/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,8 @@ func (c *Command) seeAlsosAsStr() string {
seeAlsos := make([]string, 0, len(c.SeeAlsos))

for _, cmdSeeAlso := range c.SeeAlsos {
short := fmt.Sprintf(" # %s", cmdSeeAlso.Short)
commandStr := fmt.Sprintf(" %s", cmdSeeAlso.Command)
short := " # " + cmdSeeAlso.Short
commandStr := " " + cmdSeeAlso.Command

seeAlsoLines := []string{
short,
Expand Down
3 changes: 2 additions & 1 deletion internal/core/errors.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package core

import (
"errors"
"fmt"
)

Expand Down Expand Up @@ -74,6 +75,6 @@ func ArgumentConflictError(arg1 string, arg2 string) *CliError {

func WindowIsNotSupportedError() *CliError {
return &CliError{
Err: fmt.Errorf("windows is not currently supported"),
Err: errors.New("windows is not currently supported"),
}
}
9 changes: 5 additions & 4 deletions internal/core/printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package core

import (
"encoding/json"
"errors"
"fmt"
"io"
"reflect"
Expand Down Expand Up @@ -103,7 +104,7 @@ func setupTemplatePrinter(printer *Printer, opts string) error {
printer.printerType = PrinterTypeTemplate
if opts == "" {
return &CliError{
Err: fmt.Errorf("cannot use a template output with an empty template"),
Err: errors.New("cannot use a template output with an empty template"),
Hint: `Try using golang template string: scw instance server list -o template="{{ .ID }} ☜(˚▽˚)☞ {{ .Name }}"`,
Details: `https://golang.org/pkg/text/template`,
}
Expand Down Expand Up @@ -185,7 +186,7 @@ func (p *Printer) printHuman(data interface{}, opt *human.MarshalOpt) error {
}

if len(p.humanFields) > 0 && reflect.TypeOf(data).Kind() != reflect.Slice {
return p.printHuman(fmt.Errorf("list of fields for human output is only supported for commands that return a list"), nil)
return p.printHuman(errors.New("list of fields for human output is only supported for commands that return a list"), nil)
}

if len(p.humanFields) > 0 {
Expand All @@ -203,7 +204,7 @@ func (p *Printer) printHuman(data interface{}, opt *human.MarshalOpt) error {
case *human.UnknownFieldError:
return p.printHuman(&CliError{
Err: fmt.Errorf("unknown field '%s' in output options", e.FieldName),
Hint: fmt.Sprintf("Valid fields are: %s", strings.Join(e.ValidFields, ", ")),
Hint: "Valid fields are: " + strings.Join(e.ValidFields, ", "),
}, nil)
case nil:
// Do nothing
Expand Down Expand Up @@ -299,7 +300,7 @@ func (p *Printer) printTemplate(data interface{}) error {
return p.printHuman(&CliError{
Err: err,
Message: "templating error",
Hint: fmt.Sprintf("Acceptable values are:\n - %s", strings.Join(gofields.ListFields(elemValue.Type()), "\n - ")),
Hint: "Acceptable values are:\n - " + strings.Join(gofields.ListFields(elemValue.Type()), "\n - "),
}, nil)
}
_, err = writer.Write([]byte{'\n'})
Expand Down
2 changes: 1 addition & 1 deletion internal/core/reflect.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,5 +114,5 @@ func GetValuesForFieldByName(value reflect.Value, parts []string) (values []refl

return nil, fmt.Errorf("field %v does not exist for %v", fieldName, value.Type().Name())
}
return nil, fmt.Errorf("case is not handled")
return nil, errors.New("case is not handled")
}
Loading

0 comments on commit dd557be

Please sign in to comment.