forked from containers/toolbox
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
cmd: Add shell completion command & generate completion
Cobra (the CLI library) has an advanced support for generating shell completion. It support Bash, Zsh, Fish and PowerShell. This offering covers the majority of use cases with some exceptions, of course. The generated completion scripts have one behavioral difference when compared to the existing solution: flags (--xxx) are not shown by default. User needs to type '-' first to get the completion. containers#840 Co-authored-by: Ondřej Míchal <harrymichal@seznam.cz>
- Loading branch information
1 parent
8bcb56a
commit b3e4bde
Showing
11 changed files
with
257 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,206 @@ | ||
package cmd | ||
|
||
import ( | ||
"os" | ||
"strings" | ||
|
||
"github.com/containers/toolbox/pkg/utils" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
var completionCmd = &cobra.Command{ | ||
Use: "completion [bash|zsh|fish|powershell]", | ||
Short: "Generate completion script", | ||
Long: `To load completions: | ||
Bash: | ||
$ source <(toolbox completion bash) | ||
# To load completions for each session, execute once: | ||
# Linux: | ||
$ toolbox completion bash > /etc/bash_completion.d/toolbox | ||
# macOS: | ||
$ toolbox completion bash > /usr/local/etc/bash_completion.d/toolbox | ||
Zsh: | ||
# If shell completion is not already enabled in your environment, | ||
# you will need to enable it. You can execute the following once: | ||
$ echo "autoload -U compinit; compinit" >> ~/.zshrc | ||
# To load completions for each session, execute once: | ||
$ toolbox completion zsh > "${fpath[1]}/_toolbox" | ||
# You will need to start a new shell for this setup to take effect. | ||
fish: | ||
$ toolbox completion fish | source | ||
# To load completions for each session, execute once: | ||
$ toolbox completion fish > ~/.config/fish/completions/toolbox.fish | ||
`, | ||
Hidden: true, | ||
DisableFlagsInUseLine: true, | ||
ValidArgs: []string{"bash", "zsh", "fish"}, | ||
Args: cobra.ExactValidArgs(1), | ||
Run: func(cmd *cobra.Command, args []string) { | ||
switch args[0] { | ||
case "bash": | ||
cmd.Root().GenBashCompletion(os.Stdout) | ||
case "zsh": | ||
cmd.Root().GenZshCompletion(os.Stdout) | ||
case "fish": | ||
cmd.Root().GenFishCompletion(os.Stdout, true) | ||
} | ||
}, | ||
} | ||
|
||
func init() { | ||
rootCmd.AddCommand(completionCmd) | ||
} | ||
|
||
func completionEmpty(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) { | ||
return nil, cobra.ShellCompDirectiveNoFileComp | ||
} | ||
|
||
func completionCommands(cmd *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) { | ||
commandNames := []string{} | ||
commands := cmd.Root().Commands() | ||
for _, command := range commands { | ||
if strings.Contains(command.Name(), "complet") { | ||
continue | ||
} | ||
commandNames = append(commandNames, command.Name()) | ||
} | ||
|
||
return commandNames, cobra.ShellCompDirectiveNoFileComp | ||
} | ||
|
||
func completionContainerNames(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) { | ||
containerNames := []string{} | ||
if containers, err := getContainers(); err == nil { | ||
for _, container := range containers { | ||
containerNames = append(containerNames, container.Names[0]) | ||
} | ||
} | ||
|
||
if len(containerNames) == 0 { | ||
return nil, cobra.ShellCompDirectiveNoFileComp | ||
} | ||
|
||
return containerNames, cobra.ShellCompDirectiveNoFileComp | ||
} | ||
|
||
func completionContainerNamesFiltered(cmd *cobra.Command, args []string, _ string) ([]string, cobra.ShellCompDirective) { | ||
if cmd.Name() == "enter" && len(args) >= 1 { | ||
return nil, cobra.ShellCompDirectiveNoFileComp | ||
} | ||
|
||
containerNames := []string{} | ||
if containers, err := getContainers(); err == nil { | ||
for _, container := range containers { | ||
skip := false | ||
for _, arg := range args { | ||
if container.Names[0] == arg { | ||
skip = true | ||
break | ||
} | ||
} | ||
|
||
if skip { | ||
continue | ||
} | ||
|
||
containerNames = append(containerNames, container.Names[0]) | ||
} | ||
} | ||
|
||
if len(containerNames) == 0 { | ||
return nil, cobra.ShellCompDirectiveNoFileComp | ||
} | ||
|
||
return containerNames, cobra.ShellCompDirectiveNoFileComp | ||
|
||
} | ||
|
||
func completionDistroNames(cmd *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) { | ||
imageFlag := cmd.Flag("image") | ||
if imageFlag != nil && imageFlag.Changed { | ||
return nil, cobra.ShellCompDirectiveNoFileComp | ||
} | ||
|
||
distros := []string{} | ||
supportedDistros := utils.GetSupportedDistros() | ||
for key := range supportedDistros { | ||
distros = append(distros, key) | ||
} | ||
|
||
return distros, cobra.ShellCompDirectiveNoFileComp | ||
} | ||
|
||
func completionImageNames(cmd *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) { | ||
distroFlag := cmd.Flag("distro") | ||
if distroFlag != nil && distroFlag.Changed { | ||
return nil, cobra.ShellCompDirectiveNoFileComp | ||
} | ||
|
||
imageNames := []string{} | ||
if images, err := getImages(); err == nil { | ||
for _, image := range images { | ||
if len(image.Names) > 0 { | ||
imageNames = append(imageNames, image.Names[0]) | ||
} else { | ||
imageNames = append(imageNames, image.ID) | ||
} | ||
} | ||
} | ||
|
||
if len(imageNames) == 0 { | ||
return nil, cobra.ShellCompDirectiveNoFileComp | ||
} | ||
|
||
return imageNames, cobra.ShellCompDirectiveNoFileComp | ||
} | ||
|
||
func completionImageNamesFiltered(_ *cobra.Command, args []string, _ string) ([]string, cobra.ShellCompDirective) { | ||
imageNames := []string{} | ||
if images, err := getImages(); err == nil { | ||
for _, image := range images { | ||
skip := false | ||
var imageName string | ||
|
||
if len(image.Names) > 0 { | ||
imageName = image.Names[0] | ||
} else { | ||
imageName = image.ID | ||
} | ||
|
||
for _, arg := range args { | ||
if arg == imageName { | ||
skip = true | ||
break | ||
} | ||
} | ||
|
||
if skip { | ||
continue | ||
} | ||
|
||
imageNames = append(imageNames, imageName) | ||
} | ||
} | ||
|
||
if len(imageNames) == 0 { | ||
return nil, cobra.ShellCompDirectiveNoFileComp | ||
} | ||
|
||
return imageNames, cobra.ShellCompDirectiveNoFileComp | ||
} | ||
|
||
func completionLogLevels(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) { | ||
return []string{"trace", "debug", "info", "warn", "error", "fatal", "panic"}, cobra.ShellCompDirectiveNoFileComp | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters