mirror of
https://github.com/kevin-DL/revel-cmd.git
synced 2026-01-12 02:55:16 +00:00
Compare commits
36 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4b9e74e1ea | ||
|
|
18b9e8f344 | ||
|
|
e3f469739c | ||
|
|
ced303ede6 | ||
|
|
1f8f106573 | ||
|
|
6005ac35f7 | ||
|
|
b85dd76b3e | ||
|
|
b00267450e | ||
|
|
5282ce262b | ||
|
|
4c628ef3db | ||
|
|
6ebd22021e | ||
|
|
688042ffa5 | ||
|
|
2e0697adf2 | ||
|
|
a7fb140b7a | ||
|
|
6d12b806d3 | ||
|
|
c32b5d19b7 | ||
|
|
e75cbc42cb | ||
|
|
6dbd332d6f | ||
|
|
4f0489d0e6 | ||
|
|
63ec7ed487 | ||
|
|
63b4fbe6d9 | ||
|
|
f9ba83270b | ||
|
|
ac4e5473d2 | ||
|
|
04e8dfdcbf | ||
|
|
a6836f3a41 | ||
|
|
6a02449e48 | ||
|
|
4d8dbe0fe1 | ||
|
|
eaf28d397f | ||
|
|
b2ec002b4d | ||
|
|
8a7b1a81ac | ||
|
|
3c658679bc | ||
|
|
f122160a11 | ||
|
|
7792db37e2 | ||
|
|
95d62c1bbd | ||
|
|
3eccd6ae00 | ||
|
|
0fd5bcfcba |
@@ -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{}) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
35
revel/new.go
35
revel/new.go
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
@echo off
|
||||
{{.BinName}} -importPath {{.ImportPath}} -srcPath %CD%\src -runMode prod
|
||||
{{.BinName}} -importPath {{.ImportPath}} -srcPath %CD%\src -runMode {{.Mode}}
|
||||
|
||||
@@ -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}}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
34
revel/version.go
Normal 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)
|
||||
}
|
||||
Reference in New Issue
Block a user