Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Active Help support #1482

Merged
merged 2 commits into from Jun 16, 2022
Merged

Conversation

marckhouzam
Copy link
Collaborator

@marckhouzam marckhouzam commented Sep 4, 2021

This PR is a proposal to enhance the shell completion logic with a framework for what I call "Active Help".

Active Help are messages (hints, warnings, etc) that are printed during the use of the program using the shell completion system. It aims to help teach how to use the program in an "active" fashion.

For example,

bash-5.1$ helm repo add [tab]
You must choose a name for the repo you are adding

bash-5.1$ bin/helm package [tab]
Please specify the path to the chart to package

# This last one is normal completion but shows that it works with the previous active help trigger
bash-5.1$ bin/helm package [tab][tab]
bin/    internal/    scripts/    pkg/     testdata/

Active Help messages are defined by the program by adding them as custom completions using ValidArgsFunction and RegisterFlagCompletionFunc and a new function: cobra.AppendActiveHelp(completionArray, activeHelpMessage).

Here is a 3 minute video illustrating how the feature can be used:

The PR contains documentation describing how to use the feature.

The PR adds the feature to both bash and zsh. It is probably do-able for powershell but I haven't tried. It is not possible to implement for fish currently.

I'd be interested to know if this is something of interest to the community.

Note:
For bash, version >= 4.4 of bash provides a smoother experience. In older versions of bash, when printing Active Help, the prompt will not be shown before what the user has typed, but will re-appear when normal completion is triggered. For example:

bash-4.3# bin/helm c<TAB>
HINT: The most common actions are: search, pull, install, list

# Notice the lack of prompt in the next line.  This only happens when there is an Active Help message
bin/helm c<TAB>
HINT: The most common actions are: search, pull, install, list

bin/helm c<TAB>
completion    create
bash-4.3# bin/helm c

Should Active Help be disabled completely for bash < 4.4, or is the lack of prompt acceptable?

Missing:

This can be seen in action using spf13/cobra-cli#24

Here is a test program that adds some active help:

Test program
package main

import (
	"fmt"
	"os"
	"strconv"
	"strings"

	"github.com/spf13/cobra"
)

var (
	completionNoDesc bool
	noMoreArgs       = "This command takes no more arguments"
)

var completionCmd = &cobra.Command{
	Use:   "completion [bash|bashv1|zsh|fish|powershell]",
	Short: "Generate completion script",
	Long: `Bash:
$ source <(testprog completion bash)

Zsh:
$ source <(testprog completion zsh)
$ compdef _testprog testprog

Fish:
$ testprog completion fish | source

PowerShell:
PS C:\> testprog completion powershell | Out-String | Invoke-Expression
`,
	DisableFlagsInUseLine: true,
	Args:                  cobra.ExactValidArgs(1),
	Run: func(cmd *cobra.Command, args []string) {
		switch args[0] {
		case "bash":
			cmd.Root().GenBashCompletionV2(os.Stdout, !completionNoDesc)
		case "bashv1":
			cmd.Root().GenBashCompletion(os.Stdout)
		case "zsh":
			if !completionNoDesc {
				cmd.Root().GenZshCompletion(os.Stdout)
			} else {
				cmd.Root().GenZshCompletionNoDesc(os.Stdout)
			}
		case "fish":
			cmd.Root().GenFishCompletion(os.Stdout, !completionNoDesc)
		case "powershell":
			if completionNoDesc {
				cmd.Root().GenPowerShellCompletion(os.Stdout)
			} else {
				cmd.Root().GenPowerShellCompletionWithDesc(os.Stdout)
			}
		}
	},
	ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		return []string{
			"bashv1\tBash completion V1",
			"bash\tBash completion V2",
			"zsh\tZsh completion",
			"fish\tFish completion",
			"pwsh\tPowershell completions"}, cobra.ShellCompDirectiveNoFileComp
	},
}

var rootCmd = &cobra.Command{
	Use: "testprog",
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("rootCmd called")
	},
	ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		return cobra.AppendActiveHelp(nil, "Choose a command to see different Active Help examples"),
			cobra.ShellCompDirectiveNoFileComp
	},
}

var onlyAH = &cobra.Command{
	Use:   "onlyAH",
	Short: "Command with Active Help but no args",
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("onlyAH called")
	},
	ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		return cobra.AppendActiveHelp(nil, noMoreArgs), cobra.ShellCompDirectiveNoFileComp
	},
}

var argsAndAH = &cobra.Command{
	Use:   "argsAndAH",
	Short: "Command with Active Help and one arg",
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("argsAndAH called")
	},
	ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		if len(args) == 0 {
			comps := []string{"firstArg", "secondArg"}
			comps = cobra.AppendActiveHelp(comps, "Please specify a single argument")
			comps = cobra.AppendActiveHelp(comps, "The arguments should be shown below if they match what you typed")
			return comps, cobra.ShellCompDirectiveNoFileComp
		}
		return cobra.AppendActiveHelp(nil, noMoreArgs), cobra.ShellCompDirectiveNoFileComp
	},
}

var filesAndAH = &cobra.Command{
	Use:   "filesAndAH",
	Short: "Command with Active Help and a file path",
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("filesAndAH called")
	},
	ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		if len(args) == 0 {
			return cobra.AppendActiveHelp(nil, "Please specify the path to a file"),
				cobra.ShellCompDirectiveDefault
		}
		return cobra.AppendActiveHelp(nil, noMoreArgs), cobra.ShellCompDirectiveNoFileComp
	},
}

var goFilesAndAH = &cobra.Command{
	Use:   "goFilesAndAH",
	Short: "Command with Active Help and a go file argument",
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("goFilesAndAH called")
	},
	ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		if len(args) == 0 {
			comps := cobra.AppendActiveHelp(nil, "Please specify the path to a file")
			comps = append(comps, "go")
			comps = cobra.AppendActiveHelp(comps, "On file ending with .go are allowed")
			return comps, cobra.ShellCompDirectiveFilterFileExt
		}
		return cobra.AppendActiveHelp(nil, noMoreArgs), cobra.ShellCompDirectiveNoFileComp

	},
}

var noSpaceAndAH = &cobra.Command{
	Use:   "noSpaceAndAH",
	Short: "Command with Active Help using the nospace directive",
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("noSpaceAndAH called")
	},
	ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		var comps []string
		if len(args) == 0 {
			if !strings.Contains(toComplete, "/") {
				comps = []string{"firstRepo/", "secondRepo/"}
				comps = cobra.AppendActiveHelp(comps, "Please choose a repository name")
				return comps, cobra.ShellCompDirectiveNoSpace | cobra.ShellCompDirectiveNoFileComp
			}

			repo := toComplete[:strings.Index(toComplete, "/")+1]
			comps = []string{repo + "firstChart", repo + "secondChart"}
			comps = cobra.AppendActiveHelp(comps, "Please choose a chart name")
			return comps, cobra.ShellCompDirectiveNoFileComp
		}
		return cobra.AppendActiveHelp(comps, "This command takes no more arguments"), cobra.ShellCompDirectiveNoFileComp
	},
}

var levelsForAH = &cobra.Command{
	Use:   "levelsForAH",
	Short: "Command that uses different levels of active help",
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("levelsForAH called")
	},
	ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		var comps []string
		if cobra.GetActiveHelpConfig(cmd) != "off" {
			comps = cobra.AppendActiveHelp(comps, "This msg displays as long as active help is not disabled")
			if cobra.GetActiveHelpConfig(cmd) == "on" {
				comps = cobra.AppendActiveHelp(comps, "This msg should not display if active help level is 'local'")
			}
		}

		comps = cobra.AppendActiveHelp(comps, noMoreArgs)
		return comps, cobra.ShellCompDirectiveNoFileComp

	},
}

func setFlags() {
	rootCmd.PersistentFlags().String("theme", "", "theme to use (located in /themes/THEMENAME/)")
	rootCmd.RegisterFlagCompletionFunc("theme", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		comps := []string{"themes"}
		comps = cobra.AppendActiveHelp(comps, "Please choose a theme from the list below")
		return comps, cobra.ShellCompDirectiveFilterDirs
	})

	rootCmd.PersistentFlags().Int("int", 0, "need an int as input")
	rootCmd.RegisterFlagCompletionFunc("int", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		comps := cobra.AppendActiveHelp(nil, "You must specify an integer")
		if len(toComplete) > 0 {
			if _, err := strconv.Atoi(toComplete); err != nil {
				comps = cobra.AppendActiveHelp(comps, "ERROR: What you have typed is not an integer")
			} else {
				comps = []string{toComplete}
			}
		}
		return comps, cobra.ShellCompDirectiveNoFileComp
	})

	rootCmd.PersistentFlags().Bool("bool", false, "boolean flag")
	rootCmd.RegisterFlagCompletionFunc("bool", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		return cobra.AppendActiveHelp(nil, "This is a boolean flag.  To disable it, remove the flag, or use --bool=false (the = is mandatory)"),
			cobra.ShellCompDirectiveNoFileComp
	})

}

func main() {
	completionCmd.Flags().BoolVar(
		&completionNoDesc,
		"no-descriptions", false,
		"disable completion description for shells that support it")
	rootCmd.AddCommand(completionCmd)

	rootCmd.AddCommand(
		onlyAH,
		argsAndAH,
		filesAndAH,
		goFilesAndAH,
		noSpaceAndAH,
		levelsForAH,
	)

	setFlags()

	rootCmd.Execute()
}

/cc @jpmcb @jharshman @Luap99

Copy link
Contributor

@Luap99 Luap99 left a comment

This is a very cool feature. Thanks for doing this.

completions.go Outdated Show resolved Hide resolved
@marckhouzam
Copy link
Collaborator Author

marckhouzam commented Sep 5, 2021

Here is the helm branch that uses this feature: https://github.com/VilledeMontreal/helm/tree/feat/compInfo

Without needing a kubernetes cluster, one can try:

cd helm
make
source <(bin/helm completion zsh) # or bash
bin/helm TAB
bin/helm repo add TAB
bin/helm repo add name TAB
bin/helm repo add name https TAB
bin/helm package TAB
bin/helm template TAB

I will make a smaller test program and post it in this PR. I should have thought about doing that before.

@marckhouzam
Copy link
Collaborator Author

marckhouzam commented Sep 6, 2021

I've just added a test program in the description of the PR which shows different Active Help scenarios and how to use the active help configuration

@jharshman
Copy link
Collaborator

jharshman commented Sep 8, 2021

@marckhouzam This is great IMO. I like the interactive nature of it and that it is opt-in. 🚀

@marckhouzam
Copy link
Collaborator Author

marckhouzam commented Sep 17, 2021

