1
0
mirror of https://github.com/beego/bee.git synced 2024-11-01 10:10:55 +00:00
bee/cmd/commands/run/run.go

254 lines
7.2 KiB
Go
Raw Normal View History

2013-09-03 17:23:58 +00:00
// Copyright 2013 bee authors
//
// Licensed under the Apache License, Version 2.0 (the "License"): you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
package run
2013-07-24 12:01:14 +00:00
import (
"io/ioutil"
2013-07-24 12:01:14 +00:00
"os"
path "path/filepath"
"runtime"
2013-09-11 23:06:04 +00:00
"strings"
"github.com/beego/bee/cmd/commands"
"github.com/beego/bee/cmd/commands/version"
"github.com/beego/bee/config"
beeLogger "github.com/beego/bee/logger"
"github.com/beego/bee/utils"
2013-07-24 12:01:14 +00:00
)
var CmdRun = &commands.Command{
UsageLine: "run [appname] [watchall] [-main=*.go] [-downdoc=true] [-gendoc=true] [-vendor=true] [-e=folderToExclude] [-ex=extraPackageToWatch] [-tags=goBuildTags] [-runmode=BEEGO_RUNMODE]",
Short: "Run the application by starting a local development server",
2013-07-24 12:01:14 +00:00
Long: `
Run command will supervise the filesystem of the application for any changes, and recompile/restart it.
2013-07-24 12:01:14 +00:00
`,
PreRun: func(cmd *commands.Command, args []string) { version.ShowShortVersionBanner() },
Run: RunApp,
2013-07-24 12:01:14 +00:00
}
2016-07-28 12:19:42 +00:00
var (
mainFiles utils.ListOpts
downdoc utils.DocValue
gendoc utils.DocValue
2016-07-28 12:19:42 +00:00
// The flags list of the paths excluded from watching
excludedPaths utils.StrFlags
2016-07-28 12:19:42 +00:00
// Pass through to -tags arg of "go build"
buildTags string
// Application path
currpath string
// Application name
appname string
// Channel to signal an Exit
exit chan bool
// Flag to watch the vendor folder
vendorWatch bool
// Current user workspace
currentGoPath string
// Current runmode
runmode string
2018-06-26 10:07:49 +00:00
// Extra args to run application
runargs string
// Extra directories
extraPackages utils.StrFlags
2016-07-28 12:19:42 +00:00
)
var started = make(chan bool)
2016-07-22 22:24:44 +00:00
2013-07-24 12:01:14 +00:00
func init() {
CmdRun.Flag.Var(&mainFiles, "main", "Specify main go files.")
CmdRun.Flag.Var(&gendoc, "gendoc", "Enable auto-generate the docs.")
CmdRun.Flag.Var(&downdoc, "downdoc", "Enable auto-download of the swagger file if it does not exist.")
CmdRun.Flag.Var(&excludedPaths, "e", "List of paths to exclude.")
CmdRun.Flag.BoolVar(&vendorWatch, "vendor", false, "Enable watch vendor folder.")
CmdRun.Flag.StringVar(&buildTags, "tags", "", "Set the build tags. See: https://golang.org/pkg/go/build/")
CmdRun.Flag.StringVar(&runmode, "runmode", "", "Set the Beego run mode.")
2018-06-26 10:07:49 +00:00
CmdRun.Flag.StringVar(&runargs, "runargs", "", "Extra args to run application")
CmdRun.Flag.Var(&extraPackages, "ex", "List of extra package to watch.")
2016-07-28 12:19:42 +00:00
exit = make(chan bool)
commands.AvailableCommands = append(commands.AvailableCommands, CmdRun)
2013-07-24 12:01:14 +00:00
}
// RunApp locates files to watch, and starts the beego application
func RunApp(cmd *commands.Command, args []string) int {
// The default app path is the current working directory
appPath, _ := os.Getwd()
// If an argument is presented, we use it as the app path
if len(args) != 0 && args[0] != "watchall" {
if path.IsAbs(args[0]) {
appPath = args[0]
2016-07-30 11:42:38 +00:00
} else {
appPath = path.Join(appPath, args[0])
}
}
if utils.IsInGOPATH(appPath) {
if found, _gopath, _path := utils.SearchGOPATHs(appPath); found {
appPath = _path
appname = path.Base(appPath)
currentGoPath = _gopath
} else {
beeLogger.Log.Fatalf("No application '%s' found in your GOPATH", appPath)
}
if strings.HasSuffix(appname, ".go") && utils.IsExist(appPath) {
beeLogger.Log.Warnf("The appname is in conflict with file's current path. Do you want to build appname as '%s'", appname)
beeLogger.Log.Info("Do you want to overwrite it? [yes|no] ")
if !utils.AskForConfirmation() {
2015-05-09 07:31:55 +00:00
return 0
}
}
} else {
beeLogger.Log.Warn("Running application outside of GOPATH")
appname = path.Base(appPath)
currentGoPath = appPath
2013-07-24 12:01:14 +00:00
}
beeLogger.Log.Infof("Using '%s' as 'appname'", appname)
beeLogger.Log.Debugf("Current path: %s", utils.FILE(), utils.LINE(), appPath)
2013-07-24 12:01:14 +00:00
if runmode == "prod" || runmode == "dev" {
os.Setenv("BEEGO_RUNMODE", runmode)
beeLogger.Log.Infof("Using '%s' as 'runmode'", os.Getenv("BEEGO_RUNMODE"))
} else if runmode != "" {
os.Setenv("BEEGO_RUNMODE", runmode)
beeLogger.Log.Warnf("Using '%s' as 'runmode'", os.Getenv("BEEGO_RUNMODE"))
} else if os.Getenv("BEEGO_RUNMODE") != "" {
beeLogger.Log.Warnf("Using '%s' as 'runmode'", os.Getenv("BEEGO_RUNMODE"))
2013-07-24 12:01:14 +00:00
}
2013-11-04 03:16:15 +00:00
2013-07-24 12:01:14 +00:00
var paths []string
readAppDirectories(appPath, &paths)
// Because monitor files has some issues, we watch current directory
// and ignore non-go files.
for _, p := range config.Conf.DirStruct.Others {
paths = append(paths, strings.Replace(p, "$GOPATH", currentGoPath, -1))
2013-09-11 23:06:04 +00:00
}
2013-07-24 12:01:14 +00:00
if len(extraPackages) > 0 {
// get the full path
for _, packagePath := range extraPackages {
if found, _, _fullPath := utils.SearchGOPATHs(packagePath); found {
readAppDirectories(_fullPath, &paths)
} else {
beeLogger.Log.Warnf("No extra package '%s' found in your GOPATH", packagePath)
}
}
// let paths unique
strSet := make(map[string]struct{})
for _, p := range paths {
strSet[p] = struct{}{}
}
paths = make([]string, len(strSet))
index := 0
for i := range strSet {
paths[index] = i
index++
}
}
2014-02-21 17:51:18 +00:00
files := []string{}
for _, arg := range mainFiles {
if len(arg) > 0 {
files = append(files, arg)
}
}
2016-08-16 16:52:57 +00:00
if downdoc == "true" {
if _, err := os.Stat(path.Join(appPath, "swagger", "index.html")); err != nil {
2016-08-16 16:52:57 +00:00
if os.IsNotExist(err) {
downloadFromURL(swaggerlink, "swagger.zip")
unzipAndDelete("swagger.zip")
}
}
}
2017-02-13 21:05:32 +00:00
// Start the Reload server (if enabled)
if config.Conf.EnableReload {
2017-02-13 21:05:32 +00:00
startReloadServer()
}
2014-08-08 16:55:55 +00:00
if gendoc == "true" {
NewWatcher(paths, files, true)
AutoBuild(files, true)
} else {
NewWatcher(paths, files, false)
AutoBuild(files, false)
}
2016-08-16 16:52:57 +00:00
2013-07-24 12:01:14 +00:00
for {
<-exit
runtime.Goexit()
2013-07-24 12:01:14 +00:00
}
}
func readAppDirectories(directory string, paths *[]string) {
fileInfos, err := ioutil.ReadDir(directory)
if err != nil {
return
}
useDirectory := false
for _, fileInfo := range fileInfos {
if strings.HasSuffix(fileInfo.Name(), "docs") {
continue
}
2016-08-16 16:52:57 +00:00
if strings.HasSuffix(fileInfo.Name(), "swagger") {
continue
}
2015-06-17 06:59:59 +00:00
2016-07-22 22:24:44 +00:00
if !vendorWatch && strings.HasSuffix(fileInfo.Name(), "vendor") {
continue
}
if isExcluded(path.Join(directory, fileInfo.Name())) {
2015-06-17 06:59:59 +00:00
continue
}
if fileInfo.IsDir() && fileInfo.Name()[0] != '.' {
readAppDirectories(directory+"/"+fileInfo.Name(), paths)
continue
}
if useDirectory {
continue
}
if path.Ext(fileInfo.Name()) == ".go" || (ifStaticFile(fileInfo.Name()) && config.Conf.EnableReload) {
*paths = append(*paths, directory)
useDirectory = true
}
}
}
2015-06-17 06:59:59 +00:00
// If a file is excluded
func isExcluded(filePath string) bool {
2015-06-17 06:59:59 +00:00
for _, p := range excludedPaths {
absP, err := path.Abs(p)
if err != nil {
beeLogger.Log.Errorf("Cannot get absolute path of '%s'", p)
continue
}
absFilePath, err := path.Abs(filePath)
if err != nil {
beeLogger.Log.Errorf("Cannot get absolute path of '%s'", filePath)
break
}
if strings.HasPrefix(absFilePath, absP) {
beeLogger.Log.Infof("'%s' is not being watched", filePath)
2015-06-17 06:59:59 +00:00
return true
}
}
return false
}