Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(ci): enhance lint config and resolve all lint issues #363

Merged
merged 11 commits into from
Sep 6, 2024
4 changes: 2 additions & 2 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ jobs:
- name: golangci-lint
uses: golangci/golangci-lint-action@aaa42aa0628b4ae2578232a66b541047968fac86
with:
version: v1.55
version: v1.60.3
# Optional: golangci-lint command line arguments.
args: --timeout=10m
args: --timeout=10m --out-format=colored-line-number
unit:
name: unit tests
runs-on: ubuntu-22.04
Expand Down
200 changes: 189 additions & 11 deletions .golangci.yaml
Original file line number Diff line number Diff line change
@@ -1,12 +1,190 @@
# https://github.com/golangci/golangci-lint/blob/master/.golangci.reference.yml

run:
timeout: 5m

linters-settings:
errcheck:
# Report about not checking of errors in type assertions: `a := b.(MyStruct)`.
# Such cases aren't reported by default.
# Default: false
check-type-assertions: true
# https://github.com/golangci/golangci-lint/issues/4743
ignore: ''

exhaustive:
# Program elements to check for exhaustiveness.
# Default: [ switch ]
check:
- switch
- map

gocritic:
# Settings passed to gocritic.
# The settings key is the name of a supported gocritic checker.
# The list of supported checkers can be find in https://go-critic.github.io/overview.
settings:
captLocal:
# Whether to restrict checker to params only.
# Default: true
paramsOnly: false
underef:
# Whether to skip (*x).method() calls where x is a pointer receiver.
# Default: true
skipRecvDeref: false

gomodguard:
blocked:
# List of blocked modules.
# Default: []
modules:
- github.com/golang/protobuf:
recommendations:
- google.golang.org/protobuf
reason: 'see https://developers.google.com/protocol-buffers/docs/reference/go/faq#modules'
- github.com/satori/go.uuid:
recommendations:
- github.com/google/uuid
reason: "satori's package is not maintained"
- github.com/gofrs/uuid:
recommendations:
- github.com/google/uuid
reason: "gofrs' package is not go module"

govet:
# Enable all analyzers.
# Default: false
enable-all: true
# Disable analyzers by name.
# Run `go tool vet help` to see all analyzers.
# Default: []
disable:
- fieldalignment # too strict
# Settings per analyzer.
settings:
shadow:
# Whether to be strict about shadowing; can be noisy.
# Default: false
strict: true

nakedret:
# Make an issue if func has more lines of code than this setting, and it has naked returns.
# Default: 30
max-func-lines: 0

nolintlint:
# Exclude following linters from requiring an explanation.
# Default: []
allow-no-explanation: []
# Enable to require an explanation of nonzero length after each nolint directive.
# Default: false
require-explanation: true
# Enable to require nolint directives to mention the specific linter being suppressed.
# Default: false
require-specific: true

stylecheck:
checks: ['all', '-ST1003']

tenv:
# The option `all` will run against whole test files (`_test.go`) regardless of method/function signatures.
# Otherwise, only methods that take `*testing.T`, `*testing.B`, and `testing.TB` as arguments are checked.
# Default: false
all: true

linters:
disable-all: true
enable:
## enabled by default
- errcheck # checking for unchecked errors, these unchecked errors can be critical bugs in some cases
- gosimple # specializes in simplifying a code
- govet # reports suspicious constructs, such as Printf calls whose arguments do not align with the format string
- ineffassign # detects when assignments to existing variables are not used
- staticcheck # is a go vet on steroids, applying a ton of static analysis checks
- typecheck # like the front-end of a Go compiler, parses and type-checks Go code
- unused # checks for unused constants, variables, functions and types
## disabled by default
- asasalint # checks for pass []any as any in variadic func(...any)
- asciicheck # checks that your code does not contain non-ASCII identifiers
- bidichk # checks for dangerous unicode character sequences
- bodyclose # checks whether HTTP response body is closed successfully
- canonicalheader
- containedctx # Containedctx is a linter that detects struct contained context.Context field.
- contextcheck # checks the function whether use a non-inherited context
- durationcheck # checks for two durations multiplied together
- errname # checks that sentinel errors are prefixed with the Err and error types are suffixed with the Error
- errorlint # finds code that will cause problems with the error wrapping scheme introduced in Go 1.13
- exhaustive # checks exhaustiveness of enum switch statements
- copyloopvar # checks for pointers to enclosing loop variables
# - fatcontext
- forbidigo # forbids identifiers
- forcetypeassert # finds forced type assertions
- gocheckcompilerdirectives # validates go compiler directive comments (//go:)
- goconst # finds repeated strings that could be replaced by a constant
- gocritic # provides diagnostics that check for bugs, performance and style issues
- gofmt # checks whether code was gofmt-ed
- goimports # in addition to fixing imports, goimports also formats your code in the same style as gofmt
- gomodguard # allow and block lists linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations
- goprintffuncname # checks that printf-like functions are named with f at the end
- gosec # inspects source code for security problems
# - intrange # checks for range over int (requires go 1.22)
- loggercheck # checks key value pairs for common logger libraries (kitlog,klog,logr,zap)
- makezero # finds slice declarations with non-zero initial length
- mnd # detects magic numbers
- musttag # enforces field tags in (un)marshaled structs
- nakedret # finds naked returns in functions greater than a specified function length
- nestif # reports deeply nested if statements
- nilerr # finds the code that returns nil even if it checks that the error is not nil
- nilnil # checks that there is no simultaneous return of nil error and an invalid value
- noctx # finds sending http request without context.Context
- nolintlint # reports ill-formed or insufficient nolint directives
- nonamedreturns # reports all named returns
- nosprintfhostport # checks for misuse of Sprintf to construct a host with port in a URL
- predeclared # finds code that shadows one of Go's predeclared identifiers
- promlinter # checks Prometheus metrics naming via promlint
- protogetter # Reports direct reads from proto message fields when getters should be used.
- reassign # checks that package variables are not reassigned
# - revive # fast, configurable, extensible, flexible, and beautiful linter for Go, drop-in replacement of golint
- rowserrcheck # checks whether Err of rows is checked successfully
- sloglint # Ensure consistent code style when using log/slog.
# - spancheck # checks for incorrect usage of opentracing.Span # Added in golangci-lint 1.56
- sqlclosecheck # checks that sql.Rows and sql.Stmt are closed
- stylecheck # is a replacement for golint
- tenv # detects using os.Setenv instead of t.Setenv since Go1.17
- testableexamples # checks if examples are testable (have an expected output)
- testifylint
# - testpackage # makes you use a separate _test package
- tparallel # detects inappropriate usage of t.Parallel() method in your Go test codes
- unconvert # removes unnecessary type conversions
- unparam # reports unused function parameters
- usestdlibvars # detects the possibility to use variables/constants from the Go standard library
- wastedassign # finds wasted assignment statements
- whitespace # detects leading and trailing whitespace

