github.com/coreos/rocket@v1.30.1-0.20200224141603-171c416fac02/rkt/completion.go (about)

     1  // Copyright 2017 The rkt Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package main
    16  
    17  import (
    18  	"io"
    19  	"os"
    20  
    21  	"github.com/spf13/cobra"
    22  )
    23  
    24  var (
    25  	cmdCompletion = &cobra.Command{
    26  		Use:   "completion SHELL",
    27  		Short: "Output shell completion code for the specified shell",
    28  		Long: `This command outputs completion code for the specified shell. The generated
    29  code must be evaluated to provide interactive completion of rkt sub-commands.
    30  This can be done by sourcing it from the .bash_profile.
    31  
    32  Save completion code in a home directory and then include it in .bash_profile
    33  script:
    34  
    35  	$ rkt completion bash > $HOME/.rkt.bash.inc
    36  	$ printf '
    37  # rkt shell completion
    38  source "$HOME/.rkt.bash.inc"
    39  ' >> $HOME/.bash_profile
    40  	$ source $HOME/.bash_profile
    41  
    42  Alternatively, include the completion code directly into the launched shell:
    43  
    44  	$ source <(rkt completion bash)`,
    45  		ValidArgs: []string{"bash"},
    46  		Run:       runWrapper(newCompletion(os.Stdout)),
    47  	}
    48  
    49  	bashCompletionFunc = `__rkt_parse_image()
    50  {
    51  	local rkt_output
    52  	if rkt_output=$(rkt image list --no-legend 2>/dev/null); then
    53  		out=($(echo "${rkt_output}" | awk '{print $1}'))
    54  		COMPREPLY=( $( compgen -W "${out[*]}" -- "$cur" ) )
    55  	fi
    56  }
    57  
    58  __rkt_parse_list()
    59  {
    60  	local rkt_output
    61  	if rkt_output=$(rkt list --no-legend 2>/dev/null); then
    62  		if [[ -n "$1" ]]; then
    63  			out=($(echo "${rkt_output}" | grep ${1} | awk '{print $1}'))
    64  		else
    65  			out=($(echo "${rkt_output}" | awk '{print $1}'))
    66  		fi
    67  		COMPREPLY=( $( compgen -W "${out[*]}" -- "$cur" ) )
    68  	fi
    69  }
    70  
    71  __custom_func() {
    72  	case ${last_command} in
    73  		rkt_image_export | \
    74  		rkt_image_extract | \
    75  		rkt_image_cat-manifest | \
    76  		rkt_image_render | \
    77  		rkt_image_rm | \
    78  		rkt_run | \
    79  		rkt_prepare)
    80  			__rkt_parse_image
    81  			return
    82  			;;
    83  		rkt_run-prepared)
    84  			__rkt_parse_list prepared
    85  			return
    86  			;;
    87  		rkt_enter)
    88  			__rkt_parse_list running
    89  			return
    90  			;;
    91  		rkt_rm)
    92  			__rkt_parse_list "prepare\|exited"
    93  			return
    94  			;;
    95  		rkt_status)
    96  			__rkt_parse_list
    97  			return
    98  			;;
    99  		*)
   100  			;;
   101  	esac
   102  }
   103  `
   104  
   105  	completionShells = map[string]func(io.Writer, *cobra.Command) error{
   106  		"bash": runBashCompletion,
   107  	}
   108  )
   109  
   110  func init() {
   111  	cmdRkt.AddCommand(cmdCompletion)
   112  }
   113  
   114  // newCompletion creates a new command with a bounded writer. Writer
   115  // is used to print the generated shell-completion script, which is
   116  // intended to be consumed by the CLI users.
   117  func newCompletion(w io.Writer) func(*cobra.Command, []string) int {
   118  	return func(cmd *cobra.Command, args []string) int {
   119  		return runCompletion(w, cmd, args)
   120  	}
   121  }
   122  
   123  // runCompletion is a command handler to generate the shell script with
   124  // shell completion functions.
   125  //
   126  // It ensures that there are enough arguments to generate the completion
   127  // scripts.
   128  func runCompletion(w io.Writer, cmd *cobra.Command, args []string) (exit int) {
   129  	if len(args) == 0 {
   130  		stderr.Print("shell type is not specified")
   131  		return 254
   132  	}
   133  
   134  	if len(args) > 1 {
   135  		stderr.Print("too many arguments, only shell type is expected")
   136  		return 254
   137  	}
   138  
   139  	// Right now only bash completion is supported, but zsh could be
   140  	// supported in a future as well.
   141  	completion, ok := completionShells[args[0]]
   142  	if !ok {
   143  		stderr.Printf("'%s' shell is not supported", args[0])
   144  		return 254
   145  	}
   146  
   147  	// Write the shell completion to the specified writer.
   148  	err := completion(w, cmd.Parent())
   149  	if err != nil {
   150  		stderr.PrintE("completion failed", err)
   151  		return 254
   152  	}
   153  
   154  	return 0
   155  }
   156  
   157  // runBashCompletion generates bash completion script by delegating
   158  // this responsibility to the cobra package itself.
   159  func runBashCompletion(out io.Writer, cmd *cobra.Command) error {
   160  	return cmd.GenBashCompletion(out)
   161  }