diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..6ef72f8
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+.idea/
+*.iml
+
diff --git a/harness/app.go b/harness/app.go
index a4ec244..c1b142c 100644
--- a/harness/app.go
+++ b/harness/app.go
@@ -1,14 +1,19 @@
+// Copyright (c) 2012-2016 The Revel Framework Authors, All rights reserved.
+// Revel Framework source code and usage is governed by a MIT style
+// license that can be found in the LICENSE file.
+
package harness
import (
"bytes"
"errors"
"fmt"
- "github.com/revel/revel"
"io"
"os"
"os/exec"
"time"
+
+ "github.com/revel/revel"
)
// App contains the configuration for running a Revel app. (Not for the app itself)
@@ -19,11 +24,12 @@ type App struct {
cmd AppCmd // The last cmd returned.
}
+// NewApp returns app instance with binary path in it
func NewApp(binPath string) *App {
return &App{BinaryPath: binPath}
}
-// Return a command to run the app server using the current configuration.
+// Cmd returns a command to run the app server using the current configuration.
func (a *App) Cmd() AppCmd {
a.cmd = NewAppCmd(a.BinaryPath, a.Port)
return a.cmd
@@ -40,6 +46,7 @@ type AppCmd struct {
*exec.Cmd
}
+// NewAppCmd returns the AppCmd with parameters initialized for running app
func NewAppCmd(binPath string, port int) AppCmd {
cmd := exec.Command(binPath,
fmt.Sprintf("-port=%d", port),
@@ -69,6 +76,8 @@ func (cmd AppCmd) Start() error {
case <-listeningWriter.notifyReady:
return nil
}
+
+ // TODO remove this unreachable code and document it
panic("Impossible")
}
@@ -80,7 +89,7 @@ func (cmd AppCmd) Run() {
}
}
-// Terminate the app server if it's running.
+// Kill terminates the app server if it's running.
func (cmd AppCmd) Kill() {
if cmd.Cmd != nil && (cmd.ProcessState == nil || !cmd.ProcessState.Exited()) {
revel.TRACE.Println("Killing revel server pid", cmd.Process.Pid)
@@ -95,7 +104,7 @@ func (cmd AppCmd) Kill() {
func (cmd AppCmd) waitChan() <-chan struct{} {
ch := make(chan struct{}, 1)
go func() {
- cmd.Wait()
+ _ = cmd.Wait()
ch <- struct{}{}
}()
return ch
diff --git a/harness/build.go b/harness/build.go
index c98b8c9..386a66c 100755
--- a/harness/build.go
+++ b/harness/build.go
@@ -1,3 +1,7 @@
+// Copyright (c) 2012-2016 The Revel Framework Authors, All rights reserved.
+// Revel Framework source code and usage is governed by a MIT style
+// license that can be found in the LICENSE file.
+
package harness
import (
@@ -12,6 +16,7 @@ import (
"strconv"
"strings"
"text/template"
+ "time"
"github.com/revel/revel"
)
@@ -44,8 +49,8 @@ func Build(buildFlags ...string) (app *App, compileError *revel.Error) {
"ImportPaths": calcImportAliases(sourceInfo),
"TestSuites": sourceInfo.TestSuites(),
}
- genSource("tmp", "main.go", MAIN, templateArgs)
- genSource("routes", "routes.go", ROUTES, templateArgs)
+ genSource("tmp", "main.go", RevelMainTemplate, templateArgs)
+ genSource("routes", "routes.go", RevelRoutesTemplate, templateArgs)
// Read build config.
buildTags := revel.Config.StringDefault("build.tags", "")
@@ -77,12 +82,16 @@ func Build(buildFlags ...string) (app *App, compileError *revel.Error) {
gotten := make(map[string]struct{})
for {
appVersion := getAppVersion()
- versionLinkerFlags := fmt.Sprintf("-X %s/app.APP_VERSION=%s", revel.ImportPath, appVersion)
+
+ buildTime := time.Now().UTC().Format(time.RFC3339)
+ 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, _ := strconv.ParseFloat(runtime.Version()[2:5], 64)
if goVersion < 1.5 {
- versionLinkerFlags = fmt.Sprintf("-X %s/app.APP_VERSION \"%s\"", revel.ImportPath, appVersion)
+ versionLinkerFlags = fmt.Sprintf("-X %s/app.AppVersion \"%s\" -X %s/app.BuildTime \"%s\"",
+ revel.ImportPath, appVersion, revel.ImportPath, buildTime)
}
flags := []string{
"build",
@@ -94,7 +103,8 @@ func Build(buildFlags ...string) (app *App, compileError *revel.Error) {
// Add in build flags
flags = append(flags, buildFlags...)
- // The main path
+ // This is Go main path
+ // Note: It's not applicable for filepath.* usage
flags = append(flags, path.Join(revel.ImportPath, "app", "tmp"))
buildCmd := exec.Command(goPath, flags...)
@@ -131,6 +141,8 @@ func Build(buildFlags ...string) (app *App, compileError *revel.Error) {
// Success getting the import, attempt to build again.
}
+
+ // TODO remove this unreachable code and document it
revel.ERROR.Fatalf("Not reachable")
return nil, nil
}
@@ -149,7 +161,7 @@ func getAppVersion() string {
// Check for the git binary
if gitPath, err := exec.LookPath("git"); err == nil {
// Check for the .git directory
- gitDir := path.Join(revel.BasePath, ".git")
+ gitDir := filepath.Join(revel.BasePath, ".git")
info, err := os.Stat(gitDir)
if (err != nil && os.IsNotExist(err)) || !info.IsDir() {
return ""
@@ -177,14 +189,17 @@ func cleanSource(dirs ...string) {
func cleanDir(dir string) {
revel.INFO.Println("Cleaning dir " + dir)
- tmpPath := path.Join(revel.AppPath, dir)
+ tmpPath := filepath.Join(revel.AppPath, dir)
f, err := os.Open(tmpPath)
if err != nil {
if !os.IsNotExist(err) {
revel.ERROR.Println("Failed to clean dir:", err)
}
} else {
- defer f.Close()
+ defer func() {
+ _ = f.Close()
+ }()
+
infos, err := f.Readdir(0)
if err != nil {
if !os.IsNotExist(err) {
@@ -192,7 +207,7 @@ func cleanDir(dir string) {
}
} else {
for _, info := range infos {
- path := path.Join(tmpPath, info.Name())
+ path := filepath.Join(tmpPath, info.Name())
if info.IsDir() {
err := os.RemoveAll(path)
if err != nil {
@@ -218,20 +233,22 @@ func genSource(dir, filename, templateSource string, args map[string]interface{}
// Create a fresh dir.
cleanSource(dir)
- tmpPath := path.Join(revel.AppPath, dir)
+ tmpPath := filepath.Join(revel.AppPath, dir)
err := os.Mkdir(tmpPath, 0777)
if err != nil && !os.IsExist(err) {
revel.ERROR.Fatalf("Failed to make '%v' directory: %v", dir, err)
}
// Create the file
- file, err := os.Create(path.Join(tmpPath, filename))
- defer file.Close()
+ file, err := os.Create(filepath.Join(tmpPath, filename))
if err != nil {
revel.ERROR.Fatalf("Failed to create file: %v", err)
}
- _, err = file.WriteString(sourceCode)
- if err != nil {
+ defer func() {
+ _ = file.Close()
+ }()
+
+ if _, err = file.WriteString(sourceCode); err != nil {
revel.ERROR.Fatalf("Failed to write to file: %v", err)
}
}
@@ -350,7 +367,8 @@ func newCompileError(output []byte) *revel.Error {
return compileError
}
-const MAIN = `// GENERATED CODE - DO NOT EDIT
+// RevelMainTemplate template for app/tmp/main.go
+const RevelMainTemplate = `// GENERATED CODE - DO NOT EDIT
package main
import (
@@ -404,7 +422,9 @@ func main() {
revel.Run(*port)
}
`
-const ROUTES = `// GENERATED CODE - DO NOT EDIT
+
+// RevelRoutesTemplate template for app/conf/routes
+const RevelRoutesTemplate = `// GENERATED CODE - DO NOT EDIT
package routes
import "github.com/revel/revel"
@@ -420,7 +440,7 @@ func (_ t{{$c.StructName}}) {{.Name}}({{range .Args}}
args := make(map[string]string)
{{range .Args}}
revel.Unbind(args, "{{.Name}}", {{.Name}}){{end}}
- return revel.MainRouter.Reverse("{{$c.StructName}}.{{.Name}}", args).Url
+ return revel.MainRouter.Reverse("{{$c.StructName}}.{{.Name}}", args).URL
}
{{end}}
{{end}}
diff --git a/harness/harness.go b/harness/harness.go
index a6ae1cc..ccb877e 100644
--- a/harness/harness.go
+++ b/harness/harness.go
@@ -1,13 +1,16 @@
-// The Harness for a Revel program.
+// Copyright (c) 2012-2016 The Revel Framework Authors, All rights reserved.
+// Revel Framework source code and usage is governed by a MIT style
+// license that can be found in the LICENSE file.
+
+// Package harness for a Revel Framework.
//
-// It has a couple responsibilities:
+// It has a following responsibilities:
// 1. Parse the user program, generating a main.go file that registers
// controller classes and starts the user's server.
// 2. Build and run the user program. Show compile errors.
// 3. Monitor the user source and re-build / restart the program when necessary.
//
// Source files are generated in the app/tmp directory.
-
package harness
import (
@@ -84,12 +87,14 @@ func NewHarness() *Harness {
// Prefer the app's views/errors directory, and fall back to the stock error pages.
revel.MainTemplateLoader = revel.NewTemplateLoader(
[]string{filepath.Join(revel.RevelPath, "templates")})
- revel.MainTemplateLoader.Refresh()
+ if err := revel.MainTemplateLoader.Refresh(); err != nil {
+ revel.ERROR.Println(err)
+ }
- addr := revel.HttpAddr
+ addr := revel.HTTPAddr
port := revel.Config.IntDefault("harness.port", 0)
scheme := "http"
- if revel.HttpSsl {
+ if revel.HTTPSsl {
scheme = "https"
}
@@ -110,7 +115,7 @@ func NewHarness() *Harness {
proxy: httputil.NewSingleHostReverseProxy(serverURL),
}
- if revel.HttpSsl {
+ if revel.HTTPSsl {
harness.proxy.Transport = &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
@@ -166,13 +171,16 @@ func (h *Harness) Run() {
watcher.Listen(h, paths...)
go func() {
- addr := fmt.Sprintf("%s:%d", revel.HttpAddr, revel.HttpPort)
+ addr := fmt.Sprintf("%s:%d", revel.HTTPAddr, revel.HTTPPort)
revel.INFO.Printf("Listening on %s", addr)
var err error
- if revel.HttpSsl {
- err = http.ListenAndServeTLS(addr, revel.HttpSslCert,
- revel.HttpSslKey, h)
+ if revel.HTTPSsl {
+ err = http.ListenAndServeTLS(
+ addr,
+ revel.HTTPSslCert,
+ revel.HTTPSslKey,
+ h)
} else {
err = http.ListenAndServe(addr, h)
}
@@ -213,7 +221,7 @@ func proxyWebsocket(w http.ResponseWriter, r *http.Request, host string) {
d net.Conn
err error
)
- if revel.HttpSsl {
+ if revel.HTTPSsl {
// since this proxy isn't used in production,
// it's OK to set InsecureSkipVerify to true
// no need to add another configuration option.
@@ -236,8 +244,14 @@ func proxyWebsocket(w http.ResponseWriter, r *http.Request, host string) {
revel.ERROR.Printf("Hijack error: %v", err)
return
}
- defer nc.Close()
- defer d.Close()
+ defer func() {
+ if err = nc.Close(); err != nil {
+ revel.ERROR.Println(err)
+ }
+ if err = d.Close(); err != nil {
+ revel.ERROR.Println(err)
+ }
+ }()
err = r.Write(d)
if err != nil {
diff --git a/harness/reflect.go b/harness/reflect.go
index 4c7df99..77d6007 100644
--- a/harness/reflect.go
+++ b/harness/reflect.go
@@ -1,3 +1,7 @@
+// Copyright (c) 2012-2016 The Revel Framework Authors, All rights reserved.
+// Revel Framework source code and usage is governed by a MIT style
+// license that can be found in the LICENSE file.
+
package harness
// This file handles the app code introspection.
@@ -25,7 +29,7 @@ type SourceInfo struct {
StructSpecs []*TypeInfo
// ValidationKeys provides a two-level lookup. The keys are:
// 1. The fully-qualified function name,
- // e.g. "github.com/revel/samples/chat/app/controllers.(*Application).Action"
+ // e.g. "github.com/revel/examples/chat/app/controllers.(*Application).Action"
// 2. Within that func's file, the line number of the (overall) expression statement.
// e.g. the line returned from runtime.Caller()
// The result of the lookup the name of variable being validated.
@@ -44,7 +48,7 @@ type SourceInfo struct {
// TypeInfo summarizes information about a struct type in the app source code.
type TypeInfo struct {
StructName string // e.g. "Application"
- ImportPath string // e.g. "github.com/revel/samples/chat/app/controllers"
+ ImportPath string // e.g. "github.com/revel/examples/chat/app/controllers"
PackageName string // e.g. "controllers"
MethodSpecs []*MethodSpec
@@ -60,12 +64,14 @@ type methodCall struct {
Names []string
}
+// MethodSpec holds the information of one Method
type MethodSpec struct {
Name string // Name of the method, e.g. "Index"
Args []*MethodArg // Argument descriptors
RenderCalls []*methodCall // Descriptions of Render() invocations from this Method.
}
+// MethodArg holds the information of one argument
type MethodArg struct {
Name string // Name of the argument.
TypeExpr TypeExpr // The name of the type, e.g. "int", "*pkg.UserType"
@@ -80,8 +86,9 @@ type embeddedTypeName struct {
// receiver.
type methodMap map[string][]*MethodSpec
-// Parse the app controllers directory and return a list of the controller types found.
-// Returns a CompileError if the parsing fails.
+// ProcessSource parses the app controllers directory and
+// returns a list of the controller types found.
+// Otherwise CompileError if the parsing fails.
func ProcessSource(roots []string) (*SourceInfo, *revel.Error) {
var (
srcInfo *SourceInfo
@@ -120,7 +127,7 @@ func ProcessSource(roots []string) (*SourceInfo, *revel.Error) {
}, 0)
if err != nil {
if errList, ok := err.(scanner.ErrorList); ok {
- var pos token.Position = errList[0].Pos
+ var pos = errList[0].Pos
compileError = &revel.Error{
SourceType: ".go source",
Title: "Go Compilation Error",
@@ -139,6 +146,8 @@ func ProcessSource(roots []string) (*SourceInfo, *revel.Error) {
return compileError
}
+
+ // This is exception, err alredy checked above. Here just a print
ast.Print(nil, err)
log.Fatalf("Failed to parse dir: %s", err)
}
@@ -419,7 +428,7 @@ func appendAction(fset *token.FileSet, mm methodMap, decl ast.Decl, pkgImportPat
if selExpr.Sel.Name != "Result" {
return
}
- if pkgIdent, ok := selExpr.X.(*ast.Ident); !ok || imports[pkgIdent.Name] != revel.REVEL_IMPORT_PATH {
+ if pkgIdent, ok := selExpr.X.(*ast.Ident); !ok || imports[pkgIdent.Name] != revel.RevelImportPath {
return
}
@@ -490,7 +499,7 @@ func appendAction(fset *token.FileSet, mm methodMap, decl ast.Decl, pkgImportPat
})
var recvTypeName string
- var recvType ast.Expr = funcDecl.Recv.List[0].Type
+ var recvType = funcDecl.Recv.List[0].Type
if recvStarType, ok := recvType.(*ast.StarExpr); ok {
recvTypeName = recvStarType.X.(*ast.Ident).Name
} else {
@@ -597,7 +606,7 @@ func getValidationParameter(funcDecl *ast.FuncDecl, imports map[string]string) *
continue
}
- if selExpr.Sel.Name == "Validation" && imports[xIdent.Name] == revel.REVEL_IMPORT_PATH {
+ if selExpr.Sel.Name == "Validation" && imports[xIdent.Name] == revel.RevelImportPath {
return field.Names[0].Obj
}
}
@@ -673,16 +682,20 @@ func (s *SourceInfo) TypesThatEmbed(targetType string) (filtered []*TypeInfo) {
return
}
+// ControllerSpecs returns the all the contollers that embeds
+// `revel.Controller`
func (s *SourceInfo) ControllerSpecs() []*TypeInfo {
if s.controllerSpecs == nil {
- s.controllerSpecs = s.TypesThatEmbed(revel.REVEL_IMPORT_PATH + ".Controller")
+ s.controllerSpecs = s.TypesThatEmbed(revel.RevelImportPath + ".Controller")
}
return s.controllerSpecs
}
+// TestSuites returns the all the Application tests that embeds
+// `testing.TestSuite`
func (s *SourceInfo) TestSuites() []*TypeInfo {
if s.testSuites == nil {
- s.testSuites = s.TypesThatEmbed(revel.REVEL_IMPORT_PATH + "/testing.TestSuite")
+ s.testSuites = s.TypesThatEmbed(revel.RevelImportPath + "/testing.TestSuite")
}
return s.testSuites
}
@@ -705,7 +718,7 @@ func (e TypeExpr) TypeName(pkgOverride string) string {
return e.Expr[:e.pkgIndex] + pkgName + "." + e.Expr[e.pkgIndex:]
}
-// This returns the syntactic expression for referencing this type in Go.
+// NewTypeExpr returns the syntactic expression for referencing this type in Go.
func NewTypeExpr(pkgName string, expr ast.Expr) TypeExpr {
switch t := expr.(type) {
case *ast.Ident:
@@ -731,35 +744,40 @@ func NewTypeExpr(pkgName string, expr ast.Expr) TypeExpr {
return TypeExpr{Valid: false}
}
-var _BUILTIN_TYPES = map[string]struct{}{
- "bool": struct{}{},
- "byte": struct{}{},
- "complex128": struct{}{},
- "complex64": struct{}{},
- "error": struct{}{},
- "float32": struct{}{},
- "float64": struct{}{},
- "int": struct{}{},
- "int16": struct{}{},
- "int32": struct{}{},
- "int64": struct{}{},
- "int8": struct{}{},
- "rune": struct{}{},
- "string": struct{}{},
- "uint": struct{}{},
- "uint16": struct{}{},
- "uint32": struct{}{},
- "uint64": struct{}{},
- "uint8": struct{}{},
- "uintptr": struct{}{},
+var builtInTypes = map[string]struct{}{
+ "bool": {},
+ "byte": {},
+ "complex128": {},
+ "complex64": {},
+ "error": {},
+ "float32": {},
+ "float64": {},
+ "int": {},
+ "int16": {},
+ "int32": {},
+ "int64": {},
+ "int8": {},
+ "rune": {},
+ "string": {},
+ "uint": {},
+ "uint16": {},
+ "uint32": {},
+ "uint64": {},
+ "uint8": {},
+ "uintptr": {},
}
+// IsBuiltinType checks the given type is built-in types of Go
func IsBuiltinType(name string) bool {
- _, ok := _BUILTIN_TYPES[name]
+ _, ok := builtInTypes[name]
return ok
}
func importPathFromPath(root string) string {
+ vendoringPath := revel.BasePath + "/vendor/"
+ if strings.HasPrefix(root, vendoringPath) {
+ return filepath.ToSlash(root[len(vendoringPath):])
+ }
for _, gopath := range filepath.SplitList(build.Default.GOPATH) {
srcPath := filepath.Join(gopath, "src")
if strings.HasPrefix(root, srcPath) {
diff --git a/harness/reflect_test.go b/harness/reflect_test.go
index f45364e..18116ba 100644
--- a/harness/reflect_test.go
+++ b/harness/reflect_test.go
@@ -1,7 +1,10 @@
+// Copyright (c) 2012-2016 The Revel Framework Authors, All rights reserved.
+// Revel Framework source code and usage is governed by a MIT style
+// license that can be found in the LICENSE file.
+
package harness
import (
- "github.com/revel/revel"
"go/ast"
"go/parser"
"go/token"
@@ -10,6 +13,8 @@ import (
"reflect"
"strings"
"testing"
+
+ "github.com/revel/revel"
)
const validationKeysSource = `
@@ -77,7 +82,7 @@ func TestGetValidationKeys(t *testing.T) {
}
for i, decl := range file.Decls {
- lineKeys := getValidationKeys(fset, decl.(*ast.FuncDecl), map[string]string{"revel": revel.REVEL_IMPORT_PATH})
+ lineKeys := getValidationKeys(fset, decl.(*ast.FuncDecl), map[string]string{"revel": revel.RevelImportPath})
for k, v := range expectedValidationKeys[i] {
if lineKeys[k] != v {
t.Errorf("Not found - %d: %v - Actual Map: %v", k, v, lineKeys)
@@ -91,18 +96,18 @@ func TestGetValidationKeys(t *testing.T) {
}
var TypeExprs = map[string]TypeExpr{
- "int": TypeExpr{"int", "", 0, true},
- "*int": TypeExpr{"*int", "", 1, true},
- "[]int": TypeExpr{"[]int", "", 2, true},
- "...int": TypeExpr{"[]int", "", 2, true},
- "[]*int": TypeExpr{"[]*int", "", 3, true},
- "...*int": TypeExpr{"[]*int", "", 3, true},
- "MyType": TypeExpr{"MyType", "pkg", 0, true},
- "*MyType": TypeExpr{"*MyType", "pkg", 1, true},
- "[]MyType": TypeExpr{"[]MyType", "pkg", 2, true},
- "...MyType": TypeExpr{"[]MyType", "pkg", 2, true},
- "[]*MyType": TypeExpr{"[]*MyType", "pkg", 3, true},
- "...*MyType": TypeExpr{"[]*MyType", "pkg", 3, true},
+ "int": {"int", "", 0, true},
+ "*int": {"*int", "", 1, true},
+ "[]int": {"[]int", "", 2, true},
+ "...int": {"[]int", "", 2, true},
+ "[]*int": {"[]*int", "", 3, true},
+ "...*int": {"[]*int", "", 3, true},
+ "MyType": {"MyType", "pkg", 0, true},
+ "*MyType": {"*MyType", "pkg", 1, true},
+ "[]MyType": {"[]MyType", "pkg", 2, true},
+ "...MyType": {"[]MyType", "pkg", 2, true},
+ "[]*MyType": {"[]*MyType", "pkg", 3, true},
+ "...*MyType": {"[]*MyType", "pkg", 3, true},
}
func TestTypeExpr(t *testing.T) {
@@ -125,10 +130,10 @@ func TestTypeExpr(t *testing.T) {
}
if array {
- expr = &ast.ArrayType{expr.Pos(), nil, expr}
+ expr = &ast.ArrayType{Lbrack: expr.Pos(), Len: nil, Elt: expr}
}
if ellipsis {
- expr = &ast.Ellipsis{expr.Pos(), expr}
+ expr = &ast.Ellipsis{Ellipsis: expr.Pos(), Elt: expr}
}
actual := NewTypeExpr("pkg", expr)
@@ -139,17 +144,17 @@ func TestTypeExpr(t *testing.T) {
}
func TestProcessBookingSource(t *testing.T) {
- revel.Init("prod", "github.com/revel/samples/booking", "")
+ revel.Init("prod", "github.com/revel/examples/booking", "")
sourceInfo, err := ProcessSource([]string{revel.AppPath})
if err != nil {
t.Fatal("Failed to process booking source with error:", err)
}
- CONTROLLER_PKG := "github.com/revel/samples/booking/app/controllers"
+ controllerPackage := "github.com/revel/examples/booking/app/controllers"
expectedControllerSpecs := []*TypeInfo{
- {"GorpController", CONTROLLER_PKG, "controllers", nil, nil},
- {"Application", CONTROLLER_PKG, "controllers", nil, nil},
- {"Hotels", CONTROLLER_PKG, "controllers", nil, nil},
+ {"GorpController", controllerPackage, "controllers", nil, nil},
+ {"Application", controllerPackage, "controllers", nil, nil},
+ {"Hotels", controllerPackage, "controllers", nil, nil},
}
if len(sourceInfo.ControllerSpecs()) != len(expectedControllerSpecs) {
t.Errorf("Unexpected number of controllers found. Expected %d, Found %d",
@@ -177,7 +182,7 @@ NEXT_TEST:
}
func BenchmarkProcessBookingSource(b *testing.B) {
- revel.Init("", "github.com/revel/samples/booking", "")
+ revel.Init("", "github.com/revel/examples/booking", "")
revel.TRACE = log.New(ioutil.Discard, "", 0)
b.ResetTimer()
diff --git a/revel/build.go b/revel/build.go
index 315ec70..6de71e9 100644
--- a/revel/build.go
+++ b/revel/build.go
@@ -1,9 +1,12 @@
+// Copyright (c) 2012-2016 The Revel Framework Authors, All rights reserved.
+// Revel Framework source code and usage is governed by a MIT style
+// license that can be found in the LICENSE file.
+
package main
import (
"fmt"
"os"
- "path"
"path/filepath"
"strings"
@@ -27,7 +30,7 @@ WARNING: The target path will be completely deleted, if it already exists!
For example:
- revel build github.com/revel/samples/chat /tmp/chat
+ revel build github.com/revel/examples/chat /tmp/chat
`,
}
@@ -41,7 +44,7 @@ func buildApp(args []string) {
return
}
- appImportPath, destPath, mode := args[0], args[1], "dev"
+ appImportPath, destPath, mode := args[0], args[1], DefaultRunMode
if len(args) >= 3 {
mode = args[2]
}
@@ -52,12 +55,17 @@ func buildApp(args []string) {
// First, verify that it is either already empty or looks like a previous
// build (to avoid clobbering anything)
- if exists(destPath) && !empty(destPath) && !exists(path.Join(destPath, "run.sh")) {
+ if exists(destPath) && !empty(destPath) && !exists(filepath.Join(destPath, "run.sh")) {
errorf("Abort: %s exists and does not look like a build directory.", destPath)
}
- os.RemoveAll(destPath)
- os.MkdirAll(destPath, 0777)
+ if err := os.RemoveAll(destPath); err != nil && !os.IsNotExist(err) {
+ revel.ERROR.Fatalln(err)
+ }
+
+ if err := os.MkdirAll(destPath, 0777); err != nil {
+ revel.ERROR.Fatalln(err)
+ }
app, reverr := harness.Build()
panicOnError(reverr, "Failed to build")
@@ -69,14 +77,14 @@ func buildApp(args []string) {
// - app
// Revel and the app are in a directory structure mirroring import path
- srcPath := path.Join(destPath, "src")
- destBinaryPath := path.Join(destPath, filepath.Base(app.BinaryPath))
- tmpRevelPath := path.Join(srcPath, filepath.FromSlash(revel.REVEL_IMPORT_PATH))
+ srcPath := filepath.Join(destPath, "src")
+ destBinaryPath := filepath.Join(destPath, filepath.Base(app.BinaryPath))
+ tmpRevelPath := filepath.Join(srcPath, filepath.FromSlash(revel.RevelImportPath))
mustCopyFile(destBinaryPath, app.BinaryPath)
mustChmod(destBinaryPath, 0755)
- mustCopyDir(path.Join(tmpRevelPath, "conf"), path.Join(revel.RevelPath, "conf"), nil)
- mustCopyDir(path.Join(tmpRevelPath, "templates"), path.Join(revel.RevelPath, "templates"), nil)
- mustCopyDir(path.Join(srcPath, filepath.FromSlash(appImportPath)), revel.BasePath, nil)
+ _ = mustCopyDir(filepath.Join(tmpRevelPath, "conf"), filepath.Join(revel.RevelPath, "conf"), nil)
+ _ = mustCopyDir(filepath.Join(tmpRevelPath, "templates"), filepath.Join(revel.RevelPath, "templates"), nil)
+ _ = mustCopyDir(filepath.Join(srcPath, filepath.FromSlash(appImportPath)), revel.BasePath, nil)
// Find all the modules used and copy them over.
config := revel.Config.Raw()
@@ -99,14 +107,14 @@ func buildApp(args []string) {
}
}
for importPath, fsPath := range modulePaths {
- mustCopyDir(path.Join(srcPath, importPath), fsPath, nil)
+ _ = mustCopyDir(filepath.Join(srcPath, importPath), fsPath, nil)
}
tmplData, runShPath := map[string]interface{}{
"BinName": filepath.Base(app.BinaryPath),
"ImportPath": appImportPath,
"Mode": mode,
- }, path.Join(destPath, "run.sh")
+ }, filepath.Join(destPath, "run.sh")
mustRenderTemplate(
runShPath,
diff --git a/revel/clean.go b/revel/clean.go
index 06b26f8..a05c58b 100644
--- a/revel/clean.go
+++ b/revel/clean.go
@@ -1,10 +1,14 @@
+// Copyright (c) 2012-2016 The Revel Framework Authors, All rights reserved.
+// Revel Framework source code and usage is governed by a MIT style
+// license that can be found in the LICENSE file.
+
package main
import (
"fmt"
"go/build"
"os"
- "path"
+ "path/filepath"
)
var cmdClean = &Command{
@@ -15,7 +19,7 @@ Clean the Revel web application named by the given import path.
For example:
- revel clean github.com/revel/samples/chat
+ revel clean github.com/revel/examples/chat
It removes the app/tmp and app/routes directory.
`,
@@ -38,8 +42,8 @@ func cleanApp(args []string) {
}
purgeDirs := []string{
- path.Join(appPkg.Dir, "app", "tmp"),
- path.Join(appPkg.Dir, "app", "routes"),
+ filepath.Join(appPkg.Dir, "app", "tmp"),
+ filepath.Join(appPkg.Dir, "app", "routes"),
}
for _, dir := range purgeDirs {
diff --git a/revel/new.go b/revel/new.go
index c874898..c893fbd 100644
--- a/revel/new.go
+++ b/revel/new.go
@@ -1,3 +1,7 @@
+// Copyright (c) 2012-2016 The Revel Framework Authors, All rights reserved.
+// Revel Framework source code and usage is governed by a MIT style
+// license that can be found in the LICENSE file.
+
package main
import (
@@ -46,6 +50,7 @@ var (
// revel related paths
revelPkg *build.Package
+ revelCmdPkg *build.Package
appPath string
appName string
basePath string
@@ -148,7 +153,7 @@ func setApplicationPath(args []string) {
errorf("Abort: Import path %s already exists.\n", importPath)
}
- revelPkg, err = build.Import(revel.REVEL_IMPORT_PATH, "", build.FindOnly)
+ revelPkg, err = build.Import(revel.RevelImportPath, "", build.FindOnly)
if err != nil {
errorf("Abort: Could not find Revel source code: %s\n", err)
}
@@ -190,7 +195,12 @@ func setSkeletonPath(args []string) {
} else {
// use the revel default
- skeletonPath = filepath.Join(revelPkg.Dir, "skeleton")
+ revelCmdPkg, err = build.Import(RevelCmdImportPath, "", build.FindOnly)
+ if err != nil {
+ errorf("Abort: Could not find Revel Cmd source code: %s\n", err)
+ }
+
+ skeletonPath = filepath.Join(revelCmdPkg.Dir, "revel", "skeleton")
}
}
@@ -199,7 +209,7 @@ func copyNewAppFiles() {
err = os.MkdirAll(appPath, 0777)
panicOnError(err, "Failed to create directory "+appPath)
- mustCopyDir(appPath, skeletonPath, map[string]interface{}{
+ _ = mustCopyDir(appPath, skeletonPath, map[string]interface{}{
// app.conf
"AppName": appName,
"BasePath": basePath,
diff --git a/revel/package.go b/revel/package.go
index 41ea785..31b5ff3 100644
--- a/revel/package.go
+++ b/revel/package.go
@@ -1,3 +1,7 @@
+// Copyright (c) 2012-2016 The Revel Framework Authors, All rights reserved.
+// Revel Framework source code and usage is governed by a MIT style
+// license that can be found in the LICENSE file.
+
package main
import (
@@ -23,7 +27,7 @@ Run mode defaults to "dev".
For example:
- revel package github.com/revel/samples/chat
+ revel package github.com/revel/examples/chat
`,
}
@@ -38,7 +42,7 @@ func packageApp(args []string) {
}
// Determine the run mode.
- mode := "dev"
+ mode := DefaultRunMode
if len(args) >= 2 {
mode = args[1]
}
@@ -48,7 +52,9 @@ func packageApp(args []string) {
// Remove the archive if it already exists.
destFile := filepath.Base(revel.BasePath) + ".tar.gz"
- os.Remove(destFile)
+ if err := os.Remove(destFile); err != nil && !os.IsNotExist(err) {
+ revel.ERROR.Fatal(err)
+ }
// Collect stuff in a temp directory.
tmpDir, err := ioutil.TempDir("", filepath.Base(revel.BasePath))
diff --git a/revel/rev.go b/revel/rev.go
index 6c234b8..2f8b263 100644
--- a/revel/rev.go
+++ b/revel/rev.go
@@ -1,3 +1,7 @@
+// Copyright (c) 2012-2016 The Revel Framework Authors, All rights reserved.
+// Revel Framework source code and usage is governed by a MIT style
+// license that can be found in the LICENSE file.
+
// The command line tool for running Revel apps.
package main
@@ -15,12 +19,21 @@ import (
"github.com/agtorre/gocolorize"
)
+const (
+ // RevelCmdImportPath Revel framework cmd tool import path
+ RevelCmdImportPath = "github.com/revel/cmd"
+
+ // DefaultRunMode for revel's application
+ DefaultRunMode = "dev"
+)
+
// Command structure cribbed from the genius organization of the "go" command.
type Command struct {
Run func(args []string)
UsageLine, Short, Long string
}
+// Name returns command name from usage line
func (cmd *Command) Name() string {
name := cmd.UsageLine
i := strings.Index(name, " ")
diff --git a/revel/run.go b/revel/run.go
index 7b477df..b206540 100644
--- a/revel/run.go
+++ b/revel/run.go
@@ -1,9 +1,15 @@
+// Copyright (c) 2012-2016 The Revel Framework Authors, All rights reserved.
+// Revel Framework source code and usage is governed by a MIT style
+// license that can be found in the LICENSE file.
+
package main
import (
+ "strconv"
+ "strings"
+
"github.com/revel/cmd/harness"
"github.com/revel/revel"
- "strconv"
)
var cmdRun = &Command{
@@ -14,7 +20,7 @@ Run the Revel web application named by the given import path.
For example, to run the chat room sample application:
- revel run github.com/revel/samples/chat dev
+ revel run github.com/revel/examples/chat dev
The run mode is used to select which set of app.conf configuration should
apply and may be used to determine logic in the application itself.
@@ -23,44 +29,94 @@ Run mode defaults to "dev".
You can set a port as an optional third parameter. For example:
- revel run github.com/revel/samples/chat prod 8080`,
+ revel run github.com/revel/examples/chat prod 8080`,
+}
+
+// RunArgs holds revel run parameters
+type RunArgs struct {
+ ImportPath string
+ Mode string
+ Port int
}
func init() {
cmdRun.Run = runApp
}
-func runApp(args []string) {
- if len(args) == 0 {
- errorf("No import path given.\nRun 'revel help run' for usage.\n")
+func parseRunArgs(args []string) *RunArgs {
+ inputArgs := RunArgs{
+ ImportPath: importPathFromCurrentDir(),
+ Mode: DefaultRunMode,
+ Port: revel.HTTPPort,
}
-
- // Determine the run mode.
- mode := "dev"
- if len(args) >= 2 {
- mode = args[1]
- }
-
- // Find and parse app.conf
- revel.Init(mode, args[0], "")
- revel.LoadMimeConfig()
-
- // Determine the override port, if any.
- port := revel.HttpPort
- if len(args) == 3 {
- var err error
- if port, err = strconv.Atoi(args[2]); err != nil {
+ switch len(args) {
+ case 3:
+ // Possibile combinations
+ // revel run [import-path] [run-mode] [port]
+ port, err := strconv.Atoi(args[2])
+ if err != nil {
errorf("Failed to parse port as integer: %s", args[2])
}
+ inputArgs.ImportPath = args[0]
+ inputArgs.Mode = args[1]
+ inputArgs.Port = port
+ case 2:
+ // Possibile combinations
+ // 1. revel run [import-path] [run-mode]
+ // 2. revel run [import-path] [port]
+ // 3. revel run [run-mode] [port]
+ if strings.Contains(args[0], "/") {
+ inputArgs.ImportPath = args[0]
+ if port, err := strconv.Atoi(args[1]); err == nil {
+ inputArgs.Port = port
+ } else {
+ inputArgs.Mode = args[1]
+ }
+ } else {
+ port, err := strconv.Atoi(args[1])
+ if err != nil {
+ errorf("Failed to parse port as integer: %s", args[1])
+ }
+ inputArgs.Mode = args[0]
+ inputArgs.Port = port
+ }
+ case 1:
+ // Possibile combinations
+ // 1. revel run [import-path]
+ // 2. revel run [port]
+ // 3. revel run [run-mode]
+ if strings.Contains(args[0], "/") ||
+ strings.Contains(inputArgs.ImportPath, "..") {
+ inputArgs.ImportPath = args[0]
+ } else if port, err := strconv.Atoi(args[0]); err == nil {
+ inputArgs.Port = port
+ } else {
+ inputArgs.Mode = args[0]
+ }
}
- revel.INFO.Printf("Running %s (%s) in %s mode\n", revel.AppName, revel.ImportPath, mode)
+ return &inputArgs
+}
+
+func runApp(args []string) {
+ runArgs := parseRunArgs(args)
+
+ // Find and parse app.conf
+ revel.Init(runArgs.Mode, runArgs.ImportPath, "")
+ revel.LoadMimeConfig()
+
+ // fallback to default port
+ if runArgs.Port == 0 {
+ runArgs.Port = revel.HTTPPort
+ }
+
+ 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.TRACE.Println("Running in watched mode.")
- revel.HttpPort = port
+ revel.HTTPPort = runArgs.Port
harness.NewHarness().Run() // Never returns.
}
@@ -70,6 +126,6 @@ func runApp(args []string) {
if err != nil {
errorf("Failed to build app: %s", err)
}
- app.Port = port
+ app.Port = runArgs.Port
app.Cmd().Run()
}
diff --git a/revel/skeleton/.gitignore b/revel/skeleton/.gitignore
new file mode 100644
index 0000000..dae67d0
--- /dev/null
+++ b/revel/skeleton/.gitignore
@@ -0,0 +1,3 @@
+test-results/
+tmp/
+routes/
diff --git a/revel/skeleton/README.md b/revel/skeleton/README.md
new file mode 100644
index 0000000..d418163
--- /dev/null
+++ b/revel/skeleton/README.md
@@ -0,0 +1,43 @@
+# Welcome to Revel
+
+A high-productivity web framework for the [Go language](http://www.golang.org/).
+
+
+### Start the web server:
+
+ revel run myapp
+
+### Go to http://localhost:9000/ and you'll see:
+
+ "It works"
+
+## Code Layout
+
+The directory structure of a generated Revel application:
+
+ conf/ Configuration directory
+ app.conf Main app configuration file
+ routes Routes definition file
+
+ app/ App sources
+ init.go Interceptor registration
+ controllers/ App controllers go here
+ views/ Templates directory
+
+ messages/ Message files
+
+ public/ Public static assets
+ css/ CSS files
+ js/ Javascript files
+ images/ Image files
+
+ tests/ Test suites
+
+
+## Help
+
+* The [Getting Started with Revel](http://revel.github.io/tutorial/gettingstarted.html).
+* The [Revel guides](http://revel.github.io/manual/index.html).
+* The [Revel sample apps](http://revel.github.io/examples/index.html).
+* The [API documentation](https://godoc.org/github.com/revel/revel).
+
diff --git a/revel/skeleton/app/controllers/app.go b/revel/skeleton/app/controllers/app.go
new file mode 100644
index 0000000..1e94062
--- /dev/null
+++ b/revel/skeleton/app/controllers/app.go
@@ -0,0 +1,13 @@
+package controllers
+
+import (
+ "github.com/revel/revel"
+)
+
+type App struct {
+ *revel.Controller
+}
+
+func (c App) Index() revel.Result {
+ return c.Render()
+}
diff --git a/revel/skeleton/app/init.go b/revel/skeleton/app/init.go
new file mode 100644
index 0000000..74767e9
--- /dev/null
+++ b/revel/skeleton/app/init.go
@@ -0,0 +1,59 @@
+package app
+
+import (
+ "github.com/revel/revel"
+)
+
+var (
+ // AppVersion revel app version (ldflags)
+ AppVersion string
+
+ // BuildTime revel app build-time (ldflags)
+ BuildTime string
+)
+
+func init() {
+ // Filters is the default set of global filters.
+ revel.Filters = []revel.Filter{
+ revel.PanicFilter, // Recover from panics and display an error page instead.
+ revel.RouterFilter, // Use the routing table to select the right Action
+ revel.FilterConfiguringFilter, // A hook for adding or removing per-Action filters.
+ revel.ParamsFilter, // Parse parameters into Controller.Params.
+ revel.SessionFilter, // Restore and write the session cookie.
+ revel.FlashFilter, // Restore and write the flash cookie.
+ revel.ValidationFilter, // Restore kept validation errors and save new ones from cookie.
+ revel.I18nFilter, // Resolve the requested language
+ HeaderFilter, // Add some security based headers
+ revel.InterceptorFilter, // Run interceptors around the action.
+ revel.CompressFilter, // Compress the result.
+ revel.ActionInvoker, // Invoke the action.
+ }
+
+
+ // register startup functions with OnAppStart
+ // revel.DevMode and revel.RunMode only work inside of OnAppStart. See Example Startup Script
+ // ( order dependent )
+ // revel.OnAppStart(ExampleStartupScript)
+ // revel.OnAppStart(InitDB)
+ // revel.OnAppStart(FillCache)
+}
+
+// HeaderFilter adds common security headers
+// 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")
+
+ fc[0](c, fc[1:]) // Execute the next filter stage.
+}
+
+//func ExampleStartupScript() {
+// // revel.DevMod and revel.RunMode work here
+// // Use this script to check for dev mode and set dev/prod startup scripts here!
+// if revel.DevMode == true {
+// // Dev mode
+// }
+//}
diff --git a/revel/skeleton/app/views/App/Index.html b/revel/skeleton/app/views/App/Index.html
new file mode 100644
index 0000000..abfa102
--- /dev/null
+++ b/revel/skeleton/app/views/App/Index.html
@@ -0,0 +1,21 @@
+{{set . "title" "Home"}}
+{{template "header.html" .}}
+
+It works!
+
+
+ {{.Description}} +
+ {{end}} +{{end}} + + diff --git a/revel/skeleton/app/views/errors/500.html b/revel/skeleton/app/views/errors/500.html new file mode 100644 index 0000000..0cef4de --- /dev/null +++ b/revel/skeleton/app/views/errors/500.html @@ -0,0 +1,16 @@ + + + ++ This exception has been logged. +
+ {{end}} + + diff --git a/revel/skeleton/app/views/flash.html b/revel/skeleton/app/views/flash.html new file mode 100644 index 0000000..1c764c0 --- /dev/null +++ b/revel/skeleton/app/views/flash.html @@ -0,0 +1,18 @@ +{{if .flash.success}} +