Move shell completion generation into 'kubectl completion' command

This commit is contained in:
Dr. Stefan Schimanski 2016-04-03 19:24:58 +02:00
parent 77de942e08
commit a79a420fde
9 changed files with 119 additions and 74 deletions

View File

@ -478,7 +478,6 @@ function kube::build::source_targets() {
test
third_party
vendor
contrib/completions/bash/kubectl
contrib/mesos
.generated_docs
)
@ -1022,8 +1021,6 @@ function kube::release::package_full_tarball() {
cp "${KUBE_ROOT}/README.md" "${release_stage}/"
cp "${KUBE_ROOT}/Godeps/LICENSES" "${release_stage}/"
cp "${KUBE_ROOT}/Vagrantfile" "${release_stage}/"
mkdir -p "${release_stage}/contrib/completions/bash"
cp "${KUBE_ROOT}/contrib/completions/bash/kubectl" "${release_stage}/contrib/completions/bash"
echo "${KUBE_GIT_VERSION}" > "${release_stage}/version"

View File

@ -1,49 +0,0 @@
/*
Copyright 2015 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"fmt"
"io/ioutil"
"os"
"k8s.io/kubernetes/cmd/genutils"
"k8s.io/kubernetes/pkg/kubectl/cmd"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
)
func main() {
// use os.Args instead of "flags" because "flags" will mess up the man pages!
path := "contrib/completions/bash/"
if len(os.Args) == 2 {
path = os.Args[1]
} else if len(os.Args) > 2 {
fmt.Fprintf(os.Stderr, "usage: %s [output directory]\n", os.Args[0])
os.Exit(1)
}
outDir, err := genutils.OutDir(path)
if err != nil {
fmt.Fprintf(os.Stderr, "failed to get output directory: %v\n", err)
os.Exit(1)
}
outFile := outDir + "kubectl"
// TODO os.Stdin should really be something like ioutil.Discard, but a Reader
kubectl := cmd.NewKubectlCommand(cmdutil.NewFactory(nil), os.Stdin, ioutil.Discard, ioutil.Discard)
kubectl.GenBashCompletionFile(outFile)
}

View File

@ -1,6 +0,0 @@
# Maintainers
Eric Paris <eparis@redhat.com>
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/contrib/completions/bash/MAINTAINERS.md?pixel)]()

View File

@ -111,7 +111,6 @@ kube::golang::test_targets() {
cmd/genman
cmd/genyaml
cmd/mungedocs
cmd/genbashcomp
cmd/genswaggertypedocs
cmd/linkcheck
examples/k8petstore/web-server/src

View File

@ -176,7 +176,7 @@ kube::util::find-binary() {
echo -n "${bin}"
}
# Run all known doc generators (today gendocs, genman, and genbashcomp for kubectl)
# Run all known doc generators (today gendocs and genman for kubectl)
# $1 is the directory to put those generated documents
kube::util::gen-docs() {
local dest="$1"
@ -186,7 +186,6 @@ kube::util::gen-docs() {
genkubedocs=$(kube::util::find-binary "genkubedocs")
genman=$(kube::util::find-binary "genman")
genyaml=$(kube::util::find-binary "genyaml")
genbashcomp=$(kube::util::find-binary "genbashcomp")
genfeddocs=$(kube::util::find-binary "genfeddocs")
mkdir -p "${dest}/docs/user-guide/kubectl/"
@ -203,8 +202,6 @@ kube::util::gen-docs() {
"${genman}" "${dest}/docs/man/man1/"
mkdir -p "${dest}/docs/yaml/kubectl/"
"${genyaml}" "${dest}/docs/yaml/kubectl/"
mkdir -p "${dest}/contrib/completions/bash/"
"${genbashcomp}" "${dest}/contrib/completions/bash/"
# create the list of generated files
pushd "${dest}" > /dev/null

View File

@ -28,7 +28,6 @@ kube::golang::setup_env
cmd/genkubedocs \
cmd/genman \
cmd/genyaml \
cmd/genbashcomp \
cmd/mungedocs \
federation/cmd/genfeddocs

View File

@ -28,7 +28,6 @@ kube::golang::setup_env
cmd/genkubedocs \
cmd/genman \
cmd/genyaml \
cmd/genbashcomp \
cmd/mungedocs
# Find binary

View File

@ -235,6 +235,7 @@ Find more information at https://github.com/kubernetes/kubernetes.`,
cmds.AddCommand(NewCmdVersion(f, out))
cmds.AddCommand(NewCmdExplain(f, out))
cmds.AddCommand(NewCmdConvert(f, out))
cmds.AddCommand(NewCmdCompletion(f, out))
if cmds.Flag("namespace") != nil {
if cmds.Flag("namespace").Annotations == nil {

View File

@ -1,6 +1,101 @@
#!/bin/zsh
/*
Copyright 2014 The Kubernetes Authors All rights reserved.
# Copyright 2016 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
import (
"bytes"
"io"
"github.com/spf13/cobra"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
)
const (
completion_long = `Output shell completion code for the given shell (bash or zsh).
This command prints shell code which must be evaluation to provide interactive
completion of kubectl commands.
`
completion_example = `
$ source <(kubectl completion bash)
will load the kubectl completion code for bash. Note that this depends on the bash-completion
framework. It must be sourced before sourcing the kubectl completion, i.e. on the Mac:
$ brew install bash-completion
$ source $(brew --prefix)/etc/bash_completion
$ source <(kubectl completion bash)
If you use zsh, the following will load kubectl zsh completion:
$ source <(kubectl completion zsh)
`
)
var (
completion_shells = map[string]func(out io.Writer, cmd *cobra.Command) error{
"bash": runCompletionBash,
"zsh": runCompletionZsh,
}
)
func NewCmdCompletion(f *cmdutil.Factory, out io.Writer) *cobra.Command {
shells := []string{}
for s := range completion_shells {
shells = append(shells, s)
}
cmd := &cobra.Command{
Use: "completion SHELL",
Short: "Output shell completion code for the given shell (bash or zsh)",
Long: completion_long,
Example: completion_example,
Run: func(cmd *cobra.Command, args []string) {
err := RunCompletion(f, out, cmd, args)
cmdutil.CheckErr(err)
},
ValidArgs: shells,
}
return cmd
}
func RunCompletion(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string) error {
if len(args) == 0 {
return cmdutil.UsageError(cmd, "Shell not specified.")
}
if len(args) > 1 {
return cmdutil.UsageError(cmd, "Too many arguments. Expected only the shell type.")
}
run, found := completion_shells[args[0]]
if !found {
return cmdutil.UsageError(cmd, "Unsupported shell type %q.", args[0])
}
return run(out, cmd.Parent())
}
func runCompletionBash(out io.Writer, kubectl *cobra.Command) error {
return kubectl.GenBashCompletion(out)
}
func runCompletionZsh(out io.Writer, kubectl *cobra.Command) error {
zsh_initialilzation := `# Copyright 2016 The Kubernetes Authors All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -15,13 +110,13 @@
# limitations under the License.
__kubectl_bash_source() {
alias shopt=':'
alias _expand=_bash_expand
alias _complete=_bash_comp
emulate -L sh
setopt kshglob noshglob braceexpand
alias shopt=':'
alias _expand=_bash_expand
alias _complete=_bash_comp
emulate -L sh
setopt kshglob noshglob braceexpand
source "$@"
source "$@"
}
__kubectl_type() {
@ -160,5 +255,18 @@ __kubectl_bash_source <(sed \
-e "s/${LWORD}compopt${RWORD}/__kubectl_compopt/g" \
-e "s/${LWORD}declare${RWORD}/__kubectl_declare/g" \
-e "s/\\\$(type${RWORD}/\$(__kubectl_type/g" \
$(dirname $0)/../bash/kubectl
<<'BASH_COMPLETION_EOF'
`
out.Write([]byte(zsh_initialilzation))
buf := new(bytes.Buffer)
kubectl.GenBashCompletion(buf)
out.Write(buf.Bytes())
zsh_tail := `
BASH_COMPLETION_EOF
)
`
out.Write([]byte(zsh_tail))
return nil
}