I've pushed an extra commit which uses the environment variable COBRA_ACTIVEHELP to configure Active Help instead of using a flag as mentioned by @Luap99. Looking at that one commit (and possibly reverting it) allows to compare the two approaches.

A nice thing about using an env var is that a user could set a different active help setting for individual commands by wrapping them in an alias or script which sets the env var (although that would be a pretty advanced usage).

Using a name like COBRA_ACTIVEHELP allows to set an active help level for all Cobra programs. However, I am afraid that contradicts the fact that different programs can choose whatever active help configuration they want to use. For example, helm could use active help levels of on/off/local but kubectl could use enabled/disabled/noremote; in such a case, using a global name such as COBRA_ACTIVEHELP makes the configuration not work.

We could instead use the program name in the variable, something like HELM_ACTIVEHELP and KUBECTL_ACTIVEHELP, and maybe have the global COBRA_ACTIVEHELP to only allow to disable active help for every program. I'm not sure if we need to go that far though.

Opinions on using a flag versus an env var?

@marckhouzam marckhouzam force-pushed the feat/ActiveHelp branch 2 times, most recently from 447ffb9 to 5e226f0 Compare Oct 9, 2021
@marckhouzam
Copy link
Collaborator Author

marckhouzam commented Oct 9, 2021

After some thought I agree with @Luap99 that it is best to use an environment variable to configure ActiveHelp. The fact that people install completion through a package manager does imply that using an env var is better to allow configuration changes to completion.

The latest version of the PR uses an environment variable per program (e.g, HELM_ACTIVE_HELP, PODMAN_ACTIVE_HELP). But it also support a global COBRA_ACTIVE_HELP which can only be set to "0" to turn off ActiveHelp for every program using Cobra.

I'll work on adding tests next.

@marckhouzam marckhouzam force-pushed the feat/ActiveHelp branch 4 times, most recently from dcd88bf to d84f81f Compare Oct 12, 2021
@marckhouzam
Copy link
Collaborator Author

marckhouzam commented Oct 12, 2021

I have added Go tests to the PR.

Also, thanks to the approach of using environment variables, there is nothing special to do for the default completion command provided by Cobra, as users will be able to configure Active Help using the environment variables.

This PR is ready for review. Thanks in advance.

@marckhouzam marckhouzam marked this pull request as ready for review Oct 12, 2021
@marckhouzam marckhouzam force-pushed the feat/ActiveHelp branch 2 times, most recently from e6631ac to 2a55698 Compare Oct 12, 2021
@marckhouzam marckhouzam changed the title [RFC] Add Active Help support Add Active Help support Oct 12, 2021
@marckhouzam marckhouzam force-pushed the feat/ActiveHelp branch 2 times, most recently from 3314024 to 2b81827 Compare Dec 9, 2021
@jpmcb jpmcb added this to the Next milestone Dec 10, 2021
@marckhouzam marckhouzam force-pushed the feat/ActiveHelp branch 3 times, most recently from 155729f to 397ba6d Compare Dec 18, 2021
@github-actions
Copy link

github-actions bot commented Feb 17, 2022

This PR is being marked as stale due to a long period of inactivity

@marckhouzam
Copy link
Collaborator Author

marckhouzam commented Feb 17, 2022

Still valid

Copy link
Contributor

@Luap99 Luap99 left a comment

Nice work, I really like the idea behind this.
I think it is cool to display a message when your command does not take args for example.

I tested this with bash and it works as I would expect.

func AppendActiveHelp(compArray []string, activeHelpStr string) []string {
return append(compArray, fmt.Sprintf("%s%s", activeHelpMarker, activeHelpStr))
}
Copy link
Contributor

@Luap99 Luap99 Mar 18, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure with the API here, why do I give the compArray as parameter and get the same value with the appended entry back.

IMO It would make more sense to have it like this:

func AppendActiveHelp(activeHelpStr string) string {
	return fmt.Sprintf("%s%s", activeHelpMarker, activeHelpStr)
}

and then in you code call

comps = append(comps, cobra.AppendActiveHelp("text"))

With this the caller has control over the append. While I do not think we need to worry about performance here I believe it is better when you call append only once.

text1 := cobra.AppendActiveHelp("text1")
text2 := cobra.AppendActiveHelp("text2")
comps = append(comps, text1, text2)

Copy link
Collaborator Author

@marckhouzam marckhouzam Mar 18, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I struggled to define a good API to add ActiveHelp messages. Here is how I remember choosing the AppendActiveHelp(compArray []string, activeHelpStr string) API.

  1. I was worried that it was not obvious that activeHelp messages should be included in the completions array returned by ValidArgsFunction; the two concepts could be seen as independent by users (completions and activeHelp messages). I therefore felt that by requiring the user to specify an array (and saying in the godoc that the array should be the one also containing the completion choices) we would make it much clearer that activeHelp messages should be included in the array of completions.
  2. based on that, I then thought we should mimic the behaviour of Go's append() which is why I called it AppendActiveHelp() and required the user to assign the result to an array (just like append()). All this in the hope to build on existing knowledge of an existing API.

If we end up preferring

func AppendActiveHelp(activeHelpStr string) string {
	return fmt.Sprintf("%s%s", activeHelpMarker, activeHelpStr)
}

we should probably rename the method to avoid using the word "append". We could create it as CreateActiveHelpMsg() for example.

