Repository: spf13/cobra
Pull request #1782 (2022-08-21 22:32:33)

ci: test on Golang 1.19
Golang 1.19 was released: https://go.dev/blog/go1.19

Ref: #1635


Patch:
diff --git a/command.go b/command.go
index 675bb13..5fca7dc 100644
--- a/command.go
+++ b/command.go
@@ -1505,7 +1505,8 @@ func (c *Command) LocalFlags() *flag.FlagSet {
 	}
 
 	addToLocal := func(f *flag.Flag) {
-		if c.lflags.Lookup(f.Name) == nil && c.parentsPflags.Lookup(f.Name) == nil {
+		// Add the flag if it is not a parent PFlag, or it shadows a parent PFlag
+		if c.lflags.Lookup(f.Name) == nil && f != c.parentsPflags.Lookup(f.Name) {
 			c.lflags.AddFlag(f)
 		}
 	}


Test patch:
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 0ca8367..e0c2f15 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -15,7 +15,8 @@ jobs:
 
       - uses: actions/setup-go@v3
         with:
-          go-version: '1.17'
+          go-version: '^1.19'
+          check-latest: true
 
       - uses: actions/checkout@v3
 
@@ -37,6 +38,7 @@ jobs:
         - 16
         - 17
         - 18
+        - 19
     name: '${{ matrix.platform }} | 1.${{ matrix.go }}.x'
     runs-on: ${{ matrix.platform }}-latest
     steps:
@@ -56,8 +58,8 @@ jobs:
     - run: |
         export GOBIN=$HOME/go/bin
         case "${{ matrix.go }}" in
-          16|17|18) _version='@latest';;
-          *) _version='';;
+          14|15) _version='';;
+          *) _version='@latest';;
         esac
         go install github.com/kyoh86/richgo"${_version}"
         go install github.com/mitchellh/gox"${_version}"
diff --git a/command_test.go b/command_test.go
index 0446e3c..0b0b821 100644
--- a/command_test.go
+++ b/command_test.go
@@ -707,10 +707,7 @@ func TestEmptyInputs(t *testing.T) {
 	}
 }
 
-func TestOverwrittenFlag(t *testing.T) {
-	// TODO: This test fails, but should work.
-	t.Skip()
-
+func TestChildFlagShadowsParentPersistentFlag(t *testing.T) {
 	parent := &Command{Use: "parent", Run: emptyRun}
 	child := &Command{Use: "child", Run: emptyRun}
 
@@ -732,7 +729,7 @@ func TestOverwrittenFlag(t *testing.T) {
 	}
 
 	if childInherited.Lookup("intf") != nil {
-		t.Errorf(`InheritedFlags should not contain overwritten flag "intf"`)
+		t.Errorf(`InheritedFlags should not contain shadowed flag "intf"`)
 	}
 	if childLocal.Lookup("intf") == nil {
 		t.Error(`LocalFlags expected to contain "intf", got "nil"`)
@@ -887,6 +884,38 @@ func TestHelpCommandExecutedOnChild(t *testing.T) {
 	checkStringContains(t, output, childCmd.Long)
 }
 
+func TestHelpCommandExecutedOnChildWithFlagThatShadowsParentFlag(t *testing.T) {
+	parent := &Command{Use: "parent", Run: emptyRun}
+	child := &Command{Use: "child", Run: emptyRun}
+	parent.AddCommand(child)
+
+	parent.PersistentFlags().Bool("foo", false, "parent foo usage")
+	parent.PersistentFlags().Bool("bar", false, "parent bar usage")
+	child.Flags().Bool("foo", false, "child foo usage") // This shadows parent's foo flag
+	child.Flags().Bool("baz", false, "child baz usage")
+
+	got, err := executeCommand(parent, "help", "child")
+	if err != nil {
+		t.Errorf("Unexpected error: %v", err)
+	}
+
+	expected := `Usage:
+  parent child [flags]
+
+Flags:
+      --baz    child baz usage
+      --foo    child foo usage
+  -h, --help   help for child
+
+Global Flags:
+      --bar   parent bar usage
+`
+
+	if got != expected {
+		t.Errorf("Help text mismatch.\nExpected:\n%s\n\nGot:\n%s\n", expected, got)
+	}
+}
+
 func TestSetHelpCommand(t *testing.T) {
 	c := &Command{Use: "c", Run: emptyRun}
 	c.AddCommand(&Command{Use: "empty", Run: emptyRun})