github.com/clusterize-io/tusk@v0.6.3-0.20211001020217-cfe8a8cd0d4a/appcli/flag.go (about)

     1  package appcli
     2  
     3  import (
     4  	"fmt"
     5  	"sort"
     6  	"strings"
     7  
     8  	"github.com/urfave/cli"
     9  
    10  	"github.com/clusterize-io/tusk/runner"
    11  )
    12  
    13  // copyFlags copies all command flags from one cli.App to another.
    14  func copyFlags(target, source *cli.App) {
    15  	for i := range target.Commands {
    16  		targetCommand := &target.Commands[i]
    17  		for j := range source.Commands {
    18  			sourceCommand := source.Commands[j]
    19  			if targetCommand.Name == sourceCommand.Name {
    20  				targetCommand.Flags = sourceCommand.Flags
    21  			}
    22  		}
    23  	}
    24  }
    25  
    26  // addAllFlagsUsed adds the top-level flags to tasks where interpolation is used.
    27  func addAllFlagsUsed(cfg *runner.Config, cmd *cli.Command, t *runner.Task) error {
    28  	dependencies, err := runner.FindAllOptions(t, cfg)
    29  	if err != nil {
    30  		return err
    31  	}
    32  
    33  	for _, opt := range dependencies {
    34  		if opt.Private {
    35  			continue
    36  		}
    37  
    38  		if err := addFlag(cmd, opt); err != nil {
    39  			return fmt.Errorf(
    40  				"could not add flag %q to command %q: %w",
    41  				opt.Name,
    42  				t.Name,
    43  				err,
    44  			)
    45  		}
    46  	}
    47  
    48  	sort.Sort(cli.FlagsByName(cmd.Flags))
    49  	return nil
    50  }
    51  
    52  func addFlag(command *cli.Command, opt *runner.Option) error {
    53  	newFlag, err := createCLIFlag(opt)
    54  	if err != nil {
    55  		return err
    56  	}
    57  
    58  	for _, oldFlag := range command.Flags {
    59  		if oldFlag.GetName() == newFlag.GetName() {
    60  			return nil
    61  		}
    62  	}
    63  
    64  	command.Flags = append(command.Flags, newFlag)
    65  
    66  	return nil
    67  }
    68  
    69  // createCLIFlag converts an Option into a cli.Flag.
    70  func createCLIFlag(opt *runner.Option) (cli.Flag, error) {
    71  	name := opt.Name
    72  	if opt.Short != "" {
    73  		name = fmt.Sprintf("%s, %s", name, opt.Short)
    74  	}
    75  
    76  	opt.Type = strings.ToLower(opt.Type)
    77  	switch opt.Type {
    78  	case "int", "integer":
    79  		return cli.IntFlag{
    80  			Name:  name,
    81  			Usage: opt.Usage,
    82  		}, nil
    83  	case "float", "float64", "double":
    84  		return cli.Float64Flag{
    85  			Name:  name,
    86  			Usage: opt.Usage,
    87  		}, nil
    88  	case "bool", "boolean":
    89  		return cli.BoolFlag{
    90  			Name:  name,
    91  			Usage: opt.Usage,
    92  		}, nil
    93  	case "string", "":
    94  		return cli.StringFlag{
    95  			Name:  name,
    96  			Usage: opt.Usage,
    97  		}, nil
    98  	default:
    99  		return nil, fmt.Errorf("unsupported flag type %q", opt.Type)
   100  	}
   101  }