Merge pull request #450 from thaJeztah/fix_linting

update actions, and fix linting issues
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 7adfc93..18f4425 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -1,26 +1,31 @@
 name: CI
 
-on:
-  push:
-    branches: [master]
-  pull_request:
+on: [push, pull_request]
+
+# Default to 'contents: read', which grants actions to read commits. Any
+# permission not included is implicitly set to "none".
+#
+# see https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions
+permissions:
+  contents: read
 
 jobs:
   test:
     name: Test
     runs-on: ubuntu-latest
+    timeout-minutes: 20 # guardrails timeout
 
     strategy:
       fail-fast: false
       matrix:
-        go: ["1.12", "1.21", "1.22", "1.23"]
+        go: ["1.12", "1.21", "1.22", "1.23", "oldstable", "stable"]
 
     steps:
       - name: Checkout repository
-        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+        uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
 
       - name: Set up Go
-        uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
+        uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
         with:
           go-version: ${{ matrix.go }}
 
@@ -32,17 +37,18 @@
   lint:
     name: Lint
     runs-on: ubuntu-latest
+    timeout-minutes: 20 # guardrails timeout
 
     steps:
       - name: Checkout repository
-        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+        uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
 
       - name: Set up Go
-        uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
+        uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
         with:
-          go-version: "1.23"
+          go-version: "stable"
 
       - name: Lint
-        uses: golangci/golangci-lint-action@971e284b6050e8a5849b72094c50ab08da042db8 # v6.1.1
+        uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9.2.0
         with:
-          version: v1.63.4
+          version: v2.7
diff --git a/.golangci.yaml b/.golangci.yaml
index b274f24..94ce2e0 100644
--- a/.golangci.yaml
+++ b/.golangci.yaml
@@ -1,4 +1,21 @@
+version: "2"
+
 linters:
-    disable-all: true
     enable:
+        - errorlint
         - nolintlint
+        - revive
+        - unconvert
+        - unparam
+    settings:
+        staticcheck:
+            # Enable all options, with some exceptions.
+            # For defaults, see https://golangci-lint.run/usage/linters/#staticcheck
+            checks:
+                - all
+                - -QF1008     # Omit embedded fields from selector expression; https://staticcheck.dev/docs/checks/#QF1008
+                - -ST1003     # Poorly chosen identifier; https://staticcheck.dev/docs/checks/#ST1003
+
+formatters:
+    enable:
+        - gofmt
diff --git a/bool_func_test.go b/bool_func_test.go
index 765c9c0..672d23a 100644
--- a/bool_func_test.go
+++ b/bool_func_test.go
@@ -50,7 +50,7 @@
 		// regular boolfunc flag:
 		// expect to see '--flag1' followed by the usageMessage, and no mention of a default value
 		fset := NewFlagSet("unittest", ContinueOnError)
-		fset.BoolFunc("flag1", "usage message", func(s string) error { return nil })
+		fset.BoolFunc("flag1", "usage message", func(string) error { return nil })
 		usage := fset.FlagUsagesWrapped(80)
 
 		usage = strings.TrimSpace(usage)
@@ -64,7 +64,7 @@
 		// func flag, with a placeholder name:
 		// if usageMesage contains a placeholder, expect '--flag2 {placeholder}'; still expect no mention of a default value
 		fset := NewFlagSet("unittest", ContinueOnError)
-		fset.BoolFunc("flag2", "usage message with `name` placeholder", func(s string) error { return nil })
+		fset.BoolFunc("flag2", "usage message with `name` placeholder", func(string) error { return nil })
 		usage := fset.FlagUsagesWrapped(80)
 
 		usage = strings.TrimSpace(usage)
