Repository: spf13/cobra
Pull request #1792 (2022-09-01 00:45:36)

ci: add minimum GitHub token permissions for workflows
### Description
This PR adds minimum token permissions for the GITHUB_TOKEN in GitHub Actions workflows using https://github.com/step-security/secure-workflows. 

GitHub Actions workflows have a GITHUB_TOKEN with `write` access to multiple scopes. 
Here is an example of the permissions in one of the workflows:
https://github.com/spf13/cobra/runs/8125223301?check_suite_focus=true#step:1:19

After this change, the scopes will be reduced to the minimum needed for each workflow. 

### Motivation and Context

- This is a security best practice, so if the GITHUB_TOKEN is compromised due to a vulnerability or compromised Action, the damage will be reduced. 
- GitHub recommends defining minimum GITHUB_TOKEN permissions. 
https://docs.github.com/en/actions/security-guides/automatic-token-authentication#modifying-the-permissions-for-the-github_token
- The Open Source Security Foundation (OpenSSF) [Scorecards](https://github.com/ossf/scorecard) also treats not setting token permissions as a high-risk issue. This change will help increase the Scorecard score for this repository. 

Signed-off-by: Varun Sharma <varunsh@stepsecurity.io>

CLAassistant: [![CLA assistant check](https://cla-assistant.io/pull/badge/not_signed)](https://cla-assistant.io/spf13/cobra?pullRequest=1792) <br/>Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our [Contributor License Agreement](https://cla-assistant.io/spf13/cobra?pullRequest=1792) before we can accept your contribution.<br/><sub>You have signed the CLA already but the status is still pending? Let us [recheck](https://cla-assistant.io/check/spf13/cobra?pullRequest=1792) it.</sub>

Patch:
diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml
index e8b9651..17f451f 100644
--- a/.github/workflows/labeler.yml
+++ b/.github/workflows/labeler.yml
@@ -2,8 +2,14 @@ name: "Pull Request Labeler"
 on:
 - pull_request_target
 
+permissions:
+  contents: read
+
 jobs:
   triage:
+    permissions:
+      contents: read  # for actions/labeler to determine modified files
+      pull-requests: write  # for actions/labeler to add labels to PRs
     runs-on: ubuntu-latest
     steps:
     - uses: actions/labeler@v4
diff --git a/.github/workflows/size-labeler.yml b/.github/workflows/size-labeler.yml
index f04024f..4c54d82 100644
--- a/.github/workflows/size-labeler.yml
+++ b/.github/workflows/size-labeler.yml
@@ -4,8 +4,13 @@ name: size-labeler
 
 on: [pull_request_target]
 
+permissions:
+  contents: read
+
 jobs:
   size-labeler:
+    permissions:
+      pull-requests: write  # for codelytv/pr-size-labeler to add labels & comment on PRs
     runs-on: ubuntu-latest
     name: Label the PR size
     steps:
diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml
index a63518f..2db5123 100644
--- a/.github/workflows/stale.yml
+++ b/.github/workflows/stale.yml
@@ -4,13 +4,19 @@ on:
   schedule:
   - cron: "0 0 * * *"
 
+permissions:
+  contents: read
+
 jobs:
   stale:
 
+    permissions:
+      issues: write  # for actions/stale to close stale issues
+      pull-requests: write  # for actions/stale to close stale PRs
     runs-on: ubuntu-latest
 
     steps:
-    - uses: actions/stale@v5
+    - uses: actions/stale@v6
       with:
         repo-token: ${{ secrets.GITHUB_TOKEN }}
         stale-issue-message: "The Cobra project currently lacks enough contributors to adequately respond to all issues.
@@ -39,8 +45,8 @@ jobs:
         days-before-close: 30
         stale-issue-label: 'lifecycle/stale'
         stale-pr-label: 'lifecycle/stale'
-        exempt-issue-label: 'lifecycle/frozen'
-        exempt-pr-label: 'lifecycle/frozen'
+        exempt-issue-labels: 'lifecycle/frozen'
+        exempt-pr-labels: 'lifecycle/frozen'
         close-issue-label: 'lifecycle/rotten'
         close-pr-label: 'lifecycle/rotten'
 
diff --git a/.golangci.yml b/.golangci.yml
index 0d6e617..439d3e1 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -1,3 +1,17 @@
+# Copyright 2013-2022 The Cobra 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.
+
 run:
   deadline: 5m
 
diff --git a/README.md b/README.md
index a672c23..08e4fa5 100644
--- a/README.md
+++ b/README.md
@@ -40,9 +40,9 @@ The best applications read like sentences when used, and as a result, users
 intuitively know how to interact with them.
 
 The pattern to follow is
-`APPNAME VERB NOUN --ADJECTIVE.`
+`APPNAME VERB NOUN --ADJECTIVE`
     or
-`APPNAME COMMAND ARG --FLAG`
+`APPNAME COMMAND ARG --FLAG`.
 
 A few good real world examples may better illustrate this point.
 
diff --git a/active_help.go b/active_help.go
index 0c63191..95e03ae 100644
--- a/active_help.go
+++ b/active_help.go
@@ -1,3 +1,17 @@
+// Copyright 2013-2022 The Cobra 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 cobra
 
 import (
diff --git a/args.go b/args.go
index 20a022b..2c1f99e 100644
--- a/args.go
+++ b/args.go
@@ -1,3 +1,17 @@
+// Copyright 2013-2022 The Cobra 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 cobra
 
 import (
@@ -32,7 +46,8 @@ func NoArgs(cmd *Command, args []string) error {
 	return nil
 }
 
-// OnlyValidArgs returns an error if any args are not in the list of ValidArgs.
+// OnlyValidArgs returns an error if there are any positional args that are not in
+// the `ValidArgs` field of `Command`
 func OnlyValidArgs(cmd *Command, args []string) error {
 	if len(cmd.ValidArgs) > 0 {
 		// Remove any description that may be included in ValidArgs.
@@ -41,7 +56,6 @@ func OnlyValidArgs(cmd *Command, args []string) error {
 		for _, v := range cmd.ValidArgs {
 			validArgs = append(validArgs, strings.Split(v, "\t")[0])
 		}
-
 		for _, v := range args {
 			if !stringInSlice(v, validArgs) {
 				return fmt.Errorf("invalid argument %q for %q%s", v, cmd.CommandPath(), cmd.findSuggestions(args[0]))
@@ -86,18 +100,6 @@ func ExactArgs(n int) PositionalArgs {
 	}
 }
 
-// ExactValidArgs returns an error if
-// there are not exactly N positional args OR
-// there are any positional args that are not in the `ValidArgs` field of `Command`
-func ExactValidArgs(n int) PositionalArgs {
-	return func(cmd *Command, args []string) error {
-		if err := ExactArgs(n)(cmd, args); err != nil {
-			return err
-		}
-		return OnlyValidArgs(cmd, args)
-	}
-}
-
 // RangeArgs returns an error if the number of args is not within the expected range.
 func RangeArgs(min int, max int) PositionalArgs {
 	return func(cmd *Command, args []string) error {
@@ -119,3 +121,11 @@ func MatchAll(pargs ...PositionalArgs) PositionalArgs {
 		return nil
 	}
 }
+
+// ExactValidArgs returns an error if there are not exactly N positional args OR
+// there are any positional args that are not in the `ValidArgs` field of `Command`
+//
+// Deprecated: use MatchAll(ExactArgs(n), OnlyValidArgs) instead
+func ExactValidArgs(n int) PositionalArgs {
+	return MatchAll(ExactArgs(n), OnlyValidArgs)
+}
diff --git a/bash_completions.go b/bash_completions.go
index cb7e195..3acdb27 100644
--- a/bash_completions.go
+++ b/bash_completions.go
@@ -1,3 +1,17 @@
+// Copyright 2013-2022 The Cobra 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 cobra
 
 import (
diff --git a/bash_completionsV2.go b/bash_completionsV2.go
index 351391a..bb4b718 100644
--- a/bash_completionsV2.go
+++ b/bash_completionsV2.go
@@ -1,3 +1,17 @@
+// Copyright 2013-2022 The Cobra 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 cobra
 
 import (
diff --git a/cobra.go b/cobra.go
index d6cbfd7..fe44bc8 100644
--- a/cobra.go
+++ b/cobra.go
@@ -1,9 +1,10 @@
-// Copyright © 2013 Steve Francia <spf@spf13.com>.
+// Copyright 2013-2022 The Cobra 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
+//
+//      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,
@@ -39,15 +40,25 @@ var templateFuncs = template.FuncMap{
 }
 
 var initializers []func()
+var finalizers []func()
+
+const (
+	defaultPrefixMatching  = false
+	defaultCommandSorting  = true
+	defaultCaseInsensitive = false
+)
 
 // EnablePrefixMatching allows to set automatic prefix matching. Automatic prefix matching can be a dangerous thing
 // to automatically enable in CLI tools.
 // Set this to true to enable it.
-var EnablePrefixMatching = false
+var EnablePrefixMatching = defaultPrefixMatching
 
 // EnableCommandSorting controls sorting of the slice of commands, which is turned on by default.
 // To disable sorting, set it to false.
-var EnableCommandSorting = true
+var EnableCommandSorting = defaultCommandSorting
+
+// EnableCaseInsensitive allows case-insensitive commands names. (case sensitive by default)
+var EnableCaseInsensitive = defaultCaseInsensitive
 
 // MousetrapHelpText enables an information splash screen on Windows
 // if the CLI is started from explorer.exe.
@@ -84,6 +95,12 @@ func OnInitialize(y ...func()) {
 	initializers = append(initializers, y...)
 }
 
+// OnFinalize sets the passed functions to be run when each command's
+// Execute method is terminated.
+func OnFinalize(y ...func()) {
+	finalizers = append(finalizers, y...)
+}
+
 // FIXME Gt is unused by cobra and should be removed in a version 2. It exists only for compatibility with users of cobra.
 
 // Gt takes two types and checks whether the first type is greater than the second. In case of types Arrays, Chans,
diff --git a/command.go b/command.go
index 6e61133..8ce5c3c 100644
--- a/command.go
+++ b/command.go
@@ -1,9 +1,10 @@
-// Copyright © 2013 Steve Francia <spf@spf13.com>.
+// Copyright 2013-2022 The Cobra 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
+//
+//      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,
@@ -676,7 +677,7 @@ func (c *Command) findSuggestions(arg string) string {
 func (c *Command) findNext(next string) *Command {
 	matches := make([]*Command, 0)
 	for _, cmd := range c.commands {
-		if cmd.Name() == next || cmd.HasAlias(next) {
+		if commandNameMatches(cmd.Name(), next) || cmd.HasAlias(next) {
 			cmd.commandCalledAs.name = next
 			return cmd
 		}
@@ -833,6 +834,8 @@ func (c *Command) execute(a []string) (err error) {
 
 	c.preRun()
 
+	defer c.postRun()
+
 	argWoFlags := c.Flags().Args()
 	if c.DisableFlagParsing {
 		argWoFlags = a
@@ -861,10 +864,10 @@ func (c *Command) execute(a []string) (err error) {
 		c.PreRun(c, argWoFlags)
 	}
 
-	if err := c.validateRequiredFlags(); err != nil {
+	if err := c.ValidateRequiredFlags(); err != nil {
 		return err
 	}
-	if err := c.validateFlagGroups(); err != nil {
+	if err := c.ValidateFlagGroups(); err != nil {
 		return err
 	}
 
@@ -903,6 +906,12 @@ func (c *Command) preRun() {
 	}
 }
 
+func (c *Command) postRun() {
+	for _, x := range finalizers {
+		x()
+	}
+}
+
 // ExecuteContext is the same as Execute(), but sets the ctx on the command.
 // Retrieve ctx by calling cmd.Context() inside your *Run lifecycle or ValidArgs
 // functions.
@@ -1018,7 +1027,8 @@ func (c *Command) ValidateArgs(args []string) error {
 	return c.Args(c, args)
 }
 
-func (c *Command) validateRequiredFlags() error {
+// ValidateRequiredFlags validates all required flags are present and returns an error otherwise
+func (c *Command) ValidateRequiredFlags() error {
 	if c.DisableFlagParsing {
 		return nil
 	}
@@ -1121,7 +1131,8 @@ Simply type ` + c.Name() + ` help [path to command] for full details.`,
 					c.Printf("Unknown help topic %#q\n", args)
 					CheckErr(c.Root().Usage())
 				} else {
-					cmd.InitDefaultHelpFlag() // make possible 'help' flag to be shown
+					cmd.InitDefaultHelpFlag()    // make possible 'help' flag to be shown
+					cmd.InitDefaultVersionFlag() // make possible 'version' flag to be shown
 					CheckErr(cmd.Help())
 				}
 			},
@@ -1328,7 +1339,7 @@ func (c *Command) Name() string {
 // HasAlias determines if a given string is an alias of the command.
 func (c *Command) HasAlias(s string) bool {
 	for _, a := range c.Aliases {
-		if a == s {
+		if commandNameMatches(a, s) {
 			return true
 		}
 	}
@@ -1695,3 +1706,14 @@ func (c *Command) updateParentsPflags() {
 		c.parentsPflags.AddFlagSet(parent.PersistentFlags())
 	})
 }
+
+// commandNameMatches checks if two command names are equal
+// taking into account case sensitivity according to
+// EnableCaseInsensitive global configuration.
+func commandNameMatches(s string, t string) bool {
+	if EnableCaseInsensitive {
+		return strings.EqualFold(s, t)
+	}
+
+	return s == t
+}
diff --git a/command_notwin.go b/command_notwin.go
index bb5dad9..2b77f8f 100644
--- a/command_notwin.go
+++ b/command_notwin.go
@@ -1,3 +1,17 @@
+// Copyright 2013-2022 The Cobra 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.
+
 //go:build !windows
 // +build !windows
 
diff --git a/command_win.go b/command_win.go
index a84f5a8..520f23a 100644
--- a/command_win.go
+++ b/command_win.go
@@ -1,3 +1,17 @@
+// Copyright 2013-2022 The Cobra 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.
+
 //go:build windows
 // +build windows
 
diff --git a/completions.go b/completions.go
index 2c24839..f8bf4f6 100644
--- a/completions.go
+++ b/completions.go
@@ -1,3 +1,17 @@
+// Copyright 2013-2022 The Cobra 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 cobra
 
 import (
diff --git a/doc/man_docs.go b/doc/man_docs.go
index 8dbce35..b5a2c59 100644
--- a/doc/man_docs.go
+++ b/doc/man_docs.go
@@ -1,9 +1,10 @@
-// Copyright 2015 Red Hat Inc. All rights reserved.
+// Copyright 2013-2022 The Cobra 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
+//
+//      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,
diff --git a/doc/md_docs.go b/doc/md_docs.go
index 19d7e93..bab4b49 100644
--- a/doc/md_docs.go
+++ b/doc/md_docs.go
@@ -1,9 +1,10 @@
-//Copyright 2015 Red Hat Inc. All rights reserved.
+// Copyright 2013-2022 The Cobra 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
+//
+//      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,
diff --git a/doc/rest_docs.go b/doc/rest_docs.go
index 23dca16..d658906 100644
--- a/doc/rest_docs.go
+++ b/doc/rest_docs.go
@@ -1,9 +1,10 @@
-//Copyright 2015 Red Hat Inc. All rights reserved.
+// Copyright 2013-2022 The Cobra 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
+//
+//      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,
diff --git a/doc/util.go b/doc/util.go
index bffde94..499ecdd 100644
--- a/doc/util.go
+++ b/doc/util.go
@@ -1,9 +1,10 @@
-// Copyright 2015 Red Hat Inc. All rights reserved.
+// Copyright 2013-2022 The Cobra 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
+//
+//      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,
diff --git a/doc/yaml_docs.go b/doc/yaml_docs.go
index 784c387..12f8cf3 100644
--- a/doc/yaml_docs.go
+++ b/doc/yaml_docs.go
@@ -1,9 +1,10 @@
-// Copyright 2016 French Ben. All rights reserved.
+// Copyright 2013-2022 The Cobra 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
+//
+//      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,
diff --git a/fish_completions.go b/fish_completions.go
index 005ee6b..97112a1 100644
--- a/fish_completions.go
+++ b/fish_completions.go
@@ -1,3 +1,17 @@
+// Copyright 2013-2022 The Cobra 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 cobra
 
 import (
diff --git a/flag_groups.go b/flag_groups.go
index dc78431..9c377aa 100644
--- a/flag_groups.go
+++ b/flag_groups.go
@@ -1,9 +1,10 @@
-// Copyright © 2022 Steve Francia <spf@spf13.com>.
+// Copyright 2013-2022 The Cobra 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
+//
+//      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,
@@ -58,9 +59,9 @@ func (c *Command) MarkFlagsMutuallyExclusive(flagNames ...string) {
 	}
 }
 
-// validateFlagGroups validates the mutuallyExclusive/requiredAsGroup logic and returns the
+// ValidateFlagGroups validates the mutuallyExclusive/requiredAsGroup logic and returns the
 // first error encountered.
-func (c *Command) validateFlagGroups() error {
+func (c *Command) ValidateFlagGroups() error {
 	if c.DisableFlagParsing {
 		return nil
 	}
diff --git a/powershell_completions.go b/powershell_completions.go
index 379e7c0..351ded6 100644
--- a/powershell_completions.go
+++ b/powershell_completions.go
@@ -1,3 +1,17 @@
+// Copyright 2013-2022 The Cobra 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.
+
 // The generated scripts require PowerShell v5.0+ (which comes Windows 10, but
 // can be downloaded separately for windows 7 or 8.1).
 
diff --git a/projects_using_cobra.md b/projects_using_cobra.md
index b5b9dbf..6865f88 100644
--- a/projects_using_cobra.md
+++ b/projects_using_cobra.md
@@ -1,5 +1,6 @@
 ## Projects using Cobra
 
+- [Allero](https://github.com/allero-io/allero)
 - [Arduino CLI](https://github.com/arduino/arduino-cli)
 - [Bleve](https://blevesearch.com/)
 - [Cilium](https://cilium.io/)
diff --git a/shell_completions.go b/shell_completions.go
index d99bf91..126e83c 100644
--- a/shell_completions.go
+++ b/shell_completions.go
@@ -1,3 +1,17 @@
+// Copyright 2013-2022 The Cobra 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 cobra
 
 import (
diff --git a/shell_completions.md b/shell_completions.md
index 1e2058e..a0957b4 100644
--- a/shell_completions.md
+++ b/shell_completions.md
@@ -99,6 +99,11 @@ To tell Cobra *not* to provide the default `completion` command:
 rootCmd.CompletionOptions.DisableDefaultCmd = true
 ```
 
+To tell Cobra to mark the default `completion` command as *hidden*:
+```
+rootCmd.CompletionOptions.HiddenDefaultCmd = true
+```
+
 To tell Cobra *not* to provide the user with the `--no-descriptions` flag to the completion sub-commands:
 ```
 rootCmd.CompletionOptions.DisableNoDescFlag = true
diff --git a/user_guide.md b/user_guide.md
index 5a7acf8..c694d87 100644
--- a/user_guide.md
+++ b/user_guide.md
@@ -302,15 +302,15 @@ rootCmd.MarkPersistentFlagRequired("region")
 
 ### Flag Groups
 
-If you have different flags that must be provided together (e.g. if they provide the `--username` flag they MUST provide the `--password` flag as well) then 
+If you have different flags that must be provided together (e.g. if they provide the `--username` flag they MUST provide the `--password` flag as well) then
 Cobra can enforce that requirement:
 ```go
 rootCmd.Flags().StringVarP(&u, "username", "u", "", "Username (required if password is set)")
 rootCmd.Flags().StringVarP(&pw, "password", "p", "", "Password (required if username is set)")
 rootCmd.MarkFlagsRequiredTogether("username", "password")
-``` 
+```
 
-You can also prevent different flags from being provided together if they represent mutually 
+You can also prevent different flags from being provided together if they represent mutually
 exclusive options such as specifying an output format as either `--json` or `--yaml` but never both:
 ```go
 rootCmd.Flags().BoolVar(&u, "json", false, "Output in JSON")
@@ -327,29 +327,47 @@ In both of these cases:
 ## Positional and Custom Arguments
 
 Validation of positional arguments can be specified using the `Args` field of `Command`.
+The following validators are built in:
+
+- Number of arguments:
+  - `NoArgs` - report an error if there are any positional args.
+  - `ArbitraryArgs` - accept any number of args.
+  - `MinimumNArgs(int)` - report an error if less than N positional args are provided.
+  - `MaximumNArgs(int)` - report an error if more than N positional args are provided.
+  - `ExactArgs(int)` - report an error if there are not exactly N positional args.
+  - `RangeArgs(min, max)` - report an error if the number of args is not between `min` and `max`.
+- Content of the arguments:
+  - `OnlyValidArgs` - report an error if there are any positional args not specified in the `ValidArgs` field of `Command`, which can optionally be set to a list of valid values for positional args.
+
 If `Args` is undefined or `nil`, it defaults to `ArbitraryArgs`.
 
-The following validators are built in:
+Moreover, `MatchAll(pargs ...PositionalArgs)` enables combining existing checks with arbitrary other checks.
+For instance, if you want to report an error if there are not exactly N positional args OR if there are any positional
+args that are not in the `ValidArgs` field of `Command`, you can call `MatchAll` on `ExactArgs` and `OnlyValidArgs`, as
+shown below:
 
-- `NoArgs` - the command will report an error if there are any positional args.
-- `ArbitraryArgs` - the command will accept any args.
-- `OnlyValidArgs` - the command will report an error if there are any positional args that are not in the `ValidArgs` field of `Command`.
-- `MinimumNArgs(int)` - the command will report an error if there are not at least N positional args.
-- `MaximumNArgs(int)` - the command will report an error if there are more than N positional args.
-- `ExactArgs(int)` - the command will report an error if there are not exactly N positional args.
-- `ExactValidArgs(int)` - the command will report an error if there are not exactly N positional args OR if there are any positional args that are not in the `ValidArgs` field of `Command`
-- `RangeArgs(min, max)` - the command will report an error if the number of args is not between the minimum and maximum number of expected args.
-- `MatchAll(pargs ...PositionalArgs)` - enables combining existing checks with arbitrary other checks (e.g. you want to check the ExactArgs length along with other qualities).
+```go
+var cmd = &cobra.Command{
+  Short: "hello",
+  Args: MatchAll(ExactArgs(2), OnlyValidArgs),
+  Run: func(cmd *cobra.Command, args []string) {
+    fmt.Println("Hello, World!")
+  },
+}
+```
 
-An example of setting the custom validator:
+It is possible to set any custom validator that satisfies `func(cmd *cobra.Command, args []string) error`.
+For example:
 
 ```go
 var cmd = &cobra.Command{
   Short: "hello",
   Args: func(cmd *cobra.Command, args []string) error {
-    if len(args) < 1 {
-      return errors.New("requires a color argument")
+    // Optionally run one of the validators provided by cobra
+    if err := cobra.MinimumNArgs(1)(cmd, args); err != nil {
+        return err
     }
+    // Run the custom validation logic
     if myapp.IsValidColor(args[0]) {
       return nil
     }
@@ -444,28 +462,29 @@ create' is called.  Every command will automatically have the '--help' flag adde
 The following output is automatically generated by Cobra. Nothing beyond the
 command and flag definitions are needed.
 
-    $ cobra help
+    $ cobra-cli help
 
     Cobra is a CLI library for Go that empowers applications.
     This application is a tool to generate the needed files
     to quickly create a Cobra application.
 
     Usage:
-      cobra [command]
+      cobra-cli [command]
 
     Available Commands:
       add         Add a command to a Cobra Application
+      completion  Generate the autocompletion script for the specified shell
       help        Help about any command
       init        Initialize a Cobra Application
 
     Flags:
       -a, --author string    author name for copyright attribution (default "YOUR NAME")
           --config string    config file (default is $HOME/.cobra.yaml)
-      -h, --help             help for cobra
+      -h, --help             help for cobra-cli
       -l, --license string   name of license for the project
-          --viper            use Viper for configuration (default true)
+          --viper            use Viper for configuration
 
-    Use "cobra [command] --help" for more information about a command.
+    Use "cobra-cli [command] --help" for more information about a command.
 
 
 Help is just a command like any other. There is no special logic or behavior
@@ -474,7 +493,7 @@ around it. In fact, you can provide your own if you want.
 ### Defining your own help
 
 You can provide your own Help command or your own template for the default command to use
-with following functions:
+with the following functions:
 
 ```go
 cmd.SetHelpCommand(cmd *Command)
@@ -493,22 +512,23 @@ showing the user the 'usage'.
 You may recognize this from the help above. That's because the default help
 embeds the usage as part of its output.
 
-    $ cobra --invalid
+    $ cobra-cli --invalid
     Error: unknown flag: --invalid
     Usage:
-      cobra [command]
+      cobra-cli [command]
 
     Available Commands:
       add         Add a command to a Cobra Application
+      completion  Generate the autocompletion script for the specified shell
       help        Help about any command
       init        Initialize a Cobra Application
 
     Flags:
       -a, --author string    author name for copyright attribution (default "YOUR NAME")
           --config string    config file (default is $HOME/.cobra.yaml)
-      -h, --help             help for cobra
+      -h, --help             help for cobra-cli
       -l, --license string   name of license for the project
-          --viper            use Viper for configuration (default true)
+          --viper            use Viper for configuration
 
     Use "cobra [command] --help" for more information about a command.
 
@@ -627,7 +647,7 @@ Did you mean this?
 Run 'hugo --help' for usage.
 ```
 
-Suggestions are automatic based on every subcommand registered and use an implementation of [Levenshtein distance](https://en.wikipedia.org/wiki/Levenshtein_distance). Every registered command that matches a minimum distance of 2 (ignoring case) will be displayed as a suggestion.
+Suggestions are automatically generated based on existing subcommands and use an implementation of [Levenshtein distance](https://en.wikipedia.org/wiki/Levenshtein_distance). Every registered command that matches a minimum distance of 2 (ignoring case) will be displayed as a suggestion.
 
 If you need to disable suggestions or tweak the string distance in your command, use:
 
@@ -641,7 +661,8 @@ or
 command.SuggestionsMinimumDistance = 1
 ```
 
-You can also explicitly set names for which a given command will be suggested using the `SuggestFor` attribute. This allows suggestions for strings that are not close in terms of string distance, but makes sense in your set of commands and for some which you don't want aliases. Example:
+You can also explicitly set names for which a given command will be suggested using the `SuggestFor` attribute. This allows suggestions for strings that are not close in terms of string distance, but make sense in your set of commands but for which
+you don't want aliases. Example:
 
 ```
 $ kubectl remove
diff --git a/zsh_completions.go b/zsh_completions.go
index 65cd94c..84cec76 100644
--- a/zsh_completions.go
+++ b/zsh_completions.go
@@ -1,3 +1,17 @@
+// Copyright 2013-2022 The Cobra 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 cobra
 
 import (


Test patch:
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index e0c2f15..a55d39f 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -3,20 +3,49 @@ name: Test
 on:
   push:
   pull_request:
+  workflow_dispatch:
 
 env:
   GO111MODULE: on
 
+permissions:
+  contents: read
+
 jobs:
 
+
+  lic-headers:
+    runs-on: ubuntu-latest
+    steps:
+
+      - uses: actions/checkout@v3
+
+      - run: >-
+          docker run
+          -v $(pwd):/wrk -w /wrk
+          ghcr.io/google/addlicense
+          -c 'The Cobra Authors'
+          -y '2013-2022'
+          -l apache
+          -ignore '.github/**'
+          -check
+          .
+
+
   golangci-lint:
+    permissions:
+      contents: read  # for actions/checkout to fetch code
+      pull-requests: read  # for golangci/golangci-lint-action to fetch pull requests
     runs-on: ubuntu-latest
     steps:
 
+      - uses: actions/checkout@v3
+
       - uses: actions/setup-go@v3
         with:
           go-version: '^1.19'
           check-latest: true
+          cache: true
 
       - uses: actions/checkout@v3
 
@@ -25,6 +54,7 @@ jobs:
           version: latest
           args: --verbose
 
+
   test-unix:
     strategy:
       fail-fast: false
@@ -33,7 +63,6 @@ jobs:
         - ubuntu
         - macOS
         go:
-        - 14
         - 15
         - 16
         - 17
@@ -43,17 +72,12 @@ jobs:
     runs-on: ${{ matrix.platform }}-latest
     steps:
 
-    - uses: actions/setup-go@v3
-      with:
-        go-version: 1.${{ matrix.go }}.x
-
     - uses: actions/checkout@v3
 
-    - uses: actions/cache@v3
+    - uses: actions/setup-go@v3
       with:
-        path: ~/go/pkg/mod
-        key: ${{ runner.os }}-1.${{ matrix.go }}.x-${{ hashFiles('**/go.sum') }}
-        restore-keys: ${{ runner.os }}-1.${{ matrix.go }}.x-
+        go-version: 1.${{ matrix.go }}.x
+        cache: true
 
     - run: |
         export GOBIN=$HOME/go/bin
@@ -66,6 +90,7 @@ jobs:
 
     - run: RICHGO_FORCE_COLOR=1 PATH=$HOME/go/bin/:$PATH make test
 
+
   test-win:
     name: MINGW64
     defaults:
diff --git a/active_help_test.go b/active_help_test.go
index 524be88..3653dd8 100644
--- a/active_help_test.go
+++ b/active_help_test.go
@@ -1,3 +1,17 @@
+// Copyright 2013-2022 The Cobra 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 cobra
 
 import (
diff --git a/args_test.go b/args_test.go
index 6bd41c8..fd2c3b4 100644
--- a/args_test.go
+++ b/args_test.go
@@ -1,3 +1,17 @@
+// Copyright 2013-2022 The Cobra 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 cobra
 
 import (
@@ -27,7 +41,7 @@ func expectSuccess(output string, err error, t *testing.T) {
 	}
 }
 
-func validWithInvalidArgs(err error, t *testing.T) {
+func validOnlyWithInvalidArgs(err error, t *testing.T) {
 	if err == nil {
 		t.Fatal("Expected an error")
 	}
@@ -38,12 +52,12 @@ func validWithInvalidArgs(err error, t *testing.T) {
 	}
 }
 
-func noArgsWithArgs(err error, t *testing.T) {
+func noArgsWithArgs(err error, t *testing.T, arg string) {
 	if err == nil {
 		t.Fatal("Expected an error")
 	}
 	got := err.Error()
-	expected := `unknown command "illegal" for "c"`
+	expected := `unknown command "` + arg + `" for "c"`
 	if got != expected {
 		t.Errorf("Expected: %q, got: %q", expected, got)
 	}
@@ -93,102 +107,280 @@ func rangeArgsWithInvalidCount(err error, t *testing.T) {
 	}
 }
 
+// NoArgs
+
 func TestNoArgs(t *testing.T) {
 	c := getCommand(NoArgs, false)
 	output, err := executeCommand(c)
 	expectSuccess(output, err, t)
 }
 
-func TestNoArgsWithArgs(t *testing.T) {
+func TestNoArgs_WithArgs(t *testing.T) {
 	c := getCommand(NoArgs, false)
-	_, err := executeCommand(c, "illegal")
-	noArgsWithArgs(err, t)
+	_, err := executeCommand(c, "one")
+	noArgsWithArgs(err, t, "one")
+}
+
+func TestNoArgs_WithValid_WithArgs(t *testing.T) {
+	c := getCommand(NoArgs, true)
+	_, err := executeCommand(c, "one")
+	noArgsWithArgs(err, t, "one")
+}
+
+func TestNoArgs_WithValid_WithInvalidArgs(t *testing.T) {
+	c := getCommand(NoArgs, true)
+	_, err := executeCommand(c, "a")
+	noArgsWithArgs(err, t, "a")
+}
+
+func TestNoArgs_WithValidOnly_WithInvalidArgs(t *testing.T) {
+	c := getCommand(MatchAll(OnlyValidArgs, NoArgs), true)
+	_, err := executeCommand(c, "a")
+	validOnlyWithInvalidArgs(err, t)
 }
 
+// OnlyValidArgs
+
 func TestOnlyValidArgs(t *testing.T) {
 	c := getCommand(OnlyValidArgs, true)
 	output, err := executeCommand(c, "one", "two")
 	expectSuccess(output, err, t)
 }
 
-func TestOnlyValidArgsWithInvalidArgs(t *testing.T) {
+func TestOnlyValidArgs_WithInvalidArgs(t *testing.T) {
 	c := getCommand(OnlyValidArgs, true)
 	_, err := executeCommand(c, "a")
-	validWithInvalidArgs(err, t)
+	validOnlyWithInvalidArgs(err, t)
 }
 
+// ArbitraryArgs
+
 func TestArbitraryArgs(t *testing.T) {
 	c := getCommand(ArbitraryArgs, false)
 	output, err := executeCommand(c, "a", "b")
 	expectSuccess(output, err, t)
 }
 
+func TestArbitraryArgs_WithValid(t *testing.T) {
+	c := getCommand(ArbitraryArgs, true)
+	output, err := executeCommand(c, "one", "two")
+	expectSuccess(output, err, t)
+}
+
+func TestArbitraryArgs_WithValid_WithInvalidArgs(t *testing.T) {
+	c := getCommand(ArbitraryArgs, true)
+	output, err := executeCommand(c, "a")
+	expectSuccess(output, err, t)
+}
+
+func TestArbitraryArgs_WithValidOnly_WithInvalidArgs(t *testing.T) {
+	c := getCommand(MatchAll(OnlyValidArgs, ArbitraryArgs), true)
+	_, err := executeCommand(c, "a")
+	validOnlyWithInvalidArgs(err, t)
+}
+
+// MinimumNArgs
+
 func TestMinimumNArgs(t *testing.T) {
 	c := getCommand(MinimumNArgs(2), false)
 	output, err := executeCommand(c, "a", "b", "c")
 	expectSuccess(output, err, t)
 }
 
-func TestMinimumNArgsWithLessArgs(t *testing.T) {
+func TestMinimumNArgs_WithValid(t *testing.T) {
+	c := getCommand(MinimumNArgs(2), true)
+	output, err := executeCommand(c, "one", "three")
+	expectSuccess(output, err, t)
+}
+
+func TestMinimumNArgs_WithValid__WithInvalidArgs(t *testing.T) {
+	c := getCommand(MinimumNArgs(2), true)
+	output, err := executeCommand(c, "a", "b")
+	expectSuccess(output, err, t)
+}
+
+func TestMinimumNArgs_WithValidOnly_WithInvalidArgs(t *testing.T) {
+	c := getCommand(MatchAll(OnlyValidArgs, MinimumNArgs(2)), true)
+	_, err := executeCommand(c, "a", "b")
+	validOnlyWithInvalidArgs(err, t)
+}
+
+func TestMinimumNArgs_WithLessArgs(t *testing.T) {
 	c := getCommand(MinimumNArgs(2), false)
 	_, err := executeCommand(c, "a")
 	minimumNArgsWithLessArgs(err, t)
 }
 
+func TestMinimumNArgs_WithLessArgs_WithValid(t *testing.T) {
+	c := getCommand(MinimumNArgs(2), true)
+	_, err := executeCommand(c, "one")
+	minimumNArgsWithLessArgs(err, t)
+}
+
+func TestMinimumNArgs_WithLessArgs_WithValid_WithInvalidArgs(t *testing.T) {
+	c := getCommand(MinimumNArgs(2), true)
+	_, err := executeCommand(c, "a")
+	minimumNArgsWithLessArgs(err, t)
+}
+
+func TestMinimumNArgs_WithLessArgs_WithValidOnly_WithInvalidArgs(t *testing.T) {
+	c := getCommand(MatchAll(OnlyValidArgs, MinimumNArgs(2)), true)
+	_, err := executeCommand(c, "a")
+	validOnlyWithInvalidArgs(err, t)
+}
+
+// MaximumNArgs
+
 func TestMaximumNArgs(t *testing.T) {
 	c := getCommand(MaximumNArgs(3), false)
 	output, err := executeCommand(c, "a", "b")
 	expectSuccess(output, err, t)
 }
 
-func TestMaximumNArgsWithMoreArgs(t *testing.T) {
+func TestMaximumNArgs_WithValid(t *testing.T) {
+	c := getCommand(MaximumNArgs(2), true)
+	output, err := executeCommand(c, "one", "three")
+	expectSuccess(output, err, t)
+}
+
+func TestMaximumNArgs_WithValid_WithInvalidArgs(t *testing.T) {
+	c := getCommand(MaximumNArgs(2), true)
+	output, err := executeCommand(c, "a", "b")
+	expectSuccess(output, err, t)
+}
+
+func TestMaximumNArgs_WithValidOnly_WithInvalidArgs(t *testing.T) {
+	c := getCommand(MatchAll(OnlyValidArgs, MaximumNArgs(2)), true)
+	_, err := executeCommand(c, "a", "b")
+	validOnlyWithInvalidArgs(err, t)
+}
+
+func TestMaximumNArgs_WithMoreArgs(t *testing.T) {
 	c := getCommand(MaximumNArgs(2), false)
 	_, err := executeCommand(c, "a", "b", "c")
 	maximumNArgsWithMoreArgs(err, t)
 }
 
+func TestMaximumNArgs_WithMoreArgs_WithValid(t *testing.T) {
+	c := getCommand(MaximumNArgs(2), true)
+	_, err := executeCommand(c, "one", "three", "two")
+	maximumNArgsWithMoreArgs(err, t)
+}
+
+func TestMaximumNArgs_WithMoreArgs_WithValid_WithInvalidArgs(t *testing.T) {
+	c := getCommand(MaximumNArgs(2), true)
+	_, err := executeCommand(c, "a", "b", "c")
+	maximumNArgsWithMoreArgs(err, t)
+}
+
+func TestMaximumNArgs_WithMoreArgs_WithValidOnly_WithInvalidArgs(t *testing.T) {
+	c := getCommand(MatchAll(OnlyValidArgs, MaximumNArgs(2)), true)
+	_, err := executeCommand(c, "a", "b", "c")
+	validOnlyWithInvalidArgs(err, t)
+}
+
+// ExactArgs
+
 func TestExactArgs(t *testing.T) {
 	c := getCommand(ExactArgs(3), false)
 	output, err := executeCommand(c, "a", "b", "c")
 	expectSuccess(output, err, t)
 }
 
-func TestExactArgsWithInvalidCount(t *testing.T) {
+func TestExactArgs_WithValid(t *testing.T) {
+	c := getCommand(ExactArgs(3), true)
+	output, err := executeCommand(c, "three", "one", "two")
+	expectSuccess(output, err, t)
+}
+
+func TestExactArgs_WithValid_WithInvalidArgs(t *testing.T) {
+	c := getCommand(ExactArgs(3), true)
+	output, err := executeCommand(c, "three", "a", "two")
+	expectSuccess(output, err, t)
+}
+
+func TestExactArgs_WithValidOnly_WithInvalidArgs(t *testing.T) {
+	c := getCommand(MatchAll(OnlyValidArgs, ExactArgs(3)), true)
+	_, err := executeCommand(c, "three", "a", "two")
+	validOnlyWithInvalidArgs(err, t)
+}
+
+func TestExactArgs_WithInvalidCount(t *testing.T) {
 	c := getCommand(ExactArgs(2), false)
 	_, err := executeCommand(c, "a", "b", "c")
 	exactArgsWithInvalidCount(err, t)
 }
 
-func TestExactValidArgs(t *testing.T) {
-	c := getCommand(ExactValidArgs(3), true)
-	output, err := executeCommand(c, "three", "one", "two")
-	expectSuccess(output, err, t)
+func TestExactArgs_WithInvalidCount_WithValid(t *testing.T) {
+	c := getCommand(ExactArgs(2), true)
+	_, err := executeCommand(c, "three", "one", "two")
+	exactArgsWithInvalidCount(err, t)
 }
 
-func TestExactValidArgsWithInvalidCount(t *testing.T) {
-	c := getCommand(ExactValidArgs(2), false)
-	_, err := executeCommand(c, "three", "one", "two")
+func TestExactArgs_WithInvalidCount_WithValid_WithInvalidArgs(t *testing.T) {
+	c := getCommand(ExactArgs(2), true)
+	_, err := executeCommand(c, "three", "a", "two")
 	exactArgsWithInvalidCount(err, t)
 }
 
-func TestExactValidArgsWithInvalidArgs(t *testing.T) {
-	c := getCommand(ExactValidArgs(3), true)
+func TestExactArgs_WithInvalidCount_WithValidOnly_WithInvalidArgs(t *testing.T) {
+	c := getCommand(MatchAll(OnlyValidArgs, ExactArgs(2)), true)
 	_, err := executeCommand(c, "three", "a", "two")
-	validWithInvalidArgs(err, t)
+	validOnlyWithInvalidArgs(err, t)
 }
 
+// RangeArgs
+
 func TestRangeArgs(t *testing.T) {
 	c := getCommand(RangeArgs(2, 4), false)
 	output, err := executeCommand(c, "a", "b", "c")
 	expectSuccess(output, err, t)
 }
 
-func TestRangeArgsWithInvalidCount(t *testing.T) {
+func TestRangeArgs_WithValid(t *testing.T) {
+	c := getCommand(RangeArgs(2, 4), true)
+	output, err := executeCommand(c, "three", "one", "two")
+	expectSuccess(output, err, t)
+}
+
+func TestRangeArgs_WithValid_WithInvalidArgs(t *testing.T) {
+	c := getCommand(RangeArgs(2, 4), true)
+	output, err := executeCommand(c, "three", "a", "two")
+	expectSuccess(output, err, t)
+}
+
+func TestRangeArgs_WithValidOnly_WithInvalidArgs(t *testing.T) {
+	c := getCommand(MatchAll(OnlyValidArgs, RangeArgs(2, 4)), true)
+	_, err := executeCommand(c, "three", "a", "two")
+	validOnlyWithInvalidArgs(err, t)
+}
+
+func TestRangeArgs_WithInvalidCount(t *testing.T) {
 	c := getCommand(RangeArgs(2, 4), false)
 	_, err := executeCommand(c, "a")
 	rangeArgsWithInvalidCount(err, t)
 }
 
+func TestRangeArgs_WithInvalidCount_WithValid(t *testing.T) {
+	c := getCommand(RangeArgs(2, 4), true)
+	_, err := executeCommand(c, "two")
+	rangeArgsWithInvalidCount(err, t)
+}
+
+func TestRangeArgs_WithInvalidCount_WithValid_WithInvalidArgs(t *testing.T) {
+	c := getCommand(RangeArgs(2, 4), true)
+	_, err := executeCommand(c, "a")
+	rangeArgsWithInvalidCount(err, t)
+}
+
+func TestRangeArgs_WithInvalidCount_WithValidOnly_WithInvalidArgs(t *testing.T) {
+	c := getCommand(MatchAll(OnlyValidArgs, RangeArgs(2, 4)), true)
+	_, err := executeCommand(c, "a")
+	validOnlyWithInvalidArgs(err, t)
+}
+
+// Takes(No)Args
+
 func TestRootTakesNoArgs(t *testing.T) {
 	rootCmd := &Command{Use: "root", Run: emptyRun}
 	childCmd := &Command{Use: "child", Run: emptyRun}
@@ -293,6 +485,32 @@ func TestMatchAll(t *testing.T) {
 	}
 }
 
+// DEPRECATED
+
+func TestExactValidArgs(t *testing.T) {
+	c := getCommand(ExactValidArgs(3), true)
+	output, err := executeCommand(c, "three", "one", "two")
+	expectSuccess(output, err, t)
+}
+
+func TestExactValidArgs_WithInvalidCount(t *testing.T) {
+	c := getCommand(ExactValidArgs(2), false)
+	_, err := executeCommand(c, "three", "one", "two")
+	exactArgsWithInvalidCount(err, t)
+}
+
+func TestExactValidArgs_WithInvalidCount_WithInvalidArgs(t *testing.T) {
+	c := getCommand(ExactValidArgs(2), true)
+	_, err := executeCommand(c, "three", "a", "two")
+	exactArgsWithInvalidCount(err, t)
+}
+
+func TestExactValidArgs_WithInvalidArgs(t *testing.T) {
+	c := getCommand(ExactValidArgs(2), true)
+	_, err := executeCommand(c, "three", "a")
+	validOnlyWithInvalidArgs(err, t)
+}
+
 // This test make sure we keep backwards-compatibility with respect
 // to the legacyArgs() function.
 // It makes sure the root command accepts arguments if it does not have
diff --git a/bash_completionsV2_test.go b/bash_completionsV2_test.go
index a9a277e..9302baf 100644
--- a/bash_completionsV2_test.go
+++ b/bash_completionsV2_test.go
@@ -1,3 +1,17 @@
+// Copyright 2013-2022 The Cobra 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 cobra
 
 import (
diff --git a/bash_completions_test.go b/bash_completions_test.go
index 6896e91..5c32306 100644
--- a/bash_completions_test.go
+++ b/bash_completions_test.go
@@ -1,3 +1,17 @@
+// Copyright 2013-2022 The Cobra 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 cobra
 
 import (
diff --git a/cobra_test.go b/cobra_test.go
index 1219cc0..71353c9 100644
--- a/cobra_test.go
+++ b/cobra_test.go
@@ -1,3 +1,17 @@
+// Copyright 2013-2022 The Cobra 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 cobra
 
 import (
diff --git a/command_test.go b/command_test.go
index 0b0b821..b3dd030 100644
--- a/command_test.go
+++ b/command_test.go
@@ -1,3 +1,17 @@
+// Copyright 2013-2022 The Cobra 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 cobra
 
 import (
@@ -314,7 +328,7 @@ func TestEnablePrefixMatching(t *testing.T) {
 		t.Errorf("aCmdArgs expected: %q, got: %q", onetwo, got)
 	}
 
-	EnablePrefixMatching = false
+	EnablePrefixMatching = defaultPrefixMatching
 }
 
 func TestAliasPrefixMatching(t *testing.T) {
@@ -349,7 +363,7 @@ func TestAliasPrefixMatching(t *testing.T) {
 		t.Errorf("timesCmdArgs expected: %v, got: %v", onetwo, got)
 	}
 
-	EnablePrefixMatching = false
+	EnablePrefixMatching = defaultPrefixMatching
 }
 
 // TestChildSameName checks the correct behaviour of cobra in cases,
@@ -1263,6 +1277,113 @@ func TestSuggestions(t *testing.T) {
 	}
 }
 
+func TestCaseInsensitive(t *testing.T) {
+	rootCmd := &Command{Use: "root", Run: emptyRun}
+	childCmd := &Command{Use: "child", Run: emptyRun, Aliases: []string{"alternative"}}
+	granchildCmd := &Command{Use: "GRANDCHILD", Run: emptyRun, Aliases: []string{"ALIAS"}}
+
+	childCmd.AddCommand(granchildCmd)
+	rootCmd.AddCommand(childCmd)
+
+	tests := []struct {
+		args                []string
+		failWithoutEnabling bool
+	}{
+		{
+			args:                []string{"child"},
+			failWithoutEnabling: false,
+		},
+		{
+			args:                []string{"CHILD"},
+			failWithoutEnabling: true,
+		},
+		{
+			args:                []string{"chILD"},
+			failWithoutEnabling: true,
+		},
+		{
+			args:                []string{"CHIld"},
+			failWithoutEnabling: true,
+		},
+		{
+			args:                []string{"alternative"},
+			failWithoutEnabling: false,
+		},
+		{
+			args:                []string{"ALTERNATIVE"},
+			failWithoutEnabling: true,
+		},
+		{
+			args:                []string{"ALTernatIVE"},
+			failWithoutEnabling: true,
+		},
+		{
+			args:                []string{"alternatiVE"},
+			failWithoutEnabling: true,
+		},
+		{
+			args:                []string{"child", "GRANDCHILD"},
+			failWithoutEnabling: false,
+		},
+		{
+			args:                []string{"child", "grandchild"},
+			failWithoutEnabling: true,
+		},
+		{
+			args:                []string{"CHIld", "GRANdchild"},
+			failWithoutEnabling: true,
+		},
+		{
+			args:                []string{"alternative", "ALIAS"},
+			failWithoutEnabling: false,
+		},
+		{
+			args:                []string{"alternative", "alias"},
+			failWithoutEnabling: true,
+		},
+		{
+			args:                []string{"CHILD", "alias"},
+			failWithoutEnabling: true,
+		},
+		{
+			args:                []string{"CHIld", "aliAS"},
+			failWithoutEnabling: true,
+		},
+	}
+
+	for _, test := range tests {
+		for _, enableCaseInsensitivity := range []bool{true, false} {
+			EnableCaseInsensitive = enableCaseInsensitivity
+
+			output, err := executeCommand(rootCmd, test.args...)
+			expectedFailure := test.failWithoutEnabling && !enableCaseInsensitivity
+
+			if !expectedFailure && output != "" {
+				t.Errorf("Unexpected output: %v", output)
+			}
+			if !expectedFailure && err != nil {
+				t.Errorf("Unexpected error: %v", err)
+			}
+		}
+	}
+
+	EnableCaseInsensitive = defaultCaseInsensitive
+}
+
+// This test make sure we keep backwards-compatibility with respect
+// to command names case sensitivity behavior.
+func TestCaseSensitivityBackwardCompatibility(t *testing.T) {
+	rootCmd := &Command{Use: "root", Run: emptyRun}
+	childCmd := &Command{Use: "child", Run: emptyRun}
+
+	rootCmd.AddCommand(childCmd)
+	_, err := executeCommand(rootCmd, strings.ToUpper(childCmd.Use))
+	if err == nil {
+		t.Error("Expected error on calling a command in upper case while command names are case sensitive. Got nil.")
+	}
+
+}
+
 func TestRemoveCommand(t *testing.T) {
 	rootCmd := &Command{Use: "root", Args: NoArgs, Run: emptyRun}
 	childCmd := &Command{Use: "child", Run: emptyRun}
@@ -1622,7 +1743,7 @@ func TestCommandsAreSorted(t *testing.T) {
 		}
 	}
 
-	EnableCommandSorting = true
+	EnableCommandSorting = defaultCommandSorting
 }
 
 func TestEnableCommandSortingIsDisabled(t *testing.T) {
@@ -1643,7 +1764,7 @@ func TestEnableCommandSortingIsDisabled(t *testing.T) {
 		}
 	}
 
-	EnableCommandSorting = true
+	EnableCommandSorting = defaultCommandSorting
 }
 
 func TestSetOutput(t *testing.T) {
@@ -2222,3 +2343,90 @@ func TestSetContextPersistentPreRun(t *testing.T) {
 		t.Error(err)
 	}
 }
+
+const VersionFlag = "--version"
+const HelpFlag = "--help"
+
+func TestNoRootRunCommandExecutedWithVersionSet(t *testing.T) {
+	rootCmd := &Command{Use: "root", Version: "1.0.0", Long: "Long description"}
+	rootCmd.AddCommand(&Command{Use: "child", Run: emptyRun})
+
+	output, err := executeCommand(rootCmd)
+	if err != nil {
+		t.Errorf("Unexpected error: %v", err)
+	}
+
+	checkStringContains(t, output, rootCmd.Long)
+	checkStringContains(t, output, HelpFlag)
+	checkStringContains(t, output, VersionFlag)
+}
+
+func TestNoRootRunCommandExecutedWithoutVersionSet(t *testing.T) {
+	rootCmd := &Command{Use: "root", Long: "Long description"}
+	rootCmd.AddCommand(&Command{Use: "child", Run: emptyRun})
+
+	output, err := executeCommand(rootCmd)
+	if err != nil {
+		t.Errorf("Unexpected error: %v", err)
+	}
+
+	checkStringContains(t, output, rootCmd.Long)
+	checkStringContains(t, output, HelpFlag)
+	checkStringOmits(t, output, VersionFlag)
+}
+
+func TestHelpCommandExecutedWithVersionSet(t *testing.T) {
+	rootCmd := &Command{Use: "root", Version: "1.0.0", Long: "Long description", Run: emptyRun}
+	rootCmd.AddCommand(&Command{Use: "child", Run: emptyRun})
+
+	output, err := executeCommand(rootCmd, "help")
+	if err != nil {
+		t.Errorf("Unexpected error: %v", err)
+	}
+
+	checkStringContains(t, output, rootCmd.Long)
+	checkStringContains(t, output, HelpFlag)
+	checkStringContains(t, output, VersionFlag)
+}
+
+func TestHelpCommandExecutedWithoutVersionSet(t *testing.T) {
+	rootCmd := &Command{Use: "root", Long: "Long description", Run: emptyRun}
+	rootCmd.AddCommand(&Command{Use: "child", Run: emptyRun})
+
+	output, err := executeCommand(rootCmd, "help")
+	if err != nil {
+		t.Errorf("Unexpected error: %v", err)
+	}
+
+	checkStringContains(t, output, rootCmd.Long)
+	checkStringContains(t, output, HelpFlag)
+	checkStringOmits(t, output, VersionFlag)
+}
+
+func TestHelpflagCommandExecutedWithVersionSet(t *testing.T) {
+	rootCmd := &Command{Use: "root", Version: "1.0.0", Long: "Long description", Run: emptyRun}
+	rootCmd.AddCommand(&Command{Use: "child", Run: emptyRun})
+
+	output, err := executeCommand(rootCmd, HelpFlag)
+	if err != nil {
+		t.Errorf("Unexpected error: %v", err)
+	}
+
+	checkStringContains(t, output, rootCmd.Long)
+	checkStringContains(t, output, HelpFlag)
+	checkStringContains(t, output, VersionFlag)
+}
+
+func TestHelpflagCommandExecutedWithoutVersionSet(t *testing.T) {
+	rootCmd := &Command{Use: "root", Long: "Long description", Run: emptyRun}
+	rootCmd.AddCommand(&Command{Use: "child", Run: emptyRun})
+
+	output, err := executeCommand(rootCmd, HelpFlag)
+	if err != nil {
+		t.Errorf("Unexpected error: %v", err)
+	}
+
+	checkStringContains(t, output, rootCmd.Long)
+	checkStringContains(t, output, HelpFlag)
+	checkStringOmits(t, output, VersionFlag)
+}
diff --git a/completions_test.go b/completions_test.go
index fa087fd..c5f11fa 100644
--- a/completions_test.go
+++ b/completions_test.go
@@ -1,3 +1,17 @@
+// Copyright 2013-2022 The Cobra 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 cobra
 
 import (
diff --git a/doc/cmd_test.go b/doc/cmd_test.go
index 0917d60..4f2a0f5 100644
--- a/doc/cmd_test.go
+++ b/doc/cmd_test.go
@@ -1,3 +1,17 @@
+// Copyright 2013-2022 The Cobra 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 doc
 
 import (
diff --git a/doc/man_docs_test.go b/doc/man_docs_test.go
index f7994f8..d296eeb 100644
--- a/doc/man_docs_test.go
+++ b/doc/man_docs_test.go
@@ -1,3 +1,17 @@
+// Copyright 2013-2022 The Cobra 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 doc
 
 import (
diff --git a/doc/man_examples_test.go b/doc/man_examples_test.go
index e20a34c..b995bf6 100644
--- a/doc/man_examples_test.go
+++ b/doc/man_examples_test.go
@@ -1,3 +1,17 @@
+// Copyright 2013-2022 The Cobra 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 doc_test
 
 import (
diff --git a/doc/md_docs_test.go b/doc/md_docs_test.go
index f325167..b1632e9 100644
--- a/doc/md_docs_test.go
+++ b/doc/md_docs_test.go
@@ -1,3 +1,17 @@
+// Copyright 2013-2022 The Cobra 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 doc
 
 import (
diff --git a/doc/rest_docs_test.go b/doc/rest_docs_test.go
index 330a2e5..0c197f8 100644
--- a/doc/rest_docs_test.go
+++ b/doc/rest_docs_test.go
@@ -1,3 +1,17 @@
+// Copyright 2013-2022 The Cobra 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 doc
 
 import (
diff --git a/doc/yaml_docs_test.go b/doc/yaml_docs_test.go
index 9bf5aa6..c552077 100644
--- a/doc/yaml_docs_test.go
+++ b/doc/yaml_docs_test.go
@@ -1,3 +1,17 @@
+// Copyright 2013-2022 The Cobra 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 doc
 
 import (
diff --git a/fish_completions_test.go b/fish_completions_test.go
index 381c667..935f554 100644
--- a/fish_completions_test.go
+++ b/fish_completions_test.go
@@ -1,3 +1,17 @@
+// Copyright 2013-2022 The Cobra 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 cobra
 
 import (
diff --git a/flag_groups_test.go b/flag_groups_test.go
index 404ede5..b4b65ac 100644
--- a/flag_groups_test.go
+++ b/flag_groups_test.go
@@ -1,9 +1,10 @@
-// Copyright © 2022 Steve Francia <spf@spf13.com>.
+// Copyright 2013-2022 The Cobra 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
+//
+//      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,
diff --git a/power_completions_test.go b/power_completions_test.go
deleted file mode 100644
index 7713835..0000000
--- a/power_completions_test.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package cobra
-
-import (
-	"bytes"
-	"fmt"
-	"testing"
-)
-
-func TestPwshCompletionNoActiveHelp(t *testing.T) {
-	c := &Command{Use: "c", Run: emptyRun}
-
-	buf := new(bytes.Buffer)
-	assertNoErr(t, c.GenPowerShellCompletion(buf))
-	output := buf.String()
-
-	// check that active help is being disabled
-	activeHelpVar := activeHelpEnvVar(c.Name())
-	check(t, output, fmt.Sprintf("%s=0", activeHelpVar))
-}
diff --git a/powershell_completions_test.go b/powershell_completions_test.go
new file mode 100644
index 0000000..3d3d103
--- /dev/null
+++ b/powershell_completions_test.go
@@ -0,0 +1,33 @@
+// Copyright 2013-2022 The Cobra 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 cobra
+
+import (
+	"bytes"
+	"fmt"
+	"testing"
+)
+
+func TestPwshCompletionNoActiveHelp(t *testing.T) {
+	c := &Command{Use: "c", Run: emptyRun}
+
+	buf := new(bytes.Buffer)
+	assertNoErr(t, c.GenPowerShellCompletion(buf))
+	output := buf.String()
+
+	// check that active help is being disabled
+	activeHelpVar := activeHelpEnvVar(c.Name())
+	check(t, output, fmt.Sprintf("%s=0", activeHelpVar))
+}
diff --git a/zsh_completions_test.go b/zsh_completions_test.go
index b7addb4..258b1f7 100644
--- a/zsh_completions_test.go
+++ b/zsh_completions_test.go
@@ -1,3 +1,17 @@
+// Copyright 2013-2022 The Cobra 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 cobra
 
 import (