Compare commits

..

36 Commits

Author SHA1 Message Date
Jeevanandam M
4b9e74e1ea revel/revel#1064 windows filepath fix 2016-06-06 15:36:16 -07:00
Jeevanandam M
18b9e8f344 Merging develop to master for v0.13.0 release 2016-06-05 18:32:53 -07:00
Jeevanandam M
e3f469739c golint taken care for version name 2016-05-31 22:58:56 -07:00
Jeevanandam M
ced303ede6 #19 Revel version command added 2016-05-28 11:07:43 -07:00
Jeevanandam M
1f8f106573 Related changes by #20 for Walk method 2016-05-27 23:30:14 -07:00
Jeevanandam M
6005ac35f7 Merge pull request #20 from metafex/symlink-walk
Switch to revel.Walk, the symlink-aware filepath.Walk helper
2016-05-27 23:23:41 -07:00
Jeevanandam M
b85dd76b3e revel/revel#1004 choose go path relative to current working directory 2016-05-26 17:23:52 -07:00
Jeevanandam M
b00267450e default run mode value updated dev 2016-05-26 17:14:53 -07:00
Jeevanandam M
5282ce262b revel/revel#1014 added check for path like ../dir & ./dir for new command 2016-05-25 22:49:11 -07:00
Jeevanandam M
4c628ef3db Merge branch 'mattbaird-feature/ssl-support-for-websockets' into develop 2016-05-23 22:55:04 -07:00
Jeevanandam M
6ebd22021e #32 PR merge and code improvements 2016-05-23 22:54:44 -07:00
Jeevanandam M
688042ffa5 Merge branch 'feature/ssl-support-for-websockets' of https://github.com/mattbaird/cmd into mattbaird-feature/ssl-support-for-websockets 2016-05-23 22:38:05 -07:00
Jeevanandam M
2e0697adf2 Removed print statement 2016-05-23 22:31:35 -07:00
Jeevanandam M
a7fb140b7a Merge branch 'birkirb-master' into develop 2016-05-22 20:40:58 -07:00
Jeevanandam M
6d12b806d3 Validated PR #14 and fixed issues for the PR 2016-05-22 20:40:13 -07:00
Jeevanandam M
c32b5d19b7 Merge branch 'yuki2006-develop' into develop 2016-05-22 13:50:01 -07:00
Jeevanandam M
e75cbc42cb updated msg and condition check 2016-05-22 13:49:19 -07:00
Jeevanandam M
6dbd332d6f Merge branch 'develop' of https://github.com/yuki2006/cmd into yuki2006-develop 2016-05-22 11:26:43 -07:00
Jeevanandam M
4f0489d0e6 print only valid error msg 2016-05-21 23:14:42 -07:00
Jeevanandam M
63ec7ed487 Merge branch 'tyro89-also_remove_routes' into develop 2016-05-21 22:58:30 -07:00
Jeevanandam M
63b4fbe6d9 Updated variable name 2016-05-21 22:58:02 -07:00
Erik Selin
f9ba83270b during cleanup we can also remove the routes folder. 2016-05-21 22:44:44 -07:00
Jeevanandam M
ac4e5473d2 Merge branch 'master' into develop 2016-05-21 22:30:31 -07:00
Jeevanandam M
04e8dfdcbf Merge pull request #43 from ottob/build-install-deps
Install package dependencies when building
2016-05-21 22:26:56 -07:00
Jeevanandam M
a6836f3a41 Merge branch 'master' of https://github.com/birkirb/cmd into birkirb-master 2016-05-21 20:53:19 -07:00
Jeevanandam M
6a02449e48 Merge pull request #42 from yyoshiki41/fmt
Format go code
2016-05-21 20:48:04 -07:00
yyoshiki41
4d8dbe0fe1 Format go code 2016-05-22 11:35:42 +09:00
Otto Bretz
eaf28d397f Install package dependencies when building
This speeds up recurring compiles a lot.
2016-05-21 20:26:55 +02:00
yuki2006
b2ec002b4d fix : Failed to request test list when excepting status code 200 2015-11-23 02:46:03 +09:00
Brenden Soares
8a7b1a81ac Merge pull request #31 from rnubel/fix/ignore_missing_dir_on_clean
Ignore missing temporary directories in build.cleanDir
2015-09-26 01:11:03 -07:00
Brenden Soares
3c658679bc Merge pull request #25 from roblillack/feature/improve-route-generation-warnings
Improve route generation warnings
2015-09-25 22:06:43 -07:00
Matthew Baird
f122160a11 fix issue where websockets don't work with SSL in dev mode.
As the comment says, it's ok to skip the verify on the cert since
this proxy is only used in dev mode.
2015-08-11 14:45:02 -07:00
Robert Nubel
7792db37e2 Ignore missing temporary directories when booting.
Otherwise, removing your `app/tmp` and `app/routes` folders prior
to booting (e.g., if you add them to your .gitignore and use Travis)
will cause unnecessary FATAL error messages. Addresses
revel/revel#908.
2015-07-06 23:26:36 -05:00
Robert Lillack
95d62c1bbd Improve warning message when unable to generate route for action. 2015-03-04 22:09:53 +01:00
Michael Eisendle
3eccd6ae00 Switch to revel.Walk, the symlink-aware filepath.Walk helper 2015-02-05 12:31:05 +01:00
Birkir A. Barkarson
0fd5bcfcba Add environment mode to package. 2014-11-03 23:41:52 +01:00
14 changed files with 171 additions and 65 deletions

