diff --git a/.codebeatsettings b/.codebeatsettings new file mode 100644 index 00000000..f921ed82 --- /dev/null +++ b/.codebeatsettings @@ -0,0 +1,11 @@ +{ + "GOLANG": { + "ABC":[15, 25, 50, 70], + "BLOCK_NESTING":[5, 6, 7, 8], + "CYCLO":[20, 30, 45, 60], + "TOO_MANY_IVARS": [15, 18, 20, 25], + "TOO_MANY_FUNCTIONS": [20, 30, 40, 50], + "TOTAL_COMPLEXITY": [150, 250, 400, 500], + "LOC": [50, 75, 90, 120] + } +} \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 05fca17e..87fcf178 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,11 @@ language: go go: - - 1.8 - - 1.9 - - 1.10 - - 1.11 - - tip + - "1.8" + - "1.9" + - "1.10" + - "1.11" + - "tip" os: - linux @@ -40,13 +40,13 @@ install: - 'if [[ "$TRAVIS_BRANCH" == "master" ]]; then export REVEL_BRANCH="master"; fi' - 'echo "Travis branch: $TRAVIS_BRANCH, Revel dependency branch: $REVEL_BRANCH"' - git clone -b $REVEL_BRANCH git://github.com/revel/modules ../modules/ - - git clone -b $REVEL_BRANCH git://github.com/revel/cmd ../cmd/ + - git clone -b $REVEL_BRANCH git://github.com/revel/revel ../revel/ - git clone -b $REVEL_BRANCH git://github.com/revel/config ../config/ - git clone -b $REVEL_BRANCH git://github.com/revel/cron ../cron/ - git clone -b $REVEL_BRANCH git://github.com/revel/examples ../examples/ - go get -v github.com/revel/revel/... - go get -v github.com/revel/cmd/revel - - go get -v github.com/golang/deps + - go get -u github.com/golang/dep/cmd/dep script: - go test -v github.com/revel/cmd/... diff --git a/README.md b/README.md index fad58f3a..ae8e1718 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,9 @@ # Revel command line tools +[![Build Status](https://secure.travis-ci.org/revel/cmd.svg?branch=master)](http://travis-ci.org/revel/cmd) +[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) +[![Go Report Card](https://goreportcard.com/badge/github.com/revel/cmd)](https://goreportcard.com/report/github.com/revel/cmd) + Provides the `revel` command, used to create and run Revel apps. - More info at http://revel.github.io/manual/tool.html @@ -7,5 +11,13 @@ Provides the `revel` command, used to create and run Revel apps. Install ------------ ```bash -go get github.com/revel/cmd/revel +go get -u github.com/revel/cmd/revel +``` + +New Application +------------- + +Create a new application +```commandline +revel new my/app ``` diff --git a/harness/harness.go b/harness/harness.go index af3b26f6..63f8d971 100644 --- a/harness/harness.go +++ b/harness/harness.go @@ -63,6 +63,9 @@ func (h *Harness) renderError(iw http.ResponseWriter, ir *http.Request, err erro // 1) Application/views/errors // 2) revel_home/views/errors // 3) views/errors + if err==nil { + utils.Logger.Panic("Caller passed in a nil error") + } templateSet := template.New("__root__") seekViewOnPath:=func(view string) (path string) { path = filepath.Join(h.paths.ViewsPath, "errors", view) @@ -82,7 +85,8 @@ func (h *Harness) renderError(iw http.ResponseWriter, ir *http.Request, err erro } target := []string{seekViewOnPath("500.html"),seekViewOnPath("500-dev.html")} if !utils.Exists(target[0]) { - fmt.Fprint(iw, "An error occurred %s", err) + fmt.Fprintf(iw, "Target template not found not found %s
\n", target[0]) + fmt.Fprintf(iw, "An error ocurred %s", err.Error()) return } var revelError *utils.Error diff --git a/model/revel_container.go b/model/revel_container.go index 6cef6265..88583fa3 100644 --- a/model/revel_container.go +++ b/model/revel_container.go @@ -146,7 +146,7 @@ func NewRevelPaths(mode, importPath, srcPath string, callback RevelCallback) (rp mode = config.DefaultSection } if !rp.Config.HasSection(mode) { - utils.Logger.Fatal("app.conf: No mode found:","run-more", mode) + utils.Logger.Fatal("app.conf: No mode found:","run-mode", mode) } rp.Config.SetSection(mode) diff --git a/model/type_expr.go b/model/type_expr.go index 6387b7cd..9f8d2b9d 100644 --- a/model/type_expr.go +++ b/model/type_expr.go @@ -1,11 +1,9 @@ package model - - // TypeExpr provides a type name that may be rewritten to use a package name. import ( - "go/ast" "fmt" + "go/ast" ) type TypeExpr struct { @@ -15,18 +13,13 @@ type TypeExpr struct { Valid bool } -// TypeName returns the fully-qualified type name for this expression. -// The caller may optionally specify a package name to override the default. -func (e TypeExpr) TypeName(pkgOverride string) string { - pkgName := FirstNonEmpty(pkgOverride, e.PkgName) - if pkgName == "" { - return e.Expr - } - return e.Expr[:e.pkgIndex] + pkgName + "." + e.Expr[e.pkgIndex:] +// Returns a new type from the data +func NewTypeExprFromData(expr, pkgName string, pkgIndex int, valid bool) TypeExpr { + return TypeExpr{expr, pkgName, pkgIndex, valid} } // NewTypeExpr returns the syntactic expression for referencing this type in Go. -func NewTypeExpr(pkgName string, expr ast.Expr) TypeExpr { +func NewTypeExprFromAst(pkgName string, expr ast.Expr) TypeExpr { error := "" switch t := expr.(type) { case *ast.Ident: @@ -35,28 +28,38 @@ func NewTypeExpr(pkgName string, expr ast.Expr) TypeExpr { } return TypeExpr{t.Name, pkgName, 0, true} case *ast.SelectorExpr: - e := NewTypeExpr(pkgName, t.X) - return TypeExpr{t.Sel.Name, e.Expr, 0, e.Valid} + e := NewTypeExprFromAst(pkgName, t.X) + return NewTypeExprFromData(t.Sel.Name, e.Expr, 0, e.Valid) case *ast.StarExpr: - e := NewTypeExpr(pkgName, t.X) - return TypeExpr{"*" + e.Expr, e.PkgName, e.pkgIndex + 1, e.Valid} + e := NewTypeExprFromAst(pkgName, t.X) + return NewTypeExprFromData("*"+e.Expr, e.PkgName, e.pkgIndex+1, e.Valid) case *ast.ArrayType: - e := NewTypeExpr(pkgName, t.Elt) - return TypeExpr{"[]" + e.Expr, e.PkgName, e.pkgIndex + 2, e.Valid} + e := NewTypeExprFromAst(pkgName, t.Elt) + return NewTypeExprFromData("[]"+e.Expr, e.PkgName, e.pkgIndex+2, e.Valid) case *ast.MapType: if identKey, ok := t.Key.(*ast.Ident); ok && IsBuiltinType(identKey.Name) { - e := NewTypeExpr(pkgName, t.Value) - return TypeExpr{"map[" + identKey.Name + "]" + e.Expr, e.PkgName, e.pkgIndex + len("map["+identKey.Name+"]"), e.Valid} + e := NewTypeExprFromAst(pkgName, t.Value) + return NewTypeExprFromData("map["+identKey.Name+"]"+e.Expr, e.PkgName, e.pkgIndex+len("map["+identKey.Name+"]"), e.Valid) } error = fmt.Sprintf("Failed to generate name for Map field :%v. Make sure the field name is valid.", t.Key) case *ast.Ellipsis: - e := NewTypeExpr(pkgName, t.Elt) - return TypeExpr{"[]" + e.Expr, e.PkgName, e.pkgIndex + 2, e.Valid} + e := NewTypeExprFromAst(pkgName, t.Elt) + return NewTypeExprFromData("[]"+e.Expr, e.PkgName, e.pkgIndex+2, e.Valid) default: error = fmt.Sprintf("Failed to generate name for field: %v Package: %v. Make sure the field name is valid.", expr, pkgName) } - return TypeExpr{Valid: false, Expr:error} + return NewTypeExprFromData(error, "", 0, false) +} + +// TypeName returns the fully-qualified type name for this expression. +// The caller may optionally specify a package name to override the default. +func (e TypeExpr) TypeName(pkgOverride string) string { + pkgName := FirstNonEmpty(pkgOverride, e.PkgName) + if pkgName == "" { + return e.Expr + } + return e.Expr[:e.pkgIndex] + pkgName + "." + e.Expr[e.pkgIndex:] } var builtInTypes = map[string]struct{}{ @@ -97,4 +100,3 @@ func FirstNonEmpty(strs ...string) string { } return "" } - diff --git a/parser/reflect.go b/parser/reflect.go index 4e00be56..c4a3a134 100644 --- a/parser/reflect.go +++ b/parser/reflect.go @@ -181,7 +181,7 @@ func processPackage(fset *token.FileSet, pkgImportPath, pkgPath string, pkg *ast // If this is a func... (ignore nil for external (non-Go) function) if funcDecl, ok := decl.(*ast.FuncDecl); ok && funcDecl.Body != nil { // Scan it for validation calls - lineKeys := getValidationKeys(fname, fset, funcDecl, imports) + lineKeys := GetValidationKeys(fname, fset, funcDecl, imports) if len(lineKeys) > 0 { validationKeys[pkgImportPath+"."+getFuncName(funcDecl)] = lineKeys } @@ -392,7 +392,7 @@ func appendAction(fset *token.FileSet, mm methodMap, decl ast.Decl, pkgImportPat for _, field := range funcDecl.Type.Params.List { for _, name := range field.Names { var importPath string - typeExpr := model.NewTypeExpr(pkgName, field.Type) + typeExpr := model.NewTypeExprFromAst(pkgName, field.Type) if !typeExpr.Valid { utils.Logger.Warn("Warn: Didn't understand argument '%s' of action %s. Ignoring.", name, getFuncName(funcDecl)) return // We didn't understand one of the args. Ignore this action. @@ -478,7 +478,7 @@ func appendAction(fset *token.FileSet, mm methodMap, decl ast.Decl, pkgImportPat // // The end result is that we can set the default validation key for each call to // be the same as the local variable. -func getValidationKeys(fname string, fset *token.FileSet, funcDecl *ast.FuncDecl, imports map[string]string) map[int]string { +func GetValidationKeys(fname string, fset *token.FileSet, funcDecl *ast.FuncDecl, imports map[string]string) map[int]string { var ( lineKeys = make(map[int]string) @@ -534,7 +534,7 @@ func getValidationKeys(fname string, fset *token.FileSet, funcDecl *ast.FuncDecl return true } - if typeExpr := model.NewTypeExpr("", key); typeExpr.Valid { + if typeExpr := model.NewTypeExprFromAst("", key); typeExpr.Valid { lineKeys[fset.Position(callExpr.End()).Line] = typeExpr.TypeName("") } else { utils.Logger.Error("Error: Failed to generate key for field validation. Make sure the field name is valid.", "file", fname, diff --git a/parser/reflect_test.go b/parser/reflect_test.go index fed932a4..ad8038ef 100644 --- a/parser/reflect_test.go +++ b/parser/reflect_test.go @@ -2,7 +2,7 @@ // Revel Framework source code and usage is governed by a MIT style // license that can be found in the LICENSE file. -package parser +package parser_test import ( "go/ast" @@ -12,8 +12,8 @@ import ( "strings" "testing" - "github.com/revel/revel" "github.com/revel/cmd/model" + revelParser "github.com/revel/cmd/parser" ) const validationKeysSource = ` @@ -81,7 +81,7 @@ func TestGetValidationKeys(t *testing.T) { } for i, decl := range file.Decls { - lineKeys := getValidationKeys("test", fset, decl.(*ast.FuncDecl), map[string]string{"revel": revel.RevelImportPath}) + lineKeys := revelParser.GetValidationKeys("test", fset, decl.(*ast.FuncDecl), map[string]string{"revel": model.RevelImportPath}) for k, v := range expectedValidationKeys[i] { if lineKeys[k] != v { t.Errorf("Not found - %d: %v - Actual Map: %v", k, v, lineKeys) @@ -95,20 +95,20 @@ func TestGetValidationKeys(t *testing.T) { } var TypeExprs = map[string]model.TypeExpr{ - "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}, - "map[int]MyType": {"map[int]MyType", "pkg", 8, true}, - "map[int]*MyType": {"map[int]*MyType", "pkg", 9, true}, + "int": model.NewTypeExprFromData("int", "", 0, true), + "*int": model.NewTypeExprFromData("*int", "", 1, true), + "[]int": model.NewTypeExprFromData("[]int", "", 2, true), + "...int": model.NewTypeExprFromData("[]int", "", 2, true), + "[]*int": model.NewTypeExprFromData("[]*int", "", 3, true), + "...*int": model.NewTypeExprFromData("[]*int", "", 3, true), + "MyType": model.NewTypeExprFromData("MyType", "pkg", 0, true), + "*MyType": model.NewTypeExprFromData("*MyType", "pkg", 1, true), + "[]MyType": model.NewTypeExprFromData("[]MyType", "pkg", 2, true), + "...MyType": model.NewTypeExprFromData("[]MyType", "pkg", 2, true), + "[]*MyType": model.NewTypeExprFromData("[]*MyType", "pkg", 3, true), + "...*MyType": model.NewTypeExprFromData("[]*MyType", "pkg", 3, true), + "map[int]MyType": model.NewTypeExprFromData("map[int]MyType", "pkg", 8, true), + "map[int]*MyType": model.NewTypeExprFromData("map[int]*MyType", "pkg", 9, true), } func TestTypeExpr(t *testing.T) { @@ -137,60 +137,9 @@ func TestTypeExpr(t *testing.T) { expr = &ast.Ellipsis{Ellipsis: expr.Pos(), Elt: expr} } - actual := model.NewTypeExpr("pkg", expr) + actual := model.NewTypeExprFromAst("pkg", expr) if !reflect.DeepEqual(expected, actual) { t.Error("Fail, expected", expected, ", was", actual) } } } - -func TestProcessBookingSource(t *testing.T) { - 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) - } - - controllerPackage := "github.com/revel/examples/booking/app/controllers" - expectedControllerSpecs := []*model.TypeInfo{ - {"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", - len(expectedControllerSpecs), len(sourceInfo.ControllerSpecs())) - } - -NEXT_TEST: - for _, expected := range expectedControllerSpecs { - for _, actual := range sourceInfo.ControllerSpecs() { - if actual.StructName == expected.StructName { - if actual.ImportPath != expected.ImportPath { - t.Errorf("%s expected to have import path %s, actual %s", - actual.StructName, expected.ImportPath, actual.ImportPath) - } - if actual.PackageName != expected.PackageName { - t.Errorf("%s expected to have package name %s, actual %s", - actual.StructName, expected.PackageName, actual.PackageName) - } - continue NEXT_TEST - } - } - t.Errorf("Expected to find controller %s, but did not. Actuals: %s", - expected.StructName, sourceInfo.ControllerSpecs()) - } -} - -func BenchmarkProcessBookingSource(b *testing.B) { - revel.Init("", "github.com/revel/examples/booking", "") - revel.GetRootLogHandler().Disable() - b.ResetTimer() - - for i := 0; i < b.N; i++ { - _, err := ProcessSource(revel.CodePaths) - if err != nil { - b.Error("Unexpected error:", err) - } - } -} diff --git a/revel/build.go b/revel/build.go index 5b0b3d88..589f0984 100644 --- a/revel/build.go +++ b/revel/build.go @@ -45,7 +45,7 @@ func updateBuildConfig(c *model.CommandConfig, args []string) bool { c.Build.ImportPath = args[0] c.Build.TargetPath = args[1] if len(args) > 2 { - c.Build.Mode = args[1] + c.Build.Mode = args[2] } return true } diff --git a/revel/package.go b/revel/package.go index 96071be5..f5a0a7ca 100644 --- a/revel/package.go +++ b/revel/package.go @@ -44,9 +44,9 @@ func updatePackageConfig(c *model.CommandConfig, args []string) bool { fmt.Fprintf(os.Stderr, cmdPackage.Long) return false } - c.New.ImportPath = args[0] + c.Package.ImportPath = args[0] if len(args)>1 { - c.New.Skeleton = args[1] + c.Package.Mode = args[1] } return true