mirror of
https://github.com/containers/podman.git
synced 2025-06-20 00:51:16 +08:00
Merge pull request #8635 from Luap99/shell-completion-test
Add system test for shell completion
This commit is contained in:
@ -278,7 +278,6 @@ func validCurrentCmdLine(cmd *cobra.Command, args []string, toComplete string) b
|
||||
return true
|
||||
}
|
||||
}
|
||||
cobra.CompDebugln(err.Error(), true)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
@ -445,6 +444,29 @@ func AutocompleteNetworks(cmd *cobra.Command, args []string, toComplete string)
|
||||
return getNetworks(cmd, toComplete)
|
||||
}
|
||||
|
||||
// AutocompleteDefaultOneArg - Autocomplete path only for the first argument.
|
||||
func AutocompleteDefaultOneArg(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
if len(args) == 0 {
|
||||
return nil, cobra.ShellCompDirectiveDefault
|
||||
}
|
||||
return nil, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
|
||||
// AutocompleteCommitCommand - Autocomplete podman commit command args.
|
||||
func AutocompleteCommitCommand(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
if !validCurrentCmdLine(cmd, args, toComplete) {
|
||||
return nil, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
if len(args) == 0 {
|
||||
return getContainers(cmd, toComplete, completeDefault)
|
||||
}
|
||||
if len(args) == 1 {
|
||||
return getImages(cmd, toComplete)
|
||||
}
|
||||
// don't complete more than 2 args
|
||||
return nil, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
|
||||
// AutocompleteCpCommand - Autocomplete podman cp command args.
|
||||
func AutocompleteCpCommand(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
if !validCurrentCmdLine(cmd, args, toComplete) {
|
||||
@ -465,6 +487,43 @@ func AutocompleteCpCommand(cmd *cobra.Command, args []string, toComplete string)
|
||||
return nil, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
|
||||
// AutocompleteExecCommand - Autocomplete podman exec command args.
|
||||
func AutocompleteExecCommand(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
if !validCurrentCmdLine(cmd, args, toComplete) {
|
||||
return nil, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
if len(args) == 0 {
|
||||
return getContainers(cmd, toComplete, completeDefault, "running")
|
||||
}
|
||||
return nil, cobra.ShellCompDirectiveDefault
|
||||
}
|
||||
|
||||
// AutocompleteRunlabelCommand - Autocomplete podman container runlabel command args.
|
||||
func AutocompleteRunlabelCommand(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
if !validCurrentCmdLine(cmd, args, toComplete) {
|
||||
return nil, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
if len(args) == 0 {
|
||||
// FIXME: What labels can we recommend here?
|
||||
return nil, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
if len(args) == 1 {
|
||||
return getImages(cmd, toComplete)
|
||||
}
|
||||
return nil, cobra.ShellCompDirectiveDefault
|
||||
}
|
||||
|
||||
// AutocompletePortCommand - Autocomplete podman port command args.
|
||||
func AutocompletePortCommand(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
if !validCurrentCmdLine(cmd, args, toComplete) {
|
||||
return nil, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
if len(args) == 0 {
|
||||
return getContainers(cmd, toComplete, completeDefault)
|
||||
}
|
||||
return nil, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
|
||||
// AutocompleteNetworkConnectCmd - Autocomplete podman network connect/disconnect command args.
|
||||
func AutocompleteNetworkConnectCmd(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
if len(args) == 0 {
|
||||
@ -496,6 +555,23 @@ func AutocompleteTopCmd(cmd *cobra.Command, args []string, toComplete string) ([
|
||||
return descriptors, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
|
||||
// AutocompleteInspect - Autocomplete podman inspect.
|
||||
func AutocompleteInspect(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
if !validCurrentCmdLine(cmd, args, toComplete) {
|
||||
return nil, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
containers, _ := getContainers(cmd, toComplete, completeDefault)
|
||||
images, _ := getImages(cmd, toComplete)
|
||||
pods, _ := getPods(cmd, toComplete, completeDefault)
|
||||
networks, _ := getNetworks(cmd, toComplete)
|
||||
volumes, _ := getVolumes(cmd, toComplete)
|
||||
suggestions := append(containers, images...)
|
||||
suggestions = append(suggestions, pods...)
|
||||
suggestions = append(suggestions, networks...)
|
||||
suggestions = append(suggestions, volumes...)
|
||||
return suggestions, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
|
||||
// AutocompleteSystemConnections - Autocomplete system connections.
|
||||
func AutocompleteSystemConnections(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
if !validCurrentCmdLine(cmd, args, toComplete) {
|
||||
|
@ -24,7 +24,7 @@ var (
|
||||
Long: commitDescription,
|
||||
RunE: commit,
|
||||
Args: cobra.RangeArgs(1, 2),
|
||||
ValidArgsFunction: common.AutocompleteContainers,
|
||||
ValidArgsFunction: common.AutocompleteCommitCommand,
|
||||
Example: `podman commit -q --message "committing container to image" reverent_golick image-committed
|
||||
podman commit -q --author "firstName lastName" reverent_golick image-committed
|
||||
podman commit -q --pause=false containerID image-committed
|
||||
|
@ -13,7 +13,7 @@ var (
|
||||
You can copy from the container's file system to the local machine or the reverse, from the local filesystem to the container. If "-" is specified for either the SRC_PATH or DEST_PATH, you can also stream a tar archive from STDIN or to STDOUT. The CONTAINER can be a running or stopped container. The SRC_PATH or DEST_PATH can be a file or directory.
|
||||
`
|
||||
cpCommand = &cobra.Command{
|
||||
Use: "cp [options] SRC_PATH DEST_PATH",
|
||||
Use: "cp [options] [CONTAINER:]SRC_PATH [CONTAINER:]DEST_PATH",
|
||||
Short: "Copy files/folders between a container and the local filesystem",
|
||||
Long: cpDescription,
|
||||
Args: cobra.ExactArgs(2),
|
||||
|
@ -26,7 +26,7 @@ var (
|
||||
Long: execDescription,
|
||||
RunE: exec,
|
||||
DisableFlagsInUseLine: true,
|
||||
ValidArgsFunction: common.AutocompleteContainersRunning,
|
||||
ValidArgsFunction: common.AutocompleteExecCommand,
|
||||
Example: `podman exec -it ctrID ls
|
||||
podman exec -it -w /tmp myCtr pwd
|
||||
podman exec --user root ctrID ls`,
|
||||
|
@ -69,6 +69,12 @@ var (
|
||||
)
|
||||
|
||||
func init() {
|
||||
// if run remotely we only allow one container arg
|
||||
if registry.IsRemote() {
|
||||
logsCommand.Use = "logs [options] CONTAINER"
|
||||
containerLogsCommand.Use = logsCommand.Use
|
||||
}
|
||||
|
||||
// logs
|
||||
registry.Commands = append(registry.Commands, registry.CliCommand{
|
||||
Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
|
||||
|
@ -26,7 +26,7 @@ var (
|
||||
Args: func(cmd *cobra.Command, args []string) error {
|
||||
return validate.CheckAllLatestAndCIDFile(cmd, args, true, false)
|
||||
},
|
||||
ValidArgsFunction: common.AutocompleteContainers,
|
||||
ValidArgsFunction: common.AutocompletePortCommand,
|
||||
Example: `podman port --all
|
||||
podman port ctrID 80/tcp
|
||||
podman port --latest 80`,
|
||||
|
@ -30,7 +30,7 @@ var (
|
||||
Long: runlabelDescription,
|
||||
RunE: runlabel,
|
||||
Args: cobra.MinimumNArgs(2),
|
||||
ValidArgsFunction: common.AutocompleteImages,
|
||||
ValidArgsFunction: common.AutocompleteRunlabelCommand,
|
||||
Example: `podman container runlabel run imageID
|
||||
podman container runlabel install imageID arg1 arg2
|
||||
podman container runlabel --display run myImage`,
|
||||
|
@ -18,7 +18,7 @@ var (
|
||||
// Command: podman _diff_ Object_ID
|
||||
diffDescription = `Displays changes on a container or image's filesystem. The container or image will be compared to its parent layer.`
|
||||
diffCmd = &cobra.Command{
|
||||
Use: "diff [options] {CONTAINER_ID | IMAGE_ID}",
|
||||
Use: "diff [options] {CONTAINER|IMAGE}",
|
||||
Args: validate.IDOrLatestArgs,
|
||||
Short: "Display the changes to the object's file system",
|
||||
Long: diffDescription,
|
||||
|
@ -22,7 +22,7 @@ var (
|
||||
Whether the input is for a container or pod, Podman will always generate the specification as a pod.`
|
||||
|
||||
kubeCmd = &cobra.Command{
|
||||
Use: "kube [options] CONTAINER... | POD",
|
||||
Use: "kube [options] {CONTAINER...|POD}",
|
||||
Short: "Generate Kubernetes YAML from a container or pod.",
|
||||
Long: kubeDescription,
|
||||
RunE: kube,
|
||||
|
@ -26,7 +26,7 @@ var (
|
||||
The generated units can later be controlled via systemctl(1).`
|
||||
|
||||
systemdCmd = &cobra.Command{
|
||||
Use: "systemd [options] CTR|POD",
|
||||
Use: "systemd [options] {CONTAINER|POD}",
|
||||
Short: "Generate systemd units.",
|
||||
Long: systemdDescription,
|
||||
RunE: systemd,
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
"github.com/containers/buildah/pkg/parse"
|
||||
"github.com/containers/common/pkg/completion"
|
||||
"github.com/containers/common/pkg/config"
|
||||
"github.com/containers/podman/v2/cmd/podman/common"
|
||||
"github.com/containers/podman/v2/cmd/podman/registry"
|
||||
"github.com/containers/podman/v2/cmd/podman/utils"
|
||||
"github.com/containers/podman/v2/pkg/domain/entities"
|
||||
@ -44,7 +45,7 @@ var (
|
||||
Long: buildDescription,
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
RunE: build,
|
||||
ValidArgsFunction: completion.AutocompleteDefault,
|
||||
ValidArgsFunction: common.AutocompleteDefaultOneArg,
|
||||
Example: `podman build .
|
||||
podman build --creds=username:password -t imageName -f Containerfile.simple .
|
||||
podman build --layers --force-rm --tag imageName .`,
|
||||
|
@ -25,18 +25,19 @@ var (
|
||||
Short: "Import a tarball to create a filesystem image",
|
||||
Long: importDescription,
|
||||
RunE: importCon,
|
||||
ValidArgsFunction: completion.AutocompleteDefault,
|
||||
Args: cobra.RangeArgs(1, 2),
|
||||
ValidArgsFunction: common.AutocompleteDefaultOneArg,
|
||||
Example: `podman import http://example.com/ctr.tar url-image
|
||||
cat ctr.tar | podman -q import --message "importing the ctr.tar tarball" - image-imported
|
||||
cat ctr.tar | podman import -`,
|
||||
}
|
||||
|
||||
imageImportCommand = &cobra.Command{
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
Use: importCommand.Use,
|
||||
Short: importCommand.Short,
|
||||
Long: importCommand.Long,
|
||||
RunE: importCommand.RunE,
|
||||
Args: importCommand.Args,
|
||||
ValidArgsFunction: importCommand.ValidArgsFunction,
|
||||
Example: `podman image import http://example.com/ctr.tar url-image
|
||||
cat ctr.tar | podman -q image import --message "importing the ctr.tar tarball" - image-imported
|
||||
|
@ -29,7 +29,7 @@ var (
|
||||
|
||||
// Command: podman push
|
||||
pushCmd = &cobra.Command{
|
||||
Use: "push [options] SOURCE [DESTINATION]",
|
||||
Use: "push [options] IMAGE [DESTINATION]",
|
||||
Short: "Push an image to a specified destination",
|
||||
Long: pushDescription,
|
||||
RunE: imagePush,
|
||||
|
@ -43,7 +43,7 @@ var (
|
||||
}
|
||||
return nil
|
||||
},
|
||||
ValidArgsFunction: completion.AutocompleteNone,
|
||||
ValidArgsFunction: common.AutocompleteImages,
|
||||
Example: `podman save --quiet -o myimage.tar imageID
|
||||
podman save --format docker-dir -o ubuntu-dir ubuntu
|
||||
podman save > alpine-all.tar alpine:latest`,
|
||||
|
@ -9,7 +9,7 @@ import (
|
||||
|
||||
var (
|
||||
untagCommand = &cobra.Command{
|
||||
Use: "untag IMAGE [NAME...]",
|
||||
Use: "untag IMAGE [IMAGE...]",
|
||||
Short: "Remove a name from a local image",
|
||||
Long: "Removes one or more names from a locally-stored image.",
|
||||
RunE: untag,
|
||||
|
@ -20,12 +20,12 @@ var (
|
||||
|
||||
// Command: podman _inspect_ Object_ID
|
||||
inspectCmd = &cobra.Command{
|
||||
Use: "inspect [options] {CONTAINER_ID | IMAGE_ID} [...]",
|
||||
Use: "inspect [options] {CONTAINER|IMAGE|POD|NETWORK|VOLUME} [...]",
|
||||
Short: "Display the configuration of object denoted by ID",
|
||||
RunE: inspectExec,
|
||||
Long: inspectDescription,
|
||||
TraverseChildren: true,
|
||||
ValidArgsFunction: common.AutocompleteContainersAndImages,
|
||||
ValidArgsFunction: common.AutocompleteInspect,
|
||||
Example: `podman inspect fedora
|
||||
podman inspect --type image fedora
|
||||
podman inspect CtrID ImgID
|
||||
|
@ -24,7 +24,7 @@ type manifestPushOptsWrapper struct {
|
||||
var (
|
||||
manifestPushOpts = manifestPushOptsWrapper{}
|
||||
pushCmd = &cobra.Command{
|
||||
Use: "push [options] SOURCE DESTINATION",
|
||||
Use: "push [options] LIST DESTINATION",
|
||||
Short: "Push a manifest list or image index to a registry",
|
||||
Long: "Pushes manifest lists and image indexes to registries.",
|
||||
RunE: push,
|
||||
|
@ -17,7 +17,7 @@ import (
|
||||
var (
|
||||
networkCreateDescription = `create CNI networks for containers and pods`
|
||||
networkCreateCommand = &cobra.Command{
|
||||
Use: "create [options] [NETWORK]",
|
||||
Use: "create [options] [NAME]",
|
||||
Short: "network create",
|
||||
Long: networkCreateDescription,
|
||||
RunE: networkCreate,
|
||||
|
@ -39,7 +39,7 @@ var (
|
||||
Long: kubeDescription,
|
||||
RunE: kube,
|
||||
Args: cobra.ExactArgs(1),
|
||||
ValidArgsFunction: completion.AutocompleteDefault,
|
||||
ValidArgsFunction: common.AutocompleteDefaultOneArg,
|
||||
Example: `podman play kube nginx.yml
|
||||
podman play kube --creds user:password --seccomp-profile-root /custom/path apache.yml`,
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/containers/podman/v2/cmd/podman/common"
|
||||
"github.com/containers/common/pkg/completion"
|
||||
"github.com/containers/podman/v2/cmd/podman/registry"
|
||||
"github.com/containers/podman/v2/cmd/podman/utils"
|
||||
"github.com/containers/podman/v2/cmd/podman/validate"
|
||||
@ -28,7 +28,7 @@ var (
|
||||
Short: "Remove all stopped pods and their containers",
|
||||
Long: pruneDescription,
|
||||
RunE: prune,
|
||||
ValidArgsFunction: common.AutocompletePods,
|
||||
ValidArgsFunction: completion.AutocompleteNone,
|
||||
Example: `podman pod prune`,
|
||||
}
|
||||
)
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/containers/common/pkg/completion"
|
||||
"github.com/containers/podman/v2/cmd/podman/common"
|
||||
"github.com/containers/podman/v2/cmd/podman/registry"
|
||||
"github.com/containers/podman/v2/pkg/domain/entities"
|
||||
"github.com/containers/podman/v2/pkg/rootless"
|
||||
@ -32,7 +33,7 @@ Enable a listening service for API access to Podman commands.
|
||||
Short: "Run API service",
|
||||
Long: srvDescription,
|
||||
RunE: service,
|
||||
ValidArgsFunction: completion.AutocompleteDefault,
|
||||
ValidArgsFunction: common.AutocompleteDefaultOneArg,
|
||||
Example: `podman system service --time=0 unix:///tmp/podman.sock`,
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@ import (
|
||||
var (
|
||||
unshareDescription = "Runs a command in a modified user namespace."
|
||||
unshareCommand = &cobra.Command{
|
||||
Use: "unshare [COMMAND [ARG ...]]",
|
||||
Use: "unshare [COMMAND [ARG...]]",
|
||||
DisableFlagsInUseLine: true,
|
||||
Short: "Run a command in a modified user namespace",
|
||||
Long: unshareDescription,
|
||||
|
@ -12,22 +12,11 @@
|
||||
#
|
||||
load helpers
|
||||
|
||||
# run 'podman help', parse the output looking for 'Available Commands';
|
||||
# return that list.
|
||||
function podman_commands() {
|
||||
dprint "$@"
|
||||
run_podman help "$@" |\
|
||||
awk '/^Available Commands:/{ok=1;next}/^Options:/{ok=0}ok { print $1 }' |\
|
||||
grep .
|
||||
"$output"
|
||||
}
|
||||
|
||||
|
||||
function check_help() {
|
||||
local count=0
|
||||
local -A found
|
||||
|
||||
for cmd in $(podman_commands "$@"); do
|
||||
for cmd in $(_podman_commands "$@"); do
|
||||
# Human-readable podman command string, with multiple spaces collapsed
|
||||
command_string="podman $* $cmd"
|
||||
command_string=${command_string// / } # 'podman x' -> 'podman x'
|
||||
|
272
test/system/600-completion.bats
Normal file
272
test/system/600-completion.bats
Normal file
@ -0,0 +1,272 @@
|
||||
#!/usr/bin/env bats -*- bats -*-
|
||||
#
|
||||
# Test podman shell completion
|
||||
#
|
||||
# Shell completion is provided via the cobra library
|
||||
# It is implement by calling a hidden subcommand called "__complete"
|
||||
#
|
||||
|
||||
load helpers
|
||||
|
||||
function check_shell_completion() {
|
||||
local count=0
|
||||
|
||||
# Newline character; used for confirming string output
|
||||
local nl="
|
||||
"
|
||||
|
||||
for cmd in $(_podman_commands "$@"); do
|
||||
# Human-readable podman command string, with multiple spaces collapsed
|
||||
name="podman"
|
||||
if is_remote; then
|
||||
name="podman-remote"
|
||||
fi
|
||||
command_string="$name $* $cmd"
|
||||
command_string=${command_string// / } # 'podman x' -> 'podman x'
|
||||
|
||||
run_podman "$@" $cmd --help
|
||||
local full_help="$output"
|
||||
|
||||
# The line immediately after 'Usage:' gives us a 1-line synopsis
|
||||
usage=$(echo "$full_help" | grep -A1 '^Usage:' | tail -1)
|
||||
[ -n "$usage" ] || die "podman $cmd: no Usage message found"
|
||||
|
||||
# If usage ends in '[command]', recurse into subcommands
|
||||
if expr "$usage" : '.*\[command\]$' >/dev/null; then
|
||||
check_shell_completion "$@" $cmd
|
||||
continue
|
||||
fi
|
||||
|
||||
# Trim to command path so we only have the args
|
||||
args="${usage/$command_string/}"
|
||||
# Trim leading whitespaces
|
||||
args="${args#"${args%%[![:space:]]*}"}"
|
||||
|
||||
# Extra args is used to match the correct argument number for the command
|
||||
# This is important because some commands provide different suggestions based
|
||||
# on the number of arguments.
|
||||
extra_args=()
|
||||
|
||||
for arg in $args; do
|
||||
|
||||
match=false
|
||||
i=0
|
||||
while true; do
|
||||
|
||||
case $arg in
|
||||
|
||||
# If we have options than we need to check if we are getting flag completion
|
||||
"[options]")
|
||||
# skip this for remote it fails if a command only has the latest flag e.g podman top
|
||||
if ! is_remote; then
|
||||
run_completion "$@" $cmd "--"
|
||||
# If this fails there is most likely a problem with the cobra library
|
||||
is "${lines[0]}" "--.*" "Found flag in suggestions"
|
||||
[ ${#lines[@]} -gt 2 ] || die "No flag suggestions"
|
||||
_check_completion_end NoFileComp
|
||||
fi
|
||||
# continue the outer for args loop
|
||||
continue 2
|
||||
;;
|
||||
|
||||
*CONTAINER*)
|
||||
run_completion "$@" $cmd "${extra_args[@]}" ""
|
||||
is "$output" ".*-$random_container_name${nl}" "Found expected container in suggestions"
|
||||
|
||||
match=true
|
||||
# resume
|
||||
;;&
|
||||
|
||||
*POD*)
|
||||
run_completion "$@" $cmd "${extra_args[@]}" ""
|
||||
is "$output" ".*-$random_pod_name${nl}" "Found expected pod in suggestions"
|
||||
_check_completion_end NoFileComp
|
||||
|
||||
match=true
|
||||
# resume
|
||||
;;&
|
||||
|
||||
*IMAGE*)
|
||||
run_completion "$@" $cmd "${extra_args[@]}" ""
|
||||
is "$output" ".*localhost/$random_image_name:$random_image_tag${nl}" "Found expected image in suggestions"
|
||||
|
||||
# check that we complete the image with and without tag after at least one char is typed
|
||||
run_completion "$@" $cmd "${extra_args[@]}" "${random_image_name:0:1}"
|
||||
is "$output" ".*$random_image_name:$random_image_tag${nl}" "Found expected image with tag in suggestions"
|
||||
is "$output" ".*$random_image_name${nl}" "Found expected image without tag in suggestions"
|
||||
|
||||
# check that we complete the image id after at least two chars are typed
|
||||
run_completion "$@" $cmd "${extra_args[@]}" "${random_image_id:0:2}"
|
||||
is "$output" ".*$random_image_id${nl}" "Found expected image id in suggestions"
|
||||
|
||||
match=true
|
||||
# resume
|
||||
;;&
|
||||
|
||||
*NETWORK*)
|
||||
run_completion "$@" $cmd "${extra_args[@]}" ""
|
||||
is "$output" ".*$random_network_name${nl}" "Found network in suggestions"
|
||||
_check_completion_end NoFileComp
|
||||
|
||||
match=true
|
||||
# resume
|
||||
;;&
|
||||
|
||||
*VOLUME*)
|
||||
run_completion "$@" $cmd "${extra_args[@]}" ""
|
||||
is "$output" ".*$random_volume_name${nl}" "Found volume in suggestions"
|
||||
_check_completion_end NoFileComp
|
||||
|
||||
match=true
|
||||
# resume
|
||||
;;&
|
||||
|
||||
*REGISTRY*)
|
||||
run_completion "$@" $cmd "${extra_args[@]}" ""
|
||||
### FIXME how can we get the configured registries?
|
||||
_check_completion_end NoFileComp
|
||||
### FIXME this fails if no registries are configured
|
||||
[[ ${#lines[@]} -gt 2 ]] || die "No registries found in suggestions"
|
||||
|
||||
match=true
|
||||
# resume
|
||||
;;&
|
||||
|
||||
*PATH* | *CONTEXT* | *KUBEFILE* | *COMMAND* | *ARG...* | *URI*)
|
||||
# default shell completion should be done for everthing which accepts a path
|
||||
run_completion "$@" $cmd "${extra_args[@]}" ""
|
||||
|
||||
# cp is a special case it returns ShellCompDirectiveNoSpace
|
||||
if [[ "$cmd" == "cp" ]]; then
|
||||
_check_completion_end NoSpace
|
||||
else
|
||||
_check_completion_end Default
|
||||
[[ ${#lines[@]} -eq 2 ]] || die "Suggestions are in the output"
|
||||
fi
|
||||
;;
|
||||
|
||||
*)
|
||||
if [[ "$match" == "false" ]]; then
|
||||
dprint "UNKNOWN arg: $arg for $command_string ${extra_args[*]}"
|
||||
fi
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
# Increment the argument array
|
||||
extra_args+=("arg")
|
||||
|
||||
i=$(($i + 1))
|
||||
# If the argument ends with ...] than we accept 0...n args
|
||||
# Loop three times to make sure we are not only completing the first arg
|
||||
if [[ ! ${arg} =~ "..." ]] || [[ i -gt 3 ]]; then
|
||||
break
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
done
|
||||
|
||||
# If the command takes no more parameters make sure we are getting no completion
|
||||
if [[ ! ${args##* } =~ "..." ]]; then
|
||||
run_completion "$@" $cmd "${extra_args[@]}" ""
|
||||
_check_completion_end NoFileComp
|
||||
if [ ${#lines[@]} -gt 2 ]; then
|
||||
# checking for line count is not enough since we may inlcude additional debug output
|
||||
# lines starting with [Debug] are allowed
|
||||
i=0
|
||||
length=$(( ${#lines[@]} - 2 ))
|
||||
while [[ i -lt length ]]; do
|
||||
[[ "${lines[$i]:0:7}" == "[Debug]" ]] || die "Suggestions are in the output"
|
||||
i=$(( i + 1 ))
|
||||
done
|
||||
fi
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
}
|
||||
|
||||
# run the completion cmd
|
||||
function run_completion() {
|
||||
PODMAN="$PODMAN_COMPLETION" run_podman "$@"
|
||||
}
|
||||
|
||||
# check for the given ShellCompDirective (always last line)
|
||||
function _check_completion_end() {
|
||||
is "${lines[-1]}" "Completion ended with directive: ShellCompDirective$1" "Completion has wrong ShellCompDirective set"
|
||||
}
|
||||
|
||||
|
||||
@test "podman shell completion test" {
|
||||
|
||||
random_container_name=$(random_string 30)
|
||||
random_pod_name=$(random_string 30)
|
||||
random_image_name=$(random_string 30)
|
||||
random_image_name=${random_image_name,,} # name must be lowercase
|
||||
random_image_tag=$(random_string 5)
|
||||
random_network_name=$(random_string 30)
|
||||
random_volume_name=$(random_string 30)
|
||||
|
||||
# create a container for each state since some commands are only suggesting running container for example
|
||||
run_podman create --name created-$random_container_name $IMAGE
|
||||
run_podman run --name running-$random_container_name -d $IMAGE top
|
||||
run_podman run --name pause-$random_container_name -d $IMAGE top
|
||||
run_podman pause pause-$random_container_name
|
||||
run_podman run --name exited-$random_container_name -d $IMAGE echo exited
|
||||
|
||||
# create pods for each state
|
||||
run_podman pod create --name created-$random_pod_name
|
||||
run_podman pod create --name running-$random_pod_name
|
||||
run_podman run -d --name running-$random_pod_name-con --pod running-$random_pod_name $IMAGE top
|
||||
run_podman pod create --name degraded-$random_pod_name
|
||||
run_podman run -d --name degraded-$random_pod_name-con --pod degraded-$random_pod_name $IMAGE echo degraded
|
||||
run_podman pod create --name exited-$random_pod_name
|
||||
run_podman run -d --name exited-$random_pod_name-con --pod exited-$random_pod_name $IMAGE echo exited
|
||||
run_podman pod stop exited-$random_pod_name
|
||||
|
||||
# create image name (just tag with new names no need to pull)
|
||||
run_podman image tag $IMAGE $random_image_name:$random_image_tag
|
||||
run_podman image list --format '{{.ID}}' --filter reference=$random_image_name
|
||||
random_image_id="${lines[0]}"
|
||||
|
||||
# create network
|
||||
run_podman network create $random_network_name
|
||||
|
||||
# create volume
|
||||
run_podman volume create $random_volume_name
|
||||
|
||||
|
||||
# $PODMAN may be a space-separated string, e.g. if we include a --url.
|
||||
local -a podman_as_array=($PODMAN)
|
||||
# __completeNoDesc must be the first arg if we running the completion cmd
|
||||
PODMAN_COMPLETION="${podman_as_array[0]} __completeNoDesc ${podman_as_array[@]:1}"
|
||||
|
||||
# Called with no args -- start with 'podman --help'. check_shell_completion() will
|
||||
# recurse for any subcommands.
|
||||
check_shell_completion
|
||||
|
||||
# cleanup
|
||||
run_podman volume rm $random_volume_name
|
||||
|
||||
run_podman network rm $random_network_name
|
||||
|
||||
run_podman image untag $IMAGE $random_image_name:$random_image_tag
|
||||
|
||||
for state in created running degraded exited; do
|
||||
run_podman pod rm --force $state-$random_pod_name
|
||||
done
|
||||
|
||||
for state in created running pause exited; do
|
||||
run_podman rm --force $state-$random_container_name
|
||||
done
|
||||
|
||||
# Clean up the pod pause image
|
||||
run_podman image list --format '{{.ID}} {{.Repository}}'
|
||||
while read id name; do
|
||||
if [[ "$name" =~ /pause ]]; then
|
||||
run_podman rmi $id
|
||||
fi
|
||||
done <<<"$output"
|
||||
|
||||
}
|
@ -521,5 +521,15 @@ function remove_same_dev_warning() {
|
||||
output=$(printf '%s\n' "${lines[@]}")
|
||||
}
|
||||
|
||||
# run 'podman help', parse the output looking for 'Available Commands';
|
||||
# return that list.
|
||||
function _podman_commands() {
|
||||
dprint "$@"
|
||||
run_podman help "$@" |
|
||||
awk '/^Available Commands:/{ok=1;next}/^Options:/{ok=0}ok { print $1 }' |
|
||||
grep .
|
||||
"$output"
|
||||
}
|
||||
|
||||
# END miscellaneous tools
|
||||
###############################################################################
|
||||
|
Reference in New Issue
Block a user