diff --git a/bool_slice.go b/bool_slice.go
index 3731370..58a788d 100644
--- a/bool_slice.go
+++ b/bool_slice.go
@@ -22,13 +22,12 @@
 // Set converts, and assigns, the comma-separated boolean argument string representation as the []bool value of this flag.
 // If Set is called on a flag that already has a []bool assigned, the newly converted values will be appended.
 func (s *boolSliceValue) Set(val string) error {
-
 	// remove all quote characters
 	rmQuote := strings.NewReplacer(`"`, "", `'`, "", "`", "")
 
 	// read flag arguments with CSV parser
 	boolStrSlice, err := readAsCSV(rmQuote.Replace(val))
-	if err != nil && err != io.EOF {
+	if err != nil && err != io.EOF { //nolint:errorlint // not using errors.Is for compatibility with go1.12
 		return err
 	}
 
@@ -60,7 +59,6 @@
 
 // String defines a "native" format for this boolean slice flag value.
 func (s *boolSliceValue) String() string {
-
 	boolStrSlice := make([]string, len(*s.value))
 	for i, b := range *s.value {
 		boolStrSlice[i] = strconv.FormatBool(b)
diff --git a/bool_slice_test.go b/bool_slice_test.go
index 3c5a274..e6873b7 100644
--- a/bool_slice_test.go
+++ b/bool_slice_test.go
@@ -184,7 +184,6 @@
 }
 
 func TestBSBadQuoting(t *testing.T) {
-
 	tests := []struct {
 		Want    []bool
 		FlagArg []string
diff --git a/bool_test.go b/bool_test.go
index a4319e7..e3704fc 100644
--- a/bool_test.go
+++ b/bool_test.go
@@ -26,7 +26,7 @@
 }
 
 func (v *triStateValue) Get() interface{} {
-	return triStateValue(*v)
+	return *v
 }
 
 func (v *triStateValue) Set(s string) error {
diff --git a/bytes.go b/bytes.go
index 67d5304..1c10084 100644
--- a/bytes.go
+++ b/bytes.go
@@ -18,7 +18,6 @@
 // Set implements pflag.Value.Set.
 func (bytesHex *bytesHexValue) Set(value string) error {
 	bin, err := hex.DecodeString(strings.TrimSpace(value))
-
 	if err != nil {
 		return err
 	}
@@ -39,20 +38,18 @@
 }
 
 func bytesHexConv(sval string) (interface{}, error) {
-
 	bin, err := hex.DecodeString(sval)
 
 	if err == nil {
 		return bin, nil
 	}
 
-	return nil, fmt.Errorf("invalid string being converted to Bytes: %s %s", sval, err)
+	return nil, fmt.Errorf("invalid string being converted to Bytes: %s %s", sval, err.Error())
 }
 
 // GetBytesHex return the []byte value of a flag with the given name
 func (f *FlagSet) GetBytesHex(name string) ([]byte, error) {
 	val, err := f.getFlagType(name, "bytesHex", bytesHexConv)
-
 	if err != nil {
 		return []byte{}, err
 	}
@@ -119,7 +116,6 @@
 // Set implements pflag.Value.Set.
 func (bytesBase64 *bytesBase64Value) Set(value string) error {
 	bin, err := base64.StdEncoding.DecodeString(strings.TrimSpace(value))
-
 	if err != nil {
 		return err
 	}
@@ -140,19 +136,17 @@
 }
 
 func bytesBase64ValueConv(sval string) (interface{}, error) {
-
 	bin, err := base64.StdEncoding.DecodeString(sval)
 	if err == nil {
 		return bin, nil
 	}
 
-	return nil, fmt.Errorf("invalid string being converted to Bytes: %s %s", sval, err)
+	return nil, fmt.Errorf("invalid string being converted to Bytes: %s %s", sval, err.Error())
 }
 
 // GetBytesBase64 return the []byte value of a flag with the given name
 func (f *FlagSet) GetBytesBase64(name string) ([]byte, error) {
 	val, err := f.getFlagType(name, "bytesBase64", bytesBase64ValueConv)
-
 	if err != nil {
 		return []byte{}, err
 	}
diff --git a/count.go b/count.go
index d49c014..521b5d2 100644
--- a/count.go
+++ b/count.go
@@ -13,7 +13,7 @@
 func (i *countValue) Set(s string) error {
 	// "+1" means that no specific value was passed, so increment
 	if s == "+1" {
-		*i = countValue(*i + 1)
+		*i = *i + 1
 		return nil
 	}
 	v, err := strconv.ParseInt(s, 0, 0)
diff --git a/duration_slice.go b/duration_slice.go
index badadda..ee98727 100644
--- a/duration_slice.go
+++ b/duration_slice.go
@@ -1,7 +1,6 @@
 package pflag
 
 import (
-	"fmt"
 	"strings"
 	"time"
 )
@@ -46,7 +45,7 @@
 func (s *durationSliceValue) String() string {
 	out := make([]string, len(*s.value))
 	for i, d := range *s.value {
-		out[i] = fmt.Sprintf("%s", d)
+		out[i] = d.String()
 	}
 	return "[" + strings.Join(out, ",") + "]"
 }
@@ -56,7 +55,7 @@
 }
 
 func (s *durationSliceValue) toString(val time.Duration) string {
-	return fmt.Sprintf("%s", val)
+	return val.String()
 }
 
 func (s *durationSliceValue) Append(val string) error {
diff --git a/errors.go b/errors.go
index 5d32c13..63765dd 100644
--- a/errors.go
+++ b/errors.go
@@ -138,7 +138,7 @@
 	return fmt.Sprintf("bad flag syntax: %s", e.specifiedFlag)
 }
 
-// GetSpecifiedName returns the exact flag (with dashes) as it
+// GetSpecifiedFlag returns the exact flag (with dashes) as it
 // appeared in the parsed arguments.
 func (e *InvalidSyntaxError) GetSpecifiedFlag() string {
 	return e.specifiedFlag
diff --git a/errors_test.go b/errors_test.go
index 7b4c7a4..11012f8 100644
--- a/errors_test.go
+++ b/errors_test.go
@@ -51,8 +51,8 @@
 	if err.GetValue() != "foo" {
 		t.Errorf("Expected GetValue to return %q, got %q", "foo", err.GetValue())
 	}
-	if err.Unwrap() != expectedCause {
-		t.Errorf("Expected Unwrwap to return %q, got %q", expectedCause, err.Unwrap())
+	if actual := err.Unwrap(); actual != expectedCause { //nolint:errorlint // not using errors.Is for compatibility with go1.12
+		t.Errorf("Expected Unwrwap to return %q, got %q", expectedCause, actual)
 	}
 }
 
diff --git a/flag.go b/flag.go
index d0d6e5d..dc47fff 100644
--- a/flag.go
+++ b/flag.go
@@ -270,7 +270,7 @@
 	if f.normalizeNameFunc != nil {
 		return f.normalizeNameFunc
 	}
-	return func(f *FlagSet, name string) NormalizedName { return NormalizedName(name) }
+	return func(_ *FlagSet, name string) NormalizedName { return NormalizedName(name) }
 }
 
 func (f *FlagSet) normalizeFlagName(name string) NormalizedName {
@@ -388,7 +388,7 @@
 	}
 	if len(name) > 1 {
 		msg := fmt.Sprintf("can not look up shorthand which is more than one ASCII character: %q", name)
-		fmt.Fprint(f.Output(), msg)
+		_, _ = fmt.Fprint(f.Output(), msg)
 		panic(msg)
 	}
 	c := name[0]
@@ -519,7 +519,7 @@
 	}
 
 	if flag.Deprecated != "" {
-		fmt.Fprintf(f.Output(), "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
+		_, _ = fmt.Fprintf(f.Output(), "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
 	}
 	return nil
 }
@@ -560,7 +560,7 @@
 // otherwise, the default values of all defined flags in the set.
 func (f *FlagSet) PrintDefaults() {
 	usages := f.FlagUsages()
-	fmt.Fprint(f.Output(), usages)
+	_, _ = fmt.Fprint(f.Output(), usages)
 }
 
 // defaultIsZeroValue returns true if the default value for this flag represents
@@ -666,7 +666,7 @@
 // caller). Pass `w` == 0 to do no wrapping
 func wrap(i, w int, s string) string {
 	if w == 0 {
-		return strings.Replace(s, "\n", "\n"+strings.Repeat(" ", i), -1)
+		return strings.ReplaceAll(s, "\n", "\n"+strings.Repeat(" ", i))
 	}
 
 	// space between indent i and end of line width w into which
@@ -684,7 +684,7 @@
 	}
 	// If still not enough space then don't even try to wrap.
 	if wrap < 24 {
-		return strings.Replace(s, "\n", r, -1)
+		return strings.ReplaceAll(s, "\n", r)
 	}
 
 	// Try to avoid short orphan words on the final line, by
@@ -696,18 +696,17 @@
 	// Handle first line, which is indented by the caller (or the
 	// special case above)
 	l, s = wrapN(wrap, slop, s)
-	r = r + strings.Replace(l, "\n", "\n"+strings.Repeat(" ", i), -1)
+	r = r + strings.ReplaceAll(l, "\n", "\n"+strings.Repeat(" ", i))
 
 	// Now wrap the rest
 	for s != "" {
 		var t string
 
 		t, s = wrapN(wrap, slop, s)
-		r = r + "\n" + strings.Repeat(" ", i) + strings.Replace(t, "\n", "\n"+strings.Repeat(" ", i), -1)
+		r = r + "\n" + strings.Repeat(" ", i) + strings.ReplaceAll(t, "\n", "\n"+strings.Repeat(" ", i))
 	}
 
 	return r
-
 }
 
 // FlagUsagesWrapped returns a string containing the usage information
@@ -781,7 +780,7 @@
 		sidx := strings.Index(line, "\x00")
 		spacing := strings.Repeat(" ", maxlen-sidx)
 		// maxlen + 2 comes from + 1 for the \x00 and + 1 for the (deliberate) off-by-one in maxlen-sidx
-		fmt.Fprintln(buf, line[:sidx], spacing, wrap(maxlen+2, cols, line[sidx+1:]))
+		_, _ = fmt.Fprintln(buf, line[:sidx], spacing, wrap(maxlen+2, cols, line[sidx+1:]))
 	}
 
 	return buf.String()
@@ -800,7 +799,7 @@
 
 // defaultUsage is the default function to print a usage message.
 func defaultUsage(f *FlagSet) {
-	fmt.Fprintf(f.Output(), "Usage of %s:\n", f.name)
+	_, _ = fmt.Fprintf(f.Output(), "Usage of %s:\n", f.name)
 	f.PrintDefaults()
 }
 
@@ -813,7 +812,7 @@
 // By default it prints a simple header and calls PrintDefaults; for details about the
 // format of the output and how to control it, see the documentation for PrintDefaults.
 var Usage = func() {
-	fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
+	_, _ = fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
 	PrintDefaults()
 }
 
@@ -886,7 +885,7 @@
 	_, alreadyThere := f.formal[normalizedFlagName]
 	if alreadyThere {
 		msg := fmt.Sprintf("%s flag redefined: %s", f.name, flag.Name)
-		fmt.Fprintln(f.Output(), msg)
+		_, _ = fmt.Fprintln(f.Output(), msg)
 		panic(msg) // Happens only if flags are declared with identical names
 	}
 	if f.formal == nil {
@@ -902,7 +901,7 @@
 	}
 	if len(flag.Shorthand) > 1 {
 		msg := fmt.Sprintf("%q shorthand is more than one ASCII character", flag.Shorthand)
-		fmt.Fprint(f.Output(), msg)
+		_, _ = fmt.Fprint(f.Output(), msg)
 		panic(msg)
 	}
 	if f.shorthands == nil {
@@ -912,7 +911,7 @@
 	used, alreadyThere := f.shorthands[c]
 	if alreadyThere {
 		msg := fmt.Sprintf("unable to redefine %q shorthand in %q flagset: it's already used for %q flag", c, f.name, used.Name)
-		fmt.Fprint(f.Output(), msg)
+		_, _ = fmt.Fprint(f.Output(), msg)
 		panic(msg)
 	}
 	f.shorthands[c] = flag
@@ -972,17 +971,17 @@
 // --unknown arg ... (args will be arg ...)
 func stripUnknownFlagValue(args []string) []string {
 	if len(args) == 0 {
-		//--unknown
+		// --unknown
 		return args
 	}
 
 	first := args[0]
 	if len(first) > 0 && first[0] == '-' {
-		//--unknown --next-flag ...
+		// --unknown --next-flag ...
 		return args
 	}
 
-	//--unknown arg ... (args will be arg ...)
+	// --unknown arg ... (args will be arg ...)
 	if len(args) > 1 {
 		return args[1:]
 	}
@@ -1044,7 +1043,7 @@
 
 	err = fn(flag, value)
 	if err != nil {
-		f.fail(err)
+		err = f.fail(err)
 	}
 	return
 }
@@ -1115,12 +1114,12 @@
 	}
 
 	if flag.ShorthandDeprecated != "" {
-		fmt.Fprintf(f.Output(), "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated)
+		_, _ = fmt.Fprintf(f.Output(), "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated)
 	}
 
 	err = fn(flag, value)
 	if err != nil {
-		f.fail(err)
+		err = f.fail(err)
 	}
 	return
 }
@@ -1178,7 +1177,7 @@
 func (f *FlagSet) Parse(arguments []string) error {
 	if f.addedGoFlagSets != nil {
 		for _, goFlagSet := range f.addedGoFlagSets {
-			goFlagSet.Parse(nil)
+			_ = goFlagSet.Parse(nil)
 		}
 	}
 	f.parsed = true
@@ -1199,10 +1198,10 @@
 		case ContinueOnError:
 			return err
 		case ExitOnError:
-			if err == ErrHelp {
+			if err == ErrHelp { //nolint:errorlint // not using errors.Is for compatibility with go1.12
 				os.Exit(0)
 			}
-			fmt.Fprintln(f.Output(), err)
+			_, _ = fmt.Fprintln(f.Output(), err)
 			os.Exit(2)
 		case PanicOnError:
 			panic(err)
@@ -1228,10 +1227,10 @@
 		case ContinueOnError:
 			return err
 		case ExitOnError:
-			if err == ErrHelp {
+			if err == ErrHelp { //nolint:errorlint // not using errors.Is for compatibility with go1.12
 				os.Exit(0)
 			}
-			fmt.Fprintln(f.Output(), err)
+			_, _ = fmt.Fprintln(f.Output(), err)
 			os.Exit(2)
 		case PanicOnError:
 			panic(err)
@@ -1249,7 +1248,7 @@
 // after all flags are defined and before flags are accessed by the program.
 func Parse() {
 	// Ignore errors; CommandLine is set for ExitOnError.
-	CommandLine.Parse(os.Args[1:])
+	_ = CommandLine.Parse(os.Args[1:])
 }
 
 // ParseAll parses the command-line flags from os.Args[1:] and called fn for each.
@@ -1257,7 +1256,7 @@
 // defined and before flags are accessed by the program.
 func ParseAll(fn func(flag *Flag, value string) error) {
 	// Ignore errors; CommandLine is set for ExitOnError.
-	CommandLine.ParseAll(os.Args[1:], fn)
+	_ = CommandLine.ParseAll(os.Args[1:], fn)
 }
 
 // SetInterspersed sets whether to support interspersed option/non-option arguments.
diff --git a/flag_test.go b/flag_test.go
index c60e344..b367f7d 100644
--- a/flag_test.go
+++ b/flag_test.go
@@ -20,15 +20,16 @@
 )
 
 var (
-	testBool                     = Bool("test_bool", false, "bool value")
-	testInt                      = Int("test_int", 0, "int value")
-	testInt64                    = Int64("test_int64", 0, "int64 value")
-	testUint                     = Uint("test_uint", 0, "uint value")
-	testUint64                   = Uint64("test_uint64", 0, "uint64 value")
-	testString                   = String("test_string", "0", "string value")
-	testFloat                    = Float64("test_float64", 0, "float64 value")
-	testDuration                 = Duration("test_duration", 0, "time.Duration value")
-	testOptionalInt              = Int("test_optional_int", 0, "optional int value")
+	_ = Bool("test_bool", false, "bool value")
+	_ = Int("test_int", 0, "int value")
+	_ = Int64("test_int64", 0, "int64 value")
+	_ = Uint("test_uint", 0, "uint value")
+	_ = Uint64("test_uint64", 0, "uint64 value")
+	_ = String("test_string", "0", "string value")
+	_ = Float64("test_float64", 0, "float64 value")
+	_ = Duration("test_duration", 0, "time.Duration value")
+	_ = Int("test_optional_int", 0, "optional int value")
+
 	normalizeFlagNameInvocations = 0
 )
 
@@ -75,15 +76,33 @@
 		}
 	}
 	// Now set all flags
-	Set("test_bool", "true")
-	Set("test_int", "1")
-	Set("test_int64", "1")
-	Set("test_uint", "1")
-	Set("test_uint64", "1")
-	Set("test_string", "1")
-	Set("test_float64", "1")
-	Set("test_duration", "1s")
-	Set("test_optional_int", "1")
+	if err := Set("test_bool", "true"); err != nil {
+		t.Error(err)
+	}
+	if err := Set("test_int", "1"); err != nil {
+		t.Error(err)
+	}
+	if err := Set("test_int64", "1"); err != nil {
+		t.Error(err)
+	}
+	if err := Set("test_uint", "1"); err != nil {
+		t.Error(err)
+	}
+	if err := Set("test_uint64", "1"); err != nil {
+		t.Error(err)
+	}
+	if err := Set("test_string", "1"); err != nil {
+		t.Error(err)
+	}
+	if err := Set("test_float64", "1"); err != nil {
+		t.Error(err)
+	}
+	if err := Set("test_duration", "1s"); err != nil {
+		t.Error(err)
+	}
+	if err := Set("test_optional_int", "1"); err != nil {
+		t.Error(err)
+	}
 	desired = "1"
 	Visit(visitor)
 	if len(m) != 9 {
@@ -620,7 +639,7 @@
 	}
 	flag := f.ShorthandLookup("a")
 	if flag == nil {
-		t.Errorf("f.ShorthandLookup(\"a\") returned nil")
+		t.Fatal("f.ShorthandLookup(\"a\") returned nil")
 	}
 	if flag.Name != "boola" {
 		t.Errorf("f.ShorthandLookup(\"a\") found %q instead of \"boola\"", flag.Name)
@@ -630,9 +649,9 @@
 		t.Errorf("f.ShorthandLookup(\"\") did not return nil")
 	}
 	defer func() {
-		recover()
+		_ = recover()
 	}()
-	flag = f.ShorthandLookup("ab")
+	_ = f.ShorthandLookup("ab")
 	// should NEVER get here. lookup should panic. defer'd func should recover it.
 	t.Errorf("f.ShorthandLookup(\"ab\") did not panic")
 }
@@ -732,18 +751,18 @@
 	}
 }
 
-func replaceSeparators(name string, from []string, to string) string {
+func toDotSeparated(name string, from []string) string {
 	result := name
 	for _, sep := range from {
-		result = strings.Replace(result, sep, to, -1)
+		result = strings.ReplaceAll(result, sep, ".")
 	}
 	// Type convert to indicate normalization has been done.
 	return result
 }
 
-func wordSepNormalizeFunc(f *FlagSet, name string) NormalizedName {
+func wordSepNormalizeFunc(_ *FlagSet, name string) NormalizedName {
 	seps := []string{"-", "_"}
-	name = replaceSeparators(name, seps, ".")
+	name = toDotSeparated(name, seps)
 	normalizeFlagNameInvocations++
 
 	return NormalizedName(name)
@@ -799,13 +818,13 @@
 	testWordSepNormalizedNames(args, t)
 }
 
-func aliasAndWordSepFlagNames(f *FlagSet, name string) NormalizedName {
+func aliasAndWordSepFlagNames(_ *FlagSet, name string) NormalizedName {
 	seps := []string{"-", "_"}
 
-	oldName := replaceSeparators("old-valid_flag", seps, ".")
-	newName := replaceSeparators("valid-flag", seps, ".")
+	oldName := toDotSeparated("old-valid_flag", seps)
+	newName := toDotSeparated("valid-flag", seps)
 
-	name = replaceSeparators(name, seps, ".")
+	name = toDotSeparated(name, seps)
 	switch name {
 	case oldName:
 		name = newName
@@ -906,7 +925,9 @@
 	}
 
 	f.Bool(testName, false, "bool value")
-	f.Set(testName, "true")
+	if err := f.Set(testName, "true"); err != nil {
+		t.Error(err)
+	}
 	f.SetNormalizeFunc(nfunc)
 
 	if len(f.formal) != 1 {
@@ -964,7 +985,12 @@
 	var buf bytes.Buffer
 	flags.SetOutput(&buf)
 	flags.Init("test", ContinueOnError)
-	flags.Parse([]string{"--unknown"})
+
+	expectedErr := "unknown flag: --unknown"
+	err := flags.Parse([]string{"--unknown"})
+	if err == nil || err.Error() != expectedErr {
+		t.Errorf("expected error %q got %v", expectedErr, err)
+	}
 	if out := buf.String(); !strings.Contains(out, "--unknown") {
 		t.Logf("expected output mentioning unknown; got %q", out)
 	}
@@ -975,7 +1001,7 @@
 	var buf bytes.Buffer
 	expect := "an example string"
 	flags.SetOutput(&buf)
-	fmt.Fprint(flags.Output(), expect)
+	_, _ = fmt.Fprint(flags.Output(), expect)
 	if out := buf.String(); !strings.Contains(out, expect) {
 		t.Errorf("expected output %q; got %q", expect, out)
 	}
@@ -1027,7 +1053,7 @@
 	if err == nil {
 		t.Fatal("error expected")
 	}
-	if err != ErrHelp {
+	if err != ErrHelp { //nolint:errorlint // not using errors.Is for compatibility with go1.12
 		t.Fatal("expected ErrHelp; got ", err)
 	}
 	if !helpCalled {
@@ -1101,7 +1127,7 @@
 func getDeprecatedFlagSet() *FlagSet {
 	f := NewFlagSet("bob", ContinueOnError)
 	f.Bool("badflag", true, "always true")
-	f.MarkDeprecated("badflag", "use --good-flag instead")
+	_ = f.MarkDeprecated("badflag", "use --good-flag instead")
 	return f
 }
 
@@ -1142,7 +1168,7 @@
 	f := NewFlagSet("bob", ContinueOnError)
 	name := "noshorthandflag"
 	f.BoolP(name, "n", true, "always true")
-	f.MarkShorthandDeprecated("noshorthandflag", fmt.Sprintf("use --%s instead", name))
+	_ = f.MarkShorthandDeprecated("noshorthandflag", fmt.Sprintf("use --%s instead", name))
 
 	out := new(bytes.Buffer)
 	f.SetOutput(out)
@@ -1154,6 +1180,7 @@
 }
 
 func parseReturnStderr(t *testing.T, f *FlagSet, args []string) (string, error) {
+	t.Helper()
 	oldStderr := os.Stderr
 	r, w, _ := os.Pipe()
 	os.Stderr = w
@@ -1164,11 +1191,11 @@
 	// copy the output in a separate goroutine so printing can't block indefinitely
 	go func() {
 		var buf bytes.Buffer
-		io.Copy(&buf, r)
+		_, _ = io.Copy(&buf, r)
 		outC <- buf.String()
 	}()
 
-	w.Close()
+	_ = w.Close()
 	os.Stderr = oldStderr
 	out := <-outC
 
@@ -1179,7 +1206,7 @@
 	f := NewFlagSet("bob", ContinueOnError)
 	f.Bool("badflag", true, "always true")
 	usageMsg := "use --good-flag instead"
-	f.MarkDeprecated("badflag", usageMsg)
+	_ = f.MarkDeprecated("badflag", usageMsg)
 
 	args := []string{"--badflag"}
 	out, err := parseReturnStderr(t, f, args)
@@ -1197,7 +1224,7 @@
 	name := "noshorthandflag"
 	f.BoolP(name, "n", true, "always true")
 	usageMsg := fmt.Sprintf("use --%s instead", name)
-	f.MarkShorthandDeprecated(name, usageMsg)
+	_ = f.MarkShorthandDeprecated(name, usageMsg)
 
 	args := []string{"-n"}
 	out, err := parseReturnStderr(t, f, args)
@@ -1215,7 +1242,7 @@
 	f.Bool("bad-double_flag", true, "always true")
 	f.SetNormalizeFunc(wordSepNormalizeFunc)
 	usageMsg := "use --good-flag instead"
-	f.MarkDeprecated("bad_double-flag", usageMsg)
+	_ = f.MarkDeprecated("bad_double-flag", usageMsg)
 
 	args := []string{"--bad_double_flag"}
 	out, err := parseReturnStderr(t, f, args)
@@ -1244,7 +1271,7 @@
 func TestHiddenFlagInUsage(t *testing.T) {
 	f := NewFlagSet("bob", ContinueOnError)
 	f.Bool("secretFlag", true, "shhh")
-	f.MarkHidden("secretFlag")
+	_ = f.MarkHidden("secretFlag")
 
 	out := new(bytes.Buffer)
 	f.SetOutput(out)
@@ -1258,7 +1285,7 @@
 func TestHiddenFlagUsage(t *testing.T) {
 	f := NewFlagSet("bob", ContinueOnError)
 	f.Bool("secretFlag", true, "shhh")
-	f.MarkHidden("secretFlag")
+	_ = f.MarkHidden("secretFlag")
 
 	args := []string{"--secretFlag"}
 	out, err := parseReturnStderr(t, f, args)
@@ -1360,7 +1387,7 @@
 	fs := NewFlagSet("TestVisitAllFlagOrder", ContinueOnError)
 	fs.SortFlags = false
 	// https://github.com/spf13/pflag/issues/120
-	fs.SetNormalizeFunc(func(f *FlagSet, name string) NormalizedName {
+	fs.SetNormalizeFunc(func(_ *FlagSet, name string) NormalizedName {
 		return NormalizedName(name)
 	})
 
@@ -1384,7 +1411,9 @@
 	names := []string{"C", "B", "A", "D"}
 	for _, name := range names {
 		fs.Bool(name, false, "")
-		fs.Set(name, "true")
+		if err := fs.Set(name, "true"); err != nil {
+			t.Error(err)
+		}
 	}
 
 	i := 0
diff --git a/func_test.go b/func_test.go
index 4badf93..212b137 100644
--- a/func_test.go
+++ b/func_test.go
@@ -64,7 +64,7 @@
 		// regular func flag:
 		// expect to see '--flag1 value' followed by the usageMessage, and no mention of a default value
 		fset := NewFlagSet("unittest", ContinueOnError)
-		fset.Func("flag1", "usage message", func(s string) error { return nil })
+		fset.Func("flag1", "usage message", func(string) error { return nil })
 		usage := fset.FlagUsagesWrapped(80)
 
 		usage = strings.TrimSpace(usage)
@@ -78,7 +78,7 @@
 		// func flag, with a placeholder name:
 		// if usageMesage contains a placeholder, expect that name; still expect no mention of a default value
 		fset := NewFlagSet("unittest", ContinueOnError)
-		fset.Func("flag2", "usage message with `name` placeholder", func(s string) error { return nil })
+		fset.Func("flag2", "usage message with `name` placeholder", func(string) error { return nil })
 		usage := fset.FlagUsagesWrapped(80)
 
 		usage = strings.TrimSpace(usage)
diff --git a/golangflag.go b/golangflag.go
index 2059438..88a5c49 100644
--- a/golangflag.go
+++ b/golangflag.go
@@ -71,14 +71,14 @@
 // If the *flag.Flag.Name was a single character (ex: `v`) it will be accessiblei
 // with both `-v` and `--v` in flags. If the golang flag was more than a single
 // character (ex: `verbose`) it will only be accessible via `--verbose`
-func PFlagFromGoFlag(goflag *goflag.Flag) *Flag {
+func PFlagFromGoFlag(goflag *goflag.Flag) *Flag { //nolint:revive // ignore "func name will be used as pflag.PFlagFromGoFlag by other packages, and that stutters"
 	// Remember the default value as a string; it won't change.
 	flag := &Flag{
 		Name:  goflag.Name,
 		Usage: goflag.Usage,
 		Value: wrapFlagValue(goflag.Value),
 		// Looks like golang flags don't set DefValue correctly  :-(
-		//DefValue: goflag.DefValue,
+		// DefValue: goflag.DefValue,
 		DefValue: goflag.Value.String(),
 	}
 	// Ex: if the golang flag was -v, allow both -v and --v to work
diff --git a/golangflag_test.go b/golangflag_test.go
index 7309808..9ef6494 100644
--- a/golangflag_test.go
+++ b/golangflag_test.go
@@ -74,7 +74,7 @@
 	pfs.Duration("DurationFlag", time.Second, "Duration flag usage")
 	pfs.Bool("BoolFlag", true, "Bool flag usage")
 	pfs.String("deprecated", "Deprecated value", "Deprecated flag usage")
-	pfs.MarkDeprecated("deprecated", "obsolete")
+	_ = pfs.MarkDeprecated("deprecated", "obsolete")
 
 	pfs.CopyToGoFlagSet(&gfs)
 
diff --git a/ip_slice.go b/ip_slice.go
index 775faae..84fa418 100644
--- a/ip_slice.go
+++ b/ip_slice.go
@@ -23,13 +23,12 @@
 // Set converts, and assigns, the comma-separated IP argument string representation as the []net.IP value of this flag.
 // If Set is called on a flag that already has a []net.IP assigned, the newly converted values will be appended.
 func (s *ipSliceValue) Set(val string) error {
-
 	// remove all quote characters
 	rmQuote := strings.NewReplacer(`"`, "", `'`, "", "`", "")
 
 	// read flag arguments with CSV parser
 	ipStrSlice, err := readAsCSV(rmQuote.Replace(val))
-	if err != nil && err != io.EOF {
+	if err != nil && err != io.EOF { //nolint:errorlint // not using errors.Is for compatibility with go1.12
 		return err
 	}
 
@@ -61,7 +60,6 @@
 
 // String defines a "native" format for this net.IP slice flag value.
 func (s *ipSliceValue) String() string {
-
 	ipStrSlice := make([]string, len(*s.value))
 	for i, ip := range *s.value {
 		ipStrSlice[i] = ip.String()
@@ -72,8 +70,8 @@
 	return "[" + out + "]"
 }
 
-func (s *ipSliceValue) fromString(val string) (net.IP, error) {
-	return net.ParseIP(strings.TrimSpace(val)), nil
+func (s *ipSliceValue) fromString(val string) net.IP {
+	return net.ParseIP(strings.TrimSpace(val))
 }
 
 func (s *ipSliceValue) toString(val net.IP) string {
@@ -81,22 +79,14 @@
 }
 
 func (s *ipSliceValue) Append(val string) error {
-	i, err := s.fromString(val)
-	if err != nil {
-		return err
-	}
-	*s.value = append(*s.value, i)
+	*s.value = append(*s.value, s.fromString(val))
 	return nil
 }
 
 func (s *ipSliceValue) Replace(val []string) error {
 	out := make([]net.IP, len(val))
 	for i, d := range val {
-		var err error
-		out[i], err = s.fromString(d)
-		if err != nil {
-			return err
-		}
+		out[i] = s.fromString(d)
 	}
 	*s.value = out
 	return nil
diff --git a/ip_slice_test.go b/ip_slice_test.go
index d189276..366dc19 100644
--- a/ip_slice_test.go
+++ b/ip_slice_test.go
@@ -165,7 +165,6 @@
 }
 
 func TestIPSBadQuoting(t *testing.T) {
-
 	tests := []struct {
 		Want    []net.IP
 		FlagArg []string
@@ -222,7 +221,8 @@
 			},
 			FlagArg: []string{
 				`"2e5e:66b2:6441:848:5b74:76ea:574c:3a7b,        2e5e:66b2:6441:848:5b74:76ea:574c:3a7b,2e5e:66b2:6441:848:5b74:76ea:574c:3a7b     "`,
-				" 2e5e:66b2:6441:848:5b74:76ea:574c:3a7b"},
+				" 2e5e:66b2:6441:848:5b74:76ea:574c:3a7b",
+			},
 		},
 	}
 
diff --git a/ipnet_slice.go b/ipnet_slice.go
index c6e89da..c051fbd 100644
--- a/ipnet_slice.go
+++ b/ipnet_slice.go
@@ -23,13 +23,12 @@
 // Set converts, and assigns, the comma-separated IPNet argument string representation as the []net.IPNet value of this flag.
 // If Set is called on a flag that already has a []net.IPNet assigned, the newly converted values will be appended.
 func (s *ipNetSliceValue) Set(val string) error {
-
 	// remove all quote characters
 	rmQuote := strings.NewReplacer(`"`, "", `'`, "", "`", "")
 
 	// read flag arguments with CSV parser
 	ipNetStrSlice, err := readAsCSV(rmQuote.Replace(val))
-	if err != nil && err != io.EOF {
+	if err != nil && err != io.EOF { //nolint:errorlint // not using errors.Is for compatibility with go1.12
 		return err
 	}
 
@@ -61,7 +60,6 @@
 
 // String defines a "native" format for this net.IPNet slice flag value.
 func (s *ipNetSliceValue) String() string {
-
 	ipNetStrSlice := make([]string, len(*s.value))
 	for i, n := range *s.value {
 		ipNetStrSlice[i] = n.String()
diff --git a/ipnet_slice_test.go b/ipnet_slice_test.go
index 11644c5..5ac387d 100644
--- a/ipnet_slice_test.go
+++ b/ipnet_slice_test.go
@@ -8,15 +8,12 @@
 )
 
 // Helper function to set static slices
-func getCIDR(ip net.IP, cidr *net.IPNet, err error) net.IPNet {
+func getCIDR(_ net.IP, cidr *net.IPNet, _ error) net.IPNet {
 	return *cidr
 }
 
 func equalCIDR(c1 net.IPNet, c2 net.IPNet) bool {
-	if c1.String() == c2.String() {
-		return true
-	}
-	return false
+	return c1.String() == c2.String()
 }
 
 func setUpIPNetFlagSet(ipsp *[]net.IPNet) *FlagSet {
@@ -159,7 +156,6 @@
 }
 
 func TestIPNetBadQuoting(t *testing.T) {
-
 	tests := []struct {
 		Want    []net.IPNet
 		FlagArg []string
@@ -216,7 +212,8 @@
 			},
 			FlagArg: []string{
 				`"2e5e:66b2:6441:848:5b74:76ea:574c:3a7b/128,        2e5e:66b2:6441:848:5b74:76ea:574c:3a7b/128,2e5e:66b2:6441:848:5b74:76ea:574c:3a7b/128     "`,
-				" 2e5e:66b2:6441:848:5b74:76ea:574c:3a7b/128"},
+				" 2e5e:66b2:6441:848:5b74:76ea:574c:3a7b/128",
+			},
 		},
 	}
 
diff --git a/string.go b/string.go
index 04e0a26..c96b802 100644
--- a/string.go
+++ b/string.go
@@ -12,6 +12,7 @@
 	*s = stringValue(val)
 	return nil
 }
+
 func (s *stringValue) Type() string {
 	return "string"
 }
diff --git a/string_array.go b/string_array.go
index d1ff0a9..2404407 100644
--- a/string_array.go
+++ b/string_array.go
@@ -30,18 +30,14 @@
 
 func (s *stringArrayValue) Replace(val []string) error {
 	out := make([]string, len(val))
-	for i, d := range val {
-		out[i] = d
-	}
+	copy(out, val)
 	*s.value = out
 	return nil
 }
 
 func (s *stringArrayValue) GetSlice() []string {
 	out := make([]string, len(*s.value))
-	for i, d := range *s.value {
-		out[i] = d
-	}
+	copy(out, *s.value)
 	return out
 }
 
diff --git a/text.go b/text.go
index 886d5a3..bb057ac 100644
--- a/text.go
+++ b/text.go
@@ -42,8 +42,7 @@
 	return ""
 }
 
-//end of copy
-
+// end of copy
 func (v textValue) Type() string {
 	return reflect.ValueOf(v.p).Type().Name()
 }
diff --git a/text_test.go b/text_test.go
index e60c136..2889576 100644
--- a/text_test.go
+++ b/text_test.go
@@ -20,7 +20,7 @@
 		expected time.Time
 	}{
 		{"2003-01-02T15:04:05Z", true, time.Date(2003, 1, 2, 15, 04, 05, 0, time.UTC)},
-		{"2003-01-02 15:05:01", false, time.Time{}}, //negative case, invalid layout
+		{"2003-01-02 15:05:01", false, time.Time{}}, // negative case, invalid layout
 		{"2024-11-22T03:01:02Z", true, time.Date(2024, 11, 22, 3, 1, 02, 0, time.UTC)},
 		{"2006-01-02T15:04:05+07:00", true, time.Date(2006, 1, 2, 15, 4, 5, 0, time.FixedZone("UTC+7", 7*60*60))},
 	}
diff --git a/time.go b/time.go
index 3dee424..fe457de 100644
--- a/time.go
+++ b/time.go
@@ -51,9 +51,8 @@
 func (d *timeValue) String() string {
 	if d.Time.IsZero() {
 		return ""
-	} else {
-		return d.Time.Format(time.RFC3339Nano)
 	}
+	return d.Time.Format(time.RFC3339Nano)
 }
 
 // GetTime return the time value of a flag with the given name
diff --git a/uint64.go b/uint64.go
index f62240f..86d8c7e 100644
--- a/uint64.go
+++ b/uint64.go
@@ -27,7 +27,7 @@
 	if err != nil {
 		return 0, err
 	}
-	return uint64(v), nil
+	return v, nil
 }
 
 // GetUint64 return the uint64 value of a flag with the given name