Path: blob/main/vendor/github.com/spf13/cobra/args.go
2875 views
// Copyright 2013-2023 The Cobra Authors1//2// Licensed under the Apache License, Version 2.0 (the "License");3// you may not use this file except in compliance with the License.4// You may obtain a copy of the License at5//6// http://www.apache.org/licenses/LICENSE-2.07//8// Unless required by applicable law or agreed to in writing, software9// distributed under the License is distributed on an "AS IS" BASIS,10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.11// See the License for the specific language governing permissions and12// limitations under the License.1314package cobra1516import (17"fmt"18"strings"19)2021type PositionalArgs func(cmd *Command, args []string) error2223// legacyArgs validation has the following behaviour:24// - root commands with no subcommands can take arbitrary arguments25// - root commands with subcommands will do subcommand validity checking26// - subcommands will always accept arbitrary arguments27func legacyArgs(cmd *Command, args []string) error {28// no subcommand, always take args29if !cmd.HasSubCommands() {30return nil31}3233// root command with subcommands, do subcommand checking.34if !cmd.HasParent() && len(args) > 0 {35return fmt.Errorf("unknown command %q for %q%s", args[0], cmd.CommandPath(), cmd.findSuggestions(args[0]))36}37return nil38}3940// NoArgs returns an error if any args are included.41func NoArgs(cmd *Command, args []string) error {42if len(args) > 0 {43return fmt.Errorf("unknown command %q for %q", args[0], cmd.CommandPath())44}45return nil46}4748// OnlyValidArgs returns an error if there are any positional args that are not in49// the `ValidArgs` field of `Command`50func OnlyValidArgs(cmd *Command, args []string) error {51if len(cmd.ValidArgs) > 0 {52// Remove any description that may be included in ValidArgs.53// A description is following a tab character.54validArgs := make([]string, 0, len(cmd.ValidArgs))55for _, v := range cmd.ValidArgs {56validArgs = append(validArgs, strings.SplitN(v, "\t", 2)[0])57}58for _, v := range args {59if !stringInSlice(v, validArgs) {60return fmt.Errorf("invalid argument %q for %q%s", v, cmd.CommandPath(), cmd.findSuggestions(args[0]))61}62}63}64return nil65}6667// ArbitraryArgs never returns an error.68func ArbitraryArgs(cmd *Command, args []string) error {69return nil70}7172// MinimumNArgs returns an error if there is not at least N args.73func MinimumNArgs(n int) PositionalArgs {74return func(cmd *Command, args []string) error {75if len(args) < n {76return fmt.Errorf("requires at least %d arg(s), only received %d", n, len(args))77}78return nil79}80}8182// MaximumNArgs returns an error if there are more than N args.83func MaximumNArgs(n int) PositionalArgs {84return func(cmd *Command, args []string) error {85if len(args) > n {86return fmt.Errorf("accepts at most %d arg(s), received %d", n, len(args))87}88return nil89}90}9192// ExactArgs returns an error if there are not exactly n args.93func ExactArgs(n int) PositionalArgs {94return func(cmd *Command, args []string) error {95if len(args) != n {96return fmt.Errorf("accepts %d arg(s), received %d", n, len(args))97}98return nil99}100}101102// RangeArgs returns an error if the number of args is not within the expected range.103func RangeArgs(min int, max int) PositionalArgs {104return func(cmd *Command, args []string) error {105if len(args) < min || len(args) > max {106return fmt.Errorf("accepts between %d and %d arg(s), received %d", min, max, len(args))107}108return nil109}110}111112// MatchAll allows combining several PositionalArgs to work in concert.113func MatchAll(pargs ...PositionalArgs) PositionalArgs {114return func(cmd *Command, args []string) error {115for _, parg := range pargs {116if err := parg(cmd, args); err != nil {117return err118}119}120return nil121}122}123124// ExactValidArgs returns an error if there are not exactly N positional args OR125// there are any positional args that are not in the `ValidArgs` field of `Command`126//127// Deprecated: use MatchAll(ExactArgs(n), OnlyValidArgs) instead128func ExactValidArgs(n int) PositionalArgs {129return MatchAll(ExactArgs(n), OnlyValidArgs)130}131132133