validateFlags command line options to make sure the user entered a value
When a user enters a CLI with a StringFlags or StringSliceFlags and does not add a value the CLI mistakently takes the next option and uses it as a value. This usually ends up with an error like not enough options or others. Some times it could also succeed, with weird results. This patch looks for any values that begin with a "-" and return an error. Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
parent
3e2ad8f10a
commit
04e96d05fc
20 changed files with 90 additions and 0 deletions
|
@ -2,6 +2,8 @@ package main
|
|||
|
||||
import (
|
||||
"os"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
is "github.com/containers/image/storage"
|
||||
|
@ -100,3 +102,34 @@ func splitCamelCase(src string) string {
|
|||
entries := camelcase.Split(src)
|
||||
return strings.Join(entries, " ")
|
||||
}
|
||||
|
||||
// validateFlags searches for StringFlags or StringSlice flags that never had
|
||||
// a value set. This commonly occurs when the CLI mistakenly takes the next
|
||||
// option and uses it as a value.
|
||||
func validateFlags(c *cli.Context, flags []cli.Flag) error {
|
||||
for _, flag := range flags {
|
||||
switch reflect.TypeOf(flag).String() {
|
||||
case "cli.StringSliceFlag":
|
||||
{
|
||||
f := flag.(cli.StringSliceFlag)
|
||||
name := strings.Split(f.Name, ",")
|
||||
val := c.StringSlice(name[0])
|
||||
for _, v := range val {
|
||||
if ok, _ := regexp.MatchString("^-.+", v); ok {
|
||||
return errors.Errorf("option --%s requires a value", name[0])
|
||||
}
|
||||
}
|
||||
}
|
||||
case "cli.StringFlag":
|
||||
{
|
||||
f := flag.(cli.StringFlag)
|
||||
name := strings.Split(f.Name, ",")
|
||||
val := c.String(name[0])
|
||||
if ok, _ := regexp.MatchString("^-.+", val); ok {
|
||||
return errors.Errorf("option --%s requires a value", name[0])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -77,6 +77,9 @@ func diffCmd(c *cli.Context) error {
|
|||
if len(c.Args()) != 1 {
|
||||
return errors.Errorf("container, layer, or image name must be specified: kpod diff [options [...]] ID-NAME")
|
||||
}
|
||||
if err := validateFlags(c, diffFlags); err != nil {
|
||||
return err
|
||||
}
|
||||
config, err := getConfig(c)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "could not get config")
|
||||
|
|
|
@ -48,6 +48,9 @@ func exportCmd(c *cli.Context) error {
|
|||
return errors.Errorf("too many arguments given, need 1 at most.")
|
||||
}
|
||||
container := args[0]
|
||||
if err := validateFlags(c, exportFlags); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
config, err := getConfig(c)
|
||||
if err != nil {
|
||||
|
|
|
@ -85,6 +85,9 @@ var (
|
|||
)
|
||||
|
||||
func historyCmd(c *cli.Context) error {
|
||||
if err := validateFlags(c, historyFlags); err != nil {
|
||||
return err
|
||||
}
|
||||
config, err := getConfig(c)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "Could not get config")
|
||||
|
|
|
@ -52,6 +52,9 @@ var (
|
|||
)
|
||||
|
||||
func imagesCmd(c *cli.Context) error {
|
||||
if err := validateFlags(c, imagesFlags); err != nil {
|
||||
return err
|
||||
}
|
||||
config, err := getConfig(c)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "Could not get config")
|
||||
|
|
|
@ -36,6 +36,9 @@ var (
|
|||
)
|
||||
|
||||
func infoCmd(c *cli.Context) error {
|
||||
if err := validateFlags(c, infoFlags); err != nil {
|
||||
return err
|
||||
}
|
||||
info := map[string]interface{}{}
|
||||
|
||||
infoGivers := []infoGiverFunc{
|
||||
|
|
|
@ -49,6 +49,9 @@ func inspectCmd(c *cli.Context) error {
|
|||
if len(args) > 1 {
|
||||
return errors.Errorf("too many arguments specified")
|
||||
}
|
||||
if err := validateFlags(c, inspectFlags); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
itemType := c.String("type")
|
||||
size := c.Bool("size")
|
||||
|
|
|
@ -35,6 +35,9 @@ func killCmd(c *cli.Context) error {
|
|||
if len(args) == 0 {
|
||||
return errors.Errorf("specify one or more containers to kill")
|
||||
}
|
||||
if err := validateFlags(c, killFlags); err != nil {
|
||||
return err
|
||||
}
|
||||
config, err := getConfig(c)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "could not get config")
|
||||
|
|
|
@ -45,6 +45,9 @@ func loadCmd(c *cli.Context) error {
|
|||
if len(args) > 1 {
|
||||
return errors.New("too many arguments. Requires exactly 1")
|
||||
}
|
||||
if err := validateFlags(c, loadFlags); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
runtime, err := getRuntime(c)
|
||||
if err != nil {
|
||||
|
|
|
@ -46,6 +46,9 @@ func logsCmd(c *cli.Context) error {
|
|||
if len(args) != 1 {
|
||||
return errors.Errorf("'kpod logs' requires exactly one container name/ID")
|
||||
}
|
||||
if err := validateFlags(c, logsFlags); err != nil {
|
||||
return err
|
||||
}
|
||||
container := c.Args().First()
|
||||
var opts libkpod.LogOptions
|
||||
opts.Details = c.Bool("details")
|
||||
|
|
|
@ -64,6 +64,9 @@ func mountCmd(c *cli.Context) error {
|
|||
if len(args) > 1 {
|
||||
return errors.Errorf("too many arguments specified")
|
||||
}
|
||||
if err := validateFlags(c, mountFlags); err != nil {
|
||||
return err
|
||||
}
|
||||
config, err := getConfig(c)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "Could not get config")
|
||||
|
|
|
@ -143,6 +143,9 @@ var (
|
|||
)
|
||||
|
||||
func psCmd(c *cli.Context) error {
|
||||
if err := validateFlags(c, psFlags); err != nil {
|
||||
return err
|
||||
}
|
||||
config, err := getConfig(c)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "could not get config")
|
||||
|
|
|
@ -129,6 +129,9 @@ func pullCmd(c *cli.Context) error {
|
|||
logrus.Errorf("too many arguments. Requires exactly 1")
|
||||
return nil
|
||||
}
|
||||
if err := validateFlags(c, pullFlags); err != nil {
|
||||
return err
|
||||
}
|
||||
image := args[0]
|
||||
srcRef, err := alltransports.ParseImageName(image)
|
||||
if err != nil {
|
||||
|
|
|
@ -68,6 +68,9 @@ func pushCmd(c *cli.Context) error {
|
|||
if len(args) < 2 {
|
||||
return errors.New("kpod push requires exactly 2 arguments")
|
||||
}
|
||||
if err := validateFlags(c, pushFlags); err != nil {
|
||||
return err
|
||||
}
|
||||
srcName := c.Args().Get(0)
|
||||
destName := c.Args().Get(1)
|
||||
|
||||
|
|
|
@ -23,6 +23,9 @@ func renameCmd(c *cli.Context) error {
|
|||
if len(c.Args()) != 2 {
|
||||
return errors.Errorf("Rename requires a src container name/ID and a dest container name")
|
||||
}
|
||||
if err := validateFlags(c, renameFlags); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
config, err := getConfig(c)
|
||||
if err != nil {
|
||||
|
|
|
@ -33,6 +33,9 @@ func rmCmd(c *cli.Context) error {
|
|||
if len(args) == 0 {
|
||||
return errors.Errorf("specify one or more containers to remove")
|
||||
}
|
||||
if err := validateFlags(c, rmFlags); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
config, err := getConfig(c)
|
||||
if err != nil {
|
||||
|
|
|
@ -28,6 +28,9 @@ var (
|
|||
)
|
||||
|
||||
func rmiCmd(c *cli.Context) error {
|
||||
if err := validateFlags(c, rmiFlags); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
force := false
|
||||
if c.IsSet("force") {
|
||||
|
|
|
@ -47,6 +47,9 @@ func saveCmd(c *cli.Context) error {
|
|||
if len(args) == 0 {
|
||||
return errors.Errorf("need at least 1 argument")
|
||||
}
|
||||
if err := validateFlags(c, saveFlags); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
runtime, err := getRuntime(c)
|
||||
if err != nil {
|
||||
|
|
|
@ -62,6 +62,9 @@ var (
|
|||
)
|
||||
|
||||
func statsCmd(c *cli.Context) error {
|
||||
if err := validateFlags(c, statsFlags); err != nil {
|
||||
return err
|
||||
}
|
||||
config, err := getConfig(c)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "could not read config")
|
||||
|
|
|
@ -42,6 +42,9 @@ func stopCmd(c *cli.Context) error {
|
|||
if len(args) < 1 {
|
||||
return errors.Errorf("you must provide at least one container name or id")
|
||||
}
|
||||
if err := validateFlags(c, stopFlags); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
config, err := getConfig(c)
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in a new issue