Repository: prometheus/procfs
Pull request #535 (2023-06-15 09:15:33)

Use golangci-lint for codespell
* Remove Python codespell check.
* Enable misspell golanci-lint linter.

Fixes: https://github.com/prometheus/procfs/issues/536


Patch:
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 25a6795..d53e455 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -35,15 +35,6 @@ jobs:
         steps:
         - run: make test
 
-  codespell:
-    docker:
-    - image: circleci/python
-
-    steps:
-    - checkout
-    - run: sudo pip install codespell
-    - run: codespell --skip=".git,./vendor,ttar,fixtures.ttar,./fixtures,go.mod,go.sum" -I scripts/codespell_ignore.txt
-
 workflows:
   version: 2
   procfs:
@@ -66,4 +57,3 @@ workflows:
             go_version:
             - "1.19"
             - "1.20"
-    - codespell
diff --git a/.golangci.yml b/.golangci.yml
index a197699..c24864a 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -2,6 +2,7 @@
 linters:
   enable:
   - godot
+  - misspell
   - revive
 
 linter-settings:
@@ -10,3 +11,5 @@ linter-settings:
     exclude:
     # Ignore "See: URL"
     - 'See:'
+  misspell:
+    locale: US
diff --git a/net_route.go b/net_route.go
new file mode 100644
index 0000000..deb7029
--- /dev/null
+++ b/net_route.go
@@ -0,0 +1,143 @@
+// Copyright 2023 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package procfs
+
+import (
+	"bufio"
+	"bytes"
+	"fmt"
+	"io"
+	"strconv"
+	"strings"
+
+	"github.com/prometheus/procfs/internal/util"
+)
+
+const (
+	blackholeRepresentation string = "*"
+	blackholeIfaceName      string = "blackhole"
+	routeLineColumns        int    = 11
+)
+
+// A NetRouteLine represents one line from net/route.
+type NetRouteLine struct {
+	Iface       string
+	Destination uint32
+	Gateway     uint32
+	Flags       uint32
+	RefCnt      uint32
+	Use         uint32
+	Metric      uint32
+	Mask        uint32
+	MTU         uint32
+	Window      uint32
+	IRTT        uint32
+}
+
+func (fs FS) NetRoute() ([]NetRouteLine, error) {
+	return readNetRoute(fs.proc.Path("net", "route"))
+}
+
+func readNetRoute(path string) ([]NetRouteLine, error) {
+	b, err := util.ReadFileNoStat(path)
+	if err != nil {
+		return nil, err
+	}
+
+	routelines, err := parseNetRoute(bytes.NewReader(b))
+	if err != nil {
+		return nil, fmt.Errorf("failed to read net route from %s: %w", path, err)
+	}
+	return routelines, nil
+}
+
+func parseNetRoute(r io.Reader) ([]NetRouteLine, error) {
+	var routelines []NetRouteLine
+
+	scanner := bufio.NewScanner(r)
+	scanner.Scan()
+	for scanner.Scan() {
+		fields := strings.Fields(scanner.Text())
+		routeline, err := parseNetRouteLine(fields)
+		if err != nil {
+			return nil, err
+		}
+		routelines = append(routelines, *routeline)
+	}
+	return routelines, nil
+}
+
+func parseNetRouteLine(fields []string) (*NetRouteLine, error) {
+	if len(fields) != routeLineColumns {
+		return nil, fmt.Errorf("invalid routeline, num of digits: %d", len(fields))
+	}
+	iface := fields[0]
+	if iface == blackholeRepresentation {
+		iface = blackholeIfaceName
+	}
+	destination, err := strconv.ParseUint(fields[1], 16, 32)
+	if err != nil {
+		return nil, err
+	}
+	gateway, err := strconv.ParseUint(fields[2], 16, 32)
+	if err != nil {
+		return nil, err
+	}
+	flags, err := strconv.ParseUint(fields[3], 10, 32)
+	if err != nil {
+		return nil, err
+	}
+	refcnt, err := strconv.ParseUint(fields[4], 10, 32)
+	if err != nil {
+		return nil, err
+	}
+	use, err := strconv.ParseUint(fields[5], 10, 32)
+	if err != nil {
+		return nil, err
+	}
+	metric, err := strconv.ParseUint(fields[6], 10, 32)
+	if err != nil {
+		return nil, err
+	}
+	mask, err := strconv.ParseUint(fields[7], 16, 32)
+	if err != nil {
+		return nil, err
+	}
+	mtu, err := strconv.ParseUint(fields[8], 10, 32)
+	if err != nil {
+		return nil, err
+	}
+	window, err := strconv.ParseUint(fields[9], 10, 32)
+	if err != nil {
+		return nil, err
+	}
+	irtt, err := strconv.ParseUint(fields[10], 10, 32)
+	if err != nil {
+		return nil, err
+	}
+	routeline := &NetRouteLine{
+		Iface:       iface,
+		Destination: uint32(destination),
+		Gateway:     uint32(gateway),
+		Flags:       uint32(flags),
+		RefCnt:      uint32(refcnt),
+		Use:         uint32(use),
+		Metric:      uint32(metric),
+		Mask:        uint32(mask),
+		MTU:         uint32(mtu),
+		Window:      uint32(window),
+		IRTT:        uint32(irtt),
+	}
+	return routeline, nil
+}
diff --git a/scripts/codespell_ignore.txt b/scripts/codespell_ignore.txt
deleted file mode 100644
index 4b41a23..0000000
--- a/scripts/codespell_ignore.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-alo
-als
-ded
-hart
-hda
-inflight
-packages\'
-ro
-sie
-te
-uint


Test patch:
diff --git a/net_route_test.go b/net_route_test.go
new file mode 100644
index 0000000..0464036
--- /dev/null
+++ b/net_route_test.go
@@ -0,0 +1,60 @@
+// Copyright 2023 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package procfs
+
+import (
+	"bytes"
+	"reflect"
+	"testing"
+)
+
+func TestParseNetRoute(t *testing.T) {
+	var netRoute = []byte(`Iface            Destination  Gateway   Flags  RefCnt  Use  Metric  Mask      MTU  Window  IRTT
+eno16780032      00000000     9503A8C0  0003   0       0    100     00000000  0    0       0
+eno16780032      0000A8C0     00000000  0001   0       0    100     0000FFFF  0    0       0`)
+
+	r := bytes.NewReader(netRoute)
+	parsed, _ := parseNetRoute(r)
+	want := []NetRouteLine{
+		{
+			Iface:       "eno16780032",
+			Destination: 0,
+			Gateway:     2500044992,
+			Flags:       3,
+			RefCnt:      0,
+			Use:         0,
+			Metric:      100,
+			Mask:        0,
+			MTU:         0,
+			Window:      0,
+			IRTT:        0,
+		},
+		{
+			Iface:       "eno16780032",
+			Destination: 43200,
+			Gateway:     0,
+			Flags:       1,
+			RefCnt:      0,
+			Use:         0,
+			Metric:      100,
+			Mask:        65535,
+			MTU:         0,
+			Window:      0,
+			IRTT:        0,
+		},
+	}
+	if !reflect.DeepEqual(want, parsed) {
+		t.Errorf("want %v, parsed %v", want, parsed)
+	}
+}