Skip to content

Commit

Permalink
Merge pull request #134 from notzippy/develop
Browse files Browse the repository at this point in the history
Split main file
  • Loading branch information
notzippy authored Sep 19, 2018
2 parents c87d53e + 17459d1 commit b138e35
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 45 deletions.
89 changes: 59 additions & 30 deletions harness/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func (c ByString) Less(i, j int) bool { return c[i].String() < c[j].String() }
// 2. Run the appropriate "go build" command.
// Requires that revel.Init has been called previously.
// Returns the path to the built binary, and an error if there was a problem building it.
func Build(c *model.CommandConfig, paths *model.RevelContainer, buildFlags ...string) (app *App, compileError *utils.Error) {
func Build(c *model.CommandConfig, paths *model.RevelContainer) (app *App, compileError *utils.Error) {
// First, clear the generated files (to avoid them messing with ProcessSource).
cleanSource(paths, "tmp", "routes")

Expand All @@ -56,12 +56,20 @@ func Build(c *model.CommandConfig, paths *model.RevelContainer, buildFlags ...st

// Generate two source files.
templateArgs := map[string]interface{}{
"ImportPath": paths.ImportPath,
"Controllers": controllers,
"ValidationKeys": sourceInfo.ValidationKeys,
"ImportPaths": calcImportAliases(sourceInfo),
"TestSuites": sourceInfo.TestSuites(),
}

// Generate code for the main, run and routes file.
// The run file allows external programs to launch and run the application
// without being the main thread
cleanSource(paths, "tmp", "routes")

genSource(paths, "tmp", "main.go", RevelMainTemplate, templateArgs)
genSource(paths, filepath.Join("tmp", "run"), "run.go", RevelRunTemplate, templateArgs)
genSource(paths, "routes", "routes.go", RevelRoutesTemplate, templateArgs)

// Read build config.
Expand Down Expand Up @@ -126,14 +134,14 @@ func Build(c *model.CommandConfig, paths *model.RevelContainer, buildFlags ...st
}

gotten := make(map[string]struct{})
contains := func (s []string, e string) bool {
for _, a := range s {
if a == e {
return true
}
contains := func(s []string, e string) bool {
for _, a := range s {
if a == e {
return true
}
return false
}
return false
}

for {
appVersion := getAppVersion(paths)
Expand All @@ -144,32 +152,31 @@ func Build(c *model.CommandConfig, paths *model.RevelContainer, buildFlags ...st

// Append any build flags specified, they will override existing flags
flags := []string{}
if len(c.BuildFlags)==0 {
if len(c.BuildFlags) == 0 {
flags = []string{
"build",
"-i",
"-ldflags", versionLinkerFlags,
"-tags", buildTags,
"-o", binName}
} else {
if !contains(c.BuildFlags,"build") {
if !contains(c.BuildFlags, "build") {
flags = []string{"build"}
}
flags = append(flags,c.BuildFlags...)
flags = append(flags, c.BuildFlags...)
if !contains(flags, "-ldflags") {
flags = append(flags,"-ldflags", versionLinkerFlags)
flags = append(flags, "-ldflags", versionLinkerFlags)
}
if !contains(flags, "-tags") {
flags = append(flags,"-tags", buildTags)
flags = append(flags, "-tags", buildTags)
}
if !contains(flags, "-o") {
flags = append(flags,"-o", binName)
flags = append(flags, "-o", binName)
}
}


// Add in build flags
flags = append(flags, buildFlags...)
flags = append(flags, c.BuildFlags...)

// This is Go main path
gopath := c.GoPath
Expand Down Expand Up @@ -236,7 +243,7 @@ func Build(c *model.CommandConfig, paths *model.RevelContainer, buildFlags ...st
getOutput, err := getCmd.CombinedOutput()
if err != nil {
utils.Logger.Error("Build failed", "message", stOutput)
utils.Logger.Error("Failed to fetch the output", string(getOutput))
utils.Logger.Error("Failed to fetch the output", "getOutput", string(getOutput))
return nil, newCompileError(paths, output)
}
}
Expand Down Expand Up @@ -329,7 +336,6 @@ func cleanDir(paths *model.RevelContainer, dir string) {
// genSource renders the given template to produce source code, which it writes
// to the given directory and file.
func genSource(paths *model.RevelContainer, dir, filename, templateSource string, args map[string]interface{}) {
cleanSource(paths, dir)

err := utils.MustGenerateTemplate(filepath.Join(paths.AppPath, dir, filename), templateSource, args)
if err != nil {
Expand Down Expand Up @@ -469,33 +475,32 @@ func newCompileError(paths *model.RevelContainer, output []byte) *utils.Error {
}

// RevelMainTemplate template for app/tmp/main.go
const RevelMainTemplate = `// GENERATED CODE - DO NOT EDIT
// This file is the main file for Revel.
const RevelRunTemplate = `// GENERATED CODE - DO NOT EDIT
// This file is the run file for Revel.
// It registers all the controllers and provides details for the Revel server engine to
// properly inject parameters directly into the action endpoints.
package main
package run
import (
"flag"
"reflect"
"github.com/revel/revel"{{range $k, $v := $.ImportPaths}}
{{$v}} "{{$k}}"{{end}}
"github.com/revel/revel/testing"
)
var (
runMode *string = flag.String("runMode", "", "Run mode.")
port *int = flag.Int("port", 0, "By default, read from app.conf")
importPath *string = flag.String("importPath", "", "Go Import Path for the app.")
srcPath *string = flag.String("srcPath", "", "Path to the source root.")
// So compiler won't complain if the generated code doesn't reference reflect package...
_ = reflect.Invalid
)
func main() {
flag.Parse()
revel.Init(*runMode, *importPath, *srcPath)
// Register and run the application
func Run(port int) {
Register()
revel.Run(port)
}
// Register all the controllers
func Register() {
revel.AppLog.Info("Running revel server")
{{range $i, $c := .Controllers}}
revel.RegisterController((*{{index $.ImportPaths .ImportPath}}.{{.StructName}})(nil),
Expand All @@ -522,8 +527,32 @@ func main() {
testing.TestSuites = []interface{}{ {{range .TestSuites}}
(*{{index $.ImportPaths .ImportPath}}.{{.StructName}})(nil),{{end}}
}
}
`
const RevelMainTemplate = `// GENERATED CODE - DO NOT EDIT
// This file is the main file for Revel.
// It registers all the controllers and provides details for the Revel server engine to
// properly inject parameters directly into the action endpoints.
package main
import (
"flag"
"{{.ImportPath}}/app/tmp/run"
"github.com/revel/revel"
)
revel.Run(*port)
var (
runMode *string = flag.String("runMode", "", "Run mode.")
port *int = flag.Int("port", 0, "By default, read from app.conf")
importPath *string = flag.String("importPath", "", "Go Import Path for the app.")
srcPath *string = flag.String("srcPath", "", "Path to the source root.")
)
func main() {
flag.Parse()
revel.Init(*runMode, *importPath, *srcPath)
run.Run(*port)
}
`

Expand Down
20 changes: 12 additions & 8 deletions model/source_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ package model
import (
"github.com/revel/cmd/utils"
"path/filepath"
"unicode"
"strings"
"unicode"
)

type SourceInfo struct {
Expand Down Expand Up @@ -41,9 +41,9 @@ func (s *SourceInfo) TypesThatEmbed(targetType, packageFilter string) (filtered
processed []string
)
for len(nodeQueue) > 0 {
controllerSimpleName := nodeQueue[0]
typeSimpleName := nodeQueue[0]
nodeQueue = nodeQueue[1:]
processed = append(processed, controllerSimpleName)
processed = append(processed, typeSimpleName)

// Look through all known structs.
for _, spec := range s.StructSpecs {
Expand All @@ -58,14 +58,15 @@ func (s *SourceInfo) TypesThatEmbed(targetType, packageFilter string) (filtered

// If so, add this type's simple name to the nodeQueue, and its spec to
// the filtered list.
if controllerSimpleName == embeddedType.String() {
if typeSimpleName == embeddedType.String() {
nodeQueue = append(nodeQueue, spec.String())
filtered = append(filtered, spec)
break
}
}
}
}

// Strip out any specifications that contain a lower case
for exit := false; !exit; exit = true {
for i, filteredItem := range filtered {
Expand All @@ -84,25 +85,28 @@ func (s *SourceInfo) TypesThatEmbed(targetType, packageFilter string) (filtered
for _, spec := range s.StructSpecs {
if spec.PackageName == packageFilter {
found := false
unfoundNames := ""
for _, filteredItem := range filtered {
if filteredItem.StructName == spec.StructName {
found = true
break
} else {
unfoundNames += filteredItem.StructName + ","
}
}

// Report non controller structures in controller folder.
if !found && !strings.HasPrefix(spec.StructName, "Test") {
utils.Logger.Warn("Type found in package: " + packageFilter +
", but did not embed from: " + filepath.Base(targetType),
"name", spec.StructName, "path", spec.ImportPath)
utils.Logger.Warn("Type found in package: "+packageFilter+
", but did not embed from: "+filepath.Base(targetType),
"name", spec.StructName, "importpath", spec.ImportPath, "foundstructures", unfoundNames)
}
}
}
return
}

// ControllerSpecs returns the all the contollers that embeds
// ControllerSpecs returns the all the controllers that embeds
// `revel.Controller`
func (s *SourceInfo) ControllerSpecs() []*TypeInfo {
if s.controllerSpecs == nil {
Expand Down
18 changes: 12 additions & 6 deletions parser/reflect.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,8 @@ func ProcessSource(paths *model.RevelContainer) (*model.SourceInfo, *utils.Error
// Skip "main" packages.
delete(pkgs, "main")

// If there is no code in this directory, skip it.
if len(pkgs) == 0 {
return nil
}

// Ignore packages that end with _test
// These cannot be included in source code that is not generated specifically as a test
for i := range pkgs {
if len(i) > 6 {
if string(i[len(i)-5:]) == "_test" {
Expand All @@ -108,6 +104,11 @@ func ProcessSource(paths *model.RevelContainer) (*model.SourceInfo, *utils.Error
}
}

// If there is no code in this directory, skip it.
if len(pkgs) == 0 {
return nil
}

// There should be only one package in this directory.
if len(pkgs) > 1 {
for i := range pkgs {
Expand All @@ -116,12 +117,17 @@ func ProcessSource(paths *model.RevelContainer) (*model.SourceInfo, *utils.Error
utils.Logger.Fatal("Most unexpected! Multiple packages in a single directory:", "packages", pkgs)
}


var pkg *ast.Package
for _, v := range pkgs {
pkg = v
}

srcInfo = appendSourceInfo(srcInfo, processPackage(fset, pkgImportPath, path, pkg))
if pkg != nil {
srcInfo = appendSourceInfo(srcInfo, processPackage(fset, pkgImportPath, path, pkg))
} else {
utils.Logger.Info("Ignoring package, because it contained no packages", "path", path)
}
return nil
})
}
Expand Down
1 change: 1 addition & 0 deletions revel/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ func runApp(c *model.CommandConfig) {
if c.Run.Mode == "" {
c.Run.Mode = "dev"
}
c.ImportPath = c.Run.ImportPath

revel_path := model.NewRevelPaths(c.Run.Mode, c.Run.ImportPath, "", model.DoNothingRevelCallback)
if c.Run.Port != "" {
Expand Down
1 change: 1 addition & 0 deletions revel/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ func testApp(c *model.CommandConfig) {
if c.Test.Mode != "" {
mode = c.Test.Mode
}
c.ImportPath = c.Test.ImportPath

// Find and parse app.conf
revel_path := model.NewRevelPaths(mode, c.Test.ImportPath, "", model.DoNothingRevelCallback)
Expand Down
2 changes: 1 addition & 1 deletion utils/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func MustGenerateTemplate(filename, templateSource string, args map[string]inter
sourceCode := b.String()
filePath := filepath.Dir(filename)
if !DirExists(filePath) {
err = os.Mkdir(filePath, 0777)
err = os.MkdirAll(filePath, 0777)
if err != nil && !os.IsExist(err) {
Logger.Fatal("Failed to make directory","dir", filePath, "error", err)
}
Expand Down

0 comments on commit b138e35

Please sign in to comment.