issues:
# Show only new issues: if there are unstaged changes or untracked files,
# only those changes are analyzed, else only changes in HEAD~ are analyzed.
# It's a super-useful option for integration of golangci-lint into existing large codebase.
# It's not practical to fix all existing issues at the moment of integration:
# much better don't allow issues in new code.
#
# Default: false
new: true
# Show only new issues created after git revision `REV`.
# Default: ""
new-from-rev: HEAD
# Maximum count of issues with the same text.
# Set to 0 to disable.
# Default: 3
max-same-issues: 0
# Maximum issues count per one linter.
# Set to 0 to disable.
# Default: 50
max-issues-per-linter: 0

exclude-dirs:
# too much in flight within TUI to sufficiently lint
- tui

exclude-rules:
- path: "_test\\.go"
linters:
- bodyclose
- dupl
- funlen
- goconst
- gosec
- noctx
- wrapcheck
- lll
- text: 'shadow: declaration of "(err)" shadows declaration at'
linters: [govet]
5 changes: 4 additions & 1 deletion cmd/auth-clientCredentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,14 @@ func auth_clientCredentials(cmd *cobra.Command, args []string) {
}

// Set the client credentials
cp.SetAuthCredentials(profiles.AuthCredentials{
err := cp.SetAuthCredentials(profiles.AuthCredentials{
AuthType: profiles.PROFILE_AUTH_TYPE_CLIENT_CREDENTIALS,
ClientId: clientId,
ClientSecret: clientSecret,
})
if err != nil {
c.ExitWithError("Failed to set client credentials", err)
}

// Validate the client credentials
c.Printf("Validating client credentials for %s... ", cp.GetEndpoint())
Expand Down
2 changes: 1 addition & 1 deletion cmd/auth-printAccessToken.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func auth_printAccessToken(cmd *cobra.Command, args []string) {
c.Println("ok")
c.Printf("Access Token: %s\n", tok.AccessToken)

c.PrintIfJson(tok)
c.PrintIfJSON(tok)
}

func init() {
Expand Down
7 changes: 5 additions & 2 deletions cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@ func config_updateOutput(cmd *cobra.Command, args []string) {

format := c.Flags.GetRequiredString("format")

config.UpdateOutputFormat(cfgKey, format)
fmt.Println(cli.SuccessMessage(fmt.Sprintf("Output format updated to %s", format)))
err := config.UpdateOutputFormat(cfgKey, format)
if err != nil {
c.ExitWithError("Failed to update output format", err)
}
c.Println(cli.SuccessMessage(fmt.Sprintf("Output format updated to %s", format)))
}

func init() {
Expand Down
17 changes: 7 additions & 10 deletions cmd/dev-selectors.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,7 @@ import (
"github.com/spf13/cobra"
)

var (
selectors []string

// dev_selectorsCmd *cobra.Command
)
var selectors []string

func dev_selectorsGen(cmd *cobra.Command, args []string) {
c := cli.New(cmd, args)
Expand All @@ -27,6 +23,7 @@ func dev_selectorsGen(cmd *cobra.Command, args []string) {
contextType := c.Flags.GetRequiredString("type")

var value any
//nolint:gocritic,nestif // this is more readable than a switch statement
if contextType == "json" || contextType == "" {
if err := json.Unmarshal([]byte(subject), &value); err != nil {
cli.ExitWithError(fmt.Sprintf("Could not unmarshal JSON subject context input: %s", subject), err)
Expand Down Expand Up @@ -54,7 +51,7 @@ func dev_selectorsGen(cmd *cobra.Command, args []string) {

rows := [][]string{}
for _, r := range result {
rows = append(rows, []string{r.ExternalSelectorValue, r.ExternalValue})
rows = append(rows, []string{r.GetExternalSelectorValue(), r.GetExternalValue()})
}

t := cli.NewTabular(rows...)
Expand All @@ -68,9 +65,10 @@ func dev_selectorsTest(cmd *cobra.Command, args []string) {

subject := c.Flags.GetRequiredString("subject")
contextType := c.Flags.GetRequiredString("type")
selectors := c.Flags.GetStringSlice("selectors", selectors, cli.FlagsStringSliceOptions{Min: 1})
selectors = c.Flags.GetStringSlice("selectors", selectors, cli.FlagsStringSliceOptions{Min: 1})

var value any
//nolint:gocritic,nestif // this is more readable than a switch statement
if contextType == "json" || contextType == "" {
if err := json.Unmarshal([]byte(subject), &value); err != nil {
cli.ExitWithError(fmt.Sprintf("Could not unmarshal JSON subject context input: %s", subject), err)
Expand All @@ -97,7 +95,7 @@ func dev_selectorsTest(cmd *cobra.Command, args []string) {

rows := [][]string{}
for _, r := range result {
rows = append(rows, []string{r.ExternalSelectorValue, r.ExternalValue})
rows = append(rows, []string{r.GetExternalSelectorValue(), r.GetExternalValue()})
}

t := cli.NewTabular(rows...)
Expand Down Expand Up @@ -136,8 +134,7 @@ func init() {
testCmd.GetDocFlag("type").Default,
testCmd.GetDocFlag("type").Description,
)
testCmd.Flags().StringArrayVarP(
&selectors,
testCmd.Flags().StringArrayP(
testCmd.GetDocFlag("selector").Name,
testCmd.GetDocFlag("selector").Shorthand,
[]string{},
Expand Down
21 changes: 13 additions & 8 deletions cmd/dev.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//nolint:forbidigo // print statements need flexibility
package cmd

import (
Expand All @@ -17,8 +18,10 @@ import (
// devCmd is the command for playground-style development
var devCmd = man.Docs.GetCommand("dev")

var metadataLabels []string

func dev_designSystem(cmd *cobra.Command, args []string) {
fmt.Printf("Design system\n=============\n\n")
fmt.Print("Design system\n=============\n\n")

printDSComponent("Table", renderDSTable())

Expand All @@ -27,16 +30,16 @@ func dev_designSystem(cmd *cobra.Command, args []string) {

func printDSComponent(title string, component string) {
fmt.Printf("%s\n", title)
fmt.Printf("-----\n\n")
fmt.Print("-----\n\n")
fmt.Printf("%s\n", component)
fmt.Printf("\n\n")
fmt.Print("\n\n")
}

func renderDSTable() string {
tbl := cli.NewTable(
table.NewFlexColumn("one", "One", 1),
table.NewFlexColumn("two", "Two", 1),
table.NewFlexColumn("three", "Three", 1),
table.NewFlexColumn("one", "One", cli.FlexColumnWidthOne),
table.NewFlexColumn("two", "Two", cli.FlexColumnWidthOne),
table.NewFlexColumn("three", "Three", cli.FlexColumnWidthOne),
).WithRows([]table.Row{
table.NewRow(table.RowData{
"one": "1",
Expand Down Expand Up @@ -83,13 +86,15 @@ func getMetadataRows(m *common.Metadata) [][]string {
// return nil
// }

const keyValLength = 2

func getMetadataMutable(labels []string) *common.MetadataMutable {
metadata := common.MetadataMutable{}
if len(labels) > 0 {
metadata.Labels = map[string]string{}
for _, label := range labels {
kv := strings.Split(label, "=")
if len(kv) != 2 {
if len(kv) != keyValLength {
cli.ExitWithError("Invalid label format", nil)
}
metadata.Labels[kv[0]] = kv[1]
Expand All @@ -110,7 +115,7 @@ func getMetadataUpdateBehavior() common.MetadataUpdateEnum {
func HandleSuccess(command *cobra.Command, id string, t table.Model, policyObject interface{}) {
c := cli.New(command, []string{})
if OtdfctlCfg.Output.Format == config.OutputJSON || configFlagOverrides.OutputFormatJSON {
c.ExitWithJson(policyObject)
c.ExitWithJSON(policyObject)
}
cli.PrintSuccessTable(command, id, t)
}
Expand Down
5 changes: 4 additions & 1 deletion cmd/execute.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@ func Execute(opts ...ExecuteOptFunc) {
}

if c.mountTo != nil {
MountRoot(c.mountTo, c.renameCmd)
err := MountRoot(c.mountTo, c.renameCmd)
if err != nil {
os.Exit(1)
}
} else {
err := RootCmd.Execute()
if err != nil {
Expand Down
Loading
Loading