Skip to content

Commit

Permalink
Merge pull request #76 from revel/develop
Browse files Browse the repository at this point in the history
v0.14.0
  • Loading branch information
brendensoares authored Mar 24, 2017
2 parents 62fc677 + 6ec4929 commit da79330
Show file tree
Hide file tree
Showing 37 changed files with 1,041 additions and 259 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.idea/
*.iml

17 changes: 13 additions & 4 deletions harness/app.go
Original file line number Diff line number Diff line change
@@ -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)
Expand All @@ -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
Expand All @@ -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),
Expand Down Expand Up @@ -69,6 +76,8 @@ func (cmd AppCmd) Start() error {
case <-listeningWriter.notifyReady:
return nil
}

// TODO remove this unreachable code and document it
panic("Impossible")
}

Expand All @@ -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)
Expand All @@ -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
Expand Down
54 changes: 37 additions & 17 deletions harness/build.go
Original file line number Diff line number Diff line change
@@ -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 (
Expand All @@ -12,6 +16,7 @@ import (
"strconv"
"strings"
"text/template"
"time"

"github.com/revel/revel"
)
Expand Down Expand Up @@ -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", "")
Expand Down Expand Up @@ -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",
Expand All @@ -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...)
Expand Down Expand Up @@ -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
}
Expand All @@ -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 ""
Expand Down Expand Up @@ -177,22 +189,25 @@ 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) {
revel.ERROR.Println("Failed to clean dir:", err)
}
} 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 {
Expand All @@ -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)
}
}
Expand Down Expand Up @@ -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 (
Expand Down Expand Up @@ -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"
Expand All @@ -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}}
Expand Down
42 changes: 28 additions & 14 deletions harness/harness.go
Original file line number Diff line number Diff line change
@@ -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 (
Expand Down Expand Up @@ -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"
}

Expand All @@ -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},
}
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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.
Expand All @@ -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 {
Expand Down
Loading

0 comments on commit da79330

Please sign in to comment.