mirror of
https://github.com/kevin-DL/revel-cmd.git
synced 2026-01-23 15:31:26 +00:00
Updated Revel command
Added a check to see if harness had already started, saves a recompile on load Added check to source info for local import renames Removed the go/build check for path and just check existence of the path Formatting updates
This commit is contained in:
@@ -106,7 +106,7 @@ func (cmd AppCmd) Kill() {
|
|||||||
if cmd.Cmd != nil && (cmd.ProcessState == nil || !cmd.ProcessState.Exited()) {
|
if cmd.Cmd != nil && (cmd.ProcessState == nil || !cmd.ProcessState.Exited()) {
|
||||||
// Windows appears to send the kill to all threads, shutting down the
|
// 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
|
// 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
|
// Server has already exited
|
||||||
utils.Logger.Info("Server not running revel server pid", "pid", cmd.Process.Pid)
|
utils.Logger.Info("Server not running revel server pid", "pid", cmd.Process.Pid)
|
||||||
return
|
return
|
||||||
@@ -143,9 +143,9 @@ func (cmd AppCmd) Kill() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Logger.Error(
|
utils.Logger.Info(
|
||||||
"Revel app failed to kill process.",
|
"Revel app already exited.",
|
||||||
"processid", cmd.Process.Pid,"error",err,
|
"processid", cmd.Process.Pid, "error", err,
|
||||||
"killerror", cmd.Process.Kill())
|
"killerror", cmd.Process.Kill())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ package harness
|
|||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"time"
|
||||||
"go/build"
|
"go/build"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
@@ -56,6 +57,8 @@ type Harness struct {
|
|||||||
paths *model.RevelContainer // The Revel container
|
paths *model.RevelContainer // The Revel container
|
||||||
config *model.CommandConfig // The configuration
|
config *model.CommandConfig // The configuration
|
||||||
runMode string // The runmode the harness is running in
|
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) {
|
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.
|
// Refresh method rebuilds the Revel application and run it on the given port.
|
||||||
// called by the watcher
|
// called by the watcher
|
||||||
func (h *Harness) Refresh() (err *utils.SourceError) {
|
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
|
// Allow only one thread to rebuild the process
|
||||||
// If multiple requests to rebuild are queued only the last one is executed on
|
// 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
|
// 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...)
|
paths = append(paths, h.paths.CodePaths...)
|
||||||
h.watcher = watcher.NewWatcher(h.paths, false)
|
h.watcher = watcher.NewWatcher(h.paths, false)
|
||||||
h.watcher.Listen(h, paths...)
|
h.watcher.Listen(h, paths...)
|
||||||
h.watcher.Notify()
|
go h.Refresh()
|
||||||
|
// h.watcher.Notify()
|
||||||
|
|
||||||
if h.useProxy {
|
if h.useProxy {
|
||||||
go func() {
|
go func() {
|
||||||
@@ -292,6 +311,7 @@ func (h *Harness) Run() {
|
|||||||
addr := fmt.Sprintf("%s:%d", h.paths.HTTPAddr, h.paths.HTTPPort)
|
addr := fmt.Sprintf("%s:%d", h.paths.HTTPAddr, h.paths.HTTPPort)
|
||||||
utils.Logger.Infof("Proxy server is listening on %s", addr)
|
utils.Logger.Infof("Proxy server is listening on %s", addr)
|
||||||
|
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
if h.paths.HTTPSsl {
|
if h.paths.HTTPSsl {
|
||||||
err = http.ListenAndServeTLS(
|
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)
|
ch := make(chan os.Signal)
|
||||||
signal.Notify(ch, os.Interrupt, os.Kill)
|
signal.Notify(ch, os.Interrupt, os.Kill)
|
||||||
<-ch
|
// Kill the app and exit
|
||||||
if h.app != nil {
|
if h.app != nil {
|
||||||
h.app.Kill()
|
h.app.Kill()
|
||||||
}
|
}
|
||||||
|
<-ch
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"go/token"
|
"go/token"
|
||||||
"strings"
|
"strings"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"github.com/revel/cmd/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
@@ -31,14 +32,20 @@ func (s *SourceInfoProcessor) processPackage(p *packages.Package) (sourceInfo *m
|
|||||||
strings.Contains(p.PkgPath, "/tests/")
|
strings.Contains(p.PkgPath, "/tests/")
|
||||||
methodMap = map[string][]*model.MethodSpec{}
|
methodMap = map[string][]*model.MethodSpec{}
|
||||||
)
|
)
|
||||||
|
localImportMap := map[string]string{}
|
||||||
|
log := s.sourceProcessor.log.New("package", p.PkgPath)
|
||||||
for _, tree := range p.Syntax {
|
for _, tree := range p.Syntax {
|
||||||
for _, decl := range tree.Decls {
|
for _, decl := range tree.Decls {
|
||||||
|
|
||||||
s.sourceProcessor.packageMap[p.PkgPath] = filepath.Dir(p.Fset.Position(decl.Pos()).Filename)
|
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
|
||||||
|
}
|
||||||
|
// log.Info("*** checking", p.Fset.Position(decl.Pos()).Filename)
|
||||||
spec, found := s.getStructTypeDecl(decl, p.Fset)
|
spec, found := s.getStructTypeDecl(decl, p.Fset)
|
||||||
if found {
|
if found {
|
||||||
if isController || isTest {
|
if isController || isTest {
|
||||||
controllerSpec := s.getControllerSpec(spec, p)
|
controllerSpec := s.getControllerSpec(spec, p, localImportMap)
|
||||||
sourceInfo.StructSpecs = append(sourceInfo.StructSpecs, controllerSpec)
|
sourceInfo.StructSpecs = append(sourceInfo.StructSpecs, controllerSpec)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -56,7 +63,7 @@ func (s *SourceInfoProcessor) processPackage(p *packages.Package) (sourceInfo *m
|
|||||||
// return one result
|
// return one result
|
||||||
if m, receiver := s.getControllerFunc(funcDecl, p); m != nil {
|
if m, receiver := s.getControllerFunc(funcDecl, p); m != nil {
|
||||||
methodMap[receiver] = append(methodMap[receiver], m)
|
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
|
// Check for validation
|
||||||
@@ -271,7 +278,7 @@ func (s *SourceInfoProcessor) getControllerFunc(funcDecl *ast.FuncDecl, p *packa
|
|||||||
}
|
}
|
||||||
return
|
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)
|
structType := spec.Type.(*ast.StructType)
|
||||||
|
|
||||||
// At this point we know it's a type declaration for a struct.
|
// At this point we know it's a type declaration for a struct.
|
||||||
@@ -282,7 +289,7 @@ func (s *SourceInfoProcessor) getControllerSpec(spec *ast.TypeSpec, p *packages.
|
|||||||
ImportPath: p.PkgPath,
|
ImportPath: p.PkgPath,
|
||||||
PackageName: p.Name,
|
PackageName: p.Name,
|
||||||
}
|
}
|
||||||
log := s.sourceProcessor.log.New("file", p.Fset.Position(spec.Pos()).Filename,"position", p.Fset.Position(spec.Pos()).Line)
|
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 {
|
for _, field := range structType.Fields.List {
|
||||||
// If field.Names is set, it's not an embedded type.
|
// If field.Names is set, it's not an embedded type.
|
||||||
if field.Names != nil {
|
if field.Names != nil {
|
||||||
@@ -330,11 +337,14 @@ func (s *SourceInfoProcessor) getControllerSpec(spec *ast.TypeSpec, p *packages.
|
|||||||
importPath = p.PkgPath
|
importPath = p.PkgPath
|
||||||
} else {
|
} else {
|
||||||
var ok bool
|
var ok bool
|
||||||
|
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 {
|
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", )
|
log.Error("Error: Failed to find import path for ", "package", pkgName, "type", typeName, "map", s.sourceProcessor.importMap, "usedin", )
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
controllerSpec.EmbeddedTypes = append(controllerSpec.EmbeddedTypes, &model.EmbeddedTypeName{
|
controllerSpec.EmbeddedTypes = append(controllerSpec.EmbeddedTypes, &model.EmbeddedTypeName{
|
||||||
ImportPath: importPath,
|
ImportPath: importPath,
|
||||||
@@ -378,3 +388,36 @@ func (s *SourceInfoProcessor) getFuncName(funcDecl *ast.FuncDecl) string {
|
|||||||
}
|
}
|
||||||
return prefix + funcDecl.Name.Name
|
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
|
||||||
|
}
|
||||||
@@ -43,6 +43,7 @@ func NewSourceProcessor(revelContainer *model.RevelContainer) *SourceProcessor {
|
|||||||
s.sourceInfoProcessor = NewSourceInfoProcessor(s)
|
s.sourceInfoProcessor = NewSourceInfoProcessor(s)
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SourceProcessor) parse() (compileError error) {
|
func (s *SourceProcessor) parse() (compileError error) {
|
||||||
if compileError = s.addPackages(); compileError != nil {
|
if compileError = s.addPackages(); compileError != nil {
|
||||||
return
|
return
|
||||||
@@ -71,11 +72,15 @@ func (s *SourceProcessor) parse() (compileError error) {
|
|||||||
|
|
||||||
return
|
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) {
|
func (s *SourceProcessor) addPackages() (err error) {
|
||||||
allPackages := []string{s.revelContainer.ImportPath + "/...", model.RevelImportPath + "/..."}
|
allPackages := []string{s.revelContainer.ImportPath + "/...", model.RevelImportPath + "/..."}
|
||||||
for _, module := range s.revelContainer.ModulePathMap {
|
for _, module := range s.revelContainer.ModulePathMap {
|
||||||
allPackages = append(allPackages, module.ImportPath + "/...") // +"/app/controllers/...")
|
allPackages = append(allPackages, module.ImportPath + "/...") // +"/app/controllers/...")
|
||||||
}
|
}
|
||||||
|
s.log.Info("Reading packages", "packageList", allPackages)
|
||||||
//allPackages = []string{s.revelContainer.ImportPath + "/..."} //+"/app/controllers/..."}
|
//allPackages = []string{s.revelContainer.ImportPath + "/..."} //+"/app/controllers/..."}
|
||||||
|
|
||||||
config := &packages.Config{
|
config := &packages.Config{
|
||||||
|
|||||||
@@ -11,9 +11,7 @@ import (
|
|||||||
"github.com/revel/cmd/harness"
|
"github.com/revel/cmd/harness"
|
||||||
"github.com/revel/cmd/model"
|
"github.com/revel/cmd/model"
|
||||||
"github.com/revel/cmd/utils"
|
"github.com/revel/cmd/utils"
|
||||||
"go/build"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var cmdRun = &Command{
|
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
|
// Returns true if this is an absolute path or a relative gopath
|
||||||
func runIsImportPath(pathToCheck string) bool {
|
func runIsImportPath(pathToCheck string) bool {
|
||||||
if _, err := build.Import(pathToCheck, "", build.FindOnly); err == nil {
|
return utils.DirExists(pathToCheck)
|
||||||
return true
|
|
||||||
}
|
|
||||||
return filepath.IsAbs(pathToCheck)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called to run the app
|
// Called to run the app
|
||||||
|
|||||||
@@ -322,8 +322,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
|
// 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) {
|
func FindSrcPaths(appPath string, packageList []string, packageResolver func(pkgName string) error) (sourcePathsmap map[string]string, err error) {
|
||||||
sourcePathsmap, missingList, err := findSrcPaths(appPath, packageList)
|
sourcePathsmap, missingList, err := findSrcPaths(appPath, packageList)
|
||||||
if err != nil && packageResolver != nil || len(missingList)>0 {
|
if err != nil && packageResolver != nil || len(missingList) > 0 {
|
||||||
Logger.Info("Failed to find package, attempting to call resolver for missing packages","missing packages",missingList)
|
Logger.Info("Failed to find package, attempting to call resolver for missing packages", "missing packages", missingList)
|
||||||
for _, item := range missingList {
|
for _, item := range missingList {
|
||||||
if err = packageResolver(item); err != nil {
|
if err = packageResolver(item); err != nil {
|
||||||
return
|
return
|
||||||
@@ -352,10 +352,10 @@ func findSrcPaths(appPath string, packagesList []string) (sourcePathsmap map[str
|
|||||||
Dir:appPath,
|
Dir:appPath,
|
||||||
}
|
}
|
||||||
sourcePathsmap = map[string]string{}
|
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...)
|
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)
|
Logger.Info("Loaded packages ", "len results", len(pkgs), "error", err, "basedir", appPath)
|
||||||
for _, packageName := range packagesList {
|
for _, packageName := range packagesList {
|
||||||
found := false
|
found := false
|
||||||
@@ -364,13 +364,13 @@ func findSrcPaths(appPath string, packagesList []string) (sourcePathsmap map[str
|
|||||||
log.Info("Found package", "package", pck.ID)
|
log.Info("Found package", "package", pck.ID)
|
||||||
if pck.ID == packageName {
|
if pck.ID == packageName {
|
||||||
if pck.Errors != nil && len(pck.Errors) > 0 {
|
if pck.Errors != nil && len(pck.Errors) > 0 {
|
||||||
log.Info("Error ", "count", len(pck.Errors), "App Import Path", pck.ID, "errors", pck.Errors)
|
log.Error("Error ", "count", len(pck.Errors), "App Import Path", pck.ID, "filesystem path", pck.PkgPath, "errors", pck.Errors)
|
||||||
continue
|
// continue
|
||||||
|
|
||||||
}
|
}
|
||||||
//a,_ := pck.MarshalJSON()
|
//a,_ := pck.MarshalJSON()
|
||||||
log.Info("Found ", "count", len(pck.GoFiles), "App Import Path", pck.ID, "apppath", appPath)
|
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])
|
sourcePathsmap[packageName] = filepath.Dir(pck.GoFiles[0])
|
||||||
found = true
|
found = true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,10 +52,10 @@ type Watcher struct {
|
|||||||
// Creates a new watched based on the container
|
// Creates a new watched based on the container
|
||||||
func NewWatcher(paths *model.RevelContainer, eagerRefresh bool) *Watcher {
|
func NewWatcher(paths *model.RevelContainer, eagerRefresh bool) *Watcher {
|
||||||
return &Watcher{
|
return &Watcher{
|
||||||
forceRefresh: true,
|
forceRefresh: false,
|
||||||
lastError: -1,
|
lastError: -1,
|
||||||
paths: paths,
|
paths: paths,
|
||||||
refreshTimerMS: time.Duration(paths.Config.IntDefault("watch.rebuild.delay", 10)),
|
refreshTimerMS: time.Duration(paths.Config.IntDefault("watch.rebuild.delay", 1000)),
|
||||||
eagerRefresh: eagerRefresh ||
|
eagerRefresh: eagerRefresh ||
|
||||||
paths.DevMode &&
|
paths.DevMode &&
|
||||||
paths.Config.BoolDefault("watch", true) &&
|
paths.Config.BoolDefault("watch", true) &&
|
||||||
@@ -85,7 +85,7 @@ func (w *Watcher) Listen(listener Listener, roots ...string) {
|
|||||||
for _, p := range roots {
|
for _, p := range roots {
|
||||||
// is the directory / file a symlink?
|
// is the directory / file a symlink?
|
||||||
f, err := os.Lstat(p)
|
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
|
var realPath string
|
||||||
realPath, err = filepath.EvalSymlinks(p)
|
realPath, err = filepath.EvalSymlinks(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -205,7 +205,8 @@ func (w *Watcher) Notify() *utils.SourceError {
|
|||||||
break
|
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 {
|
if w.forceRefresh || refresh || w.lastError == i {
|
||||||
var err *utils.SourceError
|
var err *utils.SourceError
|
||||||
if w.serial {
|
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, 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 false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true
|
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:])
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|||||||
Reference in New Issue
Block a user