View File

@@ -63,7 +63,7 @@ func Build(buildFlags ...string) (app *App, compileError *revel.Error) {
}
// Binary path is a combination of $GOBIN/revel.d directory, app's import path and its name.
binName := path.Join(pkg.BinDir, "revel.d", revel.ImportPath, path.Base(revel.BasePath))
binName := filepath.Join(pkg.BinDir, "revel.d", revel.ImportPath, filepath.Base(revel.BasePath))
// Change binary path for Windows build
goos := runtime.GOOS
@@ -80,6 +80,7 @@ func Build(buildFlags ...string) (app *App, compileError *revel.Error) {
versionLinkerFlags := fmt.Sprintf("-X %s/app.APP_VERSION \"%s\"", revel.ImportPath, appVersion)
flags := []string{
"build",
"-i",
"-ldflags", versionLinkerFlags,
"-tags", buildTags,
"-o", binName}
@@ -173,12 +174,16 @@ func cleanDir(dir string) {
tmpPath := path.Join(revel.AppPath, dir)
f, err := os.Open(tmpPath)
if err != nil {
revel.ERROR.Println("Failed to clean dir:", err)
if !os.IsNotExist(err) {
revel.ERROR.Println("Failed to clean dir:", err)
}
} else {
defer f.Close()
infos, err := f.Readdir(0)
if err != nil {
revel.ERROR.Println("Failed to clean dir:", err)
if !os.IsNotExist(err) {
revel.ERROR.Println("Failed to clean dir:", err)
}
} else {
for _, info := range infos {
path := path.Join(tmpPath, info.Name())
@@ -198,7 +203,6 @@ func cleanDir(dir string) {
}
}
// genSource renders the given template to produce source code, which it writes
// to the given directory and file.
func genSource(dir, filename, templateSource string, args map[string]interface{}) {

View File

@@ -13,7 +13,6 @@ package harness
import (
"crypto/tls"
"fmt"
"github.com/revel/revel"
"go/build"
"io"
"net"
@@ -22,10 +21,11 @@ import (
"net/url"
"os"
"os/signal"
"path"
"path/filepath"
"strings"
"sync/atomic"
"github.com/revel/revel"
)
var (
@@ -52,7 +52,7 @@ func renderError(w http.ResponseWriter, r *http.Request, err error) {
// ServeHTTP handles all requests.
// It checks for changes to app, rebuilds if necessary, and forwards the request.
func (hp *Harness) ServeHTTP(w http.ResponseWriter, r *http.Request) {
func (h *Harness) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// Don't rebuild the app for favicon requests.
if lastRequestHadError > 0 && r.URL.Path == "/favicon.ico" {
return
@@ -71,18 +71,19 @@ func (hp *Harness) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// Reverse proxy the request.
// (Need special code for websockets, courtesy of bradfitz)
if strings.EqualFold(r.Header.Get("Upgrade"), "websocket") {
proxyWebsocket(w, r, hp.serverHost)
proxyWebsocket(w, r, h.serverHost)
} else {
hp.proxy.ServeHTTP(w, r)
h.proxy.ServeHTTP(w, r)
}
}
// Return a reverse proxy that forwards requests to the given port.
// NewHarness method returns a reverse proxy that forwards requests
// to the given port.
func NewHarness() *Harness {
// Get a template loader to render errors.
// Prefer the app's views/errors directory, and fall back to the stock error pages.
revel.MainTemplateLoader = revel.NewTemplateLoader(
[]string{path.Join(revel.RevelPath, "templates")})
[]string{filepath.Join(revel.RevelPath, "templates")})
revel.MainTemplateLoader.Refresh()
addr := revel.HttpAddr
@@ -101,12 +102,12 @@ func NewHarness() *Harness {
port = getFreePort()
}
serverUrl, _ := url.ParseRequestURI(fmt.Sprintf(scheme+"://%s:%d", addr, port))
serverURL, _ := url.ParseRequestURI(fmt.Sprintf(scheme+"://%s:%d", addr, port))
harness := &Harness{
port: port,
serverHost: serverUrl.String()[len(scheme+"://"):],
proxy: httputil.NewSingleHostReverseProxy(serverUrl),
serverHost: serverURL.String()[len(scheme+"://"):],
proxy: httputil.NewSingleHostReverseProxy(serverURL),
}
if revel.HttpSsl {
@@ -117,7 +118,7 @@ func NewHarness() *Harness {
return harness
}
// Rebuild the Revel application and run it on the given port.
// Refresh method rebuilds the Revel application and run it on the given port.
func (h *Harness) Refresh() (err *revel.Error) {
if h.app != nil {
h.app.Kill()
@@ -140,10 +141,14 @@ func (h *Harness) Refresh() (err *revel.Error) {
return
}
// WatchDir method returns false to file matches with doNotWatch
// otheriwse true
func (h *Harness) WatchDir(info os.FileInfo) bool {
return !revel.ContainsString(doNotWatch, info.Name())
}
// WatchFile method returns true given filename HasSuffix of ".go"
// otheriwse false
func (h *Harness) WatchFile(filename string) bool {
return strings.HasSuffix(filename, ".go")
}
@@ -204,7 +209,18 @@ func getFreePort() (port int) {
// proxyWebsocket copies data between websocket client and server until one side
// closes the connection. (ReverseProxy doesn't work with websocket requests.)
func proxyWebsocket(w http.ResponseWriter, r *http.Request, host string) {
d, err := net.Dial("tcp", host)
var (
d net.Conn
err error
)
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.
d, err = tls.Dial("tcp", host, &tls.Config{InsecureSkipVerify: true})
} else {
d, err = net.Dial("tcp", host)
}
if err != nil {
http.Error(w, "Error contacting backend server.", 500)
revel.ERROR.Printf("Error dialing websocket backend %s: %v", host, err)

View File

@@ -96,7 +96,7 @@ func ProcessSource(roots []string) (*SourceInfo, *revel.Error) {
}
// Start walking the directory tree.
filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
_ = revel.Walk(root, func(path string, info os.FileInfo, err error) error {
if err != nil {
log.Println("Error scanning app source:", err)
return nil
@@ -433,7 +433,8 @@ func appendAction(fset *token.FileSet, mm methodMap, decl ast.Decl, pkgImportPat
var importPath string
typeExpr := NewTypeExpr(pkgName, field.Type)
if !typeExpr.Valid {
return // We didn't understand one of the args. Ignore this action. (Already logged)
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.
}
if typeExpr.PkgName != "" {
var ok bool

View File

@@ -7,17 +7,22 @@ import (
"path/filepath"
"strings"
"github.com/revel/revel"
"github.com/revel/cmd/harness"
"github.com/revel/revel"
)
var cmdBuild = &Command{
UsageLine: "build [import path] [target path]",
UsageLine: "build [import path] [target path] [run mode]",
Short: "build a Revel application (e.g. for deployment)",
Long: `
Build the Revel web application named by the given import path.
This allows it to be deployed and run on a machine that lacks a Go installation.
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.
Run mode defaults to "dev".
WARNING: The target path will be completely deleted, if it already exists!
For example:
@@ -31,14 +36,18 @@ func init() {
}
func buildApp(args []string) {
if len(args) != 2 {
if len(args) < 2 {
fmt.Fprintf(os.Stderr, "%s\n%s", cmdBuild.UsageLine, cmdBuild.Long)
return
}
appImportPath, destPath := args[0], args[1]
appImportPath, destPath, mode := args[0], args[1], "dev"
if len(args) >= 3 {
mode = args[2]
}
if !revel.Initialized {
revel.Init("", appImportPath, "")
revel.Init(mode, appImportPath, "")
}
// First, verify that it is either already empty or looks like a previous
@@ -96,6 +105,7 @@ func buildApp(args []string) {
tmplData, runShPath := map[string]interface{}{
"BinName": filepath.Base(app.BinaryPath),
"ImportPath": appImportPath,
"Mode": mode,
}, path.Join(destPath, "run.sh")
mustRenderTemplate(

View File

@@ -17,7 +17,7 @@ For example:
revel clean github.com/revel/samples/chat
It removes the app/tmp directory.
It removes the app/tmp and app/routes directory.
`,
}
@@ -37,12 +37,17 @@ func cleanApp(args []string) {
return
}
// Remove the app/tmp directory.
tmpDir := path.Join(appPkg.Dir, "app", "tmp")
fmt.Println("Removing:", tmpDir)
err = os.RemoveAll(tmpDir)
if err != nil {
fmt.Fprintln(os.Stderr, "Abort:", err)
return
purgeDirs := []string{
path.Join(appPkg.Dir, "app", "tmp"),
path.Join(appPkg.Dir, "app", "routes"),
}
for _, dir := range purgeDirs {
fmt.Println("Removing:", dir)
err = os.RemoveAll(dir)
if err != nil {
fmt.Fprintln(os.Stderr, "Abort:", err)
return
}
}
}

View File

@@ -4,10 +4,12 @@ import (
"bytes"
"fmt"
"go/build"
"log"
"math/rand"
"os"
"os/exec"
"path/filepath"
"strings"
"github.com/revel/revel"
)
@@ -60,6 +62,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()
@@ -96,9 +100,6 @@ func initGoPaths() {
"Please refer to http://golang.org/doc/code.html to configure your Go environment.")
}
// set go src path
srcRoot = filepath.Join(filepath.SplitList(gopath)[0], "src")
// check for go executable
var err error
gocmd, err = exec.LookPath("go")
@@ -106,12 +107,38 @@ func initGoPaths() {
errorf("Go executable not found in PATH.")
}
// revel/revel#1004 choose go path relative to current working directory
workingDir, _ := os.Getwd()
goPathList := filepath.SplitList(gopath)
for _, path := range goPathList {
if strings.HasPrefix(strings.ToLower(workingDir), strings.ToLower(path)) {
srcRoot = path
break
}
path, _ = filepath.EvalSymlinks(path)
if len(path) > 0 && strings.HasPrefix(strings.ToLower(workingDir), strings.ToLower(path)) {
srcRoot = path
break
}
}
if len(srcRoot) == 0 {
revel.ERROR.Fatalln("Abort: could not create a Revel application outside of GOPATH.")
}
// set go src path
srcRoot = filepath.Join(srcRoot, "src")
}
func setApplicationPath(args []string) {
var err error
importPath = args[0]
if filepath.IsAbs(importPath) {
// revel/revel#1014 validate relative path, we cannot use built-in functions
// since Go import path is valid relative path too.
// so check basic part of the path, which is "."
if filepath.IsAbs(importPath) || strings.HasPrefix(importPath, ".") {
errorf("Abort: '%s' looks like a directory. Please provide a Go import path instead.",
importPath)
}

View File

@@ -2,19 +2,25 @@ package main
import (
"fmt"
"github.com/revel/revel"
"io/ioutil"
"os"
"path/filepath"
"github.com/revel/revel"
)
var cmdPackage = &Command{
UsageLine: "package [import path]",
UsageLine: "package [import path] [run mode]",
Short: "package a Revel application (e.g. for deployment)",
Long: `
Package the Revel web application named by the given import path.
This allows it to be deployed and run on a machine that lacks a Go installation.
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.
Run mode defaults to "dev".
For example:
revel package github.com/revel/samples/chat
@@ -31,8 +37,14 @@ func packageApp(args []string) {
return
}
// Determine the run mode.
mode := "dev"
if len(args) >= 2 {
mode = args[1]
}
appImportPath := args[0]
revel.Init("", appImportPath, "")
revel.Init(mode, appImportPath, "")
// Remove the archive if it already exists.
destFile := filepath.Base(revel.BasePath) + ".tar.gz"
@@ -42,7 +54,7 @@ func packageApp(args []string) {
tmpDir, err := ioutil.TempDir("", filepath.Base(revel.BasePath))
panicOnError(err, "Failed to get temp dir")
buildApp([]string{args[0], tmpDir})
buildApp([]string{args[0], tmpDir, mode})
// Create the zip file.
archiveName := mustTarGzDir(destFile, tmpDir)

View File

@@ -1,2 +1,2 @@
@echo off
{{.BinName}} -importPath {{.ImportPath}} -srcPath %CD%\src -runMode prod
{{.BinName}} -importPath {{.ImportPath}} -srcPath %CD%\src -runMode {{.Mode}}

View File

@@ -1,3 +1,3 @@
#!/bin/sh
SCRIPTPATH=$(cd "$(dirname "$0")"; pwd)
"$SCRIPTPATH/{{.BinName}}" -importPath {{.ImportPath}} -srcPath "$SCRIPTPATH/src" -runMode prod
"$SCRIPTPATH/{{.BinName}}" -importPath {{.ImportPath}} -srcPath "$SCRIPTPATH/src" -runMode {{.Mode}}

View File

@@ -4,7 +4,6 @@ package main
import (
"flag"
"fmt"
"github.com/agtorre/gocolorize"
"io"
"math/rand"
"os"
@@ -12,9 +11,11 @@ import (
"strings"
"text/template"
"time"
"github.com/agtorre/gocolorize"
)
// Cribbed from the genius organization of the "go" command.
// Command structure cribbed from the genius organization of the "go" command.
type Command struct {
Run func(args []string)
UsageLine, Short, Long string
@@ -36,6 +37,7 @@ var commands = []*Command{
cmdPackage,
cmdClean,
cmdTest,
cmdVersion,
}
func main() {

View File

@@ -1,8 +1,8 @@
package main
import (
"github.com/revel/revel"
"github.com/revel/cmd/harness"
"github.com/revel/revel"
"strconv"
)
@@ -65,7 +65,7 @@ func runApp(args []string) {
}
// Else, just build and run the app.
revel.TRACE.Println("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

@@ -3,9 +3,6 @@ package main
import (
"encoding/json"
"fmt"
"github.com/revel/revel"
"github.com/revel/cmd/harness"
"github.com/revel/modules/testrunner/app/controllers"
"io"
"io/ioutil"
"net/http"
@@ -13,6 +10,10 @@ import (
"path"
"strings"
"time"
"github.com/revel/cmd/harness"
"github.com/revel/modules/testrunner/app/controllers"
"github.com/revel/revel"
)
var cmdTest = &Command{
@@ -117,13 +118,19 @@ You can add it to a run mode configuration with the following line:
)
for i := 0; ; i++ {
if resp, err = http.Get(baseUrl + "/@tests.list"); err == nil {
break
if resp.StatusCode == http.StatusOK {
break
}
}
if i < 3 {
time.Sleep(3 * time.Second)
continue
}
errorf("Failed to request test list: %s", err)
if err != nil {
errorf("Failed to request test list: %s", err)
} else {
errorf("Failed to request test list: non-200 response")
}
}
defer resp.Body.Close()
json.NewDecoder(resp.Body).Decode(&testSuites)

View File

@@ -66,22 +66,10 @@ func mustChmod(filename string, mode os.FileMode) {
// Additionally, the trailing ".template" is stripped from the file name.
// Also, dot files and dot directories are skipped.
func mustCopyDir(destDir, srcDir string, data map[string]interface{}) error {
var fullSrcDir string
// Handle symlinked directories.
f, err := os.Lstat(srcDir)
if err == nil && f.Mode()&os.ModeSymlink == os.ModeSymlink {
fullSrcDir, err = os.Readlink(srcDir)
if err != nil {
panic(err)
}
} else {
fullSrcDir = srcDir
}
return filepath.Walk(fullSrcDir, func(srcPath string, info os.FileInfo, err error) error {
return revel.Walk(srcDir, func(srcPath string, info os.FileInfo, err error) error {
// Get the relative path from the source base, and the corresponding path in
// the dest directory.
relSrcPath := strings.TrimLeft(srcPath[len(fullSrcDir):], string(os.PathSeparator))
relSrcPath := strings.TrimLeft(srcPath[len(srcDir):], string(os.PathSeparator))
destPath := path.Join(destDir, relSrcPath)
// Skip dot files and dot directories.
@@ -124,7 +112,7 @@ func mustTarGzDir(destFilename, srcDir string) string {
tarWriter := tar.NewWriter(gzipWriter)
defer tarWriter.Close()
filepath.Walk(srcDir, func(srcPath string, info os.FileInfo, err error) error {
revel.Walk(srcDir, func(srcPath string, info os.FileInfo, err error) error {
if info.IsDir() {
return nil
}

34
revel/version.go Normal file
View File

@@ -0,0 +1,34 @@
// 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"
"runtime"
"github.com/revel/revel"
)
var cmdVersion = &Command{
UsageLine: "version",
Short: "displays the Revel Framework and Go version",
Long: `
Displays the Revel Framework and Go version.
For example:
revel version
`,
}
func init() {
cmdVersion.Run = versionApp
}
func versionApp(args []string) {
fmt.Printf("Version(s):")
fmt.Printf("\n Revel v%v (%v)", revel.Version, revel.BuildDate)
fmt.Printf("\n %s %s/%s\n\n", runtime.Version(), runtime.GOOS, runtime.GOARCH)
}