mirror of
https://github.com/beego/bee.git
synced 2024-12-22 10:00:50 +00:00
Merge pull request #19 from Unknwon/master
Added func getControllerInfo
This commit is contained in:
commit
058289f79d
@ -1,5 +1,10 @@
|
||||
bee
|
||||
===
|
||||
|
||||
[![Build Status](https://drone.io/github.com/astaxie/bee/status.png)](https://drone.io/github.com/astaxie/bee/latest)
|
||||
|
||||
Bee is a tool for managing beego framework.
|
||||
Bee is a tool for managing beego framework.
|
||||
|
||||
## License
|
||||
|
||||
[Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.html).
|
282
autorouter.go
Normal file
282
autorouter.go
Normal file
@ -0,0 +1,282 @@
|
||||
// Copyright 2013 Bee Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
gobuild "go/build"
|
||||
"go/doc"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var cmdRouter = &Command{
|
||||
UsageLine: "router",
|
||||
Short: "auto-generate routers for the app controllers",
|
||||
Long: `
|
||||
|
||||
`,
|
||||
}
|
||||
|
||||
func init() {
|
||||
cmdRouter.Run = autoRouter
|
||||
}
|
||||
|
||||
func autoRouter(cmd *Command, args []string) {
|
||||
fmt.Println("[INFO] Starting auto-generating routers...")
|
||||
}
|
||||
|
||||
// getControllerInfo returns controllers that embeded "beego.controller"
|
||||
// and their methods of package in given path.
|
||||
func getControllerInfo(path string) (map[string][]string, error) {
|
||||
now := time.Now()
|
||||
path = strings.TrimSuffix(path, "/")
|
||||
dir, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fis, err := dir.Readdir(0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
files := make([]*source, 0, len(fis))
|
||||
for _, fi := range fis {
|
||||
// Only load go files.
|
||||
if strings.HasSuffix(fi.Name(), ".go") {
|
||||
f, err := os.Open(path + "/" + fi.Name())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p := make([]byte, fi.Size())
|
||||
_, err = f.Read(p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
f.Close()
|
||||
files = append(files, &source{
|
||||
name: path + "/" + fi.Name(),
|
||||
data: p,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
rw := &routerWalker{
|
||||
pdoc: &Package{
|
||||
ImportPath: path,
|
||||
},
|
||||
}
|
||||
|
||||
cm := make(map[string][]string)
|
||||
pdoc, err := rw.build(files)
|
||||
for _, t := range pdoc.Types {
|
||||
// Check if embeded "beego.Controller".
|
||||
if strings.Index(t.Decl, "beego.Controller") > -1 {
|
||||
for _, f := range t.Methods {
|
||||
cm[t.Name] = append(cm[t.Name], f.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
fmt.Println(time.Since(now))
|
||||
return cm, nil
|
||||
}
|
||||
|
||||
// A source describles a source code file.
|
||||
type source struct {
|
||||
name string
|
||||
data []byte
|
||||
}
|
||||
|
||||
func (s *source) Name() string { return s.name }
|
||||
func (s *source) Size() int64 { return int64(len(s.data)) }
|
||||
func (s *source) Mode() os.FileMode { return 0 }
|
||||
func (s *source) ModTime() time.Time { return time.Time{} }
|
||||
func (s *source) IsDir() bool { return false }
|
||||
func (s *source) Sys() interface{} { return nil }
|
||||
|
||||
// A routerWalker holds the state used when building the documentation.
|
||||
type routerWalker struct {
|
||||
pdoc *Package
|
||||
srcs map[string]*source // Source files.
|
||||
fset *token.FileSet
|
||||
buf []byte // scratch space for printNode method.
|
||||
}
|
||||
|
||||
// Package represents full information and documentation for a package.
|
||||
type Package struct {
|
||||
ImportPath string
|
||||
|
||||
// Top-level declarations.
|
||||
Types []*Type
|
||||
}
|
||||
|
||||
// Type represents structs and interfaces.
|
||||
type Type struct {
|
||||
Name string // Type name.
|
||||
Decl string
|
||||
Methods []*Func // Exported methods.
|
||||
}
|
||||
|
||||
// Func represents functions
|
||||
type Func struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
// build generates data from source files.
|
||||
func (w *routerWalker) build(srcs []*source) (*Package, error) {
|
||||
// Add source files to walker, I skipped references here.
|
||||
w.srcs = make(map[string]*source)
|
||||
for _, src := range srcs {
|
||||
w.srcs[src.name] = src
|
||||
}
|
||||
|
||||
w.fset = token.NewFileSet()
|
||||
|
||||
// Find the package and associated files.
|
||||
ctxt := gobuild.Context{
|
||||
GOOS: runtime.GOOS,
|
||||
GOARCH: runtime.GOARCH,
|
||||
CgoEnabled: true,
|
||||
JoinPath: path.Join,
|
||||
IsAbsPath: path.IsAbs,
|
||||
SplitPathList: func(list string) []string { return strings.Split(list, ":") },
|
||||
IsDir: func(path string) bool { panic("unexpected") },
|
||||
HasSubdir: func(root, dir string) (rel string, ok bool) { panic("unexpected") },
|
||||
ReadDir: func(dir string) (fi []os.FileInfo, err error) { return w.readDir(dir) },
|
||||
OpenFile: func(path string) (r io.ReadCloser, err error) { return w.openFile(path) },
|
||||
Compiler: "gc",
|
||||
}
|
||||
|
||||
bpkg, err := ctxt.ImportDir(w.pdoc.ImportPath, 0)
|
||||
// Continue if there are no Go source files; we still want the directory info.
|
||||
_, nogo := err.(*gobuild.NoGoError)
|
||||
if err != nil {
|
||||
if nogo {
|
||||
err = nil
|
||||
} else {
|
||||
return nil, errors.New("routerWalker.build -> " + err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the Go files
|
||||
files := make(map[string]*ast.File)
|
||||
for _, name := range append(bpkg.GoFiles, bpkg.CgoFiles...) {
|
||||
file, err := parser.ParseFile(w.fset, name, w.srcs[name].data, parser.ParseComments)
|
||||
if err != nil {
|
||||
return nil, errors.New("routerWalker.build -> parse go files: " + err.Error())
|
||||
}
|
||||
files[name] = file
|
||||
}
|
||||
|
||||
apkg, _ := ast.NewPackage(w.fset, files, simpleImporter, nil)
|
||||
|
||||
mode := doc.Mode(0)
|
||||
if w.pdoc.ImportPath == "builtin" {
|
||||
mode |= doc.AllDecls
|
||||
}
|
||||
|
||||
pdoc := doc.New(apkg, w.pdoc.ImportPath, mode)
|
||||
|
||||
w.pdoc.Types = w.types(pdoc.Types)
|
||||
|
||||
return w.pdoc, err
|
||||
}
|
||||
|
||||
func (w *routerWalker) funcs(fdocs []*doc.Func) []*Func {
|
||||
var result []*Func
|
||||
for _, d := range fdocs {
|
||||
result = append(result, &Func{
|
||||
Name: d.Name,
|
||||
})
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (w *routerWalker) types(tdocs []*doc.Type) []*Type {
|
||||
var result []*Type
|
||||
for _, d := range tdocs {
|
||||
result = append(result, &Type{
|
||||
Decl: w.printDecl(d.Decl),
|
||||
Name: d.Name,
|
||||
Methods: w.funcs(d.Methods),
|
||||
})
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (w *routerWalker) printDecl(decl ast.Node) string {
|
||||
var d Code
|
||||
d, w.buf = printDecl(decl, w.fset, w.buf)
|
||||
return d.Text
|
||||
}
|
||||
|
||||
func (w *routerWalker) readDir(dir string) ([]os.FileInfo, error) {
|
||||
if dir != w.pdoc.ImportPath {
|
||||
panic("unexpected")
|
||||
}
|
||||
fis := make([]os.FileInfo, 0, len(w.srcs))
|
||||
for _, src := range w.srcs {
|
||||
fis = append(fis, src)
|
||||
}
|
||||
return fis, nil
|
||||
}
|
||||
|
||||
func (w *routerWalker) openFile(path string) (io.ReadCloser, error) {
|
||||
if strings.HasPrefix(path, w.pdoc.ImportPath+"/") {
|
||||
if src, ok := w.srcs[path[len(w.pdoc.ImportPath)+1:]]; ok {
|
||||
return ioutil.NopCloser(bytes.NewReader(src.data)), nil
|
||||
}
|
||||
}
|
||||
panic("unexpected")
|
||||
}
|
||||
|
||||
func simpleImporter(imports map[string]*ast.Object, path string) (*ast.Object, error) {
|
||||
pkg := imports[path]
|
||||
if pkg == nil {
|
||||
// Guess the package name without importing it. Start with the last
|
||||
// element of the path.
|
||||
name := path[strings.LastIndex(path, "/")+1:]
|
||||
|
||||
// Trim commonly used prefixes and suffixes containing illegal name
|
||||
// runes.
|
||||
name = strings.TrimSuffix(name, ".go")
|
||||
name = strings.TrimSuffix(name, "-go")
|
||||
name = strings.TrimPrefix(name, "go.")
|
||||
name = strings.TrimPrefix(name, "go-")
|
||||
name = strings.TrimPrefix(name, "biogo.")
|
||||
|
||||
// It's also common for the last element of the path to contain an
|
||||
// extra "go" prefix, but not always. TODO: examine unresolved ids to
|
||||
// detect when trimming the "go" prefix is appropriate.
|
||||
|
||||
pkg = ast.NewObj(ast.Pkg, name)
|
||||
pkg.Data = ast.NewScope(nil)
|
||||
imports[path] = pkg
|
||||
}
|
||||
return pkg, nil
|
||||
}
|
9
autorouter_test.go
Normal file
9
autorouter_test.go
Normal file
@ -0,0 +1,9 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGetControllerInfo(t *testing.T) {
|
||||
getControllerInfo("testdata/router/")
|
||||
}
|
15
bee.go
15
bee.go
@ -1,3 +1,17 @@
|
||||
// Copyright 2013 Bee Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
// Bee is a tool for developling applications based on beego framework.
|
||||
package main
|
||||
|
||||
@ -61,6 +75,7 @@ var commands = []*Command{
|
||||
cmdRun,
|
||||
cmdPack,
|
||||
cmdApiapp,
|
||||
cmdRouter,
|
||||
//cmdReStart,
|
||||
}
|
||||
|
||||
|
11
bee.json
11
bee.json
@ -1,9 +1,12 @@
|
||||
{
|
||||
"go_install": false,
|
||||
"dir_structure":{
|
||||
"controllers": "",
|
||||
"models": ""
|
||||
"models": "",
|
||||
"others": []
|
||||
},
|
||||
"files": [
|
||||
"main.go"
|
||||
]
|
||||
"main_files":{
|
||||
"main.go": "",
|
||||
"others": []
|
||||
}
|
||||
}
|
262
code.go
Normal file
262
code.go
Normal file
@ -0,0 +1,262 @@
|
||||
// Copyright 2011 Gary Burd
|
||||
// Copyright 2013 Unknown
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"go/ast"
|
||||
"go/printer"
|
||||
"go/scanner"
|
||||
"go/token"
|
||||
"math"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const (
|
||||
notPredeclared = iota
|
||||
predeclaredType
|
||||
predeclaredConstant
|
||||
predeclaredFunction
|
||||
)
|
||||
|
||||
// predeclared represents the set of all predeclared identifiers.
|
||||
var predeclared = map[string]int{
|
||||
"bool": predeclaredType,
|
||||
"byte": predeclaredType,
|
||||
"complex128": predeclaredType,
|
||||
"complex64": predeclaredType,
|
||||
"error": predeclaredType,
|
||||
"float32": predeclaredType,
|
||||
"float64": predeclaredType,
|
||||
"int16": predeclaredType,
|
||||
"int32": predeclaredType,
|
||||
"int64": predeclaredType,
|
||||
"int8": predeclaredType,
|
||||
"int": predeclaredType,
|
||||
"rune": predeclaredType,
|
||||
"string": predeclaredType,
|
||||
"uint16": predeclaredType,
|
||||
"uint32": predeclaredType,
|
||||
"uint64": predeclaredType,
|
||||
"uint8": predeclaredType,
|
||||
"uint": predeclaredType,
|
||||
"uintptr": predeclaredType,
|
||||
|
||||
"true": predeclaredConstant,
|
||||
"false": predeclaredConstant,
|
||||
"iota": predeclaredConstant,
|
||||
"nil": predeclaredConstant,
|
||||
|
||||
"append": predeclaredFunction,
|
||||
"cap": predeclaredFunction,
|
||||
"close": predeclaredFunction,
|
||||
"complex": predeclaredFunction,
|
||||
"copy": predeclaredFunction,
|
||||
"delete": predeclaredFunction,
|
||||
"imag": predeclaredFunction,
|
||||
"len": predeclaredFunction,
|
||||
"make": predeclaredFunction,
|
||||
"new": predeclaredFunction,
|
||||
"panic": predeclaredFunction,
|
||||
"print": predeclaredFunction,
|
||||
"println": predeclaredFunction,
|
||||
"real": predeclaredFunction,
|
||||
"recover": predeclaredFunction,
|
||||
}
|
||||
|
||||
const (
|
||||
ExportLinkAnnotation AnnotationKind = iota
|
||||
AnchorAnnotation
|
||||
CommentAnnotation
|
||||
PackageLinkAnnotation
|
||||
BuiltinAnnotation
|
||||
)
|
||||
|
||||
// annotationVisitor collects annotations.
|
||||
type annotationVisitor struct {
|
||||
annotations []Annotation
|
||||
}
|
||||
|
||||
func (v *annotationVisitor) add(kind AnnotationKind, importPath string) {
|
||||
v.annotations = append(v.annotations, Annotation{Kind: kind, ImportPath: importPath})
|
||||
}
|
||||
|
||||
func (v *annotationVisitor) ignoreName() {
|
||||
v.add(-1, "")
|
||||
}
|
||||
|
||||
func (v *annotationVisitor) Visit(n ast.Node) ast.Visitor {
|
||||
switch n := n.(type) {
|
||||
case *ast.TypeSpec:
|
||||
v.ignoreName()
|
||||
ast.Walk(v, n.Type)
|
||||
case *ast.FuncDecl:
|
||||
if n.Recv != nil {
|
||||
ast.Walk(v, n.Recv)
|
||||
}
|
||||
v.ignoreName()
|
||||
ast.Walk(v, n.Type)
|
||||
case *ast.Field:
|
||||
for _ = range n.Names {
|
||||
v.ignoreName()
|
||||
}
|
||||
ast.Walk(v, n.Type)
|
||||
case *ast.ValueSpec:
|
||||
for _ = range n.Names {
|
||||
v.add(AnchorAnnotation, "")
|
||||
}
|
||||
if n.Type != nil {
|
||||
ast.Walk(v, n.Type)
|
||||
}
|
||||
for _, x := range n.Values {
|
||||
ast.Walk(v, x)
|
||||
}
|
||||
case *ast.Ident:
|
||||
switch {
|
||||
case n.Obj == nil && predeclared[n.Name] != notPredeclared:
|
||||
v.add(BuiltinAnnotation, "")
|
||||
case n.Obj != nil && ast.IsExported(n.Name):
|
||||
v.add(ExportLinkAnnotation, "")
|
||||
default:
|
||||
v.ignoreName()
|
||||
}
|
||||
case *ast.SelectorExpr:
|
||||
if x, _ := n.X.(*ast.Ident); x != nil {
|
||||
if obj := x.Obj; obj != nil && obj.Kind == ast.Pkg {
|
||||
if spec, _ := obj.Decl.(*ast.ImportSpec); spec != nil {
|
||||
if path, err := strconv.Unquote(spec.Path.Value); err == nil {
|
||||
v.add(PackageLinkAnnotation, path)
|
||||
if path == "C" {
|
||||
v.ignoreName()
|
||||
} else {
|
||||
v.add(ExportLinkAnnotation, path)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ast.Walk(v, n.X)
|
||||
v.ignoreName()
|
||||
default:
|
||||
return v
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func printDecl(decl ast.Node, fset *token.FileSet, buf []byte) (Code, []byte) {
|
||||
v := &annotationVisitor{}
|
||||
ast.Walk(v, decl)
|
||||
|
||||
buf = buf[:0]
|
||||
err := (&printer.Config{Mode: printer.UseSpaces, Tabwidth: 4}).Fprint(sliceWriter{&buf}, fset, decl)
|
||||
if err != nil {
|
||||
return Code{Text: err.Error()}, buf
|
||||
}
|
||||
|
||||
var annotations []Annotation
|
||||
var s scanner.Scanner
|
||||
fset = token.NewFileSet()
|
||||
file := fset.AddFile("", fset.Base(), len(buf))
|
||||
s.Init(file, buf, nil, scanner.ScanComments)
|
||||
loop:
|
||||
for {
|
||||
pos, tok, lit := s.Scan()
|
||||
switch tok {
|
||||
case token.EOF:
|
||||
break loop
|
||||
case token.COMMENT:
|
||||
p := file.Offset(pos)
|
||||
e := p + len(lit)
|
||||
if p > math.MaxInt16 || e > math.MaxInt16 {
|
||||
break loop
|
||||
}
|
||||
annotations = append(annotations, Annotation{Kind: CommentAnnotation, Pos: int16(p), End: int16(e)})
|
||||
case token.IDENT:
|
||||
if len(v.annotations) == 0 {
|
||||
// Oops!
|
||||
break loop
|
||||
}
|
||||
annotation := v.annotations[0]
|
||||
v.annotations = v.annotations[1:]
|
||||
if annotation.Kind == -1 {
|
||||
continue
|
||||
}
|
||||
p := file.Offset(pos)
|
||||
e := p + len(lit)
|
||||
if p > math.MaxInt16 || e > math.MaxInt16 {
|
||||
break loop
|
||||
}
|
||||
annotation.Pos = int16(p)
|
||||
annotation.End = int16(e)
|
||||
if len(annotations) > 0 && annotation.Kind == ExportLinkAnnotation {
|
||||
prev := annotations[len(annotations)-1]
|
||||
if prev.Kind == PackageLinkAnnotation &&
|
||||
prev.ImportPath == annotation.ImportPath &&
|
||||
prev.End+1 == annotation.Pos {
|
||||
// merge with previous
|
||||
annotation.Pos = prev.Pos
|
||||
annotations[len(annotations)-1] = annotation
|
||||
continue loop
|
||||
}
|
||||
}
|
||||
annotations = append(annotations, annotation)
|
||||
}
|
||||
}
|
||||
return Code{Text: string(buf), Annotations: annotations}, buf
|
||||
}
|
||||
|
||||
type AnnotationKind int16
|
||||
|
||||
type Annotation struct {
|
||||
Pos, End int16
|
||||
Kind AnnotationKind
|
||||
ImportPath string
|
||||
}
|
||||
|
||||
type Code struct {
|
||||
Text string
|
||||
Annotations []Annotation
|
||||
}
|
||||
|
||||
func commentAnnotations(src string) []Annotation {
|
||||
var annotations []Annotation
|
||||
var s scanner.Scanner
|
||||
fset := token.NewFileSet()
|
||||
file := fset.AddFile("", fset.Base(), len(src))
|
||||
s.Init(file, []byte(src), nil, scanner.ScanComments)
|
||||
for {
|
||||
pos, tok, lit := s.Scan()
|
||||
switch tok {
|
||||
case token.EOF:
|
||||
return annotations
|
||||
case token.COMMENT:
|
||||
p := file.Offset(pos)
|
||||
e := p + len(lit)
|
||||
if p > math.MaxInt16 || e > math.MaxInt16 {
|
||||
return annotations
|
||||
}
|
||||
annotations = append(annotations, Annotation{Kind: CommentAnnotation, Pos: int16(p), End: int16(e)})
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type sliceWriter struct{ p *[]byte }
|
||||
|
||||
func (w sliceWriter) Write(p []byte) (int, error) {
|
||||
*w.p = append(*w.p, p...)
|
||||
return len(p), nil
|
||||
}
|
20
run.go
20
run.go
@ -36,11 +36,19 @@ func init() {
|
||||
|
||||
var appname string
|
||||
var conf struct {
|
||||
// Indicates whether execute "go install" before "go build".
|
||||
GoInstall bool `json:"go_install"`
|
||||
|
||||
DirStruct struct {
|
||||
Controllers string
|
||||
Models string
|
||||
Others []string // Other directories.
|
||||
} `json:"dir_structure"`
|
||||
Files []string
|
||||
|
||||
MainFiles struct {
|
||||
Main string `json:"main.go"`
|
||||
Others []string // Others files of package main.
|
||||
} `json:"main_files"`
|
||||
}
|
||||
|
||||
func runApp(cmd *Command, args []string) {
|
||||
@ -58,8 +66,10 @@ func runApp(cmd *Command, args []string) {
|
||||
var paths []string
|
||||
paths = append(paths,
|
||||
path.Join(crupath, conf.DirStruct.Controllers),
|
||||
path.Join(crupath, conf.DirStruct.Models))
|
||||
paths = append(paths, conf.Files...)
|
||||
path.Join(crupath, conf.DirStruct.Models),
|
||||
path.Join(crupath, conf.MainFiles.Main))
|
||||
paths = append(paths, conf.DirStruct.Others...)
|
||||
paths = append(paths, conf.MainFiles.Others...)
|
||||
|
||||
NewWatcher(paths)
|
||||
appname = args[0]
|
||||
@ -71,6 +81,7 @@ func runApp(cmd *Command, args []string) {
|
||||
|
||||
// loadConfig loads customized configuration.
|
||||
func loadConfig() error {
|
||||
fmt.Println("[INFO] Detect bee.json")
|
||||
f, err := os.Open("bee.json")
|
||||
if err != nil {
|
||||
// Use default.
|
||||
@ -91,5 +102,8 @@ func loadConfig() error {
|
||||
if len(conf.DirStruct.Models) == 0 {
|
||||
conf.DirStruct.Models = "models"
|
||||
}
|
||||
if len(conf.MainFiles.Main) == 0 {
|
||||
conf.MainFiles.Main = "main.go"
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
28
testdata/router/router.go
vendored
Normal file
28
testdata/router/router.go
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"github.com/astaxie/beego"
|
||||
)
|
||||
|
||||
type Router struct {
|
||||
beego.Controller
|
||||
}
|
||||
|
||||
func (this *Router) Get() {
|
||||
|
||||
}
|
||||
|
||||
func (this *Router) Post() {
|
||||
|
||||
}
|
||||
|
||||
type Controller struct {
|
||||
}
|
||||
|
||||
func (this *Controller) Put() {
|
||||
|
||||
}
|
||||
|
||||
func (this *Controller) Delete() {
|
||||
|
||||
}
|
21
watch.go
21
watch.go
@ -72,10 +72,23 @@ func Autobuild() {
|
||||
fmt.Println("[INFO] Start building...")
|
||||
path, _ := os.Getwd()
|
||||
os.Chdir(path)
|
||||
bcmd := exec.Command("go", "build")
|
||||
bcmd.Stdout = os.Stdout
|
||||
bcmd.Stderr = os.Stderr
|
||||
err := bcmd.Run()
|
||||
|
||||
var err error
|
||||
// For applications use full import path like "github.com/.../.."
|
||||
// are able to use "go install" to reduce build time.
|
||||
if conf.GoInstall {
|
||||
icmd := exec.Command("go", "install")
|
||||
icmd.Stdout = os.Stdout
|
||||
icmd.Stderr = os.Stderr
|
||||
err = icmd.Run()
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
bcmd := exec.Command("go", "build")
|
||||
bcmd.Stdout = os.Stdout
|
||||
bcmd.Stderr = os.Stderr
|
||||
err = bcmd.Run()
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
fmt.Println("[ERRO] ============== Build failed ===================")
|
||||
|
Loading…
Reference in New Issue
Block a user