github.com/iron-io/functions@v0.0.0-20180820112432-d59d7d1c40b2/fn/app/app.go (about)

     1  package app
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"os"
     7  	"strings"
     8  
     9  	vers "github.com/iron-io/functions/api/version"
    10  	"github.com/iron-io/functions/fn/commands"
    11  	image_commands "github.com/iron-io/functions/fn/commands/images"
    12  	"github.com/iron-io/functions/fn/common"
    13  	"github.com/urfave/cli"
    14  )
    15  
    16  var aliases = map[string]cli.Command{
    17  	"build":  image_commands.Build(),
    18  	"bump":   image_commands.Bump(),
    19  	"deploy": image_commands.Deploy(),
    20  	"push":   image_commands.Push(),
    21  	"run":    image_commands.Run(),
    22  	"call":   commands.Call(),
    23  }
    24  
    25  func aliasesFn() []cli.Command {
    26  	cmds := []cli.Command{}
    27  	for alias, cmd := range aliases {
    28  		cmd.Name = alias
    29  		cmd.Hidden = true
    30  		cmds = append(cmds, cmd)
    31  	}
    32  	return cmds
    33  }
    34  
    35  func NewFn() *cli.App {
    36  	common.SetEnv()
    37  	app := cli.NewApp()
    38  	app.Name = "fn"
    39  	app.Version = vers.Version
    40  	app.Authors = []cli.Author{{Name: "iron.io"}}
    41  	app.Description = "IronFunctions command line tools"
    42  	app.UsageText = `Check the manual at https://github.com/iron-io/functions/blob/master/fn/README.md`
    43  
    44  	cli.AppHelpTemplate = `{{.Name}} {{.Version}}{{if .Description}}
    45  
    46  {{.Description}}{{end}}
    47  
    48  USAGE:
    49     {{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}} {{if .VisibleFlags}}[global options]{{end}}{{if .Commands}} command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}
    50  
    51  ENVIRONMENT VARIABLES:
    52     API_URL - IronFunctions remote API address{{if .VisibleCommands}}
    53  
    54  COMMANDS:{{range .VisibleCategories}}{{if .Name}}
    55     {{.Name}}:{{end}}{{range .VisibleCommands}}
    56       {{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{end}}{{end}}{{if .VisibleFlags}}
    57  
    58  ALIASES:
    59       build    (images build)
    60       bump     (images bump)
    61       deploy   (images deploy)
    62       run      (images run)
    63       call     (routes call)
    64       push     (images push)
    65  
    66  GLOBAL OPTIONS:
    67     {{range $index, $option := .VisibleFlags}}{{if $index}}
    68     {{end}}{{$option}}{{end}}{{end}}
    69  `
    70  
    71  	app.CommandNotFound = func(c *cli.Context, cmd string) {
    72  		fmt.Fprintf(os.Stderr, "command not found: %v\n", cmd)
    73  	}
    74  	app.Commands = []cli.Command{
    75  		commands.InitFn(),
    76  		commands.Apps(),
    77  		commands.Routes(),
    78  		commands.Images(),
    79  		commands.Lambda(),
    80  		commands.Version(),
    81  	}
    82  	app.Commands = append(app.Commands, aliasesFn()...)
    83  
    84  	prepareCmdArgsValidation(app.Commands)
    85  
    86  	return app
    87  }
    88  
    89  func parseArgs(c *cli.Context) ([]string, []string) {
    90  	args := strings.Split(c.Command.ArgsUsage, " ")
    91  	var reqArgs []string
    92  	var optArgs []string
    93  	for _, arg := range args {
    94  		if strings.HasPrefix(arg, "[") {
    95  			optArgs = append(optArgs, arg)
    96  		} else if strings.Trim(arg, " ") != "" {
    97  			reqArgs = append(reqArgs, arg)
    98  		}
    99  	}
   100  	return reqArgs, optArgs
   101  }
   102  
   103  func prepareCmdArgsValidation(cmds []cli.Command) {
   104  	// TODO: refactor fn to use urfave/cli.v2
   105  	// v1 doesn't let us validate args before the cmd.Action
   106  
   107  	for i, cmd := range cmds {
   108  		prepareCmdArgsValidation(cmd.Subcommands)
   109  		if cmd.Action == nil {
   110  			continue
   111  		}
   112  		action := cmd.Action
   113  		cmd.Action = func(c *cli.Context) error {
   114  			reqArgs, _ := parseArgs(c)
   115  			if c.NArg() < len(reqArgs) {
   116  				var help bytes.Buffer
   117  				cli.HelpPrinter(&help, cli.CommandHelpTemplate, c.Command)
   118  				return fmt.Errorf("ERROR: Missing required arguments: %s\n\n%s", strings.Join(reqArgs[c.NArg():], " "), help.String())
   119  			}
   120  			return cli.HandleAction(action, c)
   121  		}
   122  		cmds[i] = cmd
   123  	}
   124  }