github.com/wiselike/revel-cmd@v1.2.1/revel/run.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  package main
     6  
     7  import (
     8  	"encoding/json"
     9  	"fmt"
    10  	"os"
    11  	"strconv"
    12  
    13  	"github.com/wiselike/revel-cmd/harness"
    14  	"github.com/wiselike/revel-cmd/model"
    15  	"github.com/wiselike/revel-cmd/utils"
    16  )
    17  
    18  var cmdRun = &Command{
    19  	UsageLine: "run [-m [run mode] -p [port]] [import path] ",
    20  	Short:     "run a Revel application",
    21  	Long: `
    22  Run the Revel web application named by the given import path.
    23  
    24  For example, to run the chat room sample application:
    25  
    26      revel run -m dev github.com/revel/examples/chat
    27  
    28  The run mode is used to select which set of app.conf configuration should
    29  apply and may be used to determine logic in the application itself.
    30  
    31  Run mode defaults to "dev".
    32  
    33  You can set a port as well.  For example:
    34  
    35      revel run -m prod -p 8080 github.com/revel/examples/chat `,
    36  }
    37  
    38  func init() {
    39  	cmdRun.RunWith = runApp
    40  	cmdRun.UpdateConfig = updateRunConfig
    41  }
    42  
    43  func updateRunConfig(c *model.CommandConfig, args []string) bool {
    44  	convertPort := func(value string) int {
    45  		if value != "" {
    46  			port, err := strconv.Atoi(value)
    47  			if err != nil {
    48  				utils.Logger.Fatalf("Failed to parse port as integer: %s", c.Run.Port)
    49  			}
    50  			return port
    51  		}
    52  		return 0
    53  	}
    54  	switch len(args) {
    55  	case 3:
    56  		// Possible combinations
    57  		// revel run [import-path] [run-mode] [port]
    58  		c.Run.ImportPath = args[0]
    59  		c.Run.Mode = args[1]
    60  		c.Run.Port = convertPort(args[2])
    61  	case 2:
    62  		// Possible combinations
    63  		// 1. revel run [import-path] [run-mode]
    64  		// 2. revel run [import-path] [port]
    65  		// 3. revel run [run-mode] [port]
    66  
    67  		// Check to see if the import path evaluates out to something that may be on a gopath
    68  		if runIsImportPath(args[0]) {
    69  			// 1st arg is the import path
    70  			c.Run.ImportPath = args[0]
    71  
    72  			if _, err := strconv.Atoi(args[1]); err == nil {
    73  				// 2nd arg is the port number
    74  				c.Run.Port = convertPort(args[1])
    75  			} else {
    76  				// 2nd arg is the run mode
    77  				c.Run.Mode = args[1]
    78  			}
    79  		} else {
    80  			// 1st arg is the run mode
    81  			c.Run.Mode = args[0]
    82  			c.Run.Port = convertPort(args[1])
    83  		}
    84  	case 1:
    85  		// Possible combinations
    86  		// 1. revel run [import-path]
    87  		// 2. revel run [port]
    88  		// 3. revel run [run-mode]
    89  		if runIsImportPath(args[0]) {
    90  			// 1st arg is the import path
    91  			c.Run.ImportPath = args[0]
    92  		} else if _, err := strconv.Atoi(args[0]); err == nil {
    93  			// 1st arg is the port number
    94  			c.Run.Port = convertPort(args[0])
    95  		} else {
    96  			// 1st arg is the run mode
    97  			c.Run.Mode = args[0]
    98  		}
    99  	case 0:
   100  		// Attempt to set the import path to the current working director.
   101  		if c.Run.ImportPath == "" {
   102  			c.Run.ImportPath, _ = os.Getwd()
   103  		}
   104  	}
   105  	c.Index = model.RUN
   106  	return true
   107  }
   108  
   109  // Returns true if this is an absolute path or a relative gopath.
   110  func runIsImportPath(pathToCheck string) bool {
   111  	return utils.DirExists(pathToCheck)
   112  }
   113  
   114  // Called to run the app.
   115  func runApp(c *model.CommandConfig) (err error) {
   116  	if c.Run.Mode == "" {
   117  		c.Run.Mode = "dev"
   118  	}
   119  
   120  	revelPath, err := model.NewRevelPaths(c.Run.Mode, c.ImportPath, c.AppPath, model.NewWrappedRevelCallback(nil, c.PackageResolver))
   121  	if err != nil {
   122  		return utils.NewBuildIfError(err, "Revel paths")
   123  	}
   124  	if c.Run.Port > -1 {
   125  		revelPath.HTTPPort = c.Run.Port
   126  	} else {
   127  		c.Run.Port = revelPath.HTTPPort
   128  	}
   129  
   130  	utils.Logger.Infof("Running %s (%s) in %s mode\n", revelPath.AppName, revelPath.ImportPath, revelPath.RunMode)
   131  	utils.Logger.Debug("Base path:", "path", revelPath.BasePath)
   132  
   133  	// If the app is run in "watched" mode, use the harness to run it.
   134  	if revelPath.Config.BoolDefault("watch", true) && revelPath.Config.BoolDefault("watch.code", true) {
   135  		utils.Logger.Info("Running in watched mode.")
   136  
   137  		runMode := fmt.Sprintf(`{"mode":"%s", "specialUseFlag":%v}`, revelPath.RunMode, c.GetVerbose())
   138  		if c.HistoricMode {
   139  			runMode = revelPath.RunMode
   140  		}
   141  		// **** Never returns.
   142  		harness.NewHarness(c, revelPath, runMode, c.Run.NoProxy).Run()
   143  	}
   144  
   145  	// Else, just build and run the app.
   146  	utils.Logger.Debug("Running in live build mode.")
   147  	app, err := harness.Build(c, revelPath)
   148  	if err != nil {
   149  		utils.Logger.Errorf("Failed to build app: %s", err)
   150  	}
   151  	app.Port = revelPath.HTTPPort
   152  	var paths []byte
   153  	if len(app.PackagePathMap) > 0 {
   154  		paths, _ = json.Marshal(app.PackagePathMap)
   155  	}
   156  	runMode := fmt.Sprintf(`{"mode":"%s", "specialUseFlag":%v,"packagePathMap":%s}`, app.Paths.RunMode, c.GetVerbose(), string(paths))
   157  	if c.HistoricMode {
   158  		runMode = revelPath.RunMode
   159  	}
   160  	app.Cmd(runMode).Run(c)
   161  	return
   162  }