But then I worry again that a user won't know easily what to do after having created an activeHelp message. Will they realize they must include it in the completions array?

Some people had trouble understanding what the arguments to ValidArgsFunction(cmd, args, toComplete) represented... So I don't want to assume anything is clear 😄

Copy link
Collaborator

@jpmcb jpmcb Jun 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmmmm this is a tricky one. I'm not sure on this.

I think I'm a fan of using the API presented here by Marc, but I'm warry of introducing more complexity to how users get their completions into their program.

But from my understanding of this, it's completely opt in? It's not another required step users must take to get their completions working?

Copy link
Collaborator Author

@marckhouzam marckhouzam Jun 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, the existing API for normal completions is not affected at all. ActiveHelp is 100% opt-in and can be completely ignored by programs using Cobra.

active_help.go Outdated Show resolved Hide resolved
@marckhouzam
Copy link
Collaborator Author

marckhouzam commented Mar 18, 2022

Nice work, I really like the idea behind this. I think it is cool to display a message when your command does not take args for example.

I expect the most common use of ActiveHelp will/should be to display a message when there are no completions suggested. When there are no completions, the user doesn't really know what to do, so an ActiveHelp message can explain (e.g., "This command does not take any more arguments", or "Please specify a name for the container that will be created").

I tested this with bash and it works as I would expect.

Thanks for trying it out!

@marckhouzam
Copy link
Collaborator Author

marckhouzam commented Mar 18, 2022

I've created a draft PR for the cobra-cli that uses ActiveHelp. I hope this show very easily how the feature can be used: spf13/cobra-cli#24

@johnSchnake I've spoken to others about this but not to you. I'd love your impressions on the feature.

marckhouzam added 2 commits Jun 13, 2022
Signed-off-by: Marc Khouzam <marc.khouzam@montreal.ca>
Signed-off-by: Marc Khouzam <marc.khouzam@montreal.ca>
@github-actions github-actions bot added size/XL Denotes a PR that exceeds 200 lines. Caution! and removed area/shell-completion All shell completions labels Jun 13, 2022
@github-actions
Copy link

github-actions bot commented Jun 13, 2022

This PR exceeds the recommended size of 200 lines. Please make sure you are NOT addressing multiple issues with one PR. Note this PR might be rejected due to its size.

@marckhouzam
Copy link
Collaborator Author

marckhouzam commented Jun 13, 2022

I've rebased this PR on top of the bash-v2 improvements that were recently merged. It is ready again.

@scop if you have a moment, maybe you can have a look at the bash code modifications to see if you notice anything wrong?

Copy link
Collaborator

@jpmcb jpmcb left a comment

Wow this is incredible. I love it.

Overall, I think this is ready for the spring release of Cobra we'll be cutting soon. I'm not super up to date on the zsh/bash completions scripting but it appears to work as expected. I'm comfortable cutting a path release if we need to fix bugs if needed.

It is not possible to implement for fish currently.

I'm curious! Something due to fish's spec?

@marckhouzam
Copy link
Collaborator Author

marckhouzam commented Jun 13, 2022

Thanks for trying this out @jpmcb 🎉

It is not possible to implement for fish currently.

I'm curious! Something due to fish's spec?

