diff --git a/cmd/skopeo/completions.go b/cmd/skopeo/completions.go index 20a2f9d1..fe0f5607 100644 --- a/cmd/skopeo/completions.go +++ b/cmd/skopeo/completions.go @@ -1,13 +1,50 @@ package main import ( + "github.com/containers/image/v5/directory" + "github.com/containers/image/v5/docker" + dockerArchive "github.com/containers/image/v5/docker/archive" + ociArchive "github.com/containers/image/v5/oci/archive" + oci "github.com/containers/image/v5/oci/layout" + "github.com/containers/image/v5/sif" "github.com/containers/image/v5/tarball" "github.com/containers/image/v5/transports" "github.com/spf13/cobra" + "strings" ) -// autocompleteSupportedTransports list all supported transports with the colon suffix. -func autocompleteSupportedTransports(cmd *cobra.Command, args []string, toComplete string) ([]cobra.Completion, cobra.ShellCompDirective) { +func autocompleteImageNames(cmd *cobra.Command, args []string, toComplete string) ([]cobra.Completion, cobra.ShellCompDirective) { + transport, details, haveTransport := strings.Cut(toComplete, ":") + if !haveTransport { + transports := supportedTransportSuggestions() + return transports, cobra.ShellCompDirectiveNoSpace | cobra.ShellCompDirectiveNoFileComp + } + switch transport { + case ociArchive.Transport.Name(), dockerArchive.Transport.Name(): + // Can have [:{*reference|@source-index}] + // FIXME: `oci-archive:/path/to/a.oci:` completes paths + return nil, cobra.ShellCompDirectiveNoSpace + case sif.Transport.Name(): + return nil, cobra.ShellCompDirectiveDefault + + // Both directory and oci should have ShellCompDirectiveFilterDirs to complete only directories, but it doesn't currently work in bash: https://github.com/spf13/cobra/issues/2242 + case oci.Transport.Name(): + // Can have '[:{reference|@source-index}]' + // FIXME: `oci:/path/to/dir/:` completes paths + return nil, cobra.ShellCompDirectiveDefault | cobra.ShellCompDirectiveNoSpace + case directory.Transport.Name(): + return nil, cobra.ShellCompDirectiveDefault + + case docker.Transport.Name(): + if details == "" { + return []cobra.Completion{transport + "://"}, cobra.ShellCompDirectiveNoSpace | cobra.ShellCompDirectiveNoFileComp + } + } + return nil, cobra.ShellCompDirectiveNoSpace | cobra.ShellCompDirectiveNoFileComp +} + +// supportedTransportSuggestions list all supported transports with the colon suffix. +func supportedTransportSuggestions() []string { tps := transports.ListNames() suggestions := make([]cobra.Completion, 0, len(tps)) for _, tp := range tps { @@ -18,5 +55,5 @@ func autocompleteSupportedTransports(cmd *cobra.Command, args []string, toComple suggestions = append(suggestions, tp+":") } } - return suggestions, cobra.ShellCompDirectiveNoFileComp | cobra.ShellCompDirectiveNoSpace + return suggestions } diff --git a/cmd/skopeo/copy.go b/cmd/skopeo/copy.go index db13c998..9d47a5c4 100644 --- a/cmd/skopeo/copy.go +++ b/cmd/skopeo/copy.go @@ -71,7 +71,7 @@ See skopeo(1) section "IMAGE NAMES" for the expected format `, strings.Join(transports.ListNames(), ", ")), RunE: commandAction(opts.run), Example: `skopeo copy docker://quay.io/skopeo/stable:latest docker://registry.example.com/skopeo:latest`, - ValidArgsFunction: autocompleteSupportedTransports, + ValidArgsFunction: autocompleteImageNames, } adjustUsage(cmd) flags := cmd.Flags() diff --git a/cmd/skopeo/delete.go b/cmd/skopeo/delete.go index 84ed5f97..ddfc2cbe 100644 --- a/cmd/skopeo/delete.go +++ b/cmd/skopeo/delete.go @@ -37,7 +37,7 @@ See skopeo(1) section "IMAGE NAMES" for the expected format `, strings.Join(transports.ListNames(), ", ")), RunE: commandAction(opts.run), Example: `skopeo delete docker://registry.example.com/example/pause:latest`, - ValidArgsFunction: autocompleteSupportedTransports, + ValidArgsFunction: autocompleteImageNames, } adjustUsage(cmd) flags := cmd.Flags() diff --git a/cmd/skopeo/inspect.go b/cmd/skopeo/inspect.go index 4ca03ac1..843f26e9 100644 --- a/cmd/skopeo/inspect.go +++ b/cmd/skopeo/inspect.go @@ -53,7 +53,7 @@ See skopeo(1) section "IMAGE NAMES" for the expected format Example: `skopeo inspect docker://registry.fedoraproject.org/fedora skopeo inspect --config docker://docker.io/alpine skopeo inspect --format "Name: {{.Name}} Digest: {{.Digest}}" docker://registry.access.redhat.com/ubi8`, - ValidArgsFunction: autocompleteSupportedTransports, + ValidArgsFunction: autocompleteImageNames, } adjustUsage(cmd) flags := cmd.Flags()