github.com/terhitormanen/cmd@v1.1.4/revel/revel.go (about)

     1  // Copyright (c) 2012-2016 The Revel Framework Authors, All rights reserved.
     2  // Revel Framework source code and usage is governed by a MIT style
     3  // license that can be found in the LICENSE file.
     4  
     5  // The command line tool for running Revel apps.
     6  package main
     7  
     8  import (
     9  	"bytes"
    10  	"flag"
    11  	"fmt"
    12  	"math/rand"
    13  	"os"
    14  	"runtime"
    15  	"strings"
    16  	"time"
    17  
    18  	"github.com/agtorre/gocolorize"
    19  	"github.com/jessevdk/go-flags"
    20  	"github.com/terhitormanen/cmd/logger"
    21  	"github.com/terhitormanen/cmd/model"
    22  	"github.com/terhitormanen/cmd/utils"
    23  )
    24  
    25  // Error is used for constant errors.
    26  type Error string
    27  
    28  // Error implements the error interface.
    29  func (e Error) Error() string {
    30  	return string(e)
    31  }
    32  
    33  const ErrInvalidCommandLine Error = "invalid command line arguments"
    34  
    35  const (
    36  	// RevelCmdImportPath Revel framework cmd tool import path.
    37  	RevelSkeletonsImportPath = "github.com/terhitormanen/skeletons"
    38  
    39  	// DefaultRunMode for revel's application.
    40  	DefaultRunMode = "dev"
    41  )
    42  
    43  // Command structure cribbed from the genius organization of the "go" command.
    44  type Command struct {
    45  	UpdateConfig           func(c *model.CommandConfig, args []string) bool
    46  	RunWith                func(c *model.CommandConfig) error
    47  	UsageLine, Short, Long string
    48  }
    49  
    50  // Name returns command name from usage line.
    51  func (cmd *Command) Name() string {
    52  	name := cmd.UsageLine
    53  	i := strings.Index(name, " ")
    54  	if i >= 0 {
    55  		name = name[:i]
    56  	}
    57  	return name
    58  }
    59  
    60  // Commands defines the available commands.
    61  var Commands = []*Command{
    62  	nil, // Safety net, prevent missing index from running
    63  	cmdNew,
    64  	cmdRun,
    65  	cmdBuild,
    66  	cmdPackage,
    67  	cmdClean,
    68  	cmdTest,
    69  	cmdVersion,
    70  }
    71  
    72  func main() {
    73  	if runtime.GOOS == "windows" {
    74  		gocolorize.SetPlain(true)
    75  	}
    76  	c := &model.CommandConfig{}
    77  	wd, _ := os.Getwd()
    78  
    79  	utils.InitLogger(wd, logger.LvlError)
    80  	parser := flags.NewParser(c, flags.HelpFlag|flags.PassDoubleDash)
    81  	if len(os.Args) < 2 {
    82  		parser.WriteHelp(os.Stdout)
    83  		os.Exit(1)
    84  	}
    85  
    86  	if err := ParseArgs(c, parser, os.Args[1:]); err != nil {
    87  		fmt.Fprint(os.Stderr, err.Error()+"\n")
    88  		os.Exit(1)
    89  	}
    90  
    91  	// Switch based on the verbose flag
    92  	if len(c.Verbose) > 1 {
    93  		utils.InitLogger(wd, logger.LvlDebug)
    94  	} else if len(c.Verbose) > 0 {
    95  		utils.InitLogger(wd, logger.LvlInfo)
    96  	} else {
    97  		utils.InitLogger(wd, logger.LvlWarn)
    98  	}
    99  
   100  	// Setup package resolver
   101  	c.InitPackageResolver()
   102  
   103  	if err := c.UpdateImportPath(); err != nil {
   104  		utils.Logger.Error(err.Error())
   105  		parser.WriteHelp(os.Stdout)
   106  		os.Exit(1)
   107  	}
   108  
   109  	command := Commands[c.Index]
   110  	println("Revel executing:", command.Short)
   111  
   112  	if err := command.RunWith(c); err != nil {
   113  		utils.Logger.Error("Unable to execute", "error", err)
   114  		os.Exit(1)
   115  	}
   116  }
   117  
   118  // Parse the arguments passed into the model.CommandConfig.
   119  func ParseArgs(c *model.CommandConfig, parser *flags.Parser, args []string) (err error) {
   120  	var extraArgs []string
   121  	if ini := flag.String("ini", "none", ""); *ini != "none" {
   122  		if err = flags.NewIniParser(parser).ParseFile(*ini); err != nil {
   123  			return
   124  		}
   125  	} else {
   126  		if extraArgs, err = parser.ParseArgs(args); err != nil {
   127  			return
   128  		}
   129  
   130  		switch parser.Active.Name {
   131  		case "new":
   132  			c.Index = model.NEW
   133  		case "run":
   134  			c.Index = model.RUN
   135  		case "build":
   136  			c.Index = model.BUILD
   137  		case "package":
   138  			c.Index = model.PACKAGE
   139  		case "clean":
   140  			c.Index = model.CLEAN
   141  		case "test":
   142  			c.Index = model.TEST
   143  		case "version":
   144  			c.Index = model.VERSION
   145  		}
   146  	}
   147  
   148  	if !Commands[c.Index].UpdateConfig(c, extraArgs) {
   149  		buffer := &bytes.Buffer{}
   150  		parser.WriteHelp(buffer)
   151  		err = fmt.Errorf("%w %v\n%s", ErrInvalidCommandLine, extraArgs, buffer.String())
   152  	}
   153  
   154  	return
   155  }
   156  
   157  func init() {
   158  	rand.Seed(time.Now().UnixNano())
   159  }