From what I remember of fish completion logic, there is no way to output something else than actual completions (can't generically print to stdout like bash allows); so my expectation is that ActiveHelp would be treated as a real completion and get sorted within the list of completions and would even be selectable as a completion through repeated TABing. So it wouldn't work as we would need.

Maybe @krobelus can confirm or correct this belief.

BTW, since I first opened the PR I took the time to try ActiveHelp with PowerShell and there too it is not possible to output anything else than actual completions (cannot print to stdout like bash allows). I may have an idea to hack something that may work but it would need more investigation that I haven't had time to dive deeper into. So for now, we would have to contend with bash and zsh (which until recently were pretty much the only two shells we supported anyway).

@jpmcb
Copy link
Collaborator

jpmcb commented Jun 15, 2022

I think this is good to merge and we can iterate as we get community feedback! Thoughts @marckhouzam? 🚀

@krobelus
Copy link
Contributor

krobelus commented Jun 15, 2022

From what I remember of fish completion logic, there is no way to output something else than actual completions (can't generically print to stdout like bash allows)

yeah, fish will likely overwrite that with the completion pager. I guess we can an API for adding arbitrary text.

@marckhouzam
Copy link
Collaborator Author

marckhouzam commented Jun 16, 2022

I think this is good to merge and we can iterate as we get community feedback! Thoughts @marckhouzam? 🚀

Let's do it! Thanks @jpmcb 🚀

@marckhouzam marckhouzam merged commit f464d6c into spf13:master Jun 16, 2022
15 checks passed
@marckhouzam marckhouzam deleted the feat/ActiveHelp branch Jun 16, 2022
@marckhouzam marckhouzam modified the milestones: Next, 1.5.0 Jun 16, 2022
@marckhouzam marckhouzam added area/shell-completion All shell completions and removed lifecycle/active Actively being worked on by a community member or maintainer. Corresponds to someone being assigned labels Jun 16, 2022
@scop
Copy link
Contributor

scop commented Jun 17, 2022

@scop if you have a moment, maybe you can have a look at the bash code modifications to see if you notice anything wrong?

Skimmed it real quick and didn't notice anything wrong. There's some room for cleanups along the lines of #1702, which I suppose we should amend to cover the things added here. But the feature looks quite interesting indeed 👍

aviator-app bot pushed a commit to airplanedev/cli that referenced this issue Jun 24, 2022
[![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [github.com/golang-jwt/jwt/v4](https://togithub.com/golang-jwt/jwt) | require | patch | `v4.4.1` -> `v4.4.2` |
| [github.com/spf13/cobra](https://togithub.com/spf13/cobra) | require | minor | `v1.4.0` -> `v1.5.0` |
| [github.com/stretchr/testify](https://togithub.com/stretchr/testify) | require | patch | `v1.7.2` -> `v1.7.5` |

---

### Release Notes

<details>
<summary>golang-jwt/jwt</summary>

### [`v4.4.2`](https://togithub.com/golang-jwt/jwt/releases/tag/v4.4.2)

[Compare Source](https://togithub.com/golang-jwt/jwt/compare/v4.4.1...v4.4.2)

#### What's Changed

-   Added MicahParks/keyfunc to extensions by [@&#8203;oxisto](https://togithub.com/oxisto) in [golang-jwt/jwt#194
-   Update link to v4 on pkg.go.dev page by [@&#8203;polRk](https://togithub.com/polRk) in [golang-jwt/jwt#195
-   add installation guidelines to the README file  by [@&#8203;morelmiles](https://togithub.com/morelmiles) in [golang-jwt/jwt#204
-   chore: replace ioutil with io and os by [@&#8203;estensen](https://togithub.com/estensen) in [golang-jwt/jwt#198
-   CI check for Go code formatting by [@&#8203;mfridman](https://togithub.com/mfridman) in [golang-jwt/jwt#206
-   Create SECURITY.md by [@&#8203;mfridman](https://togithub.com/mfridman) in [golang-jwt/jwt#171
-   Update SECURITY.md by [@&#8203;oxisto](https://togithub.com/oxisto) in [golang-jwt/jwt#207
-   Fixed integer overflow in NumericDate.MarshalJSON by [@&#8203;qqiao](https://togithub.com/qqiao) in [golang-jwt/jwt#200
-   Claims in rsa_test.go Table Driven Test are Unused by [@&#8203;gkech](https://togithub.com/gkech) in [golang-jwt/jwt#212

#### New Contributors

-   [@&#8203;polRk](https://togithub.com/polRk) made their first contribution in [golang-jwt/jwt#195
-   [@&#8203;morelmiles](https://togithub.com/morelmiles) made their first contribution in [golang-jwt/jwt#204
-   [@&#8203;estensen](https://togithub.com/estensen) made their first contribution in [golang-jwt/jwt#198
-   [@&#8203;qqiao](https://togithub.com/qqiao) made their first contribution in [golang-jwt/jwt#200
-   [@&#8203;gkech](https://togithub.com/gkech) made their first contribution in [golang-jwt/jwt#212

**Full Changelog**: golang-jwt/jwt@v4.4.1...v4.4.2

</details>

<details>
<summary>spf13/cobra</summary>

### [`v1.5.0`](https://togithub.com/spf13/cobra/releases/tag/v1.5.0)

[Compare Source](https://togithub.com/spf13/cobra/compare/v1.4.0...v1.5.0)

#### Spring 2022 Release 🌥️

Hello everyone! Welcome to another release of cobra. Completions continue to get better and better. This release adds a few really cool new features. We also continue to patch versions of our dependencies as they become available via dependabot. Happy coding!

#### Active help 👐🏼

Shout out to [@&#8203;marckhouzam](https://togithub.com/marckhouzam) for a big value add: Active Help [spf13/cobra#1482. With active help, a program can provide some inline warnings or hints for users as they hit tab. Now, your CLIs can be even more intuitive to use!

Currently active help is only supported for bash V2 and zsh. Marc wrote a whole guide on how to do this, so make sure to give it a good read to learn how you can add this to your cobra code! https://github.com/spf13/cobra/blob/master/active_help.md

#### Group flags 🧑🏼‍🤝‍🧑🏼

Cobra now has the ability to mark flags as required or exclusive as a ***group***. Shout out to our newest maintainer [@&#8203;johnSchnake](https://togithub.com/johnSchnake) for this! [spf13/cobra#1654 Let's say you have a `username` flag that ***MUST*** be partnered with a `password` flag. Well, now, you can enforce those as being required together:

```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")
```

Flags may also be marked as "mutally exclusive" with the `MarkFlagsMutuallyExclusive(string, string ... )` command API. Refer to our [user guide documentation](https://togithub.com/spf13/cobra/blob/master/user_guide.md) for further info!

#### Completions 👀

-   Add backwards-compatibility tests for legacyArgs() by [@&#8203;marckhouzam](https://togithub.com/marckhouzam) in [spf13/cobra#1547
-   feat: Add how to load completions in your current zsh session by [@&#8203;ondrejsika](https://togithub.com/ondrejsika) in [spf13/cobra#1608
-   Introduce FixedCompletions by [@&#8203;emersion](https://togithub.com/emersion) in [spf13/cobra#1574
-   Add shell completion to flag groups by [@&#8203;marckhouzam](https://togithub.com/marckhouzam) in [spf13/cobra#1659
-   Modify brew prefix path in macOS system by [@&#8203;imxw](https://togithub.com/imxw) in [spf13/cobra#1719
-   perf(bash-v2): use backslash escape string expansion for tab by [@&#8203;scop](https://togithub.com/scop) in [spf13/cobra#1682
-   style(bash-v2): out is not an array variable, do not refer to it as such by [@&#8203;scop](https://togithub.com/scop) in [spf13/cobra#1681
-   perf(bash-v2): standard completion optimizations by [@&#8203;scop](https://togithub.com/scop) in [spf13/cobra#1683
-   style(bash): out is not an array variable, do not refer to it as such by [@&#8203;scop](https://togithub.com/scop) in [spf13/cobra#1684
-   perf(bash-v2): short-circuit descriptionless candidate lists by [@&#8203;scop](https://togithub.com/scop) in [spf13/cobra#1686
-   perf(bash-v2): speed up filtering entries with descriptions by [@&#8203;scop](https://togithub.com/scop) in [spf13/cobra#1689
-   perf(bash-v2): speed up filtering menu-complete descriptions by [@&#8203;scop](https://togithub.com/scop) in [spf13/cobra#1692
-   fix(bash-v2): skip empty completions when filtering descriptions by [@&#8203;scop](https://togithub.com/scop) in [spf13/cobra#1691
-   perf(bash-v2): read directly to COMPREPLY on descriptionless short circuit by [@&#8203;scop](https://togithub.com/scop) in [spf13/cobra#1700
-   fix: Don't complete \_command on zsh by [@&#8203;twpayne](https://togithub.com/twpayne) in [spf13/cobra#1690
-   Improve fish_completions code quality by [@&#8203;t29kida](https://togithub.com/t29kida) in [spf13/cobra#1515
-   Fix handling of descriptions for bash v3 by [@&#8203;marckhouzam](https://togithub.com/marckhouzam) in [spf13/cobra#1735
-   undefined or nil Args default to ArbitraryArgs by [@&#8203;umarcor](https://togithub.com/umarcor) in [spf13/cobra#1612
-   Add Command.SetContext by [@&#8203;joshcarp](https://togithub.com/joshcarp) in [spf13/cobra#1551
-   Wrap printf tab with quotes by [@&#8203;PapaCharlie](https://togithub.com/PapaCharlie) in [spf13/cobra#1665

#### Documentation 📝

-   Fixed typos in completions docs - [@&#8203;cuishuang](https://togithub.com/cuishuang) [spf13/cobra#1625
-   Removed `CHANGELOG.md` as it isn't updated - [@&#8203;johnSchnake](https://togithub.com/johnSchnake) [spf13/cobra#1634
-   Minor typo fix in `shell_completion.md` - [@&#8203;danieldn](https://togithub.com/danieldn) [spf13/cobra#1678
-   Changed branch name in the cobra generator link to 'main' - [@&#8203;skywalker2909](https://togithub.com/skywalker2909) [spf13/cobra#1645
-   Fix Command.Context comment by [@&#8203;katexochen](https://togithub.com/katexochen) in [spf13/cobra#1639
-   Change appropriate links from http:// to https:// where applicable - [@&#8203;deining](https://togithub.com/deining) [spf13/cobra#1695

#### Testing & CI ⚙️

-   Test on Golang 1.18 - [@&#8203;umarcor](https://togithub.com/umarcor) [spf13/cobra#1635
-   Use `RICHGO_FORCE_COLOR` - [@&#8203;umarcor](https://togithub.com/umarcor) [spf13/cobra#1647
-   Adds size labeler GitHub action by [@&#8203;jpmcb](https://togithub.com/jpmcb) in [spf13/cobra#1610
-   Update `stale-bot` settings - [@&#8203;jpmcb](https://togithub.com/jpmcb) [spf13/cobra#1609

#### Beep boop, bot commits 🤖

-   Bumped golangci/golangci-lint-action from 3.1.0 to 3.2.0 - [@&#8203;dependabot](https://togithub.com/dependabot) [spf13/cobra#1697
-   Bump codelytv/pr-size-labeler from 1.8.0 to 1.8.1 - [@&#8203;dependabot](https://togithub.com/dependabot) [spf13/cobra#1661
-   Bump actions/stale from 1 to 5 by [@&#8203;dependabot](https://togithub.com/dependabot) in [spf13/cobra#1618
-   Bump actions/cache from 2 to 3 by [@&#8203;dependabot](https://togithub.com/dependabot) in [spf13/cobra#1640
-   Bump actions/labeler from 3 to 4 by [@&#8203;dependabot](https://togithub.com/dependabot) in [spf13/cobra#1620
-   Bump golangci/golangci-lint-action from 2 to 3.1.0 by [@&#8203;dependabot](https://togithub.com/dependabot) in [spf13/cobra#1615
-   Bump actions/checkout from 2 to 3 by [@&#8203;dependabot](https://togithub.com/dependabot) in [spf13/cobra#1619
-   Bump github.com/cpuguy83/go-md2man/v2 from 2.0.1 to 2.0.2 by [@&#8203;dependabot](https://togithub.com/dependabot) in [spf13/cobra#1688
-   Bump actions/setup-go from 2 to 3 by [@&#8203;dependabot](https://togithub.com/dependabot) in [spf13/cobra#1660

#### Misc 💭

-   Use `errors.Is()` to check for errors - [@&#8203;Luap99](https://togithub.com/Luap99) [spf13/cobra#1730
-   Prefer ReplaceAll instead of Replace(..., -1) by [@&#8203;WhyNotHugo](https://togithub.com/WhyNotHugo) in [spf13/cobra#1530
-   Add Kubescape to projects - [@&#8203;avinashupadhya99](https://togithub.com/avinashupadhya99) [spf13/cobra#1642
-   Add Pulumi as a project using cobra by [@&#8203;iwahbe](https://togithub.com/iwahbe) in [spf13/cobra#1720
-   Add Polygon Edge as a project using Cobra by [@&#8203;zivkovicmilos](https://togithub.com/zivkovicmilos) in [spf13/cobra#1672

Shoutout to *ALL* our contributors (and all the new first time contributors!!) - great work everyone!! Cobra and it's huge impact wouldn't be possible without you 👏🏼  🚀  🐍

**Full Changelog**: spf13/cobra@v1.4.0...v1.5.0

</details>

<details>
<summary>stretchr/testify</summary>

### [`v1.7.5`](https://togithub.com/stretchr/testify/compare/v1.7.4...v1.7.5)

[Compare Source](https://togithub.com/stretchr/testify/compare/v1.7.4...v1.7.5)

### [`v1.7.4`](https://togithub.com/stretchr/testify/compare/v1.7.3...v1.7.4)

[Compare Source](https://togithub.com/stretchr/testify/compare/v1.7.3...v1.7.4)

### [`v1.7.3`](https://togithub.com/stretchr/testify/compare/v1.7.2...v1.7.3)

[Compare Source](https://togithub.com/stretchr/testify/compare/v1.7.2...v1.7.3)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "before 5am on Thursday" in timezone America/New_York, Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

 **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://togithub.com/renovatebot/renovate/discussions) if that's undesired.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, click this checkbox.
gcf-merge-on-green bot pushed a commit to googleapis/gapic-showcase that referenced this issue Jun 27, 2022
[![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [github.com/spf13/cobra](https://togithub.com/spf13/cobra) | require | minor | `v1.4.0` -> `v1.5.0` |

---

### Release Notes

<details>
<summary>spf13/cobra</summary>

### [`v1.5.0`](https://togithub.com/spf13/cobra/releases/tag/v1.5.0)

[Compare Source](https://togithub.com/spf13/cobra/compare/v1.4.0...v1.5.0)

#### Spring 2022 Release 🌥️

Hello everyone! Welcome to another release of cobra. Completions continue to get better and better. This release adds a few really cool new features. We also continue to patch versions of our dependencies as they become available via dependabot. Happy coding!

#### Active help 👐🏼

Shout out to [@&#8203;marckhouzam](https://togithub.com/marckhouzam) for a big value add: Active Help [spf13/cobra#1482. With active help, a program can provide some inline warnings or hints for users as they hit tab. Now, your CLIs can be even more intuitive to use!

Currently active help is only supported for bash V2 and zsh. Marc wrote a whole guide on how to do this, so make sure to give it a good read to learn how you can add this to your cobra code! https://github.com/spf13/cobra/blob/master/active_help.md

#### Group flags 🧑🏼‍🤝‍🧑🏼

Cobra now has the ability to mark flags as required or exclusive as a ***group***. Shout out to our newest maintainer [@&#8203;johnSchnake](https://togithub.com/johnSchnake) for this! [spf13/cobra#1654 Let's say you have a `username` flag that ***MUST*** be partnered with a `password` flag. Well, now, you can enforce those as being required together:

```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")
```

Flags may also be marked as "mutally exclusive" with the `MarkFlagsMutuallyExclusive(string, string ... )` command API. Refer to our [user guide documentation](https://togithub.com/spf13/cobra/blob/master/user_guide.md) for further info!

#### Completions 👀

-   Add backwards-compatibility tests for legacyArgs() by [@&#8203;marckhouzam](https://togithub.com/marckhouzam) in [spf13/cobra#1547
-   feat: Add how to load completions in your current zsh session by [@&#8203;ondrejsika](https://togithub.com/ondrejsika) in [spf13/cobra#1608
-   Introduce FixedCompletions by [@&#8203;emersion](https://togithub.com/emersion) in [spf13/cobra#1574
-   Add shell completion to flag groups by [@&#8203;marckhouzam](https://togithub.com/marckhouzam) in [spf13/cobra#1659
-   Modify brew prefix path in macOS system by [@&#8203;imxw](https://togithub.com/imxw) in [spf13/cobra#1719
-   perf(bash-v2): use backslash escape string expansion for tab by [@&#8203;scop](https://togithub.com/scop) in [spf13/cobra#1682
-   style(bash-v2): out is not an array variable, do not refer to it as such by [@&#8203;scop](https://togithub.com/scop) in [spf13/cobra#1681
-   perf(bash-v2): standard completion optimizations by [@&#8203;scop](https://togithub.com/scop) in [spf13/cobra#1683
-   style(bash): out is not an array variable, do not refer to it as such by [@&#8203;scop](https://togithub.com/scop) in [spf13/cobra#1684
-   perf(bash-v2): short-circuit descriptionless candidate lists by [@&#8203;scop](https://togithub.com/scop) in [spf13/cobra#1686
-   perf(bash-v2): speed up filtering entries with descriptions by [@&#8203;scop](https://togithub.com/scop) in [spf13/cobra#1689
-   perf(bash-v2): speed up filtering menu-complete descriptions by [@&#8203;scop](https://togithub.com/scop) in [spf13/cobra#1692
-   fix(bash-v2): skip empty completions when filtering descriptions by [@&#8203;scop](https://togithub.com/scop) in [spf13/cobra#1691
-   perf(bash-v2): read directly to COMPREPLY on descriptionless short circuit by [@&#8203;scop](https://togithub.com/scop) in [spf13/cobra#1700
-   fix: Don't complete \_command on zsh by [@&#8203;twpayne](https://togithub.com/twpayne) in [spf13/cobra#1690
-   Improve fish_completions code quality by [@&#8203;t29kida](https://togithub.com/t29kida) in [spf13/cobra#1515
-   Fix handling of descriptions for bash v3 by [@&#8203;marckhouzam](https://togithub.com/marckhouzam) in [spf13/cobra#1735
-   undefined or nil Args default to ArbitraryArgs by [@&#8203;umarcor](https://togithub.com/umarcor) in [spf13/cobra#1612
-   Add Command.SetContext by [@&#8203;joshcarp](https://togithub.com/joshcarp) in [spf13/cobra#1551
-   Wrap printf tab with quotes by [@&#8203;PapaCharlie](https://togithub.com/PapaCharlie) in [spf13/cobra#1665

#### Documentation 📝

-   Fixed typos in completions docs - [@&#8203;cuishuang](https://togithub.com/cuishuang) [spf13/cobra#1625
-   Removed `CHANGELOG.md` as it isn't updated - [@&#8203;johnSchnake](https://togithub.com/johnSchnake) [spf13/cobra#1634
-   Minor typo fix in `shell_completion.md` - [@&#8203;danieldn](https://togithub.com/danieldn) [spf13/cobra#1678
-   Changed branch name in the cobra generator link to 'main' - [@&#8203;skywalker2909](https://togithub.com/skywalker2909) [spf13/cobra#1645
-   Fix Command.Context comment by [@&#8203;katexochen](https://togithub.com/katexochen) in [spf13/cobra#1639
-   Change appropriate links from http:// to https:// where applicable - [@&#8203;deining](https://togithub.com/deining) [spf13/cobra#1695

#### Testing & CI ⚙️

-   Test on Golang 1.18 - [@&#8203;umarcor](https://togithub.com/umarcor) [spf13/cobra#1635
-   Use `RICHGO_FORCE_COLOR` - [@&#8203;umarcor](https://togithub.com/umarcor) [spf13/cobra#1647
-   Adds size labeler GitHub action by [@&#8203;jpmcb](https://togithub.com/jpmcb) in [spf13/cobra#1610
-   Update `stale-bot` settings - [@&#8203;jpmcb](https://togithub.com/jpmcb) [spf13/cobra#1609

#### Beep boop, bot commits 🤖

-   Bumped golangci/golangci-lint-action from 3.1.0 to 3.2.0 - [@&#8203;dependabot](https://togithub.com/dependabot) [spf13/cobra#1697
-   Bump codelytv/pr-size-labeler from 1.8.0 to 1.8.1 - [@&#8203;dependabot](https://togithub.com/dependabot) [spf13/cobra#1661
-   Bump actions/stale from 1 to 5 by [@&#8203;dependabot](https://togithub.com/dependabot) in [spf13/cobra#1618
-   Bump actions/cache from 2 to 3 by [@&#8203;dependabot](https://togithub.com/dependabot) in [spf13/cobra#1640
-   Bump actions/labeler from 3 to 4 by [@&#8203;dependabot](https://togithub.com/dependabot) in [spf13/cobra#1620
-   Bump golangci/golangci-lint-action from 2 to 3.1.0 by [@&#8203;dependabot](https://togithub.com/dependabot) in [spf13/cobra#1615
-   Bump actions/checkout from 2 to 3 by [@&#8203;dependabot](https://togithub.com/dependabot) in [spf13/cobra#1619
-   Bump github.com/cpuguy83/go-md2man/v2 from 2.0.1 to 2.0.2 by [@&#8203;dependabot](https://togithub.com/dependabot) in [spf13/cobra#1688
-   Bump actions/setup-go from 2 to 3 by [@&#8203;dependabot](https://togithub.com/dependabot) in [spf13/cobra#1660

#### Misc 💭

-   Use `errors.Is()` to check for errors - [@&#8203;Luap99](https://togithub.com/Luap99) [spf13/cobra#1730
-   Prefer ReplaceAll instead of Replace(..., -1) by [@&#8203;WhyNotHugo](https://togithub.com/WhyNotHugo) in [spf13/cobra#1530
-   Add Kubescape to projects - [@&#8203;avinashupadhya99](https://togithub.com/avinashupadhya99) [spf13/cobra#1642
-   Add Pulumi as a project using cobra by [@&#8203;iwahbe](https://togithub.com/iwahbe) in [spf13/cobra#1720
-   Add Polygon Edge as a project using Cobra by [@&#8203;zivkovicmilos](https://togithub.com/zivkovicmilos) in [spf13/cobra#1672

Shoutout to *ALL* our contributors (and all the new first time contributors!!) - great work everyone!! Cobra and it's huge impact wouldn't be possible without you 👏🏼  🚀  🐍

**Full Changelog**: spf13/cobra@v1.4.0...v1.5.0

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

 **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, click this checkbox.

---

This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/gapic-showcase).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/shell-completion All shell completions kind/feature A feature request for cobra; new or enhanced behavior size/XL Denotes a PR that exceeds 200 lines. Caution!
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants