diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index 5342cbe08..3893ef86b 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -33,7 +33,7 @@ jobs: run: sudo apt-get update && sudo apt-get -y install libsnmp-dev if: github.repository == 'prometheus/snmp_exporter' - name: Lint - uses: golangci/golangci-lint-action@55c2c1448f86e01eaae002a5a3a9624417608d84 # v6.5.2 + uses: golangci/golangci-lint-action@1481404843c368bc19ca9406f87d6e0fc97bdcfd # v7.0.0 with: args: --verbose - version: v1.64.6 + version: v2.0.2 diff --git a/.golangci.yml b/.golangci.yml index 06c70b972..3f42fd7f8 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,9 +1,6 @@ ---- -run: - timeout: 5m - -output: - sort-results: true +version: "2" +issues: + max-same-issues: 0 linters: enable: @@ -11,76 +8,83 @@ linters: - depguard - durationcheck - errorlint - # The linter 'exportloopref' is deprecated (since v1.60.2) due to: Since Go1.22 (loopvar) this linter is no longer relevant. Replaced by copyloopvar. - # - exportloopref - - gofmt - - gofumpt - - goimports - - gosimple - - ineffassign - misspell - nolintlint - perfsprint - predeclared - revive - - staticcheck - unconvert - - unused - usestdlibvars - wastedassign + exclusions: + generated: lax + presets: + - comments + - common-false-positives + - legacy + - std-error-handling + rules: + - linters: + - errcheck + - govet + - structcheck + - nolintlint + path: _test.go + paths: + - ^.*\.(pb|y)\.go$ + - third_party$ + - builtin$ + - examples$ + settings: + depguard: + rules: + main: + deny: + - pkg: github.com/stretchr/testify/assert + desc: Use github.com/stretchr/testify/require instead of github.com/stretchr/testify/assert + - pkg: github.com/go-kit/kit/log + desc: Use github.com/go-kit/log instead of github.com/go-kit/kit/log + - pkg: io/ioutil + desc: Use corresponding 'os' or 'io' functions instead. + errcheck: + exclude-functions: + # The following 2 methods always return nil as the error + - (*github.com/cespare/xxhash/v2.Digest).Write + - (*github.com/cespare/xxhash/v2.Digest).WriteString + - (*bufio.Writer).WriteRune + perfsprint: + # Optimizes even if it requires an int or uint type cast. + int-conversion: true + # Optimizes into `err.Error()` even if it is only equivalent for non-nil errors. + err-error: true + # Optimizes `fmt.Errorf`. + errorf: true + # Optimizes `fmt.Sprintf` with only one argument. + sprintf1: true + # Optimizes into strings concatenation. + strconcat: true + revive: + rules: -issues: - max-same-issues: 0 - exclude-rules: - - path: _test.go - linters: - - errcheck - - govet - - structcheck - # The configuration option `run.skip-files` is deprecated, please use `issues.exclude-files`. - exclude-files: - # Skip autogenerated files. - - ^.*\.(pb|y)\.go$ + - name: unused-parameter + severity: warning + disabled: true -linters-settings: - depguard: - rules: - main: - deny: - #- pkg: "sync/atomic" - # desc: "Use go.uber.org/atomic instead of sync/atomic" - - pkg: "github.com/stretchr/testify/assert" - desc: "Use github.com/stretchr/testify/require instead of github.com/stretchr/testify/assert" - - pkg: "github.com/go-kit/kit/log" - desc: "Use github.com/go-kit/log instead of github.com/go-kit/kit/log" - - pkg: "io/ioutil" - desc: "Use corresponding 'os' or 'io' functions instead." - #- pkg: "regexp" - # desc: "Use github.com/grafana/regexp instead of regexp" - errcheck: - exclude-functions: - # The following 2 methods always return nil as the error - - (*github.com/cespare/xxhash/v2.Digest).Write - - (*github.com/cespare/xxhash/v2.Digest).WriteString - - (*bufio.Writer).WriteRune - goimports: - local-prefixes: github.com/prometheus/client_golang - gofumpt: - extra-rules: true - perfsprint: - # Optimizes even if it requires an int or uint type cast. - int-conversion: true - # Optimizes into `err.Error()` even if it is only equivalent for non-nil errors. - err-error: true - # Optimizes `fmt.Errorf`. - errorf: true - # Optimizes `fmt.Sprintf` with only one argument. - sprintf1: true - # Optimizes into strings concatenation. - strconcat: true - revive: - rules: - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unused-parameter - - name: unused-parameter - severity: warning - disabled: true +formatters: + enable: + - gofmt + - gofumpt + - goimports + settings: + gofumpt: + extra-rules: true + goimports: + local-prefixes: + - github.com/prometheus/client_golang + exclusions: + generated: lax + paths: + - ^.*\.(pb|y)\.go$ + - third_party$ + - builtin$ + - examples$ diff --git a/Makefile.common b/Makefile.common index 8cb383859..81bad5f42 100644 --- a/Makefile.common +++ b/Makefile.common @@ -61,7 +61,7 @@ PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_ SKIP_GOLANGCI_LINT := GOLANGCI_LINT := GOLANGCI_LINT_OPTS ?= -GOLANGCI_LINT_VERSION ?= v1.64.6 +GOLANGCI_LINT_VERSION ?= v2.0.2 # golangci-lint only supports linux, darwin and windows platforms on i386/amd64/arm64. # windows isn't included here because of the path separator being different. ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux darwin)) diff --git a/prometheus/graphite/bridge.go b/prometheus/graphite/bridge.go index 84eac0de9..c763797ca 100644 --- a/prometheus/graphite/bridge.go +++ b/prometheus/graphite/bridge.go @@ -307,7 +307,8 @@ func replaceInvalidRune(c rune) rune { if c == ' ' { return '.' } - if !((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || c == ':' || c == '-' || (c >= '0' && c <= '9')) { + // TODO: Apply De Morgan's law to the condition. Make sure to test the condition first. + if !((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || c == ':' || c == '-' || (c >= '0' && c <= '9')) { //nolint:staticcheck return '_' } return c diff --git a/prometheus/internal/difflib.go b/prometheus/internal/difflib.go index 8b016355a..7bac0da33 100644 --- a/prometheus/internal/difflib.go +++ b/prometheus/internal/difflib.go @@ -453,7 +453,7 @@ func (m *SequenceMatcher) GetGroupedOpCodes(n int) [][]OpCode { } group = append(group, OpCode{c.Tag, i1, i2, j1, j2}) } - if len(group) > 0 && !(len(group) == 1 && group[0].Tag == 'e') { + if len(group) > 0 && (len(group) != 1 || group[0].Tag != 'e') { groups = append(groups, group) } return groups @@ -568,7 +568,7 @@ func WriteUnifiedDiff(writer io.Writer, diff UnifiedDiff) error { buf := bufio.NewWriter(writer) defer buf.Flush() wf := func(format string, args ...interface{}) error { - _, err := buf.WriteString(fmt.Sprintf(format, args...)) + _, err := fmt.Fprintf(buf, format, args...) return err } ws := func(s string) error { diff --git a/prometheus/process_collector_darwin.go b/prometheus/process_collector_darwin.go index 0a61b9846..b32c95fa3 100644 --- a/prometheus/process_collector_darwin.go +++ b/prometheus/process_collector_darwin.go @@ -25,9 +25,9 @@ import ( "golang.org/x/sys/unix" ) -// notImplementedErr is returned by stub functions that replace cgo functions, when cgo +// errNotImplemented is returned by stub functions that replace cgo functions, when cgo // isn't available. -var notImplementedErr = errors.New("not implemented") +var errNotImplemented = errors.New("not implemented") type memoryInfo struct { vsize uint64 // Virtual memory size in bytes @@ -101,7 +101,7 @@ func (c *processCollector) processCollect(ch chan<- Metric) { if memInfo, err := getMemory(); err == nil { ch <- MustNewConstMetric(c.rss, GaugeValue, float64(memInfo.rss)) ch <- MustNewConstMetric(c.vsize, GaugeValue, float64(memInfo.vsize)) - } else if !errors.Is(err, notImplementedErr) { + } else if !errors.Is(err, errNotImplemented) { // Don't report an error when support is not compiled in. c.reportError(ch, c.rss, err) c.reportError(ch, c.vsize, err) diff --git a/prometheus/process_collector_procfsenabled.go b/prometheus/process_collector_procfsenabled.go index 9f4b130be..8074f70f5 100644 --- a/prometheus/process_collector_procfsenabled.go +++ b/prometheus/process_collector_procfsenabled.go @@ -66,11 +66,11 @@ func (c *processCollector) processCollect(ch chan<- Metric) { if netstat, err := p.Netstat(); err == nil { var inOctets, outOctets float64 - if netstat.IpExt.InOctets != nil { - inOctets = *netstat.IpExt.InOctets + if netstat.InOctets != nil { + inOctets = *netstat.InOctets } - if netstat.IpExt.OutOctets != nil { - outOctets = *netstat.IpExt.OutOctets + if netstat.OutOctets != nil { + outOctets = *netstat.OutOctets } ch <- MustNewConstMetric(c.inBytes, CounterValue, inOctets) ch <- MustNewConstMetric(c.outBytes, CounterValue, outOctets) diff --git a/prometheus/promhttp/instrument_server.go b/prometheus/promhttp/instrument_server.go index 356edb786..9332b0249 100644 --- a/prometheus/promhttp/instrument_server.go +++ b/prometheus/promhttp/instrument_server.go @@ -392,7 +392,7 @@ func isLabelCurried(c prometheus.Collector, label string) bool { func labels(code, method bool, reqMethod string, status int, extraMethods ...string) prometheus.Labels { labels := prometheus.Labels{} - if !(code || method) { + if !code && !method { return labels } diff --git a/prometheus/vec.go b/prometheus/vec.go index 2c808eece..487b46656 100644 --- a/prometheus/vec.go +++ b/prometheus/vec.go @@ -79,7 +79,7 @@ func (m *MetricVec) DeleteLabelValues(lvs ...string) bool { return false } - return m.metricMap.deleteByHashWithLabelValues(h, lvs, m.curry) + return m.deleteByHashWithLabelValues(h, lvs, m.curry) } // Delete deletes the metric where the variable labels are the same as those @@ -101,7 +101,7 @@ func (m *MetricVec) Delete(labels Labels) bool { return false } - return m.metricMap.deleteByHashWithLabels(h, labels, m.curry) + return m.deleteByHashWithLabels(h, labels, m.curry) } // DeletePartialMatch deletes all metrics where the variable labels contain all of those @@ -114,7 +114,7 @@ func (m *MetricVec) DeletePartialMatch(labels Labels) int { labels, closer := constrainLabels(m.desc, labels) defer closer() - return m.metricMap.deleteByLabels(labels, m.curry) + return m.deleteByLabels(labels, m.curry) } // Without explicit forwarding of Describe, Collect, Reset, those methods won't @@ -216,7 +216,7 @@ func (m *MetricVec) GetMetricWithLabelValues(lvs ...string) (Metric, error) { return nil, err } - return m.metricMap.getOrCreateMetricWithLabelValues(h, lvs, m.curry), nil + return m.getOrCreateMetricWithLabelValues(h, lvs, m.curry), nil } // GetMetricWith returns the Metric for the given Labels map (the label names @@ -244,7 +244,7 @@ func (m *MetricVec) GetMetricWith(labels Labels) (Metric, error) { return nil, err } - return m.metricMap.getOrCreateMetricWithLabels(h, labels, m.curry), nil + return m.getOrCreateMetricWithLabels(h, labels, m.curry), nil } func (m *MetricVec) hashLabelValues(vals []string) (uint64, error) { diff --git a/prometheus/vec_test.go b/prometheus/vec_test.go index fdd3abc36..03223f2f6 100644 --- a/prometheus/vec_test.go +++ b/prometheus/vec_test.go @@ -183,7 +183,7 @@ func TestDeletePartialMatchWithConstraints(t *testing.T) { func testDeletePartialMatch(t *testing.T, baseVec *GaugeVec) { assertNoMetric := func(t *testing.T) { - if n := len(baseVec.metricMap.metrics); n != 0 { + if n := len(baseVec.metrics); n != 0 { t.Error("expected no metrics, got", n) } } @@ -301,7 +301,7 @@ func testMetricVec(t *testing.T, vec *GaugeVec) { } var total int - for _, metrics := range vec.metricMap.metrics { + for _, metrics := range vec.metrics { for _, metric := range metrics { total++ copy(pair[:], metric.values) @@ -336,7 +336,7 @@ func testMetricVec(t *testing.T, vec *GaugeVec) { vec.Reset() - if len(vec.metricMap.metrics) > 0 { + if len(vec.metrics) > 0 { t.Fatalf("reset failed") } } @@ -373,7 +373,7 @@ func testConstrainedMetricVec(t *testing.T, vec *GaugeVec, constrain func(string } var total int - for _, metrics := range vec.metricMap.metrics { + for _, metrics := range vec.metrics { for _, metric := range metrics { total++ copy(pair[:], metric.values) @@ -408,7 +408,7 @@ func testConstrainedMetricVec(t *testing.T, vec *GaugeVec, constrain func(string vec.Reset() - if len(vec.metricMap.metrics) > 0 { + if len(vec.metrics) > 0 { t.Fatalf("reset failed") } } @@ -506,7 +506,7 @@ func TestCurryVecWithConstraints(t *testing.T) { func testCurryVec(t *testing.T, vec *CounterVec) { assertMetrics := func(t *testing.T) { n := 0 - for _, m := range vec.metricMap.metrics { + for _, m := range vec.metrics { n += len(m) } if n != 2 { @@ -533,7 +533,7 @@ func testCurryVec(t *testing.T, vec *CounterVec) { } assertNoMetric := func(t *testing.T) { - if n := len(vec.metricMap.metrics); n != 0 { + if n := len(vec.metrics); n != 0 { t.Error("expected no metrics, got", n) } } @@ -703,7 +703,7 @@ func testCurryVec(t *testing.T, vec *CounterVec) { func testConstrainedCurryVec(t *testing.T, vec *CounterVec, constraint func(string) string) { assertMetrics := func(t *testing.T) { n := 0 - for _, m := range vec.metricMap.metrics { + for _, m := range vec.metrics { n += len(m) } if n != 2 { @@ -744,7 +744,7 @@ func testConstrainedCurryVec(t *testing.T, vec *CounterVec, constraint func(stri } assertNoMetric := func(t *testing.T) { - if n := len(vec.metricMap.metrics); n != 0 { + if n := len(vec.metrics); n != 0 { t.Error("expected no metrics, got", n) } }