Compare commits

..

11 Commits

Author SHA1 Message Date
NotZippy
18e6b92704 Spaces to tabs (gofmt) files 2017-05-03 15:56:37 -07:00
NotZippy
49041fb83d Changed build to print a warning if import-path build failed. 2017-05-02 14:31:15 -07:00
NotZippy
f86def601d Merge branch 'server-engine' of github.com:revel/cmd into server-engine 2017-05-02 14:30:04 -07:00
NotZippy
15875dc9a1 Added allowance for test packages to co-exist 2017-05-02 14:28:33 -07:00
NotZippy
16f98f92e0 Changed SetHeader to SetHttpHeader, HeaderHttpValue to GetHttpHeader 2017-04-26 21:13:46 -07:00
NotZippy
9de11613ce Revamped engine to reduce the interface size.
Added BufferedServerHeader to CompressWriter to prevent header from writing out immediately
Reduced object stack to a single controller stack which has the request and response objects already instaniated in it
Fixed go engine to match new spec
Modified code to make use of the Request object to access the ServerEngine (allows caching of ServerHeader and ResponseWriter)
Modified simple stack to add an upper bounds to the number of objects in cache, any more objects then the upper bounds will be left to garbage collect
2017-04-26 21:13:46 -07:00
notzippy
32d1f12b51 Merge pull request #89 from notzippy/server-engine
Changed SetHeader to SetHttpHeader, HeaderHttpValue to GetHttpHeader
2017-04-26 17:57:54 -07:00
NotZippy
d114a92b3d Changed SetHeader to SetHttpHeader, HeaderHttpValue to GetHttpHeader 2017-04-26 17:52:20 -07:00
notzippy
8bf654d8b0 Merge pull request #88 from notzippy/server-engine
Revamped engine to reduce the interface size.
2017-04-26 17:36:23 -07:00
NotZippy
79ed869901 Revamped engine to reduce the interface size.
Added BufferedServerHeader to CompressWriter to prevent header from writing out immediately
Reduced object stack to a single controller stack which has the request and response objects already instaniated in it
Fixed go engine to match new spec
Modified code to make use of the Request object to access the ServerEngine (allows caching of ServerHeader and ResponseWriter)
Modified simple stack to add an upper bounds to the number of objects in cache, any more objects then the upper bounds will be left to garbage collect
2017-04-26 17:32:51 -07:00
notzippy
3ba212afb4 Merge pull request #83 from notzippy/server-engine
Makes it so harness can bootstrap using the new GoRequest / response …
2017-04-06 09:44:20 -07:00
13 changed files with 188 additions and 241 deletions

View File

@@ -58,11 +58,11 @@ func NewAppCmd(binPath string, port int) AppCmd {
// Start the app server, and wait until it is ready to serve requests.
func (cmd AppCmd) Start() error {
listeningWriter := &startupListeningWriter{os.Stdout, make(chan bool)}
listeningWriter := startupListeningWriter{os.Stdout, make(chan bool)}
cmd.Stdout = listeningWriter
revel.RevelLog.Debug("Exec app:", "path", cmd.Path, "args", cmd.Args)
revel.TRACE.Println("Exec app:", cmd.Path, cmd.Args)
if err := cmd.Cmd.Start(); err != nil {
revel.RevelLog.Fatal("Error running:", "error", err)
revel.ERROR.Fatalln("Error running:", err)
}
select {
@@ -70,7 +70,6 @@ func (cmd AppCmd) Start() error {
return errors.New("revel/harness: app died")
case <-time.After(30 * time.Second):
revel.RevelLog.Debug("Killing revel server process did not respond after wait timeout", "processid", cmd.Process.Pid)
cmd.Kill()
return errors.New("revel/harness: app timed out")
@@ -84,19 +83,19 @@ func (cmd AppCmd) Start() error {
// Run the app server inline. Never returns.
func (cmd AppCmd) Run() {
revel.RevelLog.Debug("Exec app:", "path", cmd.Path, "args", cmd.Args)
revel.TRACE.Println("Exec app:", cmd.Path, cmd.Args)
if err := cmd.Cmd.Run(); err != nil {
revel.RevelLog.Fatal("Error running:", "error", err)
revel.ERROR.Fatalln("Error running:", err)
}
}
// Kill terminates the app server if it's running.
func (cmd AppCmd) Kill() {
if cmd.Cmd != nil && (cmd.ProcessState == nil || !cmd.ProcessState.Exited()) {
revel.RevelLog.Debug("Killing revel server pid", "pid", cmd.Process.Pid)
revel.TRACE.Println("Killing revel server pid", cmd.Process.Pid)
err := cmd.Process.Kill()
if err != nil {
revel.RevelLog.Fatal("Failed to kill revel server:", "error", err)
revel.ERROR.Fatalln("Failed to kill revel server:", err)
}
}
}
@@ -119,7 +118,7 @@ type startupListeningWriter struct {
notifyReady chan bool
}
func (w *startupListeningWriter) Write(p []byte) (n int, err error) {
func (w startupListeningWriter) Write(p []byte) (n int, err error) {
if w.notifyReady != nil && bytes.Contains(p, []byte("Listening")) {
w.notifyReady <- true
w.notifyReady = nil

View File

@@ -39,7 +39,7 @@ func Build(buildFlags ...string) (app *App, compileError *revel.Error) {
// Add the db.import to the import paths.
if dbImportPath, found := revel.Config.String("db.import"); found {
sourceInfo.InitImportPaths = append(sourceInfo.InitImportPaths, strings.Split(dbImportPath,",")...)
sourceInfo.InitImportPaths = append(sourceInfo.InitImportPaths, dbImportPath)
}
// Generate two source files.
@@ -59,46 +59,12 @@ func Build(buildFlags ...string) (app *App, compileError *revel.Error) {
// It relies on the user having "go" installed.
goPath, err := exec.LookPath("go")
if err != nil {
revel.RevelLog.Fatalf("Go executable not found in PATH.")
}
// Detect if deps tool should be used (is there a vendor folder ?)
useVendor := revel.DirExists(filepath.Join(revel.BasePath, "vendor"))
basePath := revel.BasePath
for !useVendor {
basePath = filepath.Dir(basePath)
found := false
// Check to see if we are still in the GOPATH
for _, path := range filepath.SplitList(build.Default.GOPATH) {
if strings.HasPrefix(basePath, path) {
found = true
break
}
}
if !found {
break
} else {
useVendor = revel.DirExists(filepath.Join(basePath, "vendor"))
}
}
var depPath string
if useVendor {
revel.RevelLog.Info("Vendor folder detected, scanning for deps in path")
depPath, err = exec.LookPath("dep")
if err != nil {
// Do not halt build unless a new package needs to be imported
revel.RevelLog.Warn("Build: `dep` executable not found in PATH, but vendor folder detected." +
"Packages can only be added automatically to the vendor folder using the `dep` tool. " +
"You can install the `dep` tool by doing a `go get -u github.com/golang/dep/cmd/dep`")
}
} else {
revel.RevelLog.Info("No vendor folder detected, not using dependency manager to import files")
revel.ERROR.Fatalf("Go executable not found in PATH.")
}
pkg, err := build.Default.Import(revel.ImportPath, "", build.FindOnly)
if err != nil {
revel.RevelLog.Fatal("Failure importing", "path", revel.ImportPath)
revel.ERROR.Fatalln("Failure importing", revel.ImportPath)
}
// Binary path is a combination of $GOBIN/revel.d directory, app's import path and its name.
@@ -121,6 +87,13 @@ func Build(buildFlags ...string) (app *App, compileError *revel.Error) {
versionLinkerFlags := fmt.Sprintf("-X %s/app.AppVersion=%s -X %s/app.BuildTime=%s",
revel.ImportPath, appVersion, revel.ImportPath, buildTime)
// TODO remove version check for versionLinkerFlags after Revel becomes Go min version to go1.5
goVersion, err := strconv.ParseFloat(runtime.Version()[2:5], 64)
// runtime.Version() may return commit hash, we assume it is above 1.5
if goVersion < 1.5 && err == nil {
versionLinkerFlags = fmt.Sprintf("-X %s/app.AppVersion \"%s\" -X %s/app.BuildTime \"%s\"",
revel.ImportPath, appVersion, revel.ImportPath, buildTime)
}
flags := []string{
"build",
"-i",
@@ -136,58 +109,42 @@ func Build(buildFlags ...string) (app *App, compileError *revel.Error) {
flags = append(flags, path.Join(revel.ImportPath, "app", "tmp"))
buildCmd := exec.Command(goPath, flags...)
revel.RevelLog.Debug("Exec:", "args", buildCmd.Args)
revel.TRACE.Println("Exec:", buildCmd.Args)
output, err := buildCmd.CombinedOutput()
// If the build succeeded, we're done.
if err == nil {
return NewApp(binName), nil
}
revel.RevelLog.Error(string(output))
revel.ERROR.Println(string(output))
// See if it was an import error that we can go get.
matches := importErrorPattern.FindAllStringSubmatch(string(output), -1)
matches := importErrorPattern.FindStringSubmatch(string(output))
if matches == nil {
return nil, newCompileError(output)
}
for _, match := range matches {
// Ensure we haven't already tried to go get it.
pkgName := match[1]
if _, alreadyTried := gotten[pkgName]; alreadyTried {
return nil, newCompileError(output)
}
gotten[pkgName] = struct{}{}
// Execute "go get <pkg>"
// Or dep `dep ensure -add <pkg>` if it is there
var getCmd *exec.Cmd
if useVendor {
if depPath == "" {
revel.RevelLog.Error("Build: Vendor folder found, but the `dep` tool was not found, " +
"if you use a different vendoring (package management) tool please add the following packages by hand, " +
"or install the `dep` tool into your gopath by doing a `go get -u github.com/golang/dep/cmd/dep`. " +
"For more information and usage of the tool please see http://github.com/golang/dep")
for _, pkg := range matches {
revel.RevelLog.Error("Missing package", "package", pkg[1])
}
}
getCmd = exec.Command(depPath, "ensure", "-add", pkgName)
} else {
getCmd = exec.Command(goPath, "get", pkgName)
}
revel.RevelLog.Debug("Exec:", "args", getCmd.Args)
getOutput, err := getCmd.CombinedOutput()
if err != nil {
revel.RevelLog.Error(string(getOutput))
return nil, newCompileError(output)
}
// Ensure we haven't already tried to go get it.
pkgName := matches[1]
if _, alreadyTried := gotten[pkgName]; alreadyTried {
return nil, newCompileError(output)
}
gotten[pkgName] = struct{}{}
// Execute "go get <pkg>"
getCmd := exec.Command(goPath, "get", pkgName)
revel.TRACE.Println("Exec:", getCmd.Args)
getOutput, err := getCmd.CombinedOutput()
if err != nil {
revel.ERROR.Println(string(getOutput))
return nil, newCompileError(output)
}
// Success getting the import, attempt to build again.
}
// TODO remove this unreachable code and document it
revel.RevelLog.Fatalf("Not reachable")
revel.ERROR.Fatalf("Not reachable")
return nil, nil
}
@@ -211,11 +168,11 @@ func getAppVersion() string {
return ""
}
gitCmd := exec.Command(gitPath, "--git-dir="+gitDir, "describe", "--always", "--dirty")
revel.RevelLog.Debug("Exec:", "args", gitCmd.Args)
revel.TRACE.Println("Exec:", gitCmd.Args)
output, err := gitCmd.Output()
if err != nil {
revel.RevelLog.Warn("Cannot determine git repository version:", "error", err)
revel.WARN.Println("Cannot determine git repository version:", err)
return ""
}
@@ -232,12 +189,12 @@ func cleanSource(dirs ...string) {
}
func cleanDir(dir string) {
revel.RevelLog.Info("Cleaning dir " + dir)
revel.INFO.Println("Cleaning dir " + dir)
tmpPath := filepath.Join(revel.AppPath, dir)
f, err := os.Open(tmpPath)
if err != nil {
if !os.IsNotExist(err) {
revel.RevelLog.Error("Failed to clean dir:", "error", err)
revel.ERROR.Println("Failed to clean dir:", err)
}
} else {
defer func() {
@@ -247,20 +204,20 @@ func cleanDir(dir string) {
infos, err := f.Readdir(0)
if err != nil {
if !os.IsNotExist(err) {
revel.RevelLog.Error("Failed to clean dir:", "error", err)
revel.ERROR.Println("Failed to clean dir:", err)
}
} else {
for _, info := range infos {
pathName := filepath.Join(tmpPath, info.Name())
path := filepath.Join(tmpPath, info.Name())
if info.IsDir() {
err := os.RemoveAll(pathName)
err := os.RemoveAll(path)
if err != nil {
revel.RevelLog.Error("Failed to remove dir:", "error", err)
revel.ERROR.Println("Failed to remove dir:", err)
}
} else {
err := os.Remove(pathName)
err := os.Remove(path)
if err != nil {
revel.RevelLog.Error("Failed to remove file:", "error", err)
revel.ERROR.Println("Failed to remove file:", err)
}
}
}
@@ -280,20 +237,20 @@ func genSource(dir, filename, templateSource string, args map[string]interface{}
tmpPath := filepath.Join(revel.AppPath, dir)
err := os.Mkdir(tmpPath, 0777)
if err != nil && !os.IsExist(err) {
revel.RevelLog.Fatalf("Failed to make '%v' directory: %v", dir, err)
revel.ERROR.Fatalf("Failed to make '%v' directory: %v", dir, err)
}
// Create the file
file, err := os.Create(filepath.Join(tmpPath, filename))
if err != nil {
revel.RevelLog.Fatalf("Failed to create file: %v", err)
revel.ERROR.Fatalf("Failed to create file: %v", err)
}
defer func() {
_ = file.Close()
}()
if _, err = file.WriteString(sourceCode); err != nil {
revel.RevelLog.Fatalf("Failed to write to file: %v", err)
revel.ERROR.Fatalf("Failed to write to file: %v", err)
}
}
@@ -330,7 +287,7 @@ func calcImportAliases(src *SourceInfo) map[string]string {
}
func addAlias(aliases map[string]string, importPath, pkgName string) {
alias, ok := aliases[importPath]
alias, ok := aliases[importPath]
if ok {
return
}
@@ -341,7 +298,7 @@ func addAlias(aliases map[string]string, importPath, pkgName string) {
func makePackageAlias(aliases map[string]string, pkgName string) string {
i := 0
alias := pkgName
for containsValue(aliases, alias) || alias == "revel" {
for containsValue(aliases, alias) || alias=="revel" {
alias = fmt.Sprintf("%s%d", pkgName, i)
i++
}
@@ -366,7 +323,7 @@ func newCompileError(output []byte) *revel.Error {
errorMatch = regexp.MustCompile(`(?m)^(.*?)\:(\d+)\:\s(.*?)$`).FindSubmatch(output)
if errorMatch == nil {
revel.RevelLog.Error("Failed to parse build errors", "error", string(output))
revel.ERROR.Println("Failed to parse build errors:\n", string(output))
return &revel.Error{
SourceType: "Go code",
Title: "Go Compilation Error",
@@ -376,7 +333,7 @@ func newCompileError(output []byte) *revel.Error {
errorMatch = append(errorMatch, errorMatch[3])
revel.RevelLog.Error("Build errors", "errors", string(output))
revel.ERROR.Println("Build errors:\n", string(output))
}
// Read the source for the offending file.
@@ -403,7 +360,7 @@ func newCompileError(output []byte) *revel.Error {
fileStr, err := revel.ReadLines(absFilename)
if err != nil {
compileError.MetaError = absFilename + ": " + err.Error()
revel.RevelLog.Error(compileError.MetaError)
revel.ERROR.Println(compileError.MetaError)
return compileError
}
@@ -436,7 +393,7 @@ var (
func main() {
flag.Parse()
revel.Init(*runMode, *importPath, *srcPath)
revel.AppLog.Info("Running revel server")
revel.INFO.Println("Running revel server")
{{range $i, $c := .Controllers}}
revel.RegisterController((*{{index $.ImportPaths .ImportPath}}.{{.StructName}})(nil),
[]*revel.MethodType{

View File

@@ -29,10 +29,10 @@ import (
"sync/atomic"
"github.com/revel/revel"
"sync"
)
var (
watcher *revel.Watcher
doNotWatch = []string{"tmp", "views", "routes"}
lastRequestHadError int32
@@ -45,12 +45,10 @@ type Harness struct {
serverHost string
port int
proxy *httputil.ReverseProxy
watcher *revel.Watcher
mutex *sync.Mutex
}
func renderError(iw http.ResponseWriter, ir *http.Request, err error) {
context := revel.NewGoContext(nil)
context := revel.NewGOContext(nil)
context.Request.SetRequest(ir)
context.Response.SetResponse(iw)
c := revel.NewController(context)
@@ -67,17 +65,12 @@ func (h *Harness) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// Flush any change events and rebuild app if necessary.
// Render an error page if the rebuild / restart failed.
err := h.watcher.Notify()
err := watcher.Notify()
if err != nil {
// In a thread safe manner update the flag so that a request for
// /favicon.ico does not trigger a rebuild
atomic.CompareAndSwapInt32(&lastRequestHadError, 0, 1)
renderError(w, r, err)
return
}
// In a thread safe manner update the flag so that a request for
// /favicon.ico is allowed
atomic.CompareAndSwapInt32(&lastRequestHadError, 1, 0)
// Reverse proxy the request.
@@ -97,7 +90,7 @@ func NewHarness() *Harness {
revel.MainTemplateLoader = revel.NewTemplateLoader(
[]string{filepath.Join(revel.RevelPath, "templates")})
if err := revel.MainTemplateLoader.Refresh(); err != nil {
revel.RevelLog.Error("Template loader error", "error", err)
revel.ERROR.Println(err)
}
addr := revel.HTTPAddr
@@ -118,32 +111,27 @@ func NewHarness() *Harness {
serverURL, _ := url.ParseRequestURI(fmt.Sprintf(scheme+"://%s:%d", addr, port))
serverHarness := &Harness{
harness := &Harness{
port: port,
serverHost: serverURL.String()[len(scheme+"://"):],
proxy: httputil.NewSingleHostReverseProxy(serverURL),
mutex: &sync.Mutex{},
}
if revel.HTTPSsl {
serverHarness.proxy.Transport = &http.Transport{
harness.proxy.Transport = &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
}
return serverHarness
return harness
}
// Refresh method rebuilds the Revel application and run it on the given port.
func (h *Harness) Refresh() (err *revel.Error) {
// Allow only one thread to rebuild the process
h.mutex.Lock()
defer h.mutex.Unlock()
if h.app != nil {
h.app.Kill()
}
revel.RevelLog.Debug("Rebuild Called")
revel.TRACE.Println("Rebuild")
h.app, err = Build()
if err != nil {
return
@@ -167,7 +155,7 @@ func (h *Harness) WatchDir(info os.FileInfo) bool {
}
// WatchFile method returns true given filename HasSuffix of ".go"
// otheriwse false - implements revel.DiscerningListener
// otheriwse false
func (h *Harness) WatchFile(filename string) bool {
return strings.HasSuffix(filename, ".go")
}
@@ -181,13 +169,12 @@ func (h *Harness) Run() {
paths = append(paths, gopaths...)
}
paths = append(paths, revel.CodePaths...)
h.watcher = revel.NewWatcher()
h.watcher.Listen(h, paths...)
h.watcher.Notify()
watcher = revel.NewWatcher()
watcher.Listen(h, paths...)
go func() {
addr := fmt.Sprintf("%s:%d", revel.HTTPAddr, revel.HTTPPort)
revel.RevelLog.Infof("Listening on %s", addr)
revel.INFO.Printf("Listening on %s", addr)
var err error
if revel.HTTPSsl {
@@ -200,7 +187,7 @@ func (h *Harness) Run() {
err = http.ListenAndServe(addr, h)
}
if err != nil {
revel.RevelLog.Error("Failed to start reverse proxy:", "error", err)
revel.ERROR.Fatalln("Failed to start reverse proxy:", err)
}
}()
@@ -218,13 +205,13 @@ func (h *Harness) Run() {
func getFreePort() (port int) {
conn, err := net.Listen("tcp", ":0")
if err != nil {
revel.RevelLog.Fatal("Unable to fetch a freee port address", "error", err)
revel.ERROR.Fatal(err)
}
port = conn.Addr().(*net.TCPAddr).Port
err = conn.Close()
if err != nil {
revel.RevelLog.Fatal("Unable to close port", "error", err)
revel.ERROR.Fatal(err)
}
return port
}
@@ -246,7 +233,7 @@ func proxyWebsocket(w http.ResponseWriter, r *http.Request, host string) {
}
if err != nil {
http.Error(w, "Error contacting backend server.", 500)
revel.RevelLog.Error("Error dialing websocket backend ", "host", host, "error", err)
revel.ERROR.Printf("Error dialing websocket backend %s: %v", host, err)
return
}
hj, ok := w.(http.Hijacker)
@@ -256,21 +243,21 @@ func proxyWebsocket(w http.ResponseWriter, r *http.Request, host string) {
}
nc, _, err := hj.Hijack()
if err != nil {
revel.RevelLog.Error("Hijack error", "error", err)
revel.ERROR.Printf("Hijack error: %v", err)
return
}
defer func() {
if err = nc.Close(); err != nil {
revel.RevelLog.Error("Connection close error", "error", err)
revel.ERROR.Println(err)
}
if err = d.Close(); err != nil {
revel.RevelLog.Error("Dial close error", "error", err)
revel.ERROR.Println(err)
}
}()
err = r.Write(d)
if err != nil {
revel.RevelLog.Error("Error copying request to target", "error", err)
revel.ERROR.Printf("Error copying request to target: %v", err)
return
}

View File

@@ -13,12 +13,12 @@ import (
"go/parser"
"go/scanner"
"go/token"
"log"
"os"
"path/filepath"
"strings"
"github.com/revel/revel"
"unicode"
)
// SourceInfo is the top-level struct containing all extracted information
@@ -98,14 +98,14 @@ func ProcessSource(roots []string) (*SourceInfo, *revel.Error) {
for _, root := range roots {
rootImportPath := importPathFromPath(root)
if rootImportPath == "" {
revel.RevelLog.Warn("Skipping empty code path", "path", root)
revel.WARN.Println("Skipping code path", root)
continue
}
// Start walking the directory tree.
_ = revel.Walk(root, func(path string, info os.FileInfo, err error) error {
if err != nil {
revel.RevelLog.Error("Error scanning app source:", "error", err)
log.Println("Error scanning app source:", err)
return nil
}
@@ -149,7 +149,7 @@ func ProcessSource(roots []string) (*SourceInfo, *revel.Error) {
// This is exception, err alredy checked above. Here just a print
ast.Print(nil, err)
revel.RevelLog.Fatal("Failed to parse dir", "error", err)
log.Fatalf("Failed to parse dir: %s", err)
}
// Skip "main" packages.
@@ -174,7 +174,7 @@ func ProcessSource(roots []string) (*SourceInfo, *revel.Error) {
for i := range pkgs {
println("Found package ", i)
}
revel.RevelLog.Error("Most unexpected! Multiple packages in a single directory:", "packages", pkgs)
log.Println("Most unexpected! Multiple packages in a single directory:", pkgs)
}
var pkg *ast.Package
@@ -199,7 +199,7 @@ func appendSourceInfo(srcInfo1, srcInfo2 *SourceInfo) *SourceInfo {
srcInfo1.InitImportPaths = append(srcInfo1.InitImportPaths, srcInfo2.InitImportPaths...)
for k, v := range srcInfo2.ValidationKeys {
if _, ok := srcInfo1.ValidationKeys[k]; ok {
revel.RevelLog.Warn("Key conflict when scanning validation calls:", "key", k)
log.Println("Key conflict when scanning validation calls:", k)
continue
}
srcInfo1.ValidationKeys[k] = v
@@ -317,7 +317,7 @@ func addImports(imports map[string]string, decl ast.Decl, srcDir string) {
// 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") {
revel.RevelLog.Debug("Could not find import:", "path", fullPath)
revel.TRACE.Println("Could not find import:", fullPath)
}
continue
}
@@ -336,7 +336,6 @@ func appendStruct(specs []*TypeInfo, pkgImportPath string, pkg *ast.Package, dec
if !found {
return specs
}
structType := spec.Type.(*ast.StructType)
// At this point we know it's a type declaration for a struct.
@@ -396,7 +395,7 @@ func appendStruct(specs []*TypeInfo, pkgImportPath string, pkg *ast.Package, dec
} else {
var ok bool
if importPath, ok = imports[pkgName]; !ok {
revel.RevelLog.Error("Failed to find import path for ", "package", pkgName, "type", typeName)
log.Print("Failed to find import path for ", pkgName, ".", typeName)
continue
}
}
@@ -455,16 +454,13 @@ func appendAction(fset *token.FileSet, mm methodMap, decl ast.Decl, pkgImportPat
var importPath string
typeExpr := NewTypeExpr(pkgName, field.Type)
if !typeExpr.Valid {
revel.RevelLog.Warnf("Didn't understand argument '%s' of action %s. Ignoring.", name, getFuncName(funcDecl))
log.Printf("Didn't understand argument '%s' of action %s. Ignoring.\n", name, getFuncName(funcDecl))
return // We didn't understand one of the args. Ignore this action.
}
// Local object
if typeExpr.PkgName == pkgName {
importPath = pkgImportPath
} else if typeExpr.PkgName != "" {
if typeExpr.PkgName != "" {
var ok bool
if importPath, ok = imports[typeExpr.PkgName]; !ok {
revel.RevelLog.Errorf("Failed to find import for arg of type: %s , %s", typeExpr.PkgName, typeExpr.TypeName(""))
log.Println("Failed to find import for arg of type:", typeExpr.TypeName(""))
}
}
method.Args = append(method.Args, &MethodArg{
@@ -498,7 +494,7 @@ func appendAction(fset *token.FileSet, mm methodMap, decl ast.Decl, pkgImportPat
}
// Add this call's args to the renderArgs.
pos := fset.Position(callExpr.Lparen)
pos := fset.Position(callExpr.Rparen)
methodCall := &methodCall{
Line: pos.Line,
Names: []string{},
@@ -650,7 +646,7 @@ func getStructTypeDecl(decl ast.Decl, fset *token.FileSet) (spec *ast.TypeSpec,
}
if len(genDecl.Specs) == 0 {
revel.RevelLog.Warnf("Surprising: %s:%d Decl contains no specifications", fset.Position(decl.Pos()).Filename, fset.Position(decl.Pos()).Line)
revel.WARN.Printf("Surprising: %s:%d Decl contains no specifications", fset.Position(decl.Pos()).Filename, fset.Position(decl.Pos()).Line)
return
}
@@ -663,7 +659,7 @@ func getStructTypeDecl(decl ast.Decl, fset *token.FileSet) (spec *ast.TypeSpec,
// TypesThatEmbed returns all types that (directly or indirectly) embed the
// target type, which must be a fully qualified type name,
// e.g. "github.com/revel/revel.Controller"
func (s *SourceInfo) TypesThatEmbed(targetType, packageFilter string) (filtered []*TypeInfo) {
func (s *SourceInfo) TypesThatEmbed(targetType string) (filtered []*TypeInfo) {
// Do a search in the "embedded type graph", starting with the target type.
var (
nodeQueue = []string{targetType}
@@ -695,37 +691,6 @@ func (s *SourceInfo) TypesThatEmbed(targetType, packageFilter string) (filtered
}
}
}
// Strip out any specifications that contain a lower case
for exit := false; !exit; exit = true {
for i, filteredItem := range filtered {
if unicode.IsLower([]rune(filteredItem.StructName)[0]) {
revel.RevelLog.Debug("Skipping adding spec for unexported type",
"type", filteredItem.StructName,
"package", filteredItem.ImportPath)
filtered = append(filtered[:i], filtered[i+1:]...)
exit = false
break
}
}
}
// Check for any missed types that where from expected packages
for _, spec := range s.StructSpecs {
if spec.PackageName == packageFilter {
found := false
for _, filteredItem := range filtered {
if filteredItem.StructName == spec.StructName {
found = true
break
}
}
if !found {
revel.RevelLog.Warn("Type found in package: "+packageFilter+
", but did not embed from: "+filepath.Base(targetType),
"name", spec.StructName, "path", spec.ImportPath)
}
}
}
return
}
@@ -733,7 +698,7 @@ func (s *SourceInfo) TypesThatEmbed(targetType, packageFilter string) (filtered
// `revel.Controller`
func (s *SourceInfo) ControllerSpecs() []*TypeInfo {
if s.controllerSpecs == nil {
s.controllerSpecs = s.TypesThatEmbed(revel.RevelImportPath+".Controller", "controllers")
s.controllerSpecs = s.TypesThatEmbed(revel.RevelImportPath + ".Controller")
}
return s.controllerSpecs
}
@@ -742,7 +707,7 @@ func (s *SourceInfo) ControllerSpecs() []*TypeInfo {
// `testing.TestSuite`
func (s *SourceInfo) TestSuites() []*TypeInfo {
if s.testSuites == nil {
s.testSuites = s.TypesThatEmbed(revel.RevelImportPath+"/testing.TestSuite", "testsuite")
s.testSuites = s.TypesThatEmbed(revel.RevelImportPath + "/testing.TestSuite")
}
return s.testSuites
}
@@ -786,7 +751,7 @@ func NewTypeExpr(pkgName string, expr ast.Expr) TypeExpr {
e := NewTypeExpr(pkgName, t.Elt)
return TypeExpr{"[]" + e.Expr, e.PkgName, e.pkgIndex + 2, e.Valid}
default:
revel.RevelLog.Error("Failed to generate name for field. Make sure the field name is valid.")
log.Println("Failed to generate name for field. Make sure the field name is valid.")
}
return TypeExpr{Valid: false}
}
@@ -834,10 +799,10 @@ func importPathFromPath(root string) string {
srcPath := filepath.Join(build.Default.GOROOT, "src", "pkg")
if strings.HasPrefix(root, srcPath) {
revel.RevelLog.Warn("Code path should be in GOPATH, but is in GOROOT:", "path", root)
revel.WARN.Println("Code path should be in GOPATH, but is in GOROOT:", root)
return filepath.ToSlash(root[len(srcPath)+1:])
}
revel.RevelLog.Error("Unexpected! Code path is not in GOPATH:", "path", root)
revel.ERROR.Println("Unexpected! Code path is not in GOPATH:", root)
return ""
}

View File

@@ -8,6 +8,8 @@ import (
"go/ast"
"go/parser"
"go/token"
"io/ioutil"
"log"
"reflect"
"strings"
"testing"
@@ -181,7 +183,7 @@ NEXT_TEST:
func BenchmarkProcessBookingSource(b *testing.B) {
revel.Init("", "github.com/revel/examples/booking", "")
revel.GetRootLogHandler().Disable()
revel.TRACE = log.New(ioutil.Discard, "", 0)
b.ResetTimer()
for i := 0; i < b.N; i++ {

View File

@@ -60,11 +60,11 @@ func buildApp(args []string) {
}
if err := os.RemoveAll(destPath); err != nil && !os.IsNotExist(err) {
revel.RevelLog.Fatal("Remove all error","error", err)
revel.ERROR.Fatalln(err)
}
if err := os.MkdirAll(destPath, 0777); err != nil {
revel.RevelLog.Fatal("makedir error","error",err)
revel.ERROR.Fatalln(err)
}
app, reverr := harness.Build()
@@ -101,7 +101,7 @@ func buildApp(args []string) {
}
modulePath, err := revel.ResolveImportPath(moduleImportPath)
if err != nil {
revel.RevelLog.Fatalf("Failed to load module %s: %s", key[len("module."):], err)
revel.ERROR.Fatalln("Failed to load module %s: %s", key[len("module."):], err)
}
modulePaths[moduleImportPath] = modulePath
}

View File

@@ -8,6 +8,7 @@ import (
"bytes"
"fmt"
"go/build"
"log"
"math/rand"
"os"
"os/exec"
@@ -66,6 +67,8 @@ func newApp(args []string) {
errorf("Too many arguments provided.\nRun 'revel help new' for usage.\n")
}
revel.ERROR.SetFlags(log.LstdFlags)
// checking and setting go paths
initGoPaths()
@@ -126,7 +129,7 @@ func initGoPaths() {
}
if len(srcRoot) == 0 {
revel.RevelLog.Fatal("Abort: could not create a Revel application outside of GOPATH.")
revel.ERROR.Fatalln("Abort: could not create a Revel application outside of GOPATH.")
}
// set go src path
@@ -145,10 +148,8 @@ func setApplicationPath(args []string) {
importPath)
}
appPath = filepath.Join(srcRoot, filepath.FromSlash(importPath))
_, err = build.Import(importPath, "", build.FindOnly)
if err == nil && !empty(appPath) {
if err == nil {
errorf("Abort: Import path %s already exists.\n", importPath)
}
@@ -157,6 +158,7 @@ func setApplicationPath(args []string) {
errorf("Abort: Could not find Revel source code: %s\n", err)
}
appPath = filepath.Join(srcRoot, filepath.FromSlash(importPath))
appName = filepath.Base(appPath)
basePath = filepath.ToSlash(filepath.Dir(importPath))

View File

@@ -53,7 +53,7 @@ func packageApp(args []string) {
// Remove the archive if it already exists.
destFile := filepath.Base(revel.BasePath) + ".tar.gz"
if err := os.Remove(destFile); err != nil && !os.IsNotExist(err) {
revel.RevelLog.Fatal("Unable to remove target file","error",err,"file",destFile)
revel.ERROR.Fatal(err)
}
// Collect stuff in a temp directory.

View File

@@ -51,7 +51,7 @@ func parseRunArgs(args []string) *RunArgs {
}
switch len(args) {
case 3:
// Possible combinations
// Possibile combinations
// revel run [import-path] [run-mode] [port]
port, err := strconv.Atoi(args[2])
if err != nil {
@@ -61,7 +61,7 @@ func parseRunArgs(args []string) *RunArgs {
inputArgs.Mode = args[1]
inputArgs.Port = port
case 2:
// Possible combinations
// Possibile combinations
// 1. revel run [import-path] [run-mode]
// 2. revel run [import-path] [port]
// 3. revel run [run-mode] [port]
@@ -85,13 +85,13 @@ func parseRunArgs(args []string) *RunArgs {
inputArgs.Port = port
}
case 1:
// Possible combinations
// Possibile combinations
// 1. revel run [import-path]
// 2. revel run [port]
// 3. revel run [run-mode]
_, err := build.Import(args[0], "", build.FindOnly)
if err != nil {
revel.RevelLog.Warn("Unable to run using an import path, assuming import path is working directory %s %s", "Argument", args[0], "error", err.Error())
revel.WARN.Printf("Unable to run using an import path, assuming import path is working directory %s %s", args[0], err.Error())
}
println("Trying to build with", args[0], err)
if err == nil {
@@ -121,18 +121,18 @@ func runApp(args []string) {
runArgs.Port = revel.HTTPPort
}
revel.RevelLog.Infof("Running %s (%s) in %s mode\n", revel.AppName, revel.ImportPath, runArgs.Mode)
revel.RevelLog.Debug("Base path:", "path", revel.BasePath)
revel.INFO.Printf("Running %s (%s) in %s mode\n", revel.AppName, revel.ImportPath, runArgs.Mode)
revel.TRACE.Println("Base path:", revel.BasePath)
// If the app is run in "watched" mode, use the harness to run it.
if revel.Config.BoolDefault("watch", true) && revel.Config.BoolDefault("watch.code", true) {
revel.RevelLog.Debug("Running in watched mode.")
revel.TRACE.Println("Running in watched mode.")
revel.HTTPPort = runArgs.Port
harness.NewHarness().Run() // Never returns.
}
// Else, just build and run the app.
revel.RevelLog.Debug("Running in live build mode.")
revel.TRACE.Println("Running in live build mode.")
app, err := harness.Build()
if err != nil {
errorf("Failed to build app: %s", err)

View File

@@ -29,7 +29,7 @@ func init() {
revel.ActionInvoker, // Invoke the action.
}
// Register startup functions with OnAppStart
// register startup functions with OnAppStart
// revel.DevMode and revel.RunMode only work inside of OnAppStart. See Example Startup Script
// ( order dependent )
// revel.OnAppStart(ExampleStartupScript)
@@ -38,12 +38,13 @@ func init() {
}
// HeaderFilter adds common security headers
// There is a full implementation of a CSRF filter in
// https://github.com/revel/modules/tree/master/csrf
// TODO turn this into revel.HeaderFilter
// should probably also have a filter for CSRF
// not sure if it can go in the same filter or not
var HeaderFilter = func(c *revel.Controller, fc []revel.Filter) {
c.Response.Out.Header().Add("X-Frame-Options", "SAMEORIGIN")
c.Response.Out.Header().Add("X-XSS-Protection", "1; mode=block")
c.Response.Out.Header().Add("X-Content-Type-Options", "nosniff")
c.Response.SetHttpHeader("X-Frame-Options", "SAMEORIGIN")
c.Response.SetHttpHeader("X-XSS-Protection", "1; mode=block")
c.Response.SetHttpHeader("X-Content-Type-Options", "nosniff")
fc[0](c, fc[1:]) // Execute the next filter stage.
}

View File

@@ -84,6 +84,15 @@ format.datetime = 2006-01-02 15:04
results.chunked = false
# Prefixes for each log message line.
# User can override these prefix values within any section
# For e.g: [dev], [prod], etc
log.trace.prefix = "TRACE "
log.info.prefix = "INFO "
log.warn.prefix = "WARN "
log.error.prefix = "ERROR "
# The default language of this application.
i18n.default_language = en
@@ -95,7 +104,7 @@ i18n.default_language = en
# Module to serve static content such as CSS, JavaScript and Media files
# Allows Routes like this:
# `Static.ServeModule("modulename","public")`
module.static = github.com/revel/modules/static
module.static=github.com/revel/modules/static
@@ -170,14 +179,37 @@ module.testrunner = github.com/revel/modules/testrunner
# Log to Os's standard error output. Default value.
# "relative/path/to/log"
# Log to file.
log.all.filter.module.app = stdout # Log all loggers for the application to the stdout
log.error.nfilter.module.app = stderr # Everything else that logs an error to stderr
log.crit.output = stderr # Everything that logs something as critical goes to this
log.trace.output = off
log.info.output = stderr
log.warn.output = stderr
log.error.output = stderr
# Revel log flags. Possible flags defined by the Go `log` package. Go log is
# "Bits OR'ed together to control what's printed
# See:
# https://golang.org/pkg/log/#pkg-constants
# Values:
# "0"
# Just log the message, turn off the flags.
# "3"
# log.LstdFlags (log.Ldate|log.Ltime)
# "19"
# log.Ldate|log.Ltime|log.Lshortfile
# "23"
# log.Ldate|log.Ltime|log.Lmicroseconds|log.Lshortfile
log.trace.flags = 19
log.info.flags = 19
log.warn.flags = 19
log.error.flags = 19
# Revel request access log
# Access log line format:
# INFO 21:53:55 static server-engine.go:169: Request Stats ip=127.0.0.1 path=/public/vendors/datatables.net-buttons/js/buttons.html5.min.js method=GET start=2017/08/31 21:53:55 status=200 duration_seconds=0.0002583 section=requestlog
log.request.output = stdout
# RequestStartTime ClientIP ResponseStatus RequestLatency HTTPMethod URLPath
# Sample format:
# 2016/05/25 17:46:37.112 127.0.0.1 200 270.157µs GET /
log.request.output = stderr
@@ -197,11 +229,30 @@ watch = false
module.testrunner =
log.warn.output = log/%(app.name)-warn.json # Log all warn messages to file
log.error.output = log/%(app.name)-error.json # Log all errors to file
log.crit.output = log/%(app.name)-critical.json # Log all critical to file
log.trace.output = off
log.info.output = off
log.warn.output = log/%(app.name)s.log
log.error.output = log/%(app.name)s.log
# Revel request access log (json format)
# Revel log flags. Possible flags defined by the Go `log` package,
# please refer https://golang.org/pkg/log/#pkg-constants
# Go log is "Bits or'ed together to control what's printed"
# Examples:
# 0 => just log the message, turn off the flags
# 3 => log.LstdFlags (log.Ldate|log.Ltime)
# 19 => log.Ldate|log.Ltime|log.Lshortfile
# 23 => log.Ldate|log.Ltime|log.Lmicroseconds|log.Lshortfile
log.trace.flags = 3
log.info.flags = 3
log.warn.flags = 3
log.error.flags = 3
# Revel request access log
# Access log line format:
# RequestStartTime ClientIP ResponseStatus RequestLatency HTTPMethod URLPath
# Sample format:
# 2016/05/25 17:46:37.112 127.0.0.1 200 270.157µs GET /
# Example:
# log.request.output = %(app.name)s-request.json
log.request.output = log/%(app.name)s-requests.json
# log.request.output = %(app.name)s-request.log
log.request.output = off

View File

@@ -15,12 +15,5 @@ GET /favicon.ico 404
# Map static resources from the /app/public folder to the /public path
GET /public/*filepath Static.Serve("public")
# Catch all, this will route any request into the controller path
#
# **** WARNING ****
# Enabling this exposes any controller and function to the web.
# ** This is a serious security issue if used online **
#
# For rapid development uncomment the following to add new controller.action endpoints
# without having to add them to the routes table.
# * /:controller/:action :controller.:action
# Catch all
* /:controller/:action :controller.:action

View File

@@ -97,18 +97,8 @@ func testApp(args []string) {
defer cmd.Kill()
revel.INFO.Printf("Testing %s (%s) in %s mode\n", revel.AppName, revel.ImportPath, mode)
var httpAddr = revel.HTTPAddr
if httpAddr == "" {
httpAddr = "127.0.0.1"
}
var httpProto = "http"
if revel.HTTPSsl {
httpProto = "https"
}
// Get a list of tests
var baseURL = fmt.Sprintf("%s://%s:%d", httpProto, httpAddr, revel.HTTPPort)
var baseURL = fmt.Sprintf("http://127.0.0.1:%d", revel.HTTPPort)
testSuites, _ := getTestsList(baseURL)
// If a specific TestSuite[.Method] is specified, only run that suite/test