Merge pull request #185 from notzippy/go-mod

Go mod updates
This commit is contained in:
Steve
2020-05-19 02:42:57 -07:00
committed by GitHub
12 changed files with 263 additions and 160 deletions

View File

@@ -47,19 +47,25 @@ script:
#- revel package my/testapp prod
# Ensure the new-app flow works (plus the other commands).
- revel new --gomod-flags "edit -replace=github.com/revel/revel=github.com/revel/revel@develop" -a my/testapp2 -v
- revel test --gomod-flags "edit -replace=github.com/revel/revel=github.com/revel/revel@develop" -a my/testapp2 -v
- revel clean --gomod-flags "edit -replace=github.com/revel/revel=github.com/revel/revel@develop" -a my/testapp2 -v
- revel build --gomod-flags "edit -replace=github.com/revel/revel=github.com/revel/revel@develop" -a my/testapp2 -v -t build/testapp2
- revel build --gomod-flags "edit -replace=github.com/revel/revel=github.com/revel/revel@develop" -a my/testapp2 -v -t build/testapp2 -m prod
- revel package --gomod-flags "edit -replace=github.com/revel/revel=github.com/revel/revel@develop" -a my/testapp2 -v
- revel package --gomod-flags "edit -replace=github.com/revel/revel=github.com/revel/revel@develop" -a my/testapp2 -v -m prod
- revel new --gomod-flags "edit -replace=github.com/revel/revel=github.com/revel/revel@$REVEL_BRANCH" -a my/testapp2 --package revelframework.com -v
- revel test --gomod-flags "edit -replace=github.com/revel/revel=github.com/revel/revel@$REVEL_BRANCH" -a my/testapp2 -v
- revel clean --gomod-flags "edit -replace=github.com/revel/revel=github.com/revel/revel@$REVEL_BRANCH" -a my/testapp2 -v
- revel build --gomod-flags "edit -replace=github.com/revel/revel=github.com/revel/revel@$REVEL_BRANCH" -a my/testapp2 -v -t build/testapp2
- revel build --gomod-flags "edit -replace=github.com/revel/revel=github.com/revel/revel@$REVEL_BRANCH" -a my/testapp2 -v -t build/testapp2 -m prod
- revel package --gomod-flags "edit -replace=github.com/revel/revel=github.com/revel/revel@$REVEL_BRANCH" -a my/testapp2 -v
- revel package --gomod-flags "edit -replace=github.com/revel/revel=github.com/revel/revel@$REVEL_BRANCH" -a my/testapp2 -v -m prod
- export INITIALWD=$PWD
# Check build works with no-vendor flag
- cd $GOPATH
- export GO111MODULE=auto
- revel new -a my/testapp2 --no-vendor
- revel test -a my/testapp2
- revel new -a my/testapp2 --no-vendor -v
- revel test -a my/testapp2 -v
# Check non verbose build, outside of GO path
- cd $INITIALWD
- revel new --gomod-flags "edit -replace=github.com/revel/revel=github.com/revel/revel@$REVEL_BRANCH" -a my/testapp3 --package revelframework.com
- revel test --gomod-flags "edit -replace=github.com/revel/revel=github.com/revel/revel@$REVEL_BRANCH" -a my/testapp3
matrix:
allow_failures:

View File

@@ -106,7 +106,7 @@ func (cmd AppCmd) Kill() {
if cmd.Cmd != nil && (cmd.ProcessState == nil || !cmd.ProcessState.Exited()) {
// Windows appears to send the kill to all threads, shutting down the
// server before this can, this check will ensure the process is still running
if _, err := os.FindProcess(int(cmd.Process.Pid));err!=nil {
if _, err := os.FindProcess(int(cmd.Process.Pid)); err != nil {
// Server has already exited
utils.Logger.Info("Server not running revel server pid", "pid", cmd.Process.Pid)
return
@@ -143,9 +143,9 @@ func (cmd AppCmd) Kill() {
}
if err != nil {
utils.Logger.Error(
"Revel app failed to kill process.",
"processid", cmd.Process.Pid,"error",err,
utils.Logger.Info(
"Revel app already exited.",
"processid", cmd.Process.Pid, "error", err,
"killerror", cmd.Process.Kill())
return
}

View File

@@ -16,6 +16,7 @@ package harness
import (
"crypto/tls"
"fmt"
"time"
"go/build"
"io"
"net"
@@ -56,6 +57,8 @@ type Harness struct {
paths *model.RevelContainer // The Revel container
config *model.CommandConfig // The configuration
runMode string // The runmode the harness is running in
isError bool // True if harness is in error state
ranOnce bool // True app compiled once
}
func (h *Harness) renderError(iw http.ResponseWriter, ir *http.Request, err error) {
@@ -202,6 +205,21 @@ func NewHarness(c *model.CommandConfig, paths *model.RevelContainer, runMode str
// Refresh method rebuilds the Revel application and run it on the given port.
// called by the watcher
func (h *Harness) Refresh() (err *utils.SourceError) {
t := time.Now();
fmt.Println("Changed detected, recompiling")
err = h.refresh()
if err!=nil && !h.ranOnce && h.useProxy {
addr := fmt.Sprintf("%s:%d", h.paths.HTTPAddr, h.paths.HTTPPort)
fmt.Printf("\nError compiling code, to view error details see proxy running on http://%s\n\n",addr)
}
h.ranOnce = true
fmt.Printf("\nTime to recompile %s\n",time.Now().Sub(t).String())
return
}
func (h *Harness) refresh() (err *utils.SourceError) {
// Allow only one thread to rebuild the process
// If multiple requests to rebuild are queued only the last one is executed on
// So before a build is started we wait for a second to determine if
@@ -281,7 +299,8 @@ func (h *Harness) Run() {
paths = append(paths, h.paths.CodePaths...)
h.watcher = watcher.NewWatcher(h.paths, false)
h.watcher.Listen(h, paths...)
h.watcher.Notify()
go h.Refresh()
// h.watcher.Notify()
if h.useProxy {
go func() {
@@ -292,6 +311,7 @@ func (h *Harness) Run() {
addr := fmt.Sprintf("%s:%d", h.paths.HTTPAddr, h.paths.HTTPPort)
utils.Logger.Infof("Proxy server is listening on %s", addr)
var err error
if h.paths.HTTPSsl {
err = http.ListenAndServeTLS(
@@ -308,13 +328,15 @@ func (h *Harness) Run() {
}()
}
// Kill the app on signal.
// Make a new channel to listen for the interrupt event
ch := make(chan os.Signal)
signal.Notify(ch, os.Interrupt, os.Kill)
<-ch
// Kill the app and exit
if h.app != nil {
h.app.Kill()
}
<-ch
os.Exit(1)
}

View File

@@ -174,8 +174,10 @@ func (c *CommandConfig) initAppFolder() (err error) {
// Use app folder to read the go.mod if it exists and extract the package information
goModFile := filepath.Join(appFolder, "go.mod")
utils.Logger.Info("Checking gomod, extracting from file", "path", goModFile,"exists", utils.Exists(goModFile))
if utils.Exists(goModFile) {
c.Vendored = true
utils.Logger.Info("Found go mod, extracting from file", "path", goModFile)
file, err := ioutil.ReadFile(goModFile)
if err != nil {
return err
@@ -220,7 +222,7 @@ func (c *CommandConfig) initAppFolder() (err error) {
c.AppPath = appFolder
}
utils.Logger.Info("Set application path", "path", c.AppPath)
utils.Logger.Info("Set application path", "path", c.AppPath, "vendored",c.Vendored, "importpath",c.ImportPath)
return nil
}
@@ -233,6 +235,7 @@ func (c *CommandConfig) InitPackageResolver() {
c.PackageResolver = func(pkgName string) error {
utils.Logger.Info("Request for package ", "package", pkgName, "use vendor", c.Vendored)
var getCmd *exec.Cmd
print("Downloading related packages ...")
if c.Vendored {
getCmd = exec.Command(c.GoCmd, "mod", "tidy")
} else {
@@ -246,6 +249,7 @@ func (c *CommandConfig) InitPackageResolver() {
if err != nil {
utils.Logger.Error("Failed to import package", "error", err, "gopath", build.Default.GOPATH, "GO-ROOT", build.Default.GOROOT, "output", string(output))
}
println(" completed.")
return nil
}

View File

@@ -57,7 +57,6 @@ func (s *SourceInfo) TypesThatEmbed(targetType, packageFilter string) (filtered
// Look through the embedded types to see if the current type is among them.
for _, embeddedType := range spec.EmbeddedTypes {
// If so, add this type's simple name to the nodeQueue, and its spec to
// the filtered list.
if typeSimpleName == embeddedType.String() {
@@ -111,6 +110,7 @@ func (s *SourceInfo) TypesThatEmbed(targetType, packageFilter string) (filtered
// ControllerSpecs returns the all the controllers that embeds
// `revel.Controller`
func (s *SourceInfo) ControllerSpecs() []*TypeInfo {
utils.Logger.Info("Scanning controller specifications for types ","typePath",RevelImportPath + ".Controller", "speclen",len(s.controllerSpecs))
if s.controllerSpecs == nil {
s.controllerSpecs = s.TypesThatEmbed(RevelImportPath + ".Controller", "controllers")
}

View File

@@ -8,6 +8,7 @@ import (
"go/token"
"strings"
"path/filepath"
"github.com/revel/cmd/logger"
)
type (
@@ -31,14 +32,21 @@ func (s *SourceInfoProcessor) processPackage(p *packages.Package) (sourceInfo *m
strings.Contains(p.PkgPath, "/tests/")
methodMap = map[string][]*model.MethodSpec{}
)
localImportMap := map[string]string{}
log := s.sourceProcessor.log.New("package", p.PkgPath)
log.Info("Processing package")
for _, tree := range p.Syntax {
for _, decl := range tree.Decls {
s.sourceProcessor.packageMap[p.PkgPath] = filepath.Dir(p.Fset.Position(decl.Pos()).Filename)
//println("*** checking", p.Fset.Position(decl.Pos()).Filename)
if !s.addImport(decl, p, localImportMap, log) {
continue
}
spec, found := s.getStructTypeDecl(decl, p.Fset)
//log.Info("Checking file","filename", p.Fset.Position(decl.Pos()).Filename,"found",found)
if found {
if isController || isTest {
controllerSpec := s.getControllerSpec(spec, p)
controllerSpec := s.getControllerSpec(spec, p, localImportMap)
sourceInfo.StructSpecs = append(sourceInfo.StructSpecs, controllerSpec)
}
} else {
@@ -56,7 +64,7 @@ func (s *SourceInfoProcessor) processPackage(p *packages.Package) (sourceInfo *m
// return one result
if m, receiver := s.getControllerFunc(funcDecl, p); m != nil {
methodMap[receiver] = append(methodMap[receiver], m)
s.sourceProcessor.log.Info("Added method map to ", "receiver", receiver, "method", m.Name)
log.Info("Added method map to ", "receiver", receiver, "method", m.Name)
}
}
// Check for validation
@@ -271,7 +279,7 @@ func (s *SourceInfoProcessor) getControllerFunc(funcDecl *ast.FuncDecl, p *packa
}
return
}
func (s *SourceInfoProcessor) getControllerSpec(spec *ast.TypeSpec, p *packages.Package) (controllerSpec *model.TypeInfo) {
func (s *SourceInfoProcessor) getControllerSpec(spec *ast.TypeSpec, p *packages.Package, localImportMap map[string]string) (controllerSpec *model.TypeInfo) {
structType := spec.Type.(*ast.StructType)
// At this point we know it's a type declaration for a struct.
@@ -282,6 +290,7 @@ func (s *SourceInfoProcessor) getControllerSpec(spec *ast.TypeSpec, p *packages.
ImportPath: p.PkgPath,
PackageName: p.Name,
}
log := s.sourceProcessor.log.New("file", p.Fset.Position(spec.Pos()).Filename, "position", p.Fset.Position(spec.Pos()).Line)
for _, field := range structType.Fields.List {
// If field.Names is set, it's not an embedded type.
if field.Names != nil {
@@ -329,9 +338,12 @@ func (s *SourceInfoProcessor) getControllerSpec(spec *ast.TypeSpec, p *packages.
importPath = p.PkgPath
} else {
var ok bool
if importPath, ok = s.sourceProcessor.importMap[pkgName]; !ok {
s.sourceProcessor.log.Error("Error: Failed to find import path for ", "package", pkgName, "type", typeName, "map", s.sourceProcessor.importMap)
continue
if importPath, ok = localImportMap[pkgName]; !ok {
log.Debug("Debug: Unusual, failed to find package locally ", "package", pkgName, "type", typeName, "map", s.sourceProcessor.importMap, "usedin", )
if importPath, ok = s.sourceProcessor.importMap[pkgName]; !ok {
log.Error("Error: Failed to find import path for ", "package", pkgName, "type", typeName, "map", s.sourceProcessor.importMap, "usedin", )
continue
}
}
}
@@ -376,4 +388,37 @@ func (s *SourceInfoProcessor) getFuncName(funcDecl *ast.FuncDecl) string {
prefix += "."
}
return prefix + funcDecl.Name.Name
}
func (s *SourceInfoProcessor) addImport(decl ast.Decl, p *packages.Package, localImportMap map[string]string, log logger.MultiLogger) (shouldContinue bool) {
shouldContinue = true
genDecl, ok := decl.(*ast.GenDecl)
if !ok {
return
}
if genDecl.Tok == token.IMPORT {
shouldContinue = false
for _, spec := range genDecl.Specs {
importSpec := spec.(*ast.ImportSpec)
//fmt.Printf("*** import specification %#v\n", importSpec)
var pkgAlias string
if importSpec.Name != nil {
pkgAlias = importSpec.Name.Name
if pkgAlias == "_" {
continue
}
}
quotedPath := importSpec.Path.Value // e.g. "\"sample/app/models\""
fullPath := quotedPath[1 : len(quotedPath) - 1] // Remove the quotes
if pkgAlias == "" {
pkgAlias = fullPath
if index := strings.LastIndex(pkgAlias, "/"); index > 0 {
pkgAlias = pkgAlias[index + 1:]
}
}
localImportMap[pkgAlias] = fullPath
}
}
return
}

View File

@@ -1,15 +1,18 @@
package parser2
import (
"go/ast"
"go/token"
"github.com/revel/cmd/model"
"golang.org/x/tools/go/packages"
"github.com/revel/cmd/utils"
"errors"
"go/parser"
"strings"
"github.com/revel/cmd/logger"
"os"
"path/filepath"
"go/ast"
"go/token"
"go/scanner"
)
type (
@@ -33,10 +36,6 @@ func ProcessSource(revelContainer *model.RevelContainer) (sourceInfo *model.Sour
processor.log.Infof("From parsers : Structures:%d InitImports:%d ValidationKeys:%d %v", len(sourceInfo.StructSpecs), len(sourceInfo.InitImportPaths), len(sourceInfo.ValidationKeys), sourceInfo.PackageMap)
}
if false {
compileError = errors.New("Incompleted")
utils.Logger.Panic("Not implemented")
}
return
}
@@ -45,16 +44,20 @@ func NewSourceProcessor(revelContainer *model.RevelContainer) *SourceProcessor {
s.sourceInfoProcessor = NewSourceInfoProcessor(s)
return s
}
func (s *SourceProcessor) parse() (compileError error) {
print("Parsing packages, (may require download if not cached)...")
if compileError = s.addPackages(); compileError != nil {
return
}
println(" Completed")
if compileError = s.addImportMap(); compileError != nil {
return
}
if compileError = s.addSourceInfo(); compileError != nil {
return
}
s.sourceInfo.PackageMap = map[string]string{}
getImportFromMap := func(packagePath string) string {
for path := range s.packageMap {
@@ -73,11 +76,15 @@ func (s *SourceProcessor) parse() (compileError error) {
return
}
// Using the packages.Load function load all the packages and type specifications (forces compile).
// this sets the SourceProcessor.packageList []*packages.Package
func (s *SourceProcessor) addPackages() (err error) {
allPackages := []string{s.revelContainer.ImportPath + "/...", model.RevelImportPath}
allPackages := []string{model.RevelImportPath + "/..."}
for _, module := range s.revelContainer.ModulePathMap {
allPackages = append(allPackages, module.ImportPath + "/...") // +"/app/controllers/...")
}
s.log.Info("Reading packages", "packageList", allPackages)
//allPackages = []string{s.revelContainer.ImportPath + "/..."} //+"/app/controllers/..."}
config := &packages.Config{
@@ -102,9 +109,115 @@ func (s *SourceProcessor) addPackages() (err error) {
Dir:s.revelContainer.AppPath,
}
s.packageList, err = packages.Load(config, allPackages...)
s.log.Info("Loaded packages ", "len results", len(s.packageList), "error", err)
s.log.Info("Loaded modules ", "len results", len(s.packageList), "error", err)
// Now process the files in the aap source folder s.revelContainer.ImportPath + "/...",
err = utils.Walk(s.revelContainer.AppPath, s.processPath)
s.log.Info("Loaded apps and modules ", "len results", len(s.packageList), "error", err)
return
}
// This callback is used to build the packages for the "app" package. This allows us to
// parse the source files without doing a full compile on them
// This callback only processes folders, so any files passed to this will return a nil
func (s *SourceProcessor) processPath(path string, info os.FileInfo, err error) error {
if err != nil {
s.log.Error("Error scanning app source:", "error", err)
return nil
}
// Ignore files and folders not marked tmp (since those are generated)
if !info.IsDir() || info.Name() == "tmp" {
return nil
}
// Real work for processing the folder
pkgImportPath := s.revelContainer.ImportPath
appPath := s.revelContainer.BasePath
if appPath != path {
pkgImportPath = s.revelContainer.ImportPath + "/" + filepath.ToSlash(path[len(appPath)+1:])
}
// Parse files within the path.
var pkgMap map[string]*ast.Package
fset := token.NewFileSet()
pkgMap, err = parser.ParseDir(
fset,
path,
func(f os.FileInfo) bool {
return !f.IsDir() && !strings.HasPrefix(f.Name(), ".") && strings.HasSuffix(f.Name(), ".go")
},
0)
if err != nil {
if errList, ok := err.(scanner.ErrorList); ok {
var pos = errList[0].Pos
newError := &utils.SourceError{
SourceType: ".go source",
Title: "Go Compilation Error",
Path: pos.Filename,
Description: errList[0].Msg,
Line: pos.Line,
Column: pos.Column,
SourceLines: utils.MustReadLines(pos.Filename),
}
errorLink := s.revelContainer.Config.StringDefault("error.link", "")
if errorLink != "" {
newError.SetLink(errorLink)
}
return newError
}
// This is exception, err already checked above. Here just a print
ast.Print(nil, err)
s.log.Fatal("Failed to parse dir", "error", err)
}
// Skip "main" packages.
delete(pkgMap, "main")
// Ignore packages that end with _test
// These cannot be included in source code that is not generated specifically as a test
for i := range pkgMap {
if len(i) > 6 {
if string(i[len(i)-5:]) == "_test" {
delete(pkgMap, i)
}
}
}
// If there is no code in this directory, skip it.
if len(pkgMap) == 0 {
return nil
}
// There should be only one package in this directory.
if len(pkgMap) > 1 {
for i := range pkgMap {
println("Found package ", i)
}
utils.Logger.Fatal("Most unexpected! Multiple packages in a single directory:", "packages", pkgMap)
}
// At this point there is only one package in the pkgs map,
p := &packages.Package{}
p.PkgPath = pkgImportPath
p.Fset = fset
for _, pkg := range pkgMap {
p.Name = pkg.Name
s.log.Info("Found package","pkg.Name", pkg.Name,"p.Name", p.PkgPath)
for filename,astFile := range pkg.Files {
p.Syntax = append(p.Syntax,astFile)
p.GoFiles = append(p.GoFiles,filename)
}
}
s.packageList = append(s.packageList, p)
return nil
}
// This function is used to populate a map so that we can lookup controller embedded types in order to determine
// if a Struct inherits from from revel.Controller
func (s *SourceProcessor) addImportMap() (err error) {
s.importMap = map[string]string{}
s.packageMap = map[string]string{}
@@ -113,41 +226,11 @@ func (s *SourceProcessor) addImportMap() (err error) {
if len(p.Errors) > 0 {
// Generate a compile error
for _, e := range p.Errors {
if !strings.Contains(e.Msg, "fsnotify") {
err = utils.NewCompileError("", "", e)
}
s.log.Info("While reading packages encountered import error ignoring ", "PkgPath", p.PkgPath, "error", e)
}
}
for _, tree := range p.Syntax {
for _, decl := range tree.Decls {
genDecl, ok := decl.(*ast.GenDecl)
if !ok {
continue
}
if genDecl.Tok == token.IMPORT {
for _, spec := range genDecl.Specs {
importSpec := spec.(*ast.ImportSpec)
//fmt.Printf("*** import specification %#v\n", importSpec)
var pkgAlias string
if importSpec.Name != nil {
pkgAlias = importSpec.Name.Name
if pkgAlias == "_" {
continue
}
}
quotedPath := importSpec.Path.Value // e.g. "\"sample/app/models\""
fullPath := quotedPath[1 : len(quotedPath) - 1] // Remove the quotes
if pkgAlias == "" {
pkgAlias = fullPath
if index := strings.LastIndex(pkgAlias, "/"); index > 0 {
pkgAlias = pkgAlias[index + 1:]
}
}
s.importMap[pkgAlias] = fullPath
}
}
}
s.importMap[tree.Name.Name] = p.PkgPath
}
}
return
@@ -165,53 +248,3 @@ func (s *SourceProcessor) addSourceInfo() (err error) {
}
return
}
// Add imports to the map from the source dir
//func addImports(imports map[string]string, decl ast.Decl, srcDir string) {
// genDecl, ok := decl.(*ast.GenDecl)
// if !ok {
// return
// }
//
// if genDecl.Tok != token.IMPORT {
// return
// }
//
// for _, spec := range genDecl.Specs {
// importSpec := spec.(*ast.ImportSpec)
// var pkgAlias string
// if importSpec.Name != nil {
// pkgAlias = importSpec.Name.Name
// if pkgAlias == "_" {
// continue
// }
// }
// quotedPath := importSpec.Path.Value // e.g. "\"sample/app/models\""
// fullPath := quotedPath[1 : len(quotedPath)-1] // Remove the quotes
//
// // If the package was not aliased (common case), we have to import it
// // to see what the package name is.
// // TODO: Can improve performance here a lot:
// // 1. Do not import everything over and over again. Keep a cache.
// // 2. Exempt the standard library; their directories always match the package name.
// // 3. Can use build.FindOnly and then use parser.ParseDir with mode PackageClauseOnly
// if pkgAlias == "" {
//
// utils.Logger.Debug("Reading from build", "path", fullPath, "srcPath", srcDir, "gopath", build.Default.GOPATH)
// pkg, err := build.Import(fullPath, srcDir, 0)
// if err != nil {
// // We expect this to happen for apps using reverse routing (since we
// // have not yet generated the routes). Don't log that.
// if !strings.HasSuffix(fullPath, "/app/routes") {
// utils.Logger.Warn("Could not find import:", "path", fullPath, "srcPath", srcDir, "error", err)
// }
// continue
// } else {
// utils.Logger.Debug("Found package in dir", "dir", pkg.Dir, "name", pkg.ImportPath)
// }
// pkgAlias = pkg.Name
// }
//
// imports[pkgAlias] = fullPath
// }
//}

View File

@@ -72,7 +72,7 @@ func newApp(c *model.CommandConfig) (err error) {
// Check for an existing folder so we don't clobber it
_, err = build.Import(c.ImportPath, "", build.FindOnly)
if err == nil || !utils.Empty(c.AppPath) {
return utils.NewBuildError("Abort: Import path already exists.", "path", c.ImportPath)
return utils.NewBuildError("Abort: Import path already exists.", "path", c.ImportPath, "apppath", c.AppPath)
}
// checking and setting skeleton
@@ -112,6 +112,10 @@ func newApp(c *model.CommandConfig) (err error) {
fmt.Fprintln(os.Stdout, "Your application has been created in:\n ", c.AppPath)
// Check to see if it should be run right off
if c.New.Run {
// Need to prep the run command
c.Run.ImportPath = c.ImportPath
updateRunConfig(c,nil)
c.UpdateImportPath()
runApp(c)
} else {
fmt.Fprintln(os.Stdout, "\nYou can run it with:\n revel run -a ", c.ImportPath)
@@ -203,13 +207,13 @@ func setApplicationPath(c *model.CommandConfig) (err error) {
// revel/revel#1014 validate relative path, we cannot use built-in functions
// since Go import path is valid relative path too.
// so check basic part of the path, which is "."
if filepath.IsAbs(c.ImportPath) || strings.HasPrefix(c.ImportPath, ".") {
utils.Logger.Fatalf("Abort: '%s' looks like a directory. Please provide a Go import path instead.",
c.ImportPath)
}
// If we are running a vendored version of Revel we do not need to check for it.
if !c.Vendored {
if filepath.IsAbs(c.ImportPath) || strings.HasPrefix(c.ImportPath, ".") {
utils.Logger.Fatalf("Abort: '%s' looks like a directory. Please provide a Go import path instead.",
c.ImportPath)
}
_, err = build.Import(model.RevelImportPath, "", build.FindOnly)
if err != nil {
//// Go get the revel project

View File

@@ -11,9 +11,7 @@ import (
"github.com/revel/cmd/harness"
"github.com/revel/cmd/model"
"github.com/revel/cmd/utils"
"go/build"
"os"
"path/filepath"
)
var cmdRun = &Command{
@@ -116,10 +114,7 @@ func updateRunConfig(c *model.CommandConfig, args []string) bool {
// Returns true if this is an absolute path or a relative gopath
func runIsImportPath(pathToCheck string) bool {
if _, err := build.Import(pathToCheck, "", build.FindOnly); err == nil {
return true
}
return filepath.IsAbs(pathToCheck)
return utils.DirExists(pathToCheck)
}
// Called to run the app

View File

@@ -34,8 +34,8 @@ func TestVersion(t *testing.T) {
a.Nil(main.Commands[model.VERSION].RunWith(c), "Failed to run version-test")
})
if !t.Failed() {
if err := os.RemoveAll(gopath); err != nil {
a.Fail("Failed to remove test path")
if err := os.RemoveAll(gopath); err != nil && err!=os.ErrNotExist {
a.Fail("Failed to remove test path",err.Error())
}
}
}

View File

@@ -203,7 +203,8 @@ func Walk(root string, walkFn filepath.WalkFunc) error {
return fsWalk(root, root, walkFn)
}
// Walk the tree using the function
// Walk the path tree using the function
// Every file found will call the function
func fsWalk(fname string, linkName string, walkFn filepath.WalkFunc) error {
fsWalkFunc := func(path string, info os.FileInfo, err error) error {
if err != nil {
@@ -308,9 +309,13 @@ func Exists(filename string) bool {
// empty returns true if the given directory is empty.
// the directory must exist.
func Empty(dirname string) bool {
if !DirExists(dirname) {
return true
}
dir, err := os.Open(dirname)
if err != nil {
Logger.Infof("error opening directory: %s", err)
return false
}
defer func() {
_ = dir.Close()
@@ -322,8 +327,8 @@ func Empty(dirname string) bool {
// Find the full source dir for the import path, uses the build.Default.GOPATH to search for the directory
func FindSrcPaths(appPath string, packageList []string, packageResolver func(pkgName string) error) (sourcePathsmap map[string]string, err error) {
sourcePathsmap, missingList, err := findSrcPaths(appPath, packageList)
if err != nil && packageResolver != nil || len(missingList)>0 {
Logger.Info("Failed to find package, attempting to call resolver for missing packages","missing packages",missingList)
if err != nil && packageResolver != nil || len(missingList) > 0 {
Logger.Info("Failed to find package, attempting to call resolver for missing packages", "missing packages", missingList)
for _, item := range missingList {
if err = packageResolver(item); err != nil {
return
@@ -352,25 +357,25 @@ func findSrcPaths(appPath string, packagesList []string) (sourcePathsmap map[str
Dir:appPath,
}
sourcePathsmap = map[string]string{}
Logger.Infof("Environment path %s root %s config env %s", os.Getenv("GOPATH"), os.Getenv("GOROOT"),config.Env)
Logger.Infof("Environment path %s root %s config env %s", os.Getenv("GOPATH"), os.Getenv("GOROOT"), config.Env)
pkgs, err := packages.Load(config, packagesList...)
Logger.Infof("Environment path %s root %s config env %s", os.Getenv("GOPATH"), os.Getenv("GOROOT"),config.Env)
Logger.Infof("Environment path %s root %s config env %s", os.Getenv("GOPATH"), os.Getenv("GOROOT"), config.Env)
Logger.Info("Loaded packages ", "len results", len(pkgs), "error", err, "basedir", appPath)
for _, packageName := range packagesList {
found := false
found := false
log := Logger.New("seeking", packageName)
for _, pck := range pkgs {
log.Info("Found package", "package", pck.ID)
if pck.ID == packageName {
if pck.Errors != nil && len(pck.Errors) > 0 {
log.Info("Error ", "count", len(pck.Errors), "App Import Path", pck.ID, "errors", pck.Errors)
continue
log.Error("Error ", "count", len(pck.Errors), "App Import Path", pck.ID, "filesystem path", pck.PkgPath, "errors", pck.Errors)
// continue
}
//a,_ := pck.MarshalJSON()
log.Info("Found ", "count", len(pck.GoFiles), "App Import Path", pck.ID, "apppath", appPath)
if len(pck.GoFiles)>0 {
if len(pck.GoFiles) > 0 {
sourcePathsmap[packageName] = filepath.Dir(pck.GoFiles[0])
found = true
}

View File

@@ -33,7 +33,7 @@ type DiscerningListener interface {
// Watcher allows listeners to register to be notified of changes under a given
// directory.
type Watcher struct {
// Parallel arrays of watcher/listener pairs.
// Parallel arrays of watcher/listener pairs.
watchers []*fsnotify.Watcher
listeners []Listener
forceRefresh bool
@@ -42,8 +42,8 @@ type Watcher struct {
lastError int
notifyMutex sync.Mutex
paths *model.RevelContainer
refreshTimer *time.Timer // The timer to countdown the next refresh
timerMutex *sync.Mutex // A mutex to prevent concurrent updates
refreshTimer *time.Timer // The timer to countdown the next refresh
timerMutex *sync.Mutex // A mutex to prevent concurrent updates
refreshChannel chan *utils.SourceError
refreshChannelCount int
refreshTimerMS time.Duration // The number of milliseconds between refreshing builds
@@ -52,10 +52,10 @@ type Watcher struct {
// Creates a new watched based on the container
func NewWatcher(paths *model.RevelContainer, eagerRefresh bool) *Watcher {
return &Watcher{
forceRefresh: true,
forceRefresh: false,
lastError: -1,
paths: paths,
refreshTimerMS: time.Duration(paths.Config.IntDefault("watch.rebuild.delay", 10)),
refreshTimerMS: time.Duration(paths.Config.IntDefault("watch.rebuild.delay", 1000)),
eagerRefresh: eagerRefresh ||
paths.DevMode &&
paths.Config.BoolDefault("watch", true) &&
@@ -85,7 +85,7 @@ func (w *Watcher) Listen(listener Listener, roots ...string) {
for _, p := range roots {
// is the directory / file a symlink?
f, err := os.Lstat(p)
if err == nil && f.Mode()&os.ModeSymlink == os.ModeSymlink {
if err == nil && f.Mode() & os.ModeSymlink == os.ModeSymlink {
var realPath string
realPath, err = filepath.EvalSymlinks(p)
if err != nil {
@@ -200,12 +200,13 @@ func (w *Watcher) Notify() *utils.SourceError {
case <-watcher.Errors:
continue
default:
// No events left to pull
// No events left to pull
}
break
}
utils.Logger.Info("Watcher:Notify refresh state", "Current Index", i, " last error index", w.lastError)
utils.Logger.Info("Watcher:Notify refresh state", "Current Index", i, " last error index", w.lastError,
"force", w.forceRefresh, "refresh", refresh, "lastError", w.lastError == i)
if w.forceRefresh || refresh || w.lastError == i {
var err *utils.SourceError
if w.serial {
@@ -285,22 +286,10 @@ func (w *Watcher) rebuildRequired(ev fsnotify.Event, listener Listener) bool {
}
if dl, ok := listener.(DiscerningListener); ok {
if !dl.WatchFile(ev.Name) || ev.Op&fsnotify.Chmod == fsnotify.Chmod {
if !dl.WatchFile(ev.Name) || ev.Op & fsnotify.Chmod == fsnotify.Chmod {
return false
}
}
return true
}
/*
var WatchFilter = func(c *Controller, fc []Filter) {
if MainWatcher != nil {
err := MainWatcher.Notify()
if err != nil {
c.Result = c.RenderError(err)
return
}
}
fc[0](c, fc[1:])
}
*/