Skip to content

chore: enable golangci-lint on Windows and MacOS #1785

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

Merged
merged 2 commits into from
Feb 20, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.go text eol=lf
6 changes: 5 additions & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,15 @@ permissions:

jobs:
golangci:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
permissions:
contents: read # for actions/checkout to fetch code
pull-requests: read # for golangci/golangci-lint-action to fetch pull requests
name: lint
runs-on: ubuntu-latest
runs-on: ${{ matrix.os }}
steps:
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
Expand Down
6 changes: 4 additions & 2 deletions cpu/cpu_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ package cpu
import (
"context"
"fmt"
"strconv"
"unsafe"

"github.com/shirou/gopsutil/v4/internal/common"
"github.com/yusufpapurcu/wmi"
"golang.org/x/sys/windows"

"github.com/shirou/gopsutil/v4/internal/common"
)

var procGetNativeSystemInfo = common.Modkernel32.NewProc("GetNativeSystemInfo")
Expand Down Expand Up @@ -110,7 +112,7 @@ func InfoWithContext(ctx context.Context) ([]InfoStat, error) {

cpu := InfoStat{
CPU: int32(i),
Family: fmt.Sprintf("%d", l.Family),
Family: strconv.FormatUint(uint64(l.Family), 10),
VendorID: l.Manufacturer,
ModelName: l.Name,
Cores: int32(l.NumberOfLogicalProcessors),
Expand Down
2 changes: 1 addition & 1 deletion disk/disk_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ func (i *ioCounters) getDriveStat(d uint32) (*IOCountersStat, error) {
defer i.ioObjectRelease(parent)

if !ioObjectConformsTo(parent, "IOBlockStorageDriver") {
//return nil, fmt.Errorf("ERROR: the object is not of the IOBlockStorageDriver class")
// return nil, fmt.Errorf("ERROR: the object is not of the IOBlockStorageDriver class")
return nil, nil
}

Expand Down
9 changes: 5 additions & 4 deletions disk/disk_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ package disk
import (
"bytes"
"context"
"fmt"
"errors"
"syscall"
"unsafe"

"github.com/shirou/gopsutil/v4/internal/common"
"golang.org/x/sys/windows"
"golang.org/x/sys/windows/registry"

"github.com/shirou/gopsutil/v4/internal/common"
)

var (
Expand Down Expand Up @@ -202,11 +203,11 @@ func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOC
if typeret != windows.DRIVE_FIXED {
continue
}
szDevice := fmt.Sprintf(`\\.\%s`, path)
szDevice := `\\.\` + path
const IOCTL_DISK_PERFORMANCE = 0x70020
h, err := windows.CreateFile(syscall.StringToUTF16Ptr(szDevice), 0, windows.FILE_SHARE_READ|windows.FILE_SHARE_WRITE, nil, windows.OPEN_EXISTING, 0, 0)
if err != nil {
if err == windows.ERROR_FILE_NOT_FOUND {
if errors.Is(err, windows.ERROR_FILE_NOT_FOUND) {
continue
}
return drivemap, err
Expand Down
23 changes: 12 additions & 11 deletions host/host_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@ import (
"time"
"unsafe"

"golang.org/x/sys/windows"

"github.com/shirou/gopsutil/v4/internal/common"
"github.com/shirou/gopsutil/v4/process"
"golang.org/x/sys/windows"
)

var (
Expand Down Expand Up @@ -79,7 +80,7 @@ func HostIDWithContext(ctx context.Context) (string, error) {
hostID := windows.UTF16ToString(regBuf[:])
hostIDLen := len(hostID)
if hostIDLen != uuidLen {
return "", fmt.Errorf("HostID incorrect: %q\n", hostID)
return "", fmt.Errorf("HostID incorrect: %q\n", hostID) //nolint:revive //FIXME
}

return strings.ToLower(hostID), nil
Expand Down Expand Up @@ -135,15 +136,15 @@ func BootTimeWithContext(ctx context.Context) (uint64, error) {
return t, nil
}

func PlatformInformationWithContext(ctx context.Context) (platform string, family string, version string, err error) {
platform, family, _, displayVersion, err := platformInformation(ctx)
func PlatformInformationWithContext(_ context.Context) (platform string, family string, version string, err error) {
platform, family, _, displayVersion, err := platformInformation()
if err != nil {
return "", "", "", err
}
return platform, family, displayVersion, nil
}

func platformInformation(ctx context.Context) (platform, family, version, displayVersion string, err error) {
func platformInformation() (platform, family, version, displayVersion string, err error) {
// GetVersionEx lies on Windows 8.1 and returns as Windows 8 if we don't declare compatibility in manifest
// RtlGetVersion bypasses this lying layer and returns the true Windows version
// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/wdm/nf-wdm-rtlgetversion
Expand All @@ -152,26 +153,26 @@ func platformInformation(ctx context.Context) (platform, family, version, displa
osInfo.dwOSVersionInfoSize = uint32(unsafe.Sizeof(osInfo))
ret, _, err := procRtlGetVersion.Call(uintptr(unsafe.Pointer(&osInfo)))
if ret != 0 {
return
return //nolint:nakedret //FIXME
}

// Platform
var h windows.Handle // like HostIDWithContext(), we query the registry using the raw windows.RegOpenKeyEx/RegQueryValueEx
err = windows.RegOpenKeyEx(windows.HKEY_LOCAL_MACHINE, windows.StringToUTF16Ptr(`SOFTWARE\Microsoft\Windows NT\CurrentVersion`), 0, windows.KEY_READ|windows.KEY_WOW64_64KEY, &h)
if err != nil {
return
return //nolint:nakedret //FIXME
}
defer windows.RegCloseKey(h)
var bufLen uint32
var valType uint32
err = windows.RegQueryValueEx(h, windows.StringToUTF16Ptr(`ProductName`), nil, &valType, nil, &bufLen)
if err != nil {
return
return //nolint:nakedret //FIXME
}
regBuf := make([]uint16, bufLen/2+1)
err = windows.RegQueryValueEx(h, windows.StringToUTF16Ptr(`ProductName`), nil, &valType, (*byte)(unsafe.Pointer(&regBuf[0])), &bufLen)
if err != nil {
return
return //nolint:nakedret //FIXME
}
platform = windows.UTF16ToString(regBuf[:])
if strings.Contains(platform, "Windows 10") { // check build number to determine whether it's actually Windows 11
Expand Down Expand Up @@ -243,8 +244,8 @@ func VirtualizationWithContext(ctx context.Context) (string, string, error) {
return "", "", common.ErrNotImplementedError
}

func KernelVersionWithContext(ctx context.Context) (string, error) {
_, _, version, _, err := platformInformation(ctx)
func KernelVersionWithContext(_ context.Context) (string, error) {
_, _, version, _, err := platformInformation()
return version, err
}

Expand Down
11 changes: 6 additions & 5 deletions internal/common/common_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package common

import (
"context"
"errors"
"fmt"
"os"
"os/exec"
Expand Down Expand Up @@ -306,7 +307,7 @@ const (

func NewSMC(ioKit *Library) (*SMC, error) {
if ioKit.path != IOKit {
return nil, fmt.Errorf("library is not IOKit")
return nil, errors.New("library is not IOKit")
}

ioServiceGetMatchingService := GetFunc[IOServiceGetMatchingServiceFunc](ioKit, IOServiceGetMatchingServiceSym)
Expand All @@ -324,7 +325,7 @@ func NewSMC(ioKit *Library) (*SMC, error) {

var conn uint32
if result := ioServiceOpen(service, machTaskSelf(), 0, &conn); result != 0 {
return nil, fmt.Errorf("ERROR: IOServiceOpen failed")
return nil, errors.New("ERROR: IOServiceOpen failed")
}

ioObjectRelease(service)
Expand All @@ -343,7 +344,7 @@ func (s *SMC) Close() error {
ioServiceClose := GetFunc[IOServiceCloseFunc](s.lib, IOServiceCloseSym)

if result := ioServiceClose(s.conn); result != 0 {
return fmt.Errorf("ERROR: IOServiceClose failed")
return errors.New("ERROR: IOServiceClose failed")
}
return nil
}
Expand All @@ -367,8 +368,8 @@ func (s CStr) Ptr() *byte {
return &s[0]
}

func (c CStr) Addr() uintptr {
return uintptr(unsafe.Pointer(c.Ptr()))
func (s CStr) Addr() uintptr {
return uintptr(unsafe.Pointer(s.Ptr()))
}

func (s CStr) GoString() string {
Expand Down
12 changes: 6 additions & 6 deletions internal/common/common_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,19 +273,19 @@ type SystemExtendedHandleInformation struct {
// CallWithExpandingBuffer https://github.com/hillu/go-ntdll
func CallWithExpandingBuffer(fn func() NtStatus, buf *[]byte, resultLength *uint32) NtStatus {
for {
if st := fn(); st == STATUS_BUFFER_OVERFLOW || st == STATUS_BUFFER_TOO_SMALL || st == STATUS_INFO_LENGTH_MISMATCH {
st := fn()
if st == STATUS_BUFFER_OVERFLOW || st == STATUS_BUFFER_TOO_SMALL || st == STATUS_INFO_LENGTH_MISMATCH {
if int(*resultLength) <= cap(*buf) {
(*reflect.SliceHeader)(unsafe.Pointer(buf)).Len = int(*resultLength)
} else {
*buf = make([]byte, int(*resultLength))
}
continue
} else {
if !st.IsError() {
*buf = (*buf)[:int(*resultLength)]
}
return st
}
if !st.IsError() {
*buf = (*buf)[:int(*resultLength)]
}
return st
}
}

Expand Down
14 changes: 7 additions & 7 deletions load/load_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ import (

var (
loadErr error
loadAvg1M float64 = 0.0
loadAvg5M float64 = 0.0
loadAvg15M float64 = 0.0
loadAvg1M = 0.0
loadAvg5M = 0.0
loadAvg15M = 0.0
loadAvgMutex sync.RWMutex
loadAvgGoroutineOnce sync.Once
)
Expand All @@ -27,10 +27,10 @@ var (
// code https://github.com/giampaolo/psutil/blob/8415355c8badc9c94418b19bdf26e622f06f0cce/psutil/arch/windows/wmi.c
func loadAvgGoroutine(ctx context.Context) {
var (
samplingFrequency time.Duration = 5 * time.Second
loadAvgFactor1M float64 = 1 / math.Exp(samplingFrequency.Seconds()/time.Minute.Seconds())
loadAvgFactor5M float64 = 1 / math.Exp(samplingFrequency.Seconds()/(5*time.Minute).Seconds())
loadAvgFactor15M float64 = 1 / math.Exp(samplingFrequency.Seconds()/(15*time.Minute).Seconds())
samplingFrequency = 5 * time.Second
loadAvgFactor1M = 1 / math.Exp(samplingFrequency.Seconds()/time.Minute.Seconds())
loadAvgFactor5M = 1 / math.Exp(samplingFrequency.Seconds()/(5*time.Minute).Seconds())
loadAvgFactor15M = 1 / math.Exp(samplingFrequency.Seconds()/(15*time.Minute).Seconds())
currentLoad float64
)

Expand Down
33 changes: 17 additions & 16 deletions mem/mem_darwin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,39 +9,40 @@ import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestVirtualMemoryDarwin(t *testing.T) {
v, err := VirtualMemory()
assert.Nil(t, err)
require.NoError(t, err)

outBytes, err := invoke.Command("/usr/sbin/sysctl", "hw.memsize")
assert.Nil(t, err)
require.NoError(t, err)
outString := string(outBytes)
outString = strings.TrimSpace(outString)
outParts := strings.Split(outString, " ")
actualTotal, err := strconv.ParseInt(outParts[1], 10, 64)
assert.Nil(t, err)
require.NoError(t, err)
assert.Equal(t, uint64(actualTotal), v.Total)

assert.True(t, v.Available > 0)
assert.Positive(t, v.Available)
assert.Equal(t, v.Available, v.Free+v.Inactive, "%v", v)

assert.True(t, v.Used > 0)
assert.True(t, v.Used < v.Total)
assert.Positive(t, v.Used)
assert.Less(t, v.Used, v.Total)

assert.True(t, v.UsedPercent > 0)
assert.True(t, v.UsedPercent < 100)
assert.Positive(t, v.UsedPercent)
assert.Less(t, v.UsedPercent, 100.0)

assert.True(t, v.Free > 0)
assert.True(t, v.Free < v.Available)
assert.Positive(t, v.Free)
assert.Less(t, v.Free, v.Available)

assert.True(t, v.Active > 0)
assert.True(t, v.Active < v.Total)
assert.Positive(t, v.Active)
assert.Less(t, v.Active, v.Total)

assert.True(t, v.Inactive > 0)
assert.True(t, v.Inactive < v.Total)
assert.Positive(t, v.Inactive)
assert.Less(t, v.Inactive, v.Total)

assert.True(t, v.Wired > 0)
assert.True(t, v.Wired < v.Total)
assert.Positive(t, v.Wired)
assert.Less(t, v.Wired, v.Total)
}
3 changes: 2 additions & 1 deletion mem/mem_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ import (
"syscall"
"unsafe"

"github.com/shirou/gopsutil/v4/internal/common"
"golang.org/x/sys/windows"

"github.com/shirou/gopsutil/v4/internal/common"
)

var (
Expand Down
10 changes: 5 additions & 5 deletions net/net_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ func parseNetstatLine(line string) (stat *IOCountersStat, linkID *uint, err erro

if columns[0] == "Name" {
err = errNetstatHeader
return
return //nolint:nakedret //FIXME
}

// try to extract the numeric value from <Link#123>
if subMatch := netstatLinkRegexp.FindStringSubmatch(columns[2]); len(subMatch) == 2 {
numericValue, err = strconv.ParseUint(subMatch[1], 10, 64)
if err != nil {
return
return //nolint:nakedret //FIXME
}
linkIDUint := uint(numericValue)
linkID = &linkIDUint
Expand All @@ -51,7 +51,7 @@ func parseNetstatLine(line string) (stat *IOCountersStat, linkID *uint, err erro
}
if numberColumns < 11 || numberColumns > 13 {
err = fmt.Errorf("Line %q do have an invalid number of columns %d", line, numberColumns)
return
return //nolint:nakedret //FIXME
}

parsed := make([]uint64, 0, 7)
Expand All @@ -74,7 +74,7 @@ func parseNetstatLine(line string) (stat *IOCountersStat, linkID *uint, err erro
}

if numericValue, err = strconv.ParseUint(target, 10, 64); err != nil {
return
return //nolint:nakedret //FIXME
}
parsed = append(parsed, numericValue)
}
Expand All @@ -91,7 +91,7 @@ func parseNetstatLine(line string) (stat *IOCountersStat, linkID *uint, err erro
if len(parsed) == 7 {
stat.Dropout = parsed[6]
}
return
return //nolint:nakedret //FIXME
}

type netstatInterface struct {
Expand Down
2 changes: 1 addition & 1 deletion net/net_darwin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,5 +137,5 @@ func TestParseNetstatTruncated(t *testing.T) {

mapUsage := newMapInterfaceNameUsage(nsInterfaces)
assert.True(t, mapUsage.isTruncated())
assert.Equal(t, 3, len(mapUsage.notTruncated()), "en0, gif0 and stf0")
assert.Len(t, mapUsage.notTruncated(), 3, "en0, gif0 and stf0")
}
Loading
Loading