mirror of
https://github.com/containers/skopeo.git
synced 2025-09-01 14:47:10 +00:00
Merge pull request #1647 from Luap99/completion
use spf13/cobra to generate shell completions
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -2,7 +2,7 @@
|
|||||||
/layers-*
|
/layers-*
|
||||||
/skopeo
|
/skopeo
|
||||||
result
|
result
|
||||||
|
/completions/
|
||||||
# ignore JetBrains IDEs (GoLand) config folder
|
# ignore JetBrains IDEs (GoLand) config folder
|
||||||
.idea
|
.idea
|
||||||
|
|
||||||
|
26
Makefile
26
Makefile
@@ -22,7 +22,10 @@ REGISTRIESDDIR ?= ${CONTAINERSCONFDIR}/registries.d
|
|||||||
SIGSTOREDIR ?= /var/lib/containers/sigstore
|
SIGSTOREDIR ?= /var/lib/containers/sigstore
|
||||||
BINDIR ?= ${PREFIX}/bin
|
BINDIR ?= ${PREFIX}/bin
|
||||||
MANDIR ?= ${PREFIX}/share/man
|
MANDIR ?= ${PREFIX}/share/man
|
||||||
BASHCOMPLETIONSDIR ?= ${PREFIX}/share/bash-completion/completions
|
|
||||||
|
BASHINSTALLDIR=${PREFIX}/share/bash-completion/completions
|
||||||
|
ZSHINSTALLDIR=${PREFIX}/share/zsh/site-functions
|
||||||
|
FISHINSTALLDIR=${PREFIX}/share/fish/vendor_completions.d
|
||||||
|
|
||||||
GO ?= go
|
GO ?= go
|
||||||
GOBIN := $(shell $(GO) env GOBIN)
|
GOBIN := $(shell $(GO) env GOBIN)
|
||||||
@@ -156,8 +159,16 @@ docs: $(MANPAGES)
|
|||||||
docs-in-container:
|
docs-in-container:
|
||||||
${CONTAINER_RUN} $(MAKE) docs $(if $(DEBUG),DEBUG=$(DEBUG))
|
${CONTAINER_RUN} $(MAKE) docs $(if $(DEBUG),DEBUG=$(DEBUG))
|
||||||
|
|
||||||
|
.PHONY: completions
|
||||||
|
completions: bin/skopeo
|
||||||
|
install -d -m 755 completions/{bash,zsh,fish,powershell}
|
||||||
|
./bin/skopeo completion bash >| completions/bash/skopeo
|
||||||
|
./bin/skopeo completion zsh >| completions/zsh/_skopeo
|
||||||
|
./bin/skopeo completion fish >| completions/fish/skopeo.fish
|
||||||
|
./bin/skopeo completion powershell >| completions/powershell/skopeo.ps1
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf bin docs/*.1
|
rm -rf bin docs/*.1 completions/
|
||||||
|
|
||||||
install: install-binary install-docs install-completions
|
install: install-binary install-docs install-completions
|
||||||
install -d -m 755 ${DESTDIR}${SIGSTOREDIR}
|
install -d -m 755 ${DESTDIR}${SIGSTOREDIR}
|
||||||
@@ -176,9 +187,14 @@ ifneq ($(DISABLE_DOCS), 1)
|
|||||||
install -m 644 docs/*.1 ${DESTDIR}${MANDIR}/man1
|
install -m 644 docs/*.1 ${DESTDIR}${MANDIR}/man1
|
||||||
endif
|
endif
|
||||||
|
|
||||||
install-completions:
|
install-completions: completions
|
||||||
install -m 755 -d ${DESTDIR}${BASHCOMPLETIONSDIR}
|
install -d -m 755 ${DESTDIR}${BASHINSTALLDIR}
|
||||||
install -m 644 completions/bash/skopeo ${DESTDIR}${BASHCOMPLETIONSDIR}/skopeo
|
install -m 644 completions/bash/skopeo ${DESTDIR}${BASHINSTALLDIR}
|
||||||
|
install -d -m 755 ${DESTDIR}${ZSHINSTALLDIR}
|
||||||
|
install -m 644 completions/zsh/_skopeo ${DESTDIR}${ZSHINSTALLDIR}
|
||||||
|
install -d -m 755 ${DESTDIR}${FISHINSTALLDIR}
|
||||||
|
install -m 644 completions/fish/skopeo.fish ${DESTDIR}${FISHINSTALLDIR}
|
||||||
|
# There is no common location for powershell files so do not install them. Users have to source the file from their powershell profile.
|
||||||
|
|
||||||
shell:
|
shell:
|
||||||
$(CONTAINER_RUN) bash
|
$(CONTAINER_RUN) bash
|
||||||
|
16
cmd/skopeo/completions.go
Normal file
16
cmd/skopeo/completions.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/containers/image/v5/transports"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// autocompleteSupportedTransports list all supported transports with the colon suffix.
|
||||||
|
func autocompleteSupportedTransports(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||||
|
tps := transports.ListNames()
|
||||||
|
suggestions := make([]string, 0, len(tps))
|
||||||
|
for _, tp := range tps {
|
||||||
|
suggestions = append(suggestions, tp+":")
|
||||||
|
}
|
||||||
|
return suggestions, cobra.ShellCompDirectiveNoFileComp
|
||||||
|
}
|
@@ -66,6 +66,7 @@ See skopeo(1) section "IMAGE NAMES" for the expected format
|
|||||||
`, strings.Join(transports.ListNames(), ", ")),
|
`, strings.Join(transports.ListNames(), ", ")),
|
||||||
RunE: commandAction(opts.run),
|
RunE: commandAction(opts.run),
|
||||||
Example: `skopeo copy docker://quay.io/skopeo/stable:latest docker://registry.example.com/skopeo:latest`,
|
Example: `skopeo copy docker://quay.io/skopeo/stable:latest docker://registry.example.com/skopeo:latest`,
|
||||||
|
ValidArgsFunction: autocompleteSupportedTransports,
|
||||||
}
|
}
|
||||||
adjustUsage(cmd)
|
adjustUsage(cmd)
|
||||||
flags := cmd.Flags()
|
flags := cmd.Flags()
|
||||||
|
@@ -37,6 +37,7 @@ See skopeo(1) section "IMAGE NAMES" for the expected format
|
|||||||
`, strings.Join(transports.ListNames(), ", ")),
|
`, strings.Join(transports.ListNames(), ", ")),
|
||||||
RunE: commandAction(opts.run),
|
RunE: commandAction(opts.run),
|
||||||
Example: `skopeo delete docker://registry.example.com/example/pause:latest`,
|
Example: `skopeo delete docker://registry.example.com/example/pause:latest`,
|
||||||
|
ValidArgsFunction: autocompleteSupportedTransports,
|
||||||
}
|
}
|
||||||
adjustUsage(cmd)
|
adjustUsage(cmd)
|
||||||
flags := cmd.Flags()
|
flags := cmd.Flags()
|
||||||
|
@@ -55,6 +55,7 @@ See skopeo(1) section "IMAGE NAMES" for the expected format
|
|||||||
Example: `skopeo inspect docker://registry.fedoraproject.org/fedora
|
Example: `skopeo inspect docker://registry.fedoraproject.org/fedora
|
||||||
skopeo inspect --config docker://docker.io/alpine
|
skopeo inspect --config docker://docker.io/alpine
|
||||||
skopeo inspect --format "Name: {{.Name}} Digest: {{.Digest}}" docker://registry.access.redhat.com/ubi8`,
|
skopeo inspect --format "Name: {{.Name}} Digest: {{.Digest}}" docker://registry.access.redhat.com/ubi8`,
|
||||||
|
ValidArgsFunction: autocompleteSupportedTransports,
|
||||||
}
|
}
|
||||||
adjustUsage(cmd)
|
adjustUsage(cmd)
|
||||||
flags := cmd.Flags()
|
flags := cmd.Flags()
|
||||||
|
@@ -63,11 +63,8 @@ func createApp() (*cobra.Command, *globalOptions) {
|
|||||||
},
|
},
|
||||||
SilenceUsage: true,
|
SilenceUsage: true,
|
||||||
SilenceErrors: true,
|
SilenceErrors: true,
|
||||||
// Currently, skopeo uses manually written completions. Cobra allows
|
// Hide the completion command which is provided by cobra
|
||||||
// for auto-generating completions for various shells. Podman is
|
CompletionOptions: cobra.CompletionOptions{HiddenDefaultCmd: true},
|
||||||
// already making us of that. If Skopeo decides to follow, please
|
|
||||||
// remove the line below (and hide the `completion` command).
|
|
||||||
CompletionOptions: cobra.CompletionOptions{DisableDefaultCmd: true},
|
|
||||||
// This is documented to parse "local" (non-PersistentFlags) flags of parent commands before
|
// This is documented to parse "local" (non-PersistentFlags) flags of parent commands before
|
||||||
// running subcommands and handling their options. We don't really run into such cases,
|
// running subcommands and handling their options. We don't really run into such cases,
|
||||||
// because all of our flags on rootCommand are in PersistentFlags, except for the deprecated --tls-verify;
|
// because all of our flags on rootCommand are in PersistentFlags, except for the deprecated --tls-verify;
|
||||||
|
@@ -1,343 +0,0 @@
|
|||||||
#! /bin/bash
|
|
||||||
|
|
||||||
_complete_() {
|
|
||||||
local options_with_args=$1
|
|
||||||
local boolean_options="$2 -h --help"
|
|
||||||
local transports=$3
|
|
||||||
|
|
||||||
local option_with_args
|
|
||||||
for option_with_args in $options_with_args $transports
|
|
||||||
do
|
|
||||||
if [ "$option_with_args" == "$prev" ] || [ "$option_with_args" == "$cur" ]
|
|
||||||
then
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
case "$cur" in
|
|
||||||
-*)
|
|
||||||
while IFS='' read -r line; do COMPREPLY+=("$line"); done < <(compgen -W "$boolean_options $options_with_args" -- "$cur")
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
if [ -n "$transports" ]
|
|
||||||
then
|
|
||||||
compopt -o nospace
|
|
||||||
while IFS='' read -r line; do COMPREPLY+=("$line"); done < <(compgen -W "$transports" -- "$cur")
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
_skopeo_supported_transports() {
|
|
||||||
local subcommand=$1
|
|
||||||
|
|
||||||
skopeo "$subcommand" --help | grep "Supported transports" -A 1 | tail -n 1 | sed -e 's/,/:/g' -e 's/$/:/'
|
|
||||||
}
|
|
||||||
|
|
||||||
_skopeo_copy() {
|
|
||||||
local options_with_args="
|
|
||||||
--authfile
|
|
||||||
--src-authfile
|
|
||||||
--dest-authfile
|
|
||||||
--format -f
|
|
||||||
--multi-arch
|
|
||||||
--sign-by
|
|
||||||
--sign-passphrase-file
|
|
||||||
--sign-identity
|
|
||||||
--src-creds --screds
|
|
||||||
--src-cert-dir
|
|
||||||
--src-tls-verify
|
|
||||||
--dest-creds --dcreds
|
|
||||||
--dest-cert-dir
|
|
||||||
--dest-tls-verify
|
|
||||||
--src-daemon-host
|
|
||||||
--dest-daemon-host
|
|
||||||
--src-registry-token
|
|
||||||
--dest-registry-token
|
|
||||||
--src-username
|
|
||||||
--src-password
|
|
||||||
--dest-username
|
|
||||||
--dest-password
|
|
||||||
"
|
|
||||||
|
|
||||||
local boolean_options="
|
|
||||||
--all
|
|
||||||
--dest-compress
|
|
||||||
--dest-decompress
|
|
||||||
--remove-signatures
|
|
||||||
--src-no-creds
|
|
||||||
--dest-no-creds
|
|
||||||
--dest-oci-accept-uncompressed-layers
|
|
||||||
--dest-precompute-digests
|
|
||||||
--preserve-digests
|
|
||||||
"
|
|
||||||
|
|
||||||
local transports
|
|
||||||
transports="
|
|
||||||
$(_skopeo_supported_transports "${FUNCNAME//"_skopeo_"/}")
|
|
||||||
"
|
|
||||||
|
|
||||||
_complete_ "$options_with_args" "$boolean_options" "$transports"
|
|
||||||
}
|
|
||||||
|
|
||||||
_skopeo_sync() {
|
|
||||||
local options_with_args="
|
|
||||||
--authfile
|
|
||||||
--dest
|
|
||||||
--dest-authfile
|
|
||||||
--dest-cert-
|
|
||||||
--dest-creds
|
|
||||||
--dest-registry-token string
|
|
||||||
--format
|
|
||||||
--retry-times
|
|
||||||
--sign-by
|
|
||||||
--sign-passphrase-file
|
|
||||||
--src
|
|
||||||
--src-authfile
|
|
||||||
--src-cert-dir
|
|
||||||
--src-creds
|
|
||||||
--src-registry-token
|
|
||||||
--src-username
|
|
||||||
--src-password
|
|
||||||
--dest-username
|
|
||||||
--dest-password
|
|
||||||
"
|
|
||||||
|
|
||||||
local boolean_options="
|
|
||||||
--all
|
|
||||||
--dest-no-creds
|
|
||||||
--dest-tls-verify
|
|
||||||
--dry-run
|
|
||||||
--remove-signatures
|
|
||||||
--scoped
|
|
||||||
--src-no-creds
|
|
||||||
--src-tls-verify
|
|
||||||
--keep-going
|
|
||||||
--preserve-digests
|
|
||||||
"
|
|
||||||
|
|
||||||
local transports
|
|
||||||
transports="
|
|
||||||
$(_skopeo_supported_transports "${FUNCNAME//"_skopeo_"/}")
|
|
||||||
"
|
|
||||||
|
|
||||||
_complete_ "$options_with_args" "$boolean_options" "$transports"
|
|
||||||
}
|
|
||||||
|
|
||||||
_skopeo_inspect() {
|
|
||||||
local options_with_args="
|
|
||||||
--authfile
|
|
||||||
--creds
|
|
||||||
--cert-dir
|
|
||||||
--format
|
|
||||||
--retry-times
|
|
||||||
--registry-token
|
|
||||||
--username
|
|
||||||
--password
|
|
||||||
"
|
|
||||||
local boolean_options="
|
|
||||||
--config
|
|
||||||
--raw
|
|
||||||
--tls-verify
|
|
||||||
--no-creds
|
|
||||||
--no-tags -n
|
|
||||||
"
|
|
||||||
|
|
||||||
local transports
|
|
||||||
transports="
|
|
||||||
$(_skopeo_supported_transports "${FUNCNAME//"_skopeo_"/}")
|
|
||||||
"
|
|
||||||
|
|
||||||
_complete_ "$options_with_args" "$boolean_options" "$transports"
|
|
||||||
}
|
|
||||||
|
|
||||||
_skopeo_standalone_sign() {
|
|
||||||
local options_with_args="
|
|
||||||
-o --output
|
|
||||||
--passphrase-file
|
|
||||||
"
|
|
||||||
local boolean_options="
|
|
||||||
"
|
|
||||||
_complete_ "$options_with_args" "$boolean_options"
|
|
||||||
}
|
|
||||||
|
|
||||||
_skopeo_standalone_verify() {
|
|
||||||
local options_with_args="
|
|
||||||
"
|
|
||||||
local boolean_options="
|
|
||||||
"
|
|
||||||
_complete_ "$options_with_args" "$boolean_options"
|
|
||||||
}
|
|
||||||
|
|
||||||
_skopeo_manifest_digest() {
|
|
||||||
local options_with_args="
|
|
||||||
"
|
|
||||||
local boolean_options="
|
|
||||||
"
|
|
||||||
_complete_ "$options_with_args" "$boolean_options"
|
|
||||||
}
|
|
||||||
|
|
||||||
_skopeo_delete() {
|
|
||||||
local options_with_args="
|
|
||||||
--authfile
|
|
||||||
--creds
|
|
||||||
--cert-dir
|
|
||||||
--registry-token
|
|
||||||
--username
|
|
||||||
--password
|
|
||||||
"
|
|
||||||
local boolean_options="
|
|
||||||
--tls-verify
|
|
||||||
--no-creds
|
|
||||||
"
|
|
||||||
|
|
||||||
local transports
|
|
||||||
transports="
|
|
||||||
$(_skopeo_supported_transports "${FUNCNAME//"_skopeo_"/}")
|
|
||||||
"
|
|
||||||
|
|
||||||
_complete_ "$options_with_args" "$boolean_options" "$transports"
|
|
||||||
}
|
|
||||||
|
|
||||||
_skopeo_layers() {
|
|
||||||
local options_with_args="
|
|
||||||
--authfile
|
|
||||||
--creds
|
|
||||||
--cert-dir
|
|
||||||
--registry-token
|
|
||||||
--username
|
|
||||||
--password
|
|
||||||
"
|
|
||||||
local boolean_options="
|
|
||||||
--tls-verify
|
|
||||||
--no-creds
|
|
||||||
"
|
|
||||||
_complete_ "$options_with_args" "$boolean_options"
|
|
||||||
}
|
|
||||||
|
|
||||||
_skopeo_list_repository_tags() {
|
|
||||||
local options_with_args="
|
|
||||||
--authfile
|
|
||||||
--creds
|
|
||||||
--cert-dir
|
|
||||||
--registry-token
|
|
||||||
--username
|
|
||||||
--password
|
|
||||||
"
|
|
||||||
|
|
||||||
local boolean_options="
|
|
||||||
--tls-verify
|
|
||||||
--no-creds
|
|
||||||
"
|
|
||||||
_complete_ "$options_with_args" "$boolean_options"
|
|
||||||
}
|
|
||||||
|
|
||||||
_skopeo_login() {
|
|
||||||
local options_with_args="
|
|
||||||
--authfile
|
|
||||||
--cert-dir
|
|
||||||
--password -p
|
|
||||||
--username -u
|
|
||||||
"
|
|
||||||
|
|
||||||
local boolean_options="
|
|
||||||
--get-login
|
|
||||||
--tls-verify
|
|
||||||
--password-stdin
|
|
||||||
"
|
|
||||||
_complete_ "$options_with_args" "$boolean_options"
|
|
||||||
}
|
|
||||||
|
|
||||||
_skopeo_logout() {
|
|
||||||
local options_with_args="
|
|
||||||
--authfile
|
|
||||||
"
|
|
||||||
|
|
||||||
local boolean_options="
|
|
||||||
--all -a
|
|
||||||
"
|
|
||||||
_complete_ "$options_with_args" "$boolean_options"
|
|
||||||
}
|
|
||||||
|
|
||||||
_skopeo_skopeo() {
|
|
||||||
# XXX: Changes here need to be reflected in the manually expanded
|
|
||||||
# string in the `case` statement below as well.
|
|
||||||
local options_with_args="
|
|
||||||
--policy
|
|
||||||
--registries.d
|
|
||||||
--override-arch
|
|
||||||
--override-os
|
|
||||||
--override-variant
|
|
||||||
--command-timeout
|
|
||||||
--tmpdir
|
|
||||||
"
|
|
||||||
local boolean_options="
|
|
||||||
--insecure-policy
|
|
||||||
--debug
|
|
||||||
--version -v
|
|
||||||
--help -h
|
|
||||||
"
|
|
||||||
|
|
||||||
local commands=(
|
|
||||||
copy
|
|
||||||
delete
|
|
||||||
inspect
|
|
||||||
list-tags
|
|
||||||
login
|
|
||||||
logout
|
|
||||||
manifest-digest
|
|
||||||
standalone-sign
|
|
||||||
standalone-verify
|
|
||||||
sync
|
|
||||||
help
|
|
||||||
h
|
|
||||||
)
|
|
||||||
|
|
||||||
case "$prev" in
|
|
||||||
# XXX: Changes here need to be reflected in $options_with_args as well.
|
|
||||||
--policy|--registries.d|--override-arch|--override-os|--override-variant|--command-timeout)
|
|
||||||
return
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
case "$cur" in
|
|
||||||
-*)
|
|
||||||
while IFS='' read -r line; do COMPREPLY+=("$line"); done < <(compgen -W "$boolean_options $options_with_args" -- "$cur")
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
while IFS='' read -r line; do COMPREPLY+=("$line"); done < <(compgen -W "${commands[*]} help" -- "$cur")
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
_cli_bash_autocomplete() {
|
|
||||||
local cur
|
|
||||||
|
|
||||||
COMPREPLY=()
|
|
||||||
cur="${COMP_WORDS[COMP_CWORD]}"
|
|
||||||
COMPREPLY=()
|
|
||||||
local cur prev words cword
|
|
||||||
|
|
||||||
_get_comp_words_by_ref -n : cur prev words cword
|
|
||||||
|
|
||||||
local command="skopeo" cpos=0
|
|
||||||
local counter=1
|
|
||||||
while [ $counter -lt "$cword" ]; do
|
|
||||||
case "${words[$counter]}" in
|
|
||||||
skopeo|copy|sync|inspect|delete|manifest-digest|standalone-sign|standalone-verify|help|h|list-repository-tags)
|
|
||||||
command="${words[$counter]//-/_}"
|
|
||||||
cpos=$counter
|
|
||||||
(( cpos++ ))
|
|
||||||
break
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
(( counter++ ))
|
|
||||||
done
|
|
||||||
|
|
||||||
local completions_func=_skopeo_${command}
|
|
||||||
declare -F "$completions_func" >/dev/null && $completions_func
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
complete -F _cli_bash_autocomplete skopeo
|
|
@@ -212,6 +212,13 @@ Building in a container is simpler, but more restrictive:
|
|||||||
$ make binary
|
$ make binary
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Shell completion scripts
|
||||||
|
|
||||||
|
Skopeo has shell completion scripts for bash, zsh, fish and powershell. They are installed as part of `make install`.
|
||||||
|
You may have to restart your shell in order for them to take effect.
|
||||||
|
|
||||||
|
For instructions to manually generate and load the scripts please see `skopeo completion --help`.
|
||||||
|
|
||||||
### Installation
|
### Installation
|
||||||
|
|
||||||
Finally, after the binary and documentation is built:
|
Finally, after the binary and documentation is built:
|
||||||
|
Reference in New Issue
Block a user