diff --git a/.golangci.yml b/.golangci.yml index 1867f739..23ecd450 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -3,6 +3,7 @@ linters: enable: - errorlint - forbidigo + - gocritic - godot - misspell - revive @@ -12,6 +13,20 @@ linters: forbid: - pattern: ^fmt\.Print.*$ msg: Do not commit print statements. + gocritic: + enable-all: true + disabled-checks: + - commentFormatting + - commentedOutCode + - deferInLoop + - filepathJoin + - hugeParam + - importShadow + - paramTypeCombine + - rangeValCopy + - tooManyResultsChecker + - unnamedResult + - whyNoLint godot: exclude: # Ignore "See: URL". diff --git a/arp.go b/arp.go index 2e533441..0c7e6c68 100644 --- a/arp.go +++ b/arp.go @@ -73,15 +73,16 @@ func parseARPEntries(data []byte) ([]ARPEntry, error) { columns := strings.Fields(line) width := len(columns) - if width == expectedHeaderWidth || width == 0 { + switch width { + case expectedHeaderWidth, 0: continue - } else if width == expectedDataWidth { + case expectedDataWidth: entry, err := parseARPEntry(columns) if err != nil { return []ARPEntry{}, fmt.Errorf("%w: Failed to parse ARP entry: %v: %w", ErrFileParse, entry, err) } entries = append(entries, entry) - } else { + default: return []ARPEntry{}, fmt.Errorf("%w: %d columns found, but expected %d: %w", ErrFileParse, width, expectedDataWidth, err) } diff --git a/bcache/get.go b/bcache/get.go index de018df0..7e28ebee 100644 --- a/bcache/get.go +++ b/bcache/get.go @@ -111,7 +111,7 @@ func parsePseudoFloat(str string) (float64, error) { // v4.12-rc3). // Restore the proper order: - fracPart = fracPart / 10.24 + fracPart /= 10.24 return intPart + fracPart, nil } diff --git a/buddyinfo.go b/buddyinfo.go index 83807500..85d61bcc 100644 --- a/buddyinfo.go +++ b/buddyinfo.go @@ -64,10 +64,8 @@ func parseBuddyInfo(r io.Reader) ([]BuddyInfo, error) { if bucketCount == -1 { bucketCount = arraySize - } else { - if bucketCount != arraySize { - return nil, fmt.Errorf("%w: mismatch in number of buddyinfo buckets, previous count %d, new count %d", ErrFileParse, bucketCount, arraySize) - } + } else if bucketCount != arraySize { + return nil, fmt.Errorf("%w: mismatch in number of buddyinfo buckets, previous count %d, new count %d", ErrFileParse, bucketCount, arraySize) } sizes := make([]float64, arraySize) diff --git a/fscache.go b/fscache.go index 7db86330..d0011006 100644 --- a/fscache.go +++ b/fscache.go @@ -388,20 +388,21 @@ func parseFscacheinfo(r io.Reader) (*Fscacheinfo, error) { } } case "CacheOp:": - if strings.Split(fields[1], "=")[0] == "alo" { + switch strings.Split(fields[1], "=")[0] { + case "alo": err := setFSCacheFields(fields[1:], &m.CacheopAllocationsinProgress, &m.CacheopLookupObjectInProgress, &m.CacheopLookupCompleteInPorgress, &m.CacheopGrabObjectInProgress) if err != nil { return &m, err } - } else if strings.Split(fields[1], "=")[0] == "inv" { + case "inv": err := setFSCacheFields(fields[1:], &m.CacheopInvalidations, &m.CacheopUpdateObjectInProgress, &m.CacheopDropObjectInProgress, &m.CacheopPutObjectInProgress, &m.CacheopAttributeChangeInProgress, &m.CacheopSyncCacheInProgress) if err != nil { return &m, err } - } else { + default: err := setFSCacheFields(fields[1:], &m.CacheopReadOrAllocPageInProgress, &m.CacheopReadOrAllocPagesInProgress, &m.CacheopAllocatePageInProgress, &m.CacheopAllocatePagesInProgress, &m.CacheopWritePagesInProgress, &m.CacheopUncachePagesInProgress, &m.CacheopDissociatePagesInProgress) diff --git a/iscsi/get.go b/iscsi/get.go index 1a77c8c5..f0bb9a86 100644 --- a/iscsi/get.go +++ b/iscsi/get.go @@ -208,7 +208,7 @@ func (fs FS) GetRBDMatch(rbdNumber string, poolImage string) (*RBD, error) { } systemImage = strings.TrimSpace(string(bSystemImage)) - if strings.Compare(strconv.FormatInt(int64(systemRbdNumber), 10), rbdNumber) == 0 && + if strconv.FormatInt(int64(systemRbdNumber), 10) == rbdNumber && matchPoolImage(systemPool, systemImage, poolImage) { rbd.Pool = systemPool rbd.Image = systemImage @@ -241,5 +241,5 @@ func (fs FS) GetRDMCPPath(rdmcpNumber string, objectName string) (*RDMCP, error) func matchPoolImage(pool string, image string, matchPoolImage string) (isEqual bool) { var poolImage = fmt.Sprintf("%s-%s", pool, image) - return strings.Compare(poolImage, matchPoolImage) == 0 + return poolImage == matchPoolImage } diff --git a/mdstat.go b/mdstat.go index 1fd4381b..6a0c0de1 100644 --- a/mdstat.go +++ b/mdstat.go @@ -129,13 +129,14 @@ func parseMDStat(mdStatData []byte) ([]MDStat, error) { // Append recovery and resyncing state info. if recovering || resyncing || checking || reshaping { - if recovering { + switch { + case recovering: state = "recovering" - } else if reshaping { + case reshaping: state = "reshaping" - } else if checking { + case checking: state = "checking" - } else { + default: state = "resyncing" } diff --git a/proc_cgroups.go b/proc_cgroups.go index 5dd49389..e93a466a 100644 --- a/proc_cgroups.go +++ b/proc_cgroups.go @@ -40,13 +40,13 @@ type CgroupSummary struct { // parseCgroupSummary parses each line of the /proc/cgroup file // Line format is `subsys_name hierarchy num_cgroups enabled`. -func parseCgroupSummaryString(CgroupSummaryStr string) (*CgroupSummary, error) { +func parseCgroupSummaryString(cgroupSummaryStr string) (*CgroupSummary, error) { var err error - fields := strings.Fields(CgroupSummaryStr) + fields := strings.Fields(cgroupSummaryStr) // require at least 4 fields if len(fields) < 4 { - return nil, fmt.Errorf("%w: 4+ fields required, found %d fields in cgroup info string: %s", ErrFileParse, len(fields), CgroupSummaryStr) + return nil, fmt.Errorf("%w: 4+ fields required, found %d fields in cgroup info string: %s", ErrFileParse, len(fields), cgroupSummaryStr) } CgroupSummary := &CgroupSummary{ diff --git a/proc_fdinfo.go b/proc_fdinfo.go index fa761b35..594616cd 100644 --- a/proc_fdinfo.go +++ b/proc_fdinfo.go @@ -60,15 +60,16 @@ func (p Proc) FDInfo(fd string) (*ProcFDInfo, error) { scanner := bufio.NewScanner(bytes.NewReader(data)) for scanner.Scan() { text = scanner.Text() - if rPos.MatchString(text) { + switch { + case rPos.MatchString(text): pos = rPos.FindStringSubmatch(text)[1] - } else if rFlags.MatchString(text) { + case rFlags.MatchString(text): flags = rFlags.FindStringSubmatch(text)[1] - } else if rMntID.MatchString(text) { + case rMntID.MatchString(text): mntid = rMntID.FindStringSubmatch(text)[1] - } else if rIno.MatchString(text) { + case rIno.MatchString(text): ino = rIno.FindStringSubmatch(text)[1] - } else if rInotify.MatchString(text) { + case rInotify.MatchString(text): newInotify, err := parseInotifyInfo(text) if err != nil { return nil, err diff --git a/proc_limits.go b/proc_limits.go index 9530b14b..79a4b94b 100644 --- a/proc_limits.go +++ b/proc_limits.go @@ -74,7 +74,7 @@ const ( ) var ( - limitsMatch = regexp.MustCompile(`(Max \w+\s{0,1}?\w*\s{0,1}\w*)\s{2,}(\w+)\s+(\w+)`) + limitsMatch = regexp.MustCompile(`(Max \w+\s??\w*\s?\w*)\s{2,}(\w+)\s+(\w+)`) ) // NewLimits returns the current soft limits of the process. diff --git a/sysfs/class_sas_device.go b/sysfs/class_sas_device.go index 644cdc08..5bfc2a44 100644 --- a/sysfs/class_sas_device.go +++ b/sysfs/class_sas_device.go @@ -42,7 +42,7 @@ type SASDeviceClass map[string]*SASDevice var ( sasTargetDeviceRegexp = regexp.MustCompile(`^target[0-9:]+$`) - sasTargetSubDeviceRegexp = regexp.MustCompile(`[0-9]+:.*`) + sasTargetSubDeviceRegexp = regexp.MustCompile(`\d+:.*`) ) // sasDeviceClasses reads all of the SAS devices from a specific set diff --git a/sysfs/class_scsitape.go b/sysfs/class_scsitape.go index 7355d64a..e2505250 100644 --- a/sysfs/class_scsitape.go +++ b/sysfs/class_scsitape.go @@ -59,10 +59,10 @@ func (fs FS) SCSITapeClass() (SCSITapeClass, error) { // There are n?st[0-9]+[a-b]? variants depending on device features. // n/2 is probably overestimated but never underestimated stc := make(SCSITapeClass, len(dirs)/2) - validDevice := regexp.MustCompile(`^st[0-9]+$`) + validDevice := regexp.MustCompile(`^st\d+$`) for _, d := range dirs { - if !validDevice.Match([]byte(d.Name())) { + if !validDevice.MatchString(d.Name()) { continue } tape, err := fs.parseSCSITape(d.Name()) diff --git a/sysfs/class_thermal.go b/sysfs/class_thermal.go index 19706c0b..7bf67762 100644 --- a/sysfs/class_thermal.go +++ b/sysfs/class_thermal.go @@ -86,11 +86,12 @@ func parseClassThermalZone(zone string) (ClassThermalZoneStats, error) { var zonePassive *uint64 passive, err := util.SysReadUintFromFile(filepath.Join(zone, "passive")) - if os.IsNotExist(err) || os.IsPermission(err) { + switch { + case os.IsNotExist(err), os.IsPermission(err): zonePassive = nil - } else if err != nil { + case err != nil: return ClassThermalZoneStats{}, err - } else { + default: zonePassive = &passive } diff --git a/sysfs/net_class.go b/sysfs/net_class.go index 20a06122..4ab27241 100644 --- a/sysfs/net_class.go +++ b/sysfs/net_class.go @@ -125,15 +125,16 @@ func (fs FS) NetClass() (NetClass, error) { func canIgnoreError(err error) bool { var errno syscall.Errno - if os.IsNotExist(err) { + switch { + case os.IsNotExist(err): return true - } else if os.IsPermission(err) { + case os.IsPermission(err): return true - } else if err.Error() == "operation not supported" { + case err.Error() == "operation not supported": return true - } else if errors.Is(err, os.ErrInvalid) { + case errors.Is(err, os.ErrInvalid): return true - } else if errors.As(err, &errno) && (errno == syscall.EINVAL) { + case errors.As(err, &errno) && (errno == syscall.EINVAL): return true } // all other errors are fatal diff --git a/sysfs/net_class_ecn.go b/sysfs/net_class_ecn.go index 51d93e73..48b839d5 100644 --- a/sysfs/net_class_ecn.go +++ b/sysfs/net_class_ecn.go @@ -284,11 +284,12 @@ func ParseRoceRpEcnAttribute(ecnPath string, attrName string, ecn *RoceRpEcn) er vp := util.NewValueParser(value) switch attrName { case "clamp_tgt_rate": - if *vp.PUInt64() == 0 { + switch *vp.PUInt64() { + case 0: ecn.ClampTgtRate = false - } else if *vp.PUInt64() == 1 { + case 1: ecn.ClampTgtRate = true - } else { + default: return fmt.Errorf("failed to parse file %q: %w", attrPath, err) } case "dce_tcp_g": diff --git a/sysfs/system_cpu.go b/sysfs/system_cpu.go index a4b2c9ea..e91804d1 100644 --- a/sysfs/system_cpu.go +++ b/sysfs/system_cpu.go @@ -172,11 +172,12 @@ func binSearch(elem uint16, elemSlice *[]uint16) bool { for start <= end { mid = (start + end) / 2 - if (*elemSlice)[mid] == elem { + switch { + case (*elemSlice)[mid] == elem: return true - } else if (*elemSlice)[mid] > elem { + case (*elemSlice)[mid] > elem: end = mid - 1 - } else if (*elemSlice)[mid] < elem { + case (*elemSlice)[mid] < elem: start = mid + 1 } } @@ -254,7 +255,8 @@ func (fs FS) SystemCpufreq() ([]SystemCPUCpufreqStats, error) { }) } - if err = g.Wait(); err != nil { + err = g.Wait() + if err != nil { return nil, err } @@ -364,7 +366,7 @@ func parseCpufreqCpuinfo(cpuPath string) (*SystemCPUCpufreqStats, error) { fields[0] = strings.TrimSuffix(fields[0], ":") cpuinfoTransitionTableRow := make([]uint64, len(fields)) for i := range fields { - if len(fields[i]) == 0 { + if fields[i] == "" { continue } f, err := strconv.ParseUint(fields[i], 10, 64) diff --git a/sysfs/vmstat_numa.go b/sysfs/vmstat_numa.go index 038a0ee3..f61d0345 100644 --- a/sysfs/vmstat_numa.go +++ b/sysfs/vmstat_numa.go @@ -30,7 +30,7 @@ import ( var ( nodePattern = "devices/system/node/node[0-9]*" - nodeNumberRegexp = regexp.MustCompile(`.*devices/system/node/node([0-9]*)`) + nodeNumberRegexp = regexp.MustCompile(`.*devices/system/node/node(\d*)`) ) type VMStat struct {