From 222c54a59f6da854aced69b761929b78ff55b3f3 Mon Sep 17 00:00:00 2001 From: Manuel Doncel Martos Date: Thu, 17 Apr 2025 19:53:26 +0200 Subject: [PATCH] feat: updating funcorder to v0.3.0, support for alphabetical. --- .golangci.next.reference.yml | 148 +++-- go.mod | 2 +- go.sum | 4 +- jsonschema/golangci.next.jsonschema.json | 540 ++++++++++++++---- pkg/config/linters_settings.go | 2 + pkg/golinters/funcorder/funcorder.go | 1 + ...corder_disable_constructor_alphabetical.go | 41 ++ ...order_disable_constructor_alphabetical.yml | 7 + ....go => funcorder_disable_struct_method.go} | 2 +- ...ml => funcorder_disable_struct_method.yml} | 0 ...rder_disable_struct_method_alphabetical.go | 45 ++ ...der_disable_struct_method_alphabetical.yml | 7 + 12 files changed, 624 insertions(+), 175 deletions(-) create mode 100644 pkg/golinters/funcorder/testdata/funcorder_disable_constructor_alphabetical.go create mode 100644 pkg/golinters/funcorder/testdata/funcorder_disable_constructor_alphabetical.yml rename pkg/golinters/funcorder/testdata/{funcorder_struct_method.go => funcorder_disable_struct_method.go} (90%) rename pkg/golinters/funcorder/testdata/{funcorder_struct_method.yml => funcorder_disable_struct_method.yml} (100%) create mode 100644 pkg/golinters/funcorder/testdata/funcorder_disable_struct_method_alphabetical.go create mode 100644 pkg/golinters/funcorder/testdata/funcorder_disable_struct_method_alphabetical.yml diff --git a/.golangci.next.reference.yml b/.golangci.next.reference.yml index 37866ff00f2c..534417b5faf0 100644 --- a/.golangci.next.reference.yml +++ b/.golangci.next.reference.yml @@ -539,6 +539,9 @@ linters: # Checks if the exported methods of a structure are placed before the non-exported ones. # Default: true struct-method: false + # Checks if the constructors and/or structure methods are sorted alphabetically. + # Default: false + alphabetical: true funlen: # Checks the number of lines in a function. @@ -642,7 +645,7 @@ linters: # Exclude strings matching the given regular expression. # Default: "" ignore-string-values: - - 'foo.+' + - "foo.+" # Detects constants with identical values. # Default: false find-duplicates: true @@ -1167,7 +1170,7 @@ linters: # # The option is passed to the ruleguard 'debug-group' argument. # Default: "" - debug: 'emptyDecl' + debug: "emptyDecl" # Determines the behavior when an error occurs while parsing ruleguard files. # If flag is not set, log error and skip rule files that contain an error. # If flag is set, the value must be a comma-separated list of error conditions. @@ -1182,7 +1185,7 @@ linters: # The placeholder '${config-path}' is substituted with a path relative to the configuration file. # Glob patterns such as 'rules-*.go' may be specified. # Default: "" - rules: '${base-path}/ruleguard/rules-*.go,${base-path}/myrule1.go' + rules: "${base-path}/ruleguard/rules-*.go,${base-path}/myrule1.go" # Comma-separated list of enabled groups or skip empty to enable everything. # Tags can be defined with # character prefix. # Default: "" @@ -1533,11 +1536,11 @@ linters: # # Default: [] escape-hatches: - - 'github.com/nicksnyder/go-i18n/v2/i18n.Message' - - 'example.com/your/project/i18n/markers.Raw' - - 'example.com/your/project/i18n/markers.OK' - - 'example.com/your/project/i18n/markers.TODO' - - 'command-line-arguments.Simple' + - "github.com/nicksnyder/go-i18n/v2/i18n.Message" + - "example.com/your/project/i18n/markers.Raw" + - "example.com/your/project/i18n/markers.OK" + - "example.com/your/project/i18n/markers.TODO" + - "command-line-arguments.Simple" # List of Unicode scripts to watch for any usage in string literals. # https://pkg.go.dev/unicode#pkg-variables # @@ -1886,9 +1889,9 @@ linters: # For example: https://github.com/timonwong/loggercheck/blob/7395ab86595781e33f7afba27ad7b55e6956ebcd/testdata/custom-rules.txt # Default: empty rules: - - k8s.io/klog/v2.InfoS # package level exported functions - - (github.com/go-logr/logr.Logger).Error # "Methods" - - (*go.uber.org/zap.SugaredLogger).With # Also "Methods", but with a pointer receiver + - k8s.io/klog/v2.InfoS # package level exported functions + - (github.com/go-logr/logr.Logger).Error # "Methods" + - (*go.uber.org/zap.SugaredLogger).With # Also "Methods", but with a pointer receiver maintidx: # Show functions with maintainability index lower than N. @@ -1941,9 +1944,9 @@ linters: # Values always ignored: "1", "1.0", "0" and "0.0". # Default: [] ignored-numbers: - - '0666' - - '0755' - - '42' + - "0666" + - "0755" + - "42" # List of file patterns to exclude from analysis. # Values always ignored: `.+_test.go`. # Default: [] @@ -2011,7 +2014,7 @@ linters: allow-unused: true # Exclude following linters from requiring an explanation. # Default: [] - allow-no-explanation: [ ] + allow-no-explanation: [] # Enable to require an explanation of nonzero length after each nolint directive. # Default: false require-explanation: true @@ -2199,7 +2202,7 @@ linters: severity: warning disabled: false exclude: [""] - arguments: [ 4 ] + arguments: [4] # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#atomic - name: atomic severity: warning @@ -2210,7 +2213,7 @@ linters: severity: warning disabled: false exclude: [""] - arguments: [ "Ω","Σ","σ", "7" ] + arguments: ["Ω", "Σ", "σ", "7"] # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#bare-return - name: bare-return severity: warning @@ -2236,7 +2239,7 @@ linters: severity: warning disabled: false exclude: [""] - arguments: [ 7 ] + arguments: [7] # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#comment-spacings - name: comment-spacings severity: warning @@ -2250,7 +2253,7 @@ linters: severity: warning disabled: false exclude: [""] - arguments: [ 15 ] + arguments: [15] # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#confusing-naming - name: confusing-naming severity: warning @@ -2283,7 +2286,7 @@ linters: severity: warning disabled: false exclude: [""] - arguments: [ 3 ] + arguments: [3] # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#datarace - name: datarace severity: warning @@ -2312,7 +2315,8 @@ linters: disabled: false exclude: [""] arguments: - - allowed-packages: ["github.com/onsi/ginkgo/v2", "github.com/onsi/gomega"] + - allowed-packages: + ["github.com/onsi/ginkgo/v2", "github.com/onsi/gomega"] # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#duplicated-imports - name: duplicated-imports severity: warning @@ -2430,13 +2434,13 @@ linters: severity: warning disabled: false exclude: [""] - arguments: [ 10, 0 ] + arguments: [10, 0] # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#function-result-limit - name: function-result-limit severity: warning disabled: false exclude: [""] - arguments: [ 3 ] + arguments: [3] # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#get-return - name: get-return severity: warning @@ -2492,19 +2496,19 @@ linters: severity: warning disabled: false exclude: [""] - arguments: [ 80 ] + arguments: [80] # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#max-control-nesting - name: max-control-nesting severity: warning disabled: false exclude: [""] - arguments: [ 3 ] + arguments: [3] # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#max-public-structs - name: max-public-structs severity: warning disabled: false exclude: [""] - arguments: [ 3 ] + arguments: [3] # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#modifies-parameter - name: modifies-parameter severity: warning @@ -2578,10 +2582,10 @@ linters: disabled: false exclude: [""] arguments: - - - 'core.WriteError[1].Message' - - '/^([^A-Z]|$)/' + - - "core.WriteError[1].Message" + - "/^([^A-Z]|$)/" - must not start with a capital letter - - - 'fmt.Errorf[0]' + - - "fmt.Errorf[0]" - '/(^|[^\.!?])$/' - must not end in punctuation - - panic @@ -2697,8 +2701,8 @@ linters: disabled: false exclude: [""] arguments: - - [ "ID" ] # AllowList - - [ "VM" ] # DenyList + - ["ID"] # AllowList + - ["VM"] # DenyList - - upper-case-const: true # Extra parameter (upper-case-const|skip-package-name-checks) # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#waitgroup-by-value - name: waitgroup-by-value @@ -2805,10 +2809,54 @@ linters: - fmt # https://staticcheck.dev/docs/configuration/options/#initialisms # Default: ["ACL", "API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", "IP", "JSON", "QPS", "RAM", "RPC", "SLA", "SMTP", "SQL", "SSH", "TCP", "TLS", "TTL", "UDP", "UI", "GID", "UID", "UUID", "URI", "URL", "UTF8", "VM", "XML", "XMPP", "XSRF", "XSS", "SIP", "RTP", "AMQP", "DB", "TS"] - initialisms: [ "ACL", "API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", "IP", "JSON", "QPS", "RAM", "RPC", "SLA", "SMTP", "SQL", "SSH", "TCP", "TLS", "TTL", "UDP", "UI", "GID", "UID", "UUID", "URI", "URL", "UTF8", "VM", "XML", "XMPP", "XSRF", "XSS", "SIP", "RTP", "AMQP", "DB", "TS" ] + initialisms: + [ + "ACL", + "API", + "ASCII", + "CPU", + "CSS", + "DNS", + "EOF", + "GUID", + "HTML", + "HTTP", + "HTTPS", + "ID", + "IP", + "JSON", + "QPS", + "RAM", + "RPC", + "SLA", + "SMTP", + "SQL", + "SSH", + "TCP", + "TLS", + "TTL", + "UDP", + "UI", + "GID", + "UID", + "UUID", + "URI", + "URL", + "UTF8", + "VM", + "XML", + "XMPP", + "XSRF", + "XSS", + "SIP", + "RTP", + "AMQP", + "DB", + "TS", + ] # https://staticcheck.dev/docs/configuration/options/#http_status_code_whitelist # Default: ["200", "400", "404", "500"] - http-status-code-whitelist: [ "200", "400", "404", "500" ] + http-status-code-whitelist: ["200", "400", "404", "500"] # SAxxxx checks in https://staticcheck.dev/docs/configuration/options/#checks # Example (to disable some checks): [ "all", "-SA1000", "-SA1001"] # Default: ["all", "-ST1000", "-ST1003", "-ST1016", "-ST1020", "-ST1021", "-ST1022"] @@ -3404,8 +3452,7 @@ linters: # Overrides the default/root configuration. # Default: [] overrides: - - - # The package path (uses `/` only as a separator). + - # The package path (uses `/` only as a separator). # Required pkg: foo/bar # Default: empty or the same as the default/root configuration. @@ -3835,12 +3882,12 @@ linters: # A list of call idents that everything can be cuddled with. # Defaults: [ "Lock", "RLock" ] - allow-cuddle-with-calls: [ "Foo", "Bar" ] + allow-cuddle-with-calls: ["Foo", "Bar"] # AllowCuddleWithRHS is a list of right hand side variables that is allowed # to be cuddled with anything. # Defaults: [ "Unlock", "RUnlock" ] - allow-cuddle-with-rhs: [ "Foo", "Bar" ] + allow-cuddle-with-rhs: ["Foo", "Bar"] # Allow cuddling with any block as long as the variable is used somewhere in # the block. @@ -3857,7 +3904,7 @@ linters: # When force-err-cuddling is enabled this is a list of names # used for error variables to check for in the conditional. # Default: [ "err" ] - error-variable-names: [ "foo" ] + error-variable-names: ["foo"] # Causes an error if a short declaration (:=) cuddles with anything other than # another short declaration. @@ -3979,13 +4026,13 @@ formatters: # If `custom-order` is `true`, it follows the order of `sections` option. # Default: ["standard", "default"] sections: - - standard # Standard section: captures all standard packages. - - default # Default section: contains all imports that could not be matched to another section type. + - standard # Standard section: captures all standard packages. + - default # Default section: contains all imports that could not be matched to another section type. - prefix(github.com/org/project) # Custom section: groups all imports with the specified Prefix. - - blank # Blank section: contains all blank imports. This section is not present unless explicitly enabled. - - dot # Dot section: contains all dot imports. This section is not present unless explicitly enabled. - - alias # Alias section: contains all alias imports. This section is not present unless explicitly enabled. - - localmodule # Local module section: contains all local packages. This section is not present unless explicitly enabled. + - blank # Blank section: contains all blank imports. This section is not present unless explicitly enabled. + - dot # Dot section: contains all dot imports. This section is not present unless explicitly enabled. + - alias # Alias section: contains all alias imports. This section is not present unless explicitly enabled. + - localmodule # Local module section: contains all local packages. This section is not present unless explicitly enabled. # Checks that no inline comments are present. # Default: false @@ -4012,10 +4059,10 @@ formatters: # https://pkg.go.dev/cmd/gofmt # Default: [] rewrite-rules: - - pattern: 'interface{}' - replacement: 'any' - - pattern: 'a[b:len(a)]' - replacement: 'a[b:]' + - pattern: "interface{}" + replacement: "any" + - pattern: "a[b:len(a)]" + replacement: "a[b:]" gofumpt: # Module path which contains the source code being formatted. @@ -4114,7 +4161,6 @@ issues: # Default: false fix: true - # Output configuration options. output: # The formats used to render issues. @@ -4217,7 +4263,6 @@ output: # Default: true show-stats: false - # Options for analysis running. run: # Timeout for total work, e.g. 30s, 5m, 5m30s. @@ -4273,14 +4318,13 @@ run: # Define the Go version limit. # Default: use Go version from the go.mod file, fallback on the env var `GOVERSION`, fallback on 1.22. - go: '1.23' + go: "1.23" # Number of operating system threads (`GOMAXPROCS`) that can execute golangci-lint simultaneously. # Default: 0 (automatically set to match Linux container CPU quota and # fall back to the number of logical CPUs in the machine) concurrency: 4 - severity: # Set the default severity for issues. # diff --git a/go.mod b/go.mod index 00695fdf37ad..cfdbc0b02765 100644 --- a/go.mod +++ b/go.mod @@ -74,7 +74,7 @@ require ( github.com/ldez/usetesting v0.4.3 github.com/leonklingele/grouper v1.1.2 github.com/macabu/inamedparam v0.2.0 - github.com/manuelarte/funcorder v0.2.1 + github.com/manuelarte/funcorder v0.3.0 github.com/maratori/testableexamples v1.0.0 github.com/maratori/testpackage v1.1.1 github.com/matoous/godox v1.1.0 diff --git a/go.sum b/go.sum index 9bc80fb7cd9b..b89f9c35faf7 100644 --- a/go.sum +++ b/go.sum @@ -391,8 +391,8 @@ github.com/macabu/inamedparam v0.2.0 h1:VyPYpOc10nkhI2qeNUdh3Zket4fcZjEWe35poddB github.com/macabu/inamedparam v0.2.0/go.mod h1:+Pee9/YfGe5LJ62pYXqB89lJ+0k5bsR8Wgz/C0Zlq3U= github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= -github.com/manuelarte/funcorder v0.2.1 h1:7QJsw3qhljoZ5rH0xapIvjw31EcQeFbF31/7kQ/xS34= -github.com/manuelarte/funcorder v0.2.1/go.mod h1:BQQ0yW57+PF9ZpjpeJDKOffEsQbxDFKW8F8zSMe/Zd0= +github.com/manuelarte/funcorder v0.3.0 h1:mV1joNYIjIUnnyZ6wfaC+sCWB6IvG62ay3xuhbklHps= +github.com/manuelarte/funcorder v0.3.0/go.mod h1:wBFktqsi8PyQvNYEUpF5Lt+V/xqgaevfCi4SSpUhyPo= github.com/maratori/testableexamples v1.0.0 h1:dU5alXRrD8WKSjOUnmJZuzdxWOEQ57+7s93SLMxb2vI= github.com/maratori/testableexamples v1.0.0/go.mod h1:4rhjL1n20TUTT4vdh3RDqSizKLyXp7K2u6HgraZCGzE= github.com/maratori/testpackage v1.1.1 h1:S58XVV5AD7HADMmD0fNnziNHqKvSdDuEKdPD1rNTU04= diff --git a/jsonschema/golangci.next.jsonschema.json b/jsonschema/golangci.next.jsonschema.json index 0f2ef5fcc50b..2f85f5d54fd4 100644 --- a/jsonschema/golangci.next.jsonschema.json +++ b/jsonschema/golangci.next.jsonschema.json @@ -698,7 +698,7 @@ } } }, - "formats-path" : { + "formats-path": { "anyOf": [ { "enum": [ @@ -851,7 +851,11 @@ "uniqueItems": true, "items": { "type": "string", - "examples": ["the", "and", "a"] + "examples": [ + "the", + "and", + "a" + ] } }, "ignore": { @@ -860,7 +864,9 @@ "uniqueItems": true, "items": { "type": "string", - "examples": ["0C0C"] + "examples": [ + "0C0C" + ] } } } @@ -875,7 +881,9 @@ "uniqueItems": true, "items": { "type": "string", - "examples": ["\\.Wrapf"] + "examples": [ + "\\.Wrapf" + ] } }, "use-builtin-exclusions": { @@ -960,9 +968,21 @@ "properties": { "dec-order": { "type": "array", - "default": [["type", "const", "var", "func"]], + "default": [ + [ + "type", + "const", + "var", + "func" + ] + ], "items": { - "enum": ["type", "const", "var", "func"] + "enum": [ + "type", + "const", + "var", + "func" + ] } }, "ignore-underscore-vars": { @@ -1018,7 +1038,11 @@ "properties": { "list-mode": { "description": "Used to determine the package matching priority.", - "enum": ["original", "strict", "lax"], + "enum": [ + "original", + "strict", + "lax" + ], "default": "original" }, "files": { @@ -1102,7 +1126,10 @@ "exclude-functions": { "description": "List of functions to exclude from checking, where each entry is a single function to exclude", "type": "array", - "examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"], + "examples": [ + "io/ioutil.ReadFile", + "io.Copy(*bytes.Buffer)" + ], "items": { "type": "string" } @@ -1195,7 +1222,10 @@ "uniqueItems": true, "items": { "type": "string", - "examples": ["switch", "map"] + "examples": [ + "switch", + "map" + ] } }, "explicit-exhaustive-switch": { @@ -1240,7 +1270,9 @@ "include": { "description": "List of regular expressions to match struct packages and names.", "type": "array", - "examples": [".*\\.Test"], + "examples": [ + ".*\\.Test" + ], "items": { "type": "string" } @@ -1248,7 +1280,9 @@ "exclude": { "description": "List of regular expressions to exclude struct packages and names from check.", "type": "array", - "examples": ["cobra\\.Command$"], + "examples": [ + "cobra\\.Command$" + ], "items": { "type": "string" } @@ -1317,6 +1351,11 @@ "description": "Checks if the exported methods of a structure are placed before the non-exported ones.", "type": "boolean", "default": true + }, + "alphabetical": { + "description": "Checks if the constructors and/or structure methods are sorted alphabetically.", + "type": "boolean", + "default": false } } }, @@ -1365,7 +1404,10 @@ } ] }, - "default": ["standard", "default"] + "default": [ + "standard", + "default" + ] }, "no-inline-comments": { "description": "Checks that no inline Comments are present.", @@ -1582,7 +1624,7 @@ "type": "object", "additionalProperties": false, "properties": { - "paramsOnly" : { + "paramsOnly": { "type": "boolean", "default": true } @@ -1592,7 +1634,7 @@ "type": "object", "additionalProperties": false, "properties": { - "minLength" : { + "minLength": { "type": "number", "default": 15 } @@ -1602,7 +1644,7 @@ "type": "object", "additionalProperties": false, "properties": { - "skipBalanced" : { + "skipBalanced": { "type": "boolean", "default": true } @@ -1612,7 +1654,7 @@ "type": "object", "additionalProperties": false, "properties": { - "sizeThreshold" : { + "sizeThreshold": { "type": "number", "default": 80 } @@ -1622,7 +1664,7 @@ "type": "object", "additionalProperties": false, "properties": { - "minThreshold" : { + "minThreshold": { "type": "number", "default": 2 } @@ -1632,7 +1674,7 @@ "type": "object", "additionalProperties": false, "properties": { - "bodyWidth" : { + "bodyWidth": { "type": "number", "default": 5 } @@ -1642,11 +1684,11 @@ "type": "object", "additionalProperties": false, "properties": { - "sizeThreshold" : { + "sizeThreshold": { "type": "number", "default": 512 }, - "skipTestFuncs" : { + "skipTestFuncs": { "type": "boolean", "default": true } @@ -1656,11 +1698,11 @@ "type": "object", "additionalProperties": false, "properties": { - "sizeThreshold" : { + "sizeThreshold": { "type": "number", "default": 128 }, - "skipTestFuncs" : { + "skipTestFuncs": { "type": "boolean", "default": true } @@ -1670,19 +1712,19 @@ "type": "object", "additionalProperties": false, "properties": { - "debug" : { + "debug": { "type": "string" }, - "enable" : { + "enable": { "type": "string" }, - "disable" : { + "disable": { "type": "string" }, - "failOn" : { + "failOn": { "type": "string" }, - "rules" : { + "rules": { "type": "string" } } @@ -1691,7 +1733,7 @@ "type": "object", "additionalProperties": false, "properties": { - "maxResults" : { + "maxResults": { "type": "number", "default": 5 } @@ -1701,7 +1743,7 @@ "type": "object", "additionalProperties": false, "properties": { - "skipArchDependent" : { + "skipArchDependent": { "type": "boolean", "default": true } @@ -1711,7 +1753,7 @@ "type": "object", "additionalProperties": false, "properties": { - "skipRecvDeref" : { + "skipRecvDeref": { "type": "boolean", "default": true } @@ -1721,7 +1763,7 @@ "type": "object", "additionalProperties": false, "properties": { - "checkExported" : { + "checkExported": { "type": "boolean", "default": false } @@ -1756,7 +1798,11 @@ "properties": { "scope": { "description": "Comments to be checked.", - "enum": ["declarations", "toplevel", "all"], + "enum": [ + "declarations", + "toplevel", + "all" + ], "default": "declarations" }, "exclude": { @@ -1793,7 +1839,11 @@ "items": { "type": "string" }, - "default": ["TODO", "BUG", "FIXME"] + "default": [ + "TODO", + "BUG", + "FIXME" + ] } } }, @@ -1927,12 +1977,22 @@ "template-path": { "description": "Path to the file containing the template source.", "type": "string", - "examples": ["my_header_template.txt"] + "examples": [ + "my_header_template.txt" + ] } }, "oneOf": [ - { "required": ["template"] }, - { "required": ["template-path"] } + { + "required": [ + "template" + ] + }, + { + "required": [ + "template-path" + ] + } ] }, "goimportsSettings": { @@ -2013,7 +2073,9 @@ "type": "array", "items": { "type": "string", - "examples": ["gopkg.in/yaml.v2"] + "examples": [ + "gopkg.in/yaml.v2" + ] } }, "domains": { @@ -2021,7 +2083,9 @@ "type": "array", "items": { "type": "string", - "examples": ["golang.org"] + "examples": [ + "golang.org" + ] } } } @@ -2076,7 +2140,9 @@ "type": "string" } }, - "required": ["reason"] + "required": [ + "reason" + ] } } } @@ -2097,7 +2163,11 @@ "includes": { "type": "array", "description": "To select a subset of rules to run", - "examples": [["G401"]], + "examples": [ + [ + "G401" + ] + ], "items": { "$ref": "#/definitions/gosec-rules" } @@ -2105,7 +2175,11 @@ "excludes": { "type": "array", "description": "To specify a set of rules to explicitly exclude", - "examples": [["G401"]], + "examples": [ + [ + "G401" + ] + ], "items": { "$ref": "#/definitions/gosec-rules" } @@ -2113,13 +2187,21 @@ "severity": { "description": "Filter out the issues with a lower severity than the given value", "type": "string", - "enum": ["low", "medium", "high"], + "enum": [ + "low", + "medium", + "high" + ], "default": "low" }, "confidence": { "description": "Filter out the issues with a lower confidence than the given value", "type": "string", - "enum": ["low", "medium", "high"], + "enum": [ + "low", + "medium", + "high" + ], "default": "low" }, "config": { @@ -2299,7 +2381,10 @@ "type": "string" } }, - "required": ["pkg", "alias"] + "required": [ + "pkg", + "alias" + ] } } } @@ -2328,7 +2413,12 @@ "type": "string" }, { - "enum": ["anon", "error", "empty", "stdlib"] + "enum": [ + "anon", + "error", + "empty", + "stdlib" + ] } ] } @@ -2341,7 +2431,12 @@ "type": "string" }, { - "enum": ["anon", "error", "empty", "stdlib"] + "enum": [ + "anon", + "error", + "empty", + "stdlib" + ] } ] } @@ -2356,10 +2451,14 @@ } } }, - "required": ["allow"] + "required": [ + "allow" + ] }, { - "required": ["reject"] + "required": [ + "reject" + ] } ] }, @@ -2458,7 +2557,10 @@ "additionalProperties": false, "properties": { "locale": { - "enum": ["US", "UK"] + "enum": [ + "US", + "UK" + ] }, "ignore-rules": { "description": "List of rules to ignore.", @@ -2469,7 +2571,11 @@ }, "mode": { "description": "Mode of the analysis.", - "enum": ["restricted", "", "default"], + "enum": [ + "restricted", + "", + "default" + ], "default": "" }, "extra-words": { @@ -2541,7 +2647,7 @@ "type": "object", "additionalProperties": false, "properties": { - "only-two": { + "only-two": { "type": "boolean", "description": "To check functions with only two return values.", "default": true @@ -2555,9 +2661,25 @@ "type": "array", "description": "List of return types to check.", "items": { - "enum": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"] + "enum": [ + "chan", + "func", + "iface", + "map", + "ptr", + "uintptr", + "unsafeptr" + ] }, - "default": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"] + "default": [ + "chan", + "func", + "iface", + "map", + "ptr", + "uintptr", + "unsafeptr" + ] } } }, @@ -2579,7 +2701,11 @@ "properties": { "ignored-files": { "description": "List of file patterns to exclude from analysis.", - "examples": [["magic1_.*.go"]], + "examples": [ + [ + "magic1_.*.go" + ] + ], "type": "array", "items": { "type": "string" @@ -2587,7 +2713,13 @@ }, "ignored-functions": { "description": "Comma-separated list of function patterns to exclude from the analysis.", - "examples": [["math.*", "http.StatusText", "make"]], + "examples": [ + [ + "math.*", + "http.StatusText", + "make" + ] + ], "type": "array", "items": { "type": "string" @@ -2595,7 +2727,13 @@ }, "ignored-numbers": { "description": "List of numbers to exclude from analysis.", - "examples": [["1000", "1234_567_890", "3.14159264"]], + "examples": [ + [ + "1000", + "1234_567_890", + "3.14159264" + ] + ], "type": "array", "items": { "type": "string" @@ -2829,14 +2967,18 @@ "type": "array", "items": { "type": "string", - "examples": ["protoc-gen-go-my-own-generator"] + "examples": [ + "protoc-gen-go-my-own-generator" + ] } }, "skip-files": { "type": "array", "items": { "type": "string", - "examples": ["*.pb.go"] + "examples": [ + "*.pb.go" + ] } }, "skip-any-generated": { @@ -2887,7 +3029,10 @@ }, "severity": { "type": "string", - "enum": ["warning", "error"] + "enum": [ + "warning", + "error" + ] }, "enable-all-rules": { "type": "boolean", @@ -2901,11 +3046,16 @@ "properties": { "name": { "type": "string", - "enum": ["specify-disable-reason"] + "enum": [ + "specify-disable-reason" + ] }, "severity": { "type": "string", - "enum": ["warning", "error"] + "enum": [ + "warning", + "error" + ] }, "exclude": { "type": "array", @@ -2924,7 +3074,9 @@ "items": { "type": "object", "additionalProperties": false, - "required": ["name"], + "required": [ + "name" + ], "properties": { "name": { "$ref": "#/definitions/revive-rules", @@ -2935,7 +3087,10 @@ }, "severity": { "type": "string", - "enum": ["warning", "error"] + "enum": [ + "warning", + "error" + ] }, "exclude": { "type": "array", @@ -2960,7 +3115,9 @@ "items": { "description": "", "type": "string", - "examples": ["github.com/jmoiron/sqlx"] + "examples": [ + "github.com/jmoiron/sqlx" + ] } } } @@ -2976,7 +3133,11 @@ }, "no-global": { "description": "Enforce not using global loggers.", - "enum": ["", "all", "default"], + "enum": [ + "", + "all", + "default" + ], "default": "" }, "no-mixed-args": { @@ -2986,7 +3147,11 @@ }, "context": { "description": "Enforce using methods that accept a context.", - "enum": ["", "all", "scope"], + "enum": [ + "", + "all", + "scope" + ], "default": "" }, "static-msg": { @@ -2996,12 +3161,21 @@ }, "msg-style": { "description": "Enforce message style.", - "enum": ["", "lowercased", "capitalized"], + "enum": [ + "", + "lowercased", + "capitalized" + ], "default": "" }, "key-naming-case": { "description": "Enforce a single key naming convention.", - "enum": ["snake", "kebab", "camel", "pascal"] + "enum": [ + "snake", + "kebab", + "camel", + "pascal" + ] }, "attr-only": { "description": "Enforce using attributes only (incompatible with kv-only).", @@ -3035,7 +3209,11 @@ "description": "Checks to enable.", "type": "array", "items": { - "enum": ["end", "record-error", "set-status"] + "enum": [ + "end", + "record-error", + "set-status" + ] } }, "ignore-check-signatures": { @@ -3080,7 +3258,12 @@ }, "http-status-code-whitelist": { "description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.", - "default": ["200", "400", "404", "500"], + "default": [ + "200", + "400", + "404", + "500" + ], "type": "array", "items": { "enum": [ @@ -3261,7 +3444,9 @@ "type": "array", "items": { "type": "string", - "examples": ["example"] + "examples": [ + "example" + ] } }, "rules": { @@ -3279,7 +3464,9 @@ "^.+$": { "type": "object", "additionalProperties": false, - "required": ["case"], + "required": [ + "case" + ], "properties": { "case": { "$ref": "#/definitions/tagliatelle-cases" @@ -3307,7 +3494,9 @@ "items": { "type": "object", "additionalProperties": false, - "required": ["pkg"], + "required": [ + "pkg" + ], "properties": { "pkg": { "description": "A package path.", @@ -3323,7 +3512,9 @@ "type": "array", "items": { "type": "string", - "examples": ["example"] + "examples": [ + "example" + ] } }, "ignore": { @@ -3346,7 +3537,9 @@ "^.+$": { "type": "object", "additionalProperties": false, - "required": ["case"], + "required": [ + "case" + ], "properties": { "case": { "$ref": "#/definitions/tagliatelle-cases" @@ -3556,7 +3749,10 @@ "mode": { "description": "To require or remove extra Assert() call?", "type": "string", - "enum": ["remove", "require"], + "enum": [ + "remove", + "require" + ], "default": "remove" } } @@ -3570,7 +3766,9 @@ "skip-regexp": { "description": "Files with names matching this regular expression are skipped.", "type": "string", - "examples": ["(export|internal)_test\\.go"] + "examples": [ + "(export|internal)_test\\.go" + ] }, "allow-packages": { "description": "List of packages that don't end with _test that tests are allowed to be in.", @@ -3578,7 +3776,9 @@ "uniqueItems": true, "items": { "type": "string", - "examples": ["example"] + "examples": [ + "example" + ] } } } @@ -3870,7 +4070,9 @@ }, "ignore-names": { "description": "Optional list of variable names that should be ignored completely.", - "default": [[]], + "default": [ + [] + ], "type": "array", "items": { "type": "string" @@ -3883,7 +4085,12 @@ "type": "string" }, "examples": [ - ["c echo.Context", "t testing.T", "f *foo.Bar", "const C"] + [ + "c echo.Context", + "t testing.T", + "f *foo.Bar", + "const C" + ] ] } } @@ -3938,7 +4145,9 @@ }, "ignore-sig-regexps": { "description": "An array of strings which specify regular expressions of signatures to ignore.", - "default": [""], + "default": [ + "" + ], "type": "array", "items": { "type": "string" @@ -3946,7 +4155,9 @@ }, "ignore-package-globs": { "description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.", - "default": [""], + "default": [ + "" + ], "type": "array", "items": { "type": "string" @@ -3954,7 +4165,9 @@ }, "ignore-interface-regexps": { "description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.", - "default": [""], + "default": [ + "" + ], "type": "array", "items": { "type": "string" @@ -4070,13 +4283,18 @@ "properties": { "type": { "description": "The plugin type.", - "enum": ["module", "goplugin"], + "enum": [ + "module", + "goplugin" + ], "default": "goplugin" }, "path": { "description": "The path to the plugin *.so. Can be absolute or local.", "type": "string", - "examples": ["/path/to/example.so"] + "examples": [ + "/path/to/example.so" + ] }, "description": { "description": "The description of the linter, for documentation purposes only.", @@ -4094,12 +4312,20 @@ "oneOf": [ { "properties": { - "type": {"enum": ["module"] } + "type": { + "enum": [ + "module" + ] + } }, - "required": ["type"] + "required": [ + "type" + ] }, { - "required": ["path"] + "required": [ + "path" + ] } ] } @@ -4110,7 +4336,9 @@ }, "type": "object", "additionalProperties": false, - "required": ["version"], + "required": [ + "version" + ], "properties": { "version": { "type": "string", @@ -4125,14 +4353,20 @@ "description": "Number of concurrent runners. Defaults to the number of available CPU cores.", "type": "integer", "minimum": 0, - "examples": [4] + "examples": [ + 4 + ] }, "timeout": { "description": "Timeout for the analysis.", "type": "string", "pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$", "default": "1m", - "examples": ["30s", "5m", "5m30s"] + "examples": [ + "30s", + "5m", + "5m30s" + ] }, "issues-exit-code": { "description": "Exit code when at least one issue was found.", @@ -4151,11 +4385,19 @@ "type": "string" }, "default": [], - "examples": [["mytag"]] + "examples": [ + [ + "mytag" + ] + ] }, "modules-download-mode": { "description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.", - "enum": ["mod", "readonly", "vendor"] + "enum": [ + "mod", + "readonly", + "vendor" + ] }, "allow-parallel-runners": { "description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.", @@ -4267,7 +4509,9 @@ "path-mode": { "type": "string", "default": "", - "examples": ["abs"] + "examples": [ + "abs" + ] }, "path-prefix": { "description": "Add a prefix to the output file references.", @@ -4282,7 +4526,11 @@ "sort-order": { "type": "array", "items": { - "enum": ["linter", "severity", "file"] + "enum": [ + "linter", + "severity", + "file" + ] } } } @@ -4333,7 +4581,7 @@ "decorder": { "$ref": "#/definitions/settings/definitions/decorderSettings" }, - "depguard":{ + "depguard": { "$ref": "#/definitions/settings/definitions/depguardSettings" }, "dogsled": { @@ -4393,7 +4641,7 @@ "godox": { "$ref": "#/definitions/settings/definitions/godoxSettings" }, - "interfacebloat":{ + "interfacebloat": { "$ref": "#/definitions/settings/definitions/interfacebloatSettings" }, "goheader": { @@ -4435,7 +4683,7 @@ "maintidx": { "$ref": "#/definitions/settings/definitions/maintidxSettings" }, - "makezero":{ + "makezero": { "$ref": "#/definitions/settings/definitions/makezeroSettings" }, "loggercheck": { @@ -4462,7 +4710,7 @@ "mnd": { "$ref": "#/definitions/settings/definitions/mndSettings" }, - "nolintlint":{ + "nolintlint": { "$ref": "#/definitions/settings/definitions/nolintlintSettings" }, "reassign": { @@ -4504,7 +4752,7 @@ "spancheck": { "$ref": "#/definitions/settings/definitions/spancheckSettings" }, - "staticcheck":{ + "staticcheck": { "$ref": "#/definitions/settings/definitions/staticcheckSettings" }, "tagalign": { @@ -4552,17 +4800,21 @@ "copyloopvar": { "$ref": "#/definitions/settings/definitions/copyloopvarSettings" }, - "custom":{ + "custom": { "$ref": "#/definitions/settings/definitions/customSettings" } } }, - "exclusions":{ + "exclusions": { "type": "object", "additionalProperties": false, "properties": { "generated": { - "enum": ["strict", "lax", "disable"], + "enum": [ + "strict", + "lax", + "disable" + ], "default": "strict" }, "warn-unused": { @@ -4605,21 +4857,41 @@ } }, "anyOf": [ - { "required": ["path"] }, - { "required": ["path-except"] }, - { "required": ["linters"] }, - { "required": ["text"] }, - { "required": ["source"] } + { + "required": [ + "path" + ] + }, + { + "required": [ + "path-except" + ] + }, + { + "required": [ + "linters" + ] + }, + { + "required": [ + "text" + ] + }, + { + "required": [ + "source" + ] + } ] } }, - "paths": { + "paths": { "type": "array", "items": { "type": "string" } }, - "paths-except": { + "paths-except": { "type": "array", "items": { "type": "string" @@ -4666,7 +4938,11 @@ "additionalProperties": false, "properties": { "generated": { - "enum": ["strict", "lax", "disable"], + "enum": [ + "strict", + "lax", + "disable" + ], "default": "strict" }, "paths": { @@ -4715,7 +4991,9 @@ "new-from-patch": { "description": "Show only new issues created in git patch with this file path.", "type": "string", - "examples": ["path/to/patch/file"] + "examples": [ + "path/to/patch/file" + ] }, "fix": { "description": "Fix found issues (if it's supported by the linter).", @@ -4772,19 +5050,43 @@ "type": "string" } }, - "required": ["severity"], + "required": [ + "severity" + ], "anyOf": [ - { "required": ["path"] }, - { "required": ["path-except"] }, - { "required": ["linters"] }, - { "required": ["text"] }, - { "required": ["source"] } + { + "required": [ + "path" + ] + }, + { + "required": [ + "path-except" + ] + }, + { + "required": [ + "linters" + ] + }, + { + "required": [ + "text" + ] + }, + { + "required": [ + "source" + ] + } ] }, "default": [] } }, - "required": ["default"] + "required": [ + "default" + ] } } } diff --git a/pkg/config/linters_settings.go b/pkg/config/linters_settings.go index 16a8bb9501b9..a78f8403d822 100644 --- a/pkg/config/linters_settings.go +++ b/pkg/config/linters_settings.go @@ -44,6 +44,7 @@ var defaultLintersSettings = LintersSettings{ FuncOrder: FuncOrderSettings{ Constructor: true, StructMethod: true, + Alphabetical: false, }, Funlen: FunlenSettings{ IgnoreComments: true, @@ -428,6 +429,7 @@ type ForbidigoPattern struct { type FuncOrderSettings struct { Constructor bool `mapstructure:"constructor,omitempty"` StructMethod bool `mapstructure:"struct-method,omitempty"` + Alphabetical bool `mapstructure:"alphabetical,omitempty"` } type FunlenSettings struct { diff --git a/pkg/golinters/funcorder/funcorder.go b/pkg/golinters/funcorder/funcorder.go index 7b8e9689e587..605304f26203 100644 --- a/pkg/golinters/funcorder/funcorder.go +++ b/pkg/golinters/funcorder/funcorder.go @@ -17,6 +17,7 @@ func New(settings *config.FuncOrderSettings) *goanalysis.Linter { cfg[a.Name] = map[string]any{ analyzer.ConstructorCheckName: settings.Constructor, analyzer.StructMethodCheckName: settings.StructMethod, + analyzer.AlphabeticalCheckName: settings.Alphabetical, } } diff --git a/pkg/golinters/funcorder/testdata/funcorder_disable_constructor_alphabetical.go b/pkg/golinters/funcorder/testdata/funcorder_disable_constructor_alphabetical.go new file mode 100644 index 000000000000..61ef217ff904 --- /dev/null +++ b/pkg/golinters/funcorder/testdata/funcorder_disable_constructor_alphabetical.go @@ -0,0 +1,41 @@ +//golangcitest:args -Efuncorder +//golangcitest:config_path testdata/funcorder_disable_constructor_alphabetical.yml +package testdata + +import "time" + +type MyStruct struct { + Name string +} + +func (m MyStruct) lenName() int { // want `unexported method "lenName" for struct "MyStruct" should be placed after the exported method "GetName"` + return len(m.Name) +} + +func (m *MyStruct) SetName(name string) { + m.Name = name +} + +func (m MyStruct) GetName() string { // want `"GetName" for struct "MyStruct" should be placed before method "SetName"` + return m.Name +} + +type MyStruct2 struct { + Name string +} + +func (m *MyStruct2) SetName(name string) { + m.Name = name +} + +func (m MyStruct2) GetName() string { // want `"GetName" for struct "MyStruct2" should be placed before method "SetName"` + return m.Name +} + +func NewMyStruct2() *MyStruct2 { + return &MyStruct2{Name: "John"} +} + +func NewTime() time.Time { + return time.Now() +} diff --git a/pkg/golinters/funcorder/testdata/funcorder_disable_constructor_alphabetical.yml b/pkg/golinters/funcorder/testdata/funcorder_disable_constructor_alphabetical.yml new file mode 100644 index 000000000000..ce49c15031ca --- /dev/null +++ b/pkg/golinters/funcorder/testdata/funcorder_disable_constructor_alphabetical.yml @@ -0,0 +1,7 @@ +version: "2" + +linters: + settings: + funcorder: + constructor: false + alphabetical: true diff --git a/pkg/golinters/funcorder/testdata/funcorder_struct_method.go b/pkg/golinters/funcorder/testdata/funcorder_disable_struct_method.go similarity index 90% rename from pkg/golinters/funcorder/testdata/funcorder_struct_method.go rename to pkg/golinters/funcorder/testdata/funcorder_disable_struct_method.go index a44f980e8b9e..7f61cf3dd632 100644 --- a/pkg/golinters/funcorder/testdata/funcorder_struct_method.go +++ b/pkg/golinters/funcorder/testdata/funcorder_disable_struct_method.go @@ -1,5 +1,5 @@ //golangcitest:args -Efuncorder -//golangcitest:config_path testdata/funcorder_struct_method.yml +//golangcitest:config_path testdata/funcorder_disable_struct_method.yml package testdata import "time" diff --git a/pkg/golinters/funcorder/testdata/funcorder_struct_method.yml b/pkg/golinters/funcorder/testdata/funcorder_disable_struct_method.yml similarity index 100% rename from pkg/golinters/funcorder/testdata/funcorder_struct_method.yml rename to pkg/golinters/funcorder/testdata/funcorder_disable_struct_method.yml diff --git a/pkg/golinters/funcorder/testdata/funcorder_disable_struct_method_alphabetical.go b/pkg/golinters/funcorder/testdata/funcorder_disable_struct_method_alphabetical.go new file mode 100644 index 000000000000..3b121b040739 --- /dev/null +++ b/pkg/golinters/funcorder/testdata/funcorder_disable_struct_method_alphabetical.go @@ -0,0 +1,45 @@ +//golangcitest:args -Efuncorder +//golangcitest:config_path testdata/funcorder_disable_struct_method_alphabetical.yml +package testdata + +import "time" + +type MyStruct struct { + Name string +} + +func (m MyStruct) lenName() int { + return len(m.Name) +} + +func (m MyStruct) GetName() string { + return m.Name +} + +func (m *MyStruct) SetName(name string) { + m.Name = name +} + +type MyStruct2 struct { + Name string +} + +func (m MyStruct2) GetName() string { + return m.Name +} + +func (m *MyStruct2) SetName(name string) { + m.Name = name +} + +func NewMyStruct2() *MyStruct2 { // want `constructor "NewMyStruct2" for struct "MyStruct2" should be placed before struct method "GetName"` + return &MyStruct2{Name: "John"} +} + +func MustMyStruct2() *MyStruct2 { // want `constructor "MustMyStruct2" for struct "MyStruct2" should be placed before constructor "NewMyStruct2"` + return &MyStruct2{Name: "John"} +} + +func NewTime() time.Time { + return time.Now() +} diff --git a/pkg/golinters/funcorder/testdata/funcorder_disable_struct_method_alphabetical.yml b/pkg/golinters/funcorder/testdata/funcorder_disable_struct_method_alphabetical.yml new file mode 100644 index 000000000000..00a1f874e338 --- /dev/null +++ b/pkg/golinters/funcorder/testdata/funcorder_disable_struct_method_alphabetical.yml @@ -0,0 +1,7 @@ +version: "2" + +linters: + settings: + funcorder: + struct-method: false + alphabetical: true