mirror of
https://github.com/beego/bee.git
synced 2024-11-22 05:00:54 +00:00
Implementing the new logging infrastructure
Moved logging to the new logging infrastructure by removing the use of ColorLog() function. Added more documentation. Also fixed some typos in comments and function names.
This commit is contained in:
parent
0e54238559
commit
cf7aef47f0
23
apiapp.go
23
apiapp.go
@ -549,8 +549,7 @@ func createapi(cmd *Command, args []string) int {
|
|||||||
w := NewColorWriter(os.Stdout)
|
w := NewColorWriter(os.Stdout)
|
||||||
|
|
||||||
if len(args) < 1 {
|
if len(args) < 1 {
|
||||||
ColorLog("[ERRO] Argument [appname] is missing\n")
|
logger.Fatal("Argument [appname] is missing")
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(args) > 1 {
|
if len(args) > 1 {
|
||||||
@ -568,7 +567,7 @@ func createapi(cmd *Command, args []string) int {
|
|||||||
if conn == "" {
|
if conn == "" {
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorLog("[INFO] Creating API...\n")
|
logger.Info("Creating API...")
|
||||||
|
|
||||||
os.MkdirAll(apppath, 0755)
|
os.MkdirAll(apppath, 0755)
|
||||||
fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", apppath, "\x1b[0m")
|
fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", apppath, "\x1b[0m")
|
||||||
@ -599,9 +598,9 @@ func createapi(cmd *Command, args []string) int {
|
|||||||
-1,
|
-1,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
ColorLog("[INFO] Using '%s' as 'driver'\n", driver)
|
logger.Infof("Using '%s' as 'driver'", driver)
|
||||||
ColorLog("[INFO] Using '%s' as 'conn'\n", conn)
|
logger.Infof("Using '%s' as 'conn'", conn)
|
||||||
ColorLog("[INFO] Using '%s' as 'tables'\n", tables)
|
logger.Infof("Using '%s' as 'tables'", tables)
|
||||||
generateAppcode(string(driver), string(conn), "3", string(tables), apppath)
|
generateAppcode(string(driver), string(conn), "3", string(tables), apppath)
|
||||||
} else {
|
} else {
|
||||||
os.Mkdir(path.Join(apppath, "models"), 0755)
|
os.Mkdir(path.Join(apppath, "models"), 0755)
|
||||||
@ -635,15 +634,14 @@ func createapi(cmd *Command, args []string) int {
|
|||||||
WriteToFile(path.Join(apppath, "main.go"),
|
WriteToFile(path.Join(apppath, "main.go"),
|
||||||
strings.Replace(apiMaingo, "{{.Appname}}", packpath, -1))
|
strings.Replace(apiMaingo, "{{.Appname}}", packpath, -1))
|
||||||
}
|
}
|
||||||
ColorLog("[SUCC] New API successfully created!\n")
|
logger.Success("New API successfully created!")
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkEnv(appname string) (apppath, packpath string, err error) {
|
func checkEnv(appname string) (apppath, packpath string, err error) {
|
||||||
gps := GetGOPATHs()
|
gps := GetGOPATHs()
|
||||||
if len(gps) == 0 {
|
if len(gps) == 0 {
|
||||||
ColorLog("[ERRO] Fail to start[ %s ]\n", "GOPATH environment variable is not set or empty")
|
logger.Fatal("GOPATH environment variable is not set or empty")
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
currpath, _ := os.Getwd()
|
currpath, _ := os.Getwd()
|
||||||
currpath = path.Join(currpath, appname)
|
currpath = path.Join(currpath, appname)
|
||||||
@ -658,15 +656,16 @@ func checkEnv(appname string) (apppath, packpath string, err error) {
|
|||||||
// In case of multiple paths in the GOPATH, by default
|
// In case of multiple paths in the GOPATH, by default
|
||||||
// we use the first path
|
// we use the first path
|
||||||
gopath := gps[0]
|
gopath := gps[0]
|
||||||
ColorLog("[%s]You current workdir is not a $GOPATH/src, bee will create the application in GOPATH: %s\n", WARN, gopath)
|
|
||||||
Debugf("GOPATH: %s", gopath)
|
logger.Warn("You current workdir is not inside $GOPATH/src")
|
||||||
|
logger.Debugf("GOPATH: %s", gopath)
|
||||||
|
|
||||||
gosrcpath := path.Join(gopath, "src")
|
gosrcpath := path.Join(gopath, "src")
|
||||||
apppath = path.Join(gosrcpath, appname)
|
apppath = path.Join(gosrcpath, appname)
|
||||||
|
|
||||||
if _, e := os.Stat(apppath); os.IsNotExist(e) == false {
|
if _, e := os.Stat(apppath); os.IsNotExist(e) == false {
|
||||||
err = fmt.Errorf("Cannot create application without removing '%s' first.", apppath)
|
err = fmt.Errorf("Cannot create application without removing '%s' first.", apppath)
|
||||||
ColorLog("[ERRO] Path '%s' already exists\n", apppath)
|
logger.Errorf("Path '%s' already exists", apppath)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
packpath = strings.Join(strings.Split(apppath[len(gosrcpath)+1:], string(path.Separator)), "/")
|
packpath = strings.Join(strings.Split(apppath[len(gosrcpath)+1:], string(path.Separator)), "/")
|
||||||
|
@ -66,7 +66,7 @@ func getControllerInfo(path string) (map[string][]string, error) {
|
|||||||
|
|
||||||
files := make([]*source, 0, len(fis))
|
files := make([]*source, 0, len(fis))
|
||||||
for _, fi := range fis {
|
for _, fi := range fis {
|
||||||
// Only load go files.
|
// Only load Go files
|
||||||
if strings.HasSuffix(fi.Name(), ".go") {
|
if strings.HasSuffix(fi.Name(), ".go") {
|
||||||
f, err := os.Open(path + "/" + fi.Name())
|
f, err := os.Open(path + "/" + fi.Name())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -107,7 +107,7 @@ func getControllerInfo(path string) (map[string][]string, error) {
|
|||||||
return cm, nil
|
return cm, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// A source describles a source code file.
|
// source represents a source code file.
|
||||||
type source struct {
|
type source struct {
|
||||||
name string
|
name string
|
||||||
data []byte
|
data []byte
|
||||||
@ -120,27 +120,25 @@ func (s *source) ModTime() time.Time { return time.Time{} }
|
|||||||
func (s *source) IsDir() bool { return false }
|
func (s *source) IsDir() bool { return false }
|
||||||
func (s *source) Sys() interface{} { return nil }
|
func (s *source) Sys() interface{} { return nil }
|
||||||
|
|
||||||
// A routerWalker holds the state used when building the documentation.
|
// routerWalker holds the state used when building the documentation.
|
||||||
type routerWalker struct {
|
type routerWalker struct {
|
||||||
pdoc *Package
|
pdoc *Package
|
||||||
srcs map[string]*source // Source files.
|
srcs map[string]*source // Source files
|
||||||
fset *token.FileSet
|
fset *token.FileSet
|
||||||
buf []byte // scratch space for printNode method.
|
buf []byte // scratch space for printNode method
|
||||||
}
|
}
|
||||||
|
|
||||||
// Package represents full information and documentation for a package.
|
// Package represents full information and documentation for a package.
|
||||||
type Package struct {
|
type Package struct {
|
||||||
ImportPath string
|
ImportPath string
|
||||||
|
Types []*Type // Top-level declarations
|
||||||
// Top-level declarations.
|
|
||||||
Types []*Type
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type represents structs and interfaces.
|
// Type represents structs and interfaces.
|
||||||
type Type struct {
|
type Type struct {
|
||||||
Name string // Type name.
|
Name string // Type name
|
||||||
Decl string
|
Decl string
|
||||||
Methods []*Func // Exported methods.
|
Methods []*Func // Exported methods
|
||||||
}
|
}
|
||||||
|
|
||||||
// Func represents functions
|
// Func represents functions
|
||||||
@ -150,7 +148,7 @@ type Func struct {
|
|||||||
|
|
||||||
// build generates data from source files.
|
// build generates data from source files.
|
||||||
func (w *routerWalker) build(srcs []*source) (*Package, error) {
|
func (w *routerWalker) build(srcs []*source) (*Package, error) {
|
||||||
// Add source files to walker, I skipped references here.
|
// Add source files to walker, I skipped references here
|
||||||
w.srcs = make(map[string]*source)
|
w.srcs = make(map[string]*source)
|
||||||
for _, src := range srcs {
|
for _, src := range srcs {
|
||||||
w.srcs[src.name] = src
|
w.srcs[src.name] = src
|
||||||
@ -158,7 +156,7 @@ func (w *routerWalker) build(srcs []*source) (*Package, error) {
|
|||||||
|
|
||||||
w.fset = token.NewFileSet()
|
w.fset = token.NewFileSet()
|
||||||
|
|
||||||
// Find the package and associated files.
|
// Find the package and associated files
|
||||||
ctxt := gobuild.Context{
|
ctxt := gobuild.Context{
|
||||||
GOOS: runtime.GOOS,
|
GOOS: runtime.GOOS,
|
||||||
GOARCH: runtime.GOARCH,
|
GOARCH: runtime.GOARCH,
|
||||||
@ -174,7 +172,7 @@ func (w *routerWalker) build(srcs []*source) (*Package, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bpkg, err := ctxt.ImportDir(w.pdoc.ImportPath, 0)
|
bpkg, err := ctxt.ImportDir(w.pdoc.ImportPath, 0)
|
||||||
// Continue if there are no Go source files; we still want the directory info.
|
// Continue if there are no Go source files; we still want the directory info
|
||||||
_, nogo := err.(*gobuild.NoGoError)
|
_, nogo := err.(*gobuild.NoGoError)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if nogo {
|
if nogo {
|
||||||
@ -272,9 +270,8 @@ func simpleImporter(imports map[string]*ast.Object, path string) (*ast.Object, e
|
|||||||
name = strings.TrimPrefix(name, "biogo.")
|
name = strings.TrimPrefix(name, "biogo.")
|
||||||
|
|
||||||
// It's also common for the last element of the path to contain an
|
// 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
|
// extra "go" prefix, but not always.
|
||||||
// detect when trimming the "go" prefix is appropriate.
|
// TODO: examine unresolved ids to detect when trimming the "go" prefix is appropriate.
|
||||||
|
|
||||||
pkg = ast.NewObj(ast.Pkg, name)
|
pkg = ast.NewObj(ast.Pkg, name)
|
||||||
pkg.Data = ast.NewScope(nil)
|
pkg.Data = ast.NewScope(nil)
|
||||||
imports[path] = pkg
|
imports[path] = pkg
|
||||||
|
39
bale.go
39
bale.go
@ -50,19 +50,19 @@ func runBale(cmd *Command, args []string) int {
|
|||||||
|
|
||||||
err := loadConfig()
|
err := loadConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[ERRO] Fail to parse bee.json[ %s ]\n", err)
|
logger.Fatalf("Failed to load configuration: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
os.RemoveAll("bale")
|
os.RemoveAll("bale")
|
||||||
os.Mkdir("bale", os.ModePerm)
|
os.Mkdir("bale", os.ModePerm)
|
||||||
|
|
||||||
// Pack and compress data.
|
// Pack and compress data
|
||||||
for _, p := range conf.Bale.Dirs {
|
for _, p := range conf.Bale.Dirs {
|
||||||
if !isExist(p) {
|
if !isExist(p) {
|
||||||
ColorLog("[WARN] Skipped directory( %s )\n", p)
|
logger.Warnf("Skipped directory: %s", p)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
ColorLog("[INFO] Packaging directory( %s )\n", p)
|
logger.Infof("Packaging directory: %s", p)
|
||||||
filepath.Walk(p, walkFn)
|
filepath.Walk(p, walkFn)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,22 +74,21 @@ func runBale(cmd *Command, args []string) int {
|
|||||||
|
|
||||||
fw, err := os.Create("bale.go")
|
fw, err := os.Create("bale.go")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[ERRO] Fail to create file[ %s ]\n", err)
|
logger.Fatalf("Failed to create file: %s", err)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
defer fw.Close()
|
defer fw.Close()
|
||||||
|
|
||||||
_, err = fw.Write(buf.Bytes())
|
_, err = fw.Write(buf.Bytes())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[ERRO] Fail to write data[ %s ]\n", err)
|
logger.Fatalf("Failed to write data: %s", err)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorLog("[SUCC] Baled resources successfully!\n")
|
logger.Success("Baled resources successfully!")
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// BaleHeader ...
|
||||||
BaleHeader = `package main
|
BaleHeader = `package main
|
||||||
|
|
||||||
import(
|
import(
|
||||||
@ -150,14 +149,13 @@ func walkFn(resPath string, info os.FileInfo, err error) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open resource files.
|
// Open resource files
|
||||||
fr, err := os.Open(resPath)
|
fr, err := os.Open(resPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[ERRO] Fail to read file[ %s ]\n", err)
|
logger.Fatalf("Failed to read file: %s", err)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert path.
|
// Convert path
|
||||||
resPath = strings.Replace(resPath, "_", "_0_", -1)
|
resPath = strings.Replace(resPath, "_", "_0_", -1)
|
||||||
resPath = strings.Replace(resPath, ".", "_1_", -1)
|
resPath = strings.Replace(resPath, ".", "_1_", -1)
|
||||||
resPath = strings.Replace(resPath, "-", "_2_", -1)
|
resPath = strings.Replace(resPath, "-", "_2_", -1)
|
||||||
@ -168,19 +166,18 @@ func walkFn(resPath string, info os.FileInfo, err error) error {
|
|||||||
}
|
}
|
||||||
resPath = strings.Replace(resPath, sep, "_4_", -1)
|
resPath = strings.Replace(resPath, sep, "_4_", -1)
|
||||||
|
|
||||||
// Create corresponding Go source files.
|
// Create corresponding Go source files
|
||||||
os.MkdirAll(path.Dir(resPath), os.ModePerm)
|
os.MkdirAll(path.Dir(resPath), os.ModePerm)
|
||||||
fw, err := os.Create("bale/" + resPath + ".go")
|
fw, err := os.Create("bale/" + resPath + ".go")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[ERRO] Fail to create file[ %s ]\n", err)
|
logger.Fatalf("Failed to create file: %s", err)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
defer fw.Close()
|
defer fw.Close()
|
||||||
|
|
||||||
// Write header.
|
// Write header
|
||||||
fmt.Fprintf(fw, Header, resPath)
|
fmt.Fprintf(fw, Header, resPath)
|
||||||
|
|
||||||
// Copy and compress data.
|
// Copy and compress data
|
||||||
gz := gzip.NewWriter(&ByteWriter{Writer: fw})
|
gz := gzip.NewWriter(&ByteWriter{Writer: fw})
|
||||||
io.Copy(gz, fr)
|
io.Copy(gz, fr)
|
||||||
gz.Close()
|
gz.Close()
|
||||||
@ -202,6 +199,7 @@ func filterSuffix(name string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// Header ...
|
||||||
Header = `package bale
|
Header = `package bale
|
||||||
|
|
||||||
import(
|
import(
|
||||||
@ -212,6 +210,7 @@ import(
|
|||||||
|
|
||||||
func R%s() []byte {
|
func R%s() []byte {
|
||||||
gz, err := gzip.NewReader(bytes.NewBuffer([]byte{`
|
gz, err := gzip.NewReader(bytes.NewBuffer([]byte{`
|
||||||
|
// Footer ...
|
||||||
Footer = `
|
Footer = `
|
||||||
}))
|
}))
|
||||||
|
|
||||||
@ -229,6 +228,7 @@ func R%s() []byte {
|
|||||||
|
|
||||||
var newline = []byte{'\n'}
|
var newline = []byte{'\n'}
|
||||||
|
|
||||||
|
// ByteWriter ...
|
||||||
type ByteWriter struct {
|
type ByteWriter struct {
|
||||||
io.Writer
|
io.Writer
|
||||||
c int
|
c int
|
||||||
@ -244,12 +244,9 @@ func (w *ByteWriter) Write(p []byte) (n int, err error) {
|
|||||||
w.Writer.Write(newline)
|
w.Writer.Write(newline)
|
||||||
w.c = 0
|
w.c = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintf(w.Writer, "0x%02x,", p[n])
|
fmt.Fprintf(w.Writer, "0x%02x,", p[n])
|
||||||
w.c++
|
w.c++
|
||||||
}
|
}
|
||||||
|
|
||||||
n++
|
n++
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
21
banner.go
21
banner.go
@ -6,7 +6,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
"text/template"
|
"text/template"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type vars struct {
|
type vars struct {
|
||||||
@ -21,25 +20,17 @@ type vars struct {
|
|||||||
BeegoVersion string
|
BeegoVersion string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now returns the current local time in the specified layout
|
|
||||||
func Now(layout string) string {
|
|
||||||
return time.Now().Format(layout)
|
|
||||||
}
|
|
||||||
|
|
||||||
// InitBanner loads the banner and prints it to output
|
// InitBanner loads the banner and prints it to output
|
||||||
// All errors are ignored, the application will not
|
// All errors are ignored, the application will not
|
||||||
// print the banner in case of error.
|
// print the banner in case of error.
|
||||||
func InitBanner(out io.Writer, in io.Reader) {
|
func InitBanner(out io.Writer, in io.Reader) {
|
||||||
if in == nil {
|
if in == nil {
|
||||||
ColorLog("[ERRO] The input is nil\n")
|
logger.Fatal("The input is nil")
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
banner, err := ioutil.ReadAll(in)
|
banner, err := ioutil.ReadAll(in)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[ERRO] Error trying to read the banner\n")
|
logger.Fatalf("Error while trying to read the banner: %s", err)
|
||||||
ColorLog("[HINT] %v\n", err)
|
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
show(out, string(banner))
|
show(out, string(banner))
|
||||||
@ -51,9 +42,7 @@ func show(out io.Writer, content string) {
|
|||||||
Parse(content)
|
Parse(content)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[ERRO] Cannot parse the banner template\n")
|
logger.Fatalf("Cannot parse the banner template: %s", err)
|
||||||
ColorLog("[HINT] %v\n", err)
|
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = t.Execute(out, vars{
|
err = t.Execute(out, vars{
|
||||||
@ -67,7 +56,5 @@ func show(out io.Writer, content string) {
|
|||||||
version,
|
version,
|
||||||
getBeegoVersion(),
|
getBeegoVersion(),
|
||||||
})
|
})
|
||||||
if err != nil {
|
MustCheck(err)
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
2
bee.go
2
bee.go
@ -27,6 +27,7 @@ import (
|
|||||||
|
|
||||||
const version = "1.5.2"
|
const version = "1.5.2"
|
||||||
|
|
||||||
|
// Command is the unit of execution
|
||||||
type Command struct {
|
type Command struct {
|
||||||
// Run runs the command.
|
// Run runs the command.
|
||||||
// The args are the arguments after the command name.
|
// The args are the arguments after the command name.
|
||||||
@ -60,6 +61,7 @@ func (c *Command) Name() string {
|
|||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Usage puts out the usage for the command.
|
||||||
func (c *Command) Usage() {
|
func (c *Command) Usage() {
|
||||||
fmt.Fprintf(os.Stderr, "usage: %s\n\n", c.UsageLine)
|
fmt.Fprintf(os.Stderr, "usage: %s\n\n", c.UsageLine)
|
||||||
fmt.Fprintf(os.Stderr, "%s\n", strings.TrimSpace(string(c.Long)))
|
fmt.Fprintf(os.Stderr, "%s\n", strings.TrimSpace(string(c.Long)))
|
||||||
|
4
code.go
4
code.go
@ -109,12 +109,12 @@ func (v *annotationVisitor) Visit(n ast.Node) ast.Visitor {
|
|||||||
v.ignoreName()
|
v.ignoreName()
|
||||||
ast.Walk(v, n.Type)
|
ast.Walk(v, n.Type)
|
||||||
case *ast.Field:
|
case *ast.Field:
|
||||||
for _ = range n.Names {
|
for range n.Names {
|
||||||
v.ignoreName()
|
v.ignoreName()
|
||||||
}
|
}
|
||||||
ast.Walk(v, n.Type)
|
ast.Walk(v, n.Type)
|
||||||
case *ast.ValueSpec:
|
case *ast.ValueSpec:
|
||||||
for _ = range n.Names {
|
for range n.Names {
|
||||||
v.add(AnchorAnnotation, "")
|
v.add(AnchorAnnotation, "")
|
||||||
}
|
}
|
||||||
if n.Type != nil {
|
if n.Type != nil {
|
||||||
|
18
conf.go
18
conf.go
@ -25,7 +25,7 @@ import (
|
|||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
const ConfVer = 0
|
const confVer = 0
|
||||||
|
|
||||||
var defaultConf = `{
|
var defaultConf = `{
|
||||||
"version": 0,
|
"version": 0,
|
||||||
@ -89,20 +89,20 @@ func loadConfig() (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if fileInfo.Name() == "bee.json" {
|
if fileInfo.Name() == "bee.json" {
|
||||||
ColorLog("[INFO] Loading configuration from 'bee.json'...\n")
|
logger.Info("Loading configuration from 'bee.json'...")
|
||||||
err = parseJSON(path, conf)
|
err = parseJSON(path, conf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[ERRO] Failed to parse JSON file: %v\n", err)
|
logger.Errorf("Failed to parse JSON file: %s", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return io.EOF
|
return io.EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
if fileInfo.Name() == "Beefile" {
|
if fileInfo.Name() == "Beefile" {
|
||||||
ColorLog("[INFO] Loading configuration from 'Beefile'...\n")
|
logger.Info("Loading configuration from 'Beefile'...")
|
||||||
err = parseYAML(path, conf)
|
err = parseYAML(path, conf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[ERRO] Failed to parse YAML file: %v\n", err)
|
logger.Errorf("Failed to parse YAML file: %s", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return io.EOF
|
return io.EOF
|
||||||
@ -113,7 +113,7 @@ func loadConfig() (err error) {
|
|||||||
// In case no configuration file found or an error different than io.EOF,
|
// In case no configuration file found or an error different than io.EOF,
|
||||||
// fallback to default configuration
|
// fallback to default configuration
|
||||||
if err != io.EOF {
|
if err != io.EOF {
|
||||||
ColorLog("[INFO] Loading default configuration...\n")
|
logger.Info("Loading default configuration...")
|
||||||
err = json.Unmarshal([]byte(defaultConf), &conf)
|
err = json.Unmarshal([]byte(defaultConf), &conf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
@ -124,9 +124,9 @@ func loadConfig() (err error) {
|
|||||||
err = nil
|
err = nil
|
||||||
|
|
||||||
// Check format version
|
// Check format version
|
||||||
if conf.Version != ConfVer {
|
if conf.Version != confVer {
|
||||||
ColorLog("[WARN] Your bee.json is outdated. Please do consider updating it.\n")
|
logger.Warn("Your configuration file is outdated. Please do consider updating it.")
|
||||||
ColorLog("[HINT] Compare bee.json under bee source code path and yours\n")
|
logger.Hint("Check the latest version of bee's configuration file.")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set variables
|
// Set variables
|
||||||
|
21
fix.go
21
fix.go
@ -1,6 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"go/parser"
|
"go/parser"
|
||||||
"go/token"
|
"go/token"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
@ -8,7 +9,6 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"fmt"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var cmdFix = &Command{
|
var cmdFix = &Command{
|
||||||
@ -28,11 +28,12 @@ func init() {
|
|||||||
func runFix(cmd *Command, args []string) int {
|
func runFix(cmd *Command, args []string) int {
|
||||||
ShowShortVersionBanner()
|
ShowShortVersionBanner()
|
||||||
|
|
||||||
ColorLog("[INFO] Upgrading the application...\n")
|
logger.Info("Upgrading the application...")
|
||||||
dir, err := os.Getwd()
|
dir, err := os.Getwd()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[ERRO] GetCurrent Path:%s\n", err)
|
logger.Fatalf("Error while getting the current working directory: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
|
filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
|
||||||
if info.IsDir() {
|
if info.IsDir() {
|
||||||
if strings.HasPrefix(info.Name(), ".") {
|
if strings.HasPrefix(info.Name(), ".") {
|
||||||
@ -49,11 +50,11 @@ func runFix(cmd *Command, args []string) int {
|
|||||||
err = fixFile(path)
|
err = fixFile(path)
|
||||||
fmt.Println("\tfix\t", path)
|
fmt.Println("\tfix\t", path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[ERRO] Could not fix file: %s\n", err)
|
logger.Errorf("Could not fix file: %s", err)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
ColorLog("[INFO] Upgrade done!\n")
|
logger.Success("Upgrade done!")
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,18 +168,18 @@ func fixFile(file string) error {
|
|||||||
}
|
}
|
||||||
fixed := rp.Replace(string(content))
|
fixed := rp.Replace(string(content))
|
||||||
|
|
||||||
// forword the RequestBody from the replace
|
// Forword the RequestBody from the replace
|
||||||
// "Input.Request", "Input.Context.Request",
|
// "Input.Request", "Input.Context.Request",
|
||||||
fixed = strings.Replace(fixed, "Input.Context.RequestBody", "Input.RequestBody", -1)
|
fixed = strings.Replace(fixed, "Input.Context.RequestBody", "Input.RequestBody", -1)
|
||||||
|
|
||||||
// regexp replace
|
// Regexp replace
|
||||||
pareg := regexp.MustCompile(`(Input.Params\[")(.*)("])`)
|
pareg := regexp.MustCompile(`(Input.Params\[")(.*)("])`)
|
||||||
fixed = pareg.ReplaceAllString(fixed, "Input.Param(\"$2\")")
|
fixed = pareg.ReplaceAllString(fixed, "Input.Param(\"$2\")")
|
||||||
pareg = regexp.MustCompile(`(Input.Data\[\")(.*)(\"\])(\s)(=)(\s)(.*)`)
|
pareg = regexp.MustCompile(`(Input.Data\[\")(.*)(\"\])(\s)(=)(\s)(.*)`)
|
||||||
fixed = pareg.ReplaceAllString(fixed, "Input.SetData(\"$2\", $7)")
|
fixed = pareg.ReplaceAllString(fixed, "Input.SetData(\"$2\", $7)")
|
||||||
pareg = regexp.MustCompile(`(Input.Data\[\")(.*)(\"\])`)
|
pareg = regexp.MustCompile(`(Input.Data\[\")(.*)(\"\])`)
|
||||||
fixed = pareg.ReplaceAllString(fixed, "Input.Data(\"$2\")")
|
fixed = pareg.ReplaceAllString(fixed, "Input.Data(\"$2\")")
|
||||||
// fix the cache object Put method
|
// Fix the cache object Put method
|
||||||
pareg = regexp.MustCompile(`(\.Put\(\")(.*)(\",)(\s)(.*)(,\s*)([^\*.]*)(\))`)
|
pareg = regexp.MustCompile(`(\.Put\(\")(.*)(\",)(\s)(.*)(,\s*)([^\*.]*)(\))`)
|
||||||
if pareg.MatchString(fixed) && strings.HasSuffix(file, ".go") {
|
if pareg.MatchString(fixed) && strings.HasSuffix(file, ".go") {
|
||||||
fixed = pareg.ReplaceAllString(fixed, ".Put(\"$2\", $5, $7*time.Second)")
|
fixed = pareg.ReplaceAllString(fixed, ".Put(\"$2\", $5, $7*time.Second)")
|
||||||
@ -199,11 +200,11 @@ func fixFile(file string) error {
|
|||||||
fixed = strings.Replace(fixed, "import (", "import (\n\t\"time\"", 1)
|
fixed = strings.Replace(fixed, "import (", "import (\n\t\"time\"", 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// replace the v.Apis in docs.go
|
// Replace the v.Apis in docs.go
|
||||||
if strings.Contains(file, "docs.go") {
|
if strings.Contains(file, "docs.go") {
|
||||||
fixed = strings.Replace(fixed, "v.Apis", "v.APIs", -1)
|
fixed = strings.Replace(fixed, "v.Apis", "v.APIs", -1)
|
||||||
}
|
}
|
||||||
// replace the config file
|
// Replace the config file
|
||||||
if strings.HasSuffix(file, ".conf") {
|
if strings.HasSuffix(file, ".conf") {
|
||||||
fixed = strings.Replace(fixed, "HttpCertFile", "HTTPSCertFile", -1)
|
fixed = strings.Replace(fixed, "HttpCertFile", "HTTPSCertFile", -1)
|
||||||
fixed = strings.Replace(fixed, "HttpKeyFile", "HTTPSKeyFile", -1)
|
fixed = strings.Replace(fixed, "HttpKeyFile", "HTTPSKeyFile", -1)
|
||||||
|
63
g.go
63
g.go
@ -81,29 +81,28 @@ func generateCode(cmd *Command, args []string) int {
|
|||||||
|
|
||||||
currpath, _ := os.Getwd()
|
currpath, _ := os.Getwd()
|
||||||
if len(args) < 1 {
|
if len(args) < 1 {
|
||||||
ColorLog("[ERRO] command is missing\n")
|
logger.Fatal("Command is missing")
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gps := GetGOPATHs()
|
gps := GetGOPATHs()
|
||||||
if len(gps) == 0 {
|
if len(gps) == 0 {
|
||||||
ColorLog("[ERRO] Fail to start[ %s ]\n", "GOPATH environment variable is not set or empty")
|
logger.Fatal("GOPATH environment variable is not set or empty")
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gopath := gps[0]
|
gopath := gps[0]
|
||||||
Debugf("GOPATH: %s", gopath)
|
|
||||||
|
logger.Debugf("GOPATH: %s", gopath)
|
||||||
|
|
||||||
gcmd := args[0]
|
gcmd := args[0]
|
||||||
switch gcmd {
|
switch gcmd {
|
||||||
case "scaffold":
|
case "scaffold":
|
||||||
if len(args) < 2 {
|
if len(args) < 2 {
|
||||||
ColorLog("[ERRO] Wrong number of arguments\n")
|
logger.Fatal("Wrong number of arguments. Run: bee help generate")
|
||||||
ColorLog("[HINT] Usage: bee generate scaffold [scaffoldname] [-fields=\"\"]\n")
|
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
|
// Load the configuration
|
||||||
err := loadConfig()
|
err := loadConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[ERRO] Fail to parse bee.json[ %s ]\n", err)
|
logger.Fatalf("Failed to load configuration: %s", err)
|
||||||
}
|
}
|
||||||
cmd.Flag.Parse(args[2:])
|
cmd.Flag.Parse(args[2:])
|
||||||
if driver == "" {
|
if driver == "" {
|
||||||
@ -119,19 +118,18 @@ func generateCode(cmd *Command, args []string) int {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if fields == "" {
|
if fields == "" {
|
||||||
ColorLog("[ERRO] Wrong number of arguments\n")
|
logger.Hint("fields option should not be empty, i.e. -fields=\"title:string,body:text\"")
|
||||||
ColorLog("[HINT] Usage: bee generate scaffold [scaffoldname] [-fields=\"title:string,body:text\"]\n")
|
logger.Fatal("Wrong number of arguments. Run: bee help generate")
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
sname := args[1]
|
sname := args[1]
|
||||||
generateScaffold(sname, fields.String(), currpath, driver.String(), conn.String())
|
generateScaffold(sname, fields.String(), currpath, driver.String(), conn.String())
|
||||||
case "docs":
|
case "docs":
|
||||||
generateDocs(currpath)
|
generateDocs(currpath)
|
||||||
case "appcode":
|
case "appcode":
|
||||||
// load config
|
// Load the configuration
|
||||||
err := loadConfig()
|
err := loadConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[ERRO] Fail to parse bee.json[ %s ]\n", err)
|
logger.Fatalf("Failed to load configuration: %s", err)
|
||||||
}
|
}
|
||||||
cmd.Flag.Parse(args[1:])
|
cmd.Flag.Parse(args[1:])
|
||||||
if driver == "" {
|
if driver == "" {
|
||||||
@ -153,20 +151,20 @@ func generateCode(cmd *Command, args []string) int {
|
|||||||
if level == "" {
|
if level == "" {
|
||||||
level = "3"
|
level = "3"
|
||||||
}
|
}
|
||||||
ColorLog("[INFO] Using '%s' as 'driver'\n", driver)
|
logger.Infof("Using '%s' as 'driver'", driver)
|
||||||
ColorLog("[INFO] Using '%s' as 'conn'\n", conn)
|
logger.Infof("Using '%s' as 'conn'", conn)
|
||||||
ColorLog("[INFO] Using '%s' as 'tables'\n", tables)
|
logger.Infof("Using '%s' as 'tables'", tables)
|
||||||
ColorLog("[INFO] Using '%s' as 'level'\n", level)
|
logger.Infof("Using '%s' as 'level'", level)
|
||||||
generateAppcode(driver.String(), conn.String(), level.String(), tables.String(), currpath)
|
generateAppcode(driver.String(), conn.String(), level.String(), tables.String(), currpath)
|
||||||
case "migration":
|
case "migration":
|
||||||
if len(args) < 2 {
|
if len(args) < 2 {
|
||||||
ColorLog("[ERRO] Wrong number of arguments\n")
|
logger.Fatal("Wrong number of arguments. Run: bee help generate")
|
||||||
ColorLog("[HINT] Usage: bee generate migration [migrationname] [-fields=\"\"]\n")
|
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
cmd.Flag.Parse(args[2:])
|
cmd.Flag.Parse(args[2:])
|
||||||
mname := args[1]
|
mname := args[1]
|
||||||
ColorLog("[INFO] Using '%s' as migration name\n", mname)
|
|
||||||
|
logger.Infof("Using '%s' as migration name", mname)
|
||||||
|
|
||||||
upsql := ""
|
upsql := ""
|
||||||
downsql := ""
|
downsql := ""
|
||||||
if fields != "" {
|
if fields != "" {
|
||||||
@ -180,21 +178,16 @@ func generateCode(cmd *Command, args []string) int {
|
|||||||
cname := args[1]
|
cname := args[1]
|
||||||
generateController(cname, currpath)
|
generateController(cname, currpath)
|
||||||
} else {
|
} else {
|
||||||
ColorLog("[ERRO] Wrong number of arguments\n")
|
logger.Fatal("Wrong number of arguments. Run: bee help generate")
|
||||||
ColorLog("[HINT] Usage: bee generate controller [controllername]\n")
|
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
case "model":
|
case "model":
|
||||||
if len(args) < 2 {
|
if len(args) < 2 {
|
||||||
ColorLog("[ERRO] Wrong number of arguments\n")
|
logger.Fatal("Wrong number of arguments. Run: bee help generate")
|
||||||
ColorLog("[HINT] Usage: bee generate model [modelname] [-fields=\"\"]\n")
|
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
cmd.Flag.Parse(args[2:])
|
cmd.Flag.Parse(args[2:])
|
||||||
if fields == "" {
|
if fields == "" {
|
||||||
ColorLog("[ERRO] Wrong number of arguments\n")
|
logger.Hint("fields option should not be empty, i.e. -fields=\"title:string,body:text\"")
|
||||||
ColorLog("[HINT] Usage: bee generate model [modelname] [-fields=\"title:string,body:text\"]\n")
|
logger.Fatal("Wrong number of arguments. Run: bee help generate")
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
sname := args[1]
|
sname := args[1]
|
||||||
generateModel(sname, fields.String(), currpath)
|
generateModel(sname, fields.String(), currpath)
|
||||||
@ -203,13 +196,11 @@ func generateCode(cmd *Command, args []string) int {
|
|||||||
cname := args[1]
|
cname := args[1]
|
||||||
generateView(cname, currpath)
|
generateView(cname, currpath)
|
||||||
} else {
|
} else {
|
||||||
ColorLog("[ERRO] Wrong number of arguments\n")
|
logger.Fatal("Wrong number of arguments. Run: bee help generate")
|
||||||
ColorLog("[HINT] Usage: bee generate view [viewpath]\n")
|
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
ColorLog("[ERRO] Command is missing\n")
|
logger.Fatal("Command is missing")
|
||||||
}
|
}
|
||||||
ColorLog("[SUCC] %s successfully generated!\n", strings.Title(gcmd))
|
logger.Successf("%s successfully generated!", strings.Title(gcmd))
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
196
g_appcode.go
196
g_appcode.go
@ -18,7 +18,6 @@ import (
|
|||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
@ -39,7 +38,7 @@ type DbTransformer interface {
|
|||||||
GetTableNames(conn *sql.DB) []string
|
GetTableNames(conn *sql.DB) []string
|
||||||
GetConstraints(conn *sql.DB, table *Table, blackList map[string]bool)
|
GetConstraints(conn *sql.DB, table *Table, blackList map[string]bool)
|
||||||
GetColumns(conn *sql.DB, table *Table, blackList map[string]bool)
|
GetColumns(conn *sql.DB, table *Table, blackList map[string]bool)
|
||||||
GetGoDataType(sqlType string) string
|
GetGoDataType(sqlType string) (string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MysqlDB is the MySQL version of DbTransformer
|
// MysqlDB is the MySQL version of DbTransformer
|
||||||
@ -265,9 +264,7 @@ func generateAppcode(driver, connStr, level, tables, currpath string) {
|
|||||||
case "3":
|
case "3":
|
||||||
mode = OModel | OController | ORouter
|
mode = OModel | OController | ORouter
|
||||||
default:
|
default:
|
||||||
ColorLog("[ERRO] Invalid 'level' option: %s\n", level)
|
logger.Fatal("Invalid level value. Must be either \"1\", \"2\", or \"3\"")
|
||||||
ColorLog("[HINT] Level must be either 1, 2 or 3\n")
|
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
var selectedTables map[string]bool
|
var selectedTables map[string]bool
|
||||||
if tables != "" {
|
if tables != "" {
|
||||||
@ -280,12 +277,9 @@ func generateAppcode(driver, connStr, level, tables, currpath string) {
|
|||||||
case "mysql":
|
case "mysql":
|
||||||
case "postgres":
|
case "postgres":
|
||||||
case "sqlite":
|
case "sqlite":
|
||||||
ColorLog("[ERRO] Generating app code from SQLite database is not supported yet.\n")
|
logger.Fatal("Generating app code from SQLite database is not supported yet.")
|
||||||
os.Exit(2)
|
|
||||||
default:
|
default:
|
||||||
ColorLog("[ERRO] Unknown database driver: %s\n", driver)
|
logger.Fatal("Unknown database driver. Must be either \"mysql\", \"postgres\" or \"sqlite\"")
|
||||||
ColorLog("[HINT] Driver must be one of mysql, postgres or sqlite\n")
|
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
gen(driver, connStr, mode, selectedTables, currpath)
|
gen(driver, connStr, mode, selectedTables, currpath)
|
||||||
}
|
}
|
||||||
@ -295,12 +289,11 @@ func generateAppcode(driver, connStr, level, tables, currpath string) {
|
|||||||
func gen(dbms, connStr string, mode byte, selectedTableNames map[string]bool, apppath string) {
|
func gen(dbms, connStr string, mode byte, selectedTableNames map[string]bool, apppath string) {
|
||||||
db, err := sql.Open(dbms, connStr)
|
db, err := sql.Open(dbms, connStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[ERRO] Could not connect to %s database: %s, %s\n", dbms, connStr, err)
|
logger.Fatalf("Could not connect to '%s' database using '%s': %s", dbms, connStr, err)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
if trans, ok := dbDriver[dbms]; ok {
|
if trans, ok := dbDriver[dbms]; ok {
|
||||||
ColorLog("[INFO] Analyzing database tables...\n")
|
logger.Info("Analyzing database tables...")
|
||||||
tableNames := trans.GetTableNames(db)
|
tableNames := trans.GetTableNames(db)
|
||||||
tables := getTableObjects(tableNames, db, trans)
|
tables := getTableObjects(tableNames, db, trans)
|
||||||
mvcPath := new(MvcPath)
|
mvcPath := new(MvcPath)
|
||||||
@ -311,25 +304,21 @@ func gen(dbms, connStr string, mode byte, selectedTableNames map[string]bool, ap
|
|||||||
pkgPath := getPackagePath(apppath)
|
pkgPath := getPackagePath(apppath)
|
||||||
writeSourceFiles(pkgPath, tables, mode, mvcPath, selectedTableNames)
|
writeSourceFiles(pkgPath, tables, mode, mvcPath, selectedTableNames)
|
||||||
} else {
|
} else {
|
||||||
ColorLog("[ERRO] Generating app code from %s database is not supported yet.\n", dbms)
|
logger.Fatalf("Generating app code from '%s' database is not supported yet.", dbms)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// getTables gets a list table names in current database
|
// GetTableNames returns a slice of table names in the current database
|
||||||
func (*MysqlDB) GetTableNames(db *sql.DB) (tables []string) {
|
func (*MysqlDB) GetTableNames(db *sql.DB) (tables []string) {
|
||||||
rows, err := db.Query("SHOW TABLES")
|
rows, err := db.Query("SHOW TABLES")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[ERRO] Could not show tables\n")
|
logger.Fatalf("Could not show tables: %s", err)
|
||||||
ColorLog("[HINT] Check your connection string\n")
|
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var name string
|
var name string
|
||||||
if err := rows.Scan(&name); err != nil {
|
if err := rows.Scan(&name); err != nil {
|
||||||
ColorLog("[ERRO] Could not show tables\n")
|
logger.Fatalf("Could not show tables: %s", err)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
tables = append(tables, name)
|
tables = append(tables, name)
|
||||||
}
|
}
|
||||||
@ -358,8 +347,8 @@ func getTableObjects(tableNames []string, db *sql.DB, dbTransformer DbTransforme
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// getConstraints gets primary key, unique key and foreign keys of a table from information_schema
|
// GetConstraints gets primary key, unique key and foreign keys of a table from
|
||||||
// and fill in Table struct
|
// information_schema and fill in the Table struct
|
||||||
func (*MysqlDB) GetConstraints(db *sql.DB, table *Table, blackList map[string]bool) {
|
func (*MysqlDB) GetConstraints(db *sql.DB, table *Table, blackList map[string]bool) {
|
||||||
rows, err := db.Query(
|
rows, err := db.Query(
|
||||||
`SELECT
|
`SELECT
|
||||||
@ -372,14 +361,12 @@ func (*MysqlDB) GetConstraints(db *sql.DB, table *Table, blackList map[string]bo
|
|||||||
c.table_schema = database() AND c.table_name = ? AND u.table_schema = database() AND u.table_name = ?`,
|
c.table_schema = database() AND c.table_name = ? AND u.table_schema = database() AND u.table_name = ?`,
|
||||||
table.Name, table.Name) // u.position_in_unique_constraint,
|
table.Name, table.Name) // u.position_in_unique_constraint,
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[ERRO] Could not query INFORMATION_SCHEMA for PK/UK/FK information\n")
|
logger.Fatal("Could not query INFORMATION_SCHEMA for PK/UK/FK information")
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var constraintTypeBytes, columnNameBytes, refTableSchemaBytes, refTableNameBytes, refColumnNameBytes, refOrdinalPosBytes []byte
|
var constraintTypeBytes, columnNameBytes, refTableSchemaBytes, refTableNameBytes, refColumnNameBytes, refOrdinalPosBytes []byte
|
||||||
if err := rows.Scan(&constraintTypeBytes, &columnNameBytes, &refTableSchemaBytes, &refTableNameBytes, &refColumnNameBytes, &refOrdinalPosBytes); err != nil {
|
if err := rows.Scan(&constraintTypeBytes, &columnNameBytes, &refTableSchemaBytes, &refTableNameBytes, &refColumnNameBytes, &refOrdinalPosBytes); err != nil {
|
||||||
ColorLog("[ERRO] Could not read INFORMATION_SCHEMA for PK/UK/FK information\n")
|
logger.Fatal("Could not read INFORMATION_SCHEMA for PK/UK/FK information")
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
constraintType, columnName, refTableSchema, refTableName, refColumnName, refOrdinalPos :=
|
constraintType, columnName, refTableSchema, refTableName, refColumnName, refOrdinalPos :=
|
||||||
string(constraintTypeBytes), string(columnNameBytes), string(refTableSchemaBytes),
|
string(constraintTypeBytes), string(columnNameBytes), string(refTableSchemaBytes),
|
||||||
@ -389,7 +376,7 @@ func (*MysqlDB) GetConstraints(db *sql.DB, table *Table, blackList map[string]bo
|
|||||||
table.Pk = columnName
|
table.Pk = columnName
|
||||||
} else {
|
} else {
|
||||||
table.Pk = ""
|
table.Pk = ""
|
||||||
// add table to blacklist so that other struct will not reference it, because we are not
|
// Add table to blacklist so that other struct will not reference it, because we are not
|
||||||
// registering blacklisted tables
|
// registering blacklisted tables
|
||||||
blackList[table.Name] = true
|
blackList[table.Name] = true
|
||||||
}
|
}
|
||||||
@ -406,11 +393,11 @@ func (*MysqlDB) GetConstraints(db *sql.DB, table *Table, blackList map[string]bo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// getColumns retrieve columns details from information_schema
|
// GetColumns retrieves columns details from
|
||||||
// and fill in the Column struct
|
// information_schema and fill in the Column struct
|
||||||
func (mysqlDB *MysqlDB) GetColumns(db *sql.DB, table *Table, blackList map[string]bool) {
|
func (mysqlDB *MysqlDB) GetColumns(db *sql.DB, table *Table, blackList map[string]bool) {
|
||||||
// retrieve columns
|
// retrieve columns
|
||||||
colDefRows, _ := db.Query(
|
colDefRows, err := db.Query(
|
||||||
`SELECT
|
`SELECT
|
||||||
column_name, data_type, column_type, is_nullable, column_default, extra
|
column_name, data_type, column_type, is_nullable, column_default, extra
|
||||||
FROM
|
FROM
|
||||||
@ -418,20 +405,28 @@ func (mysqlDB *MysqlDB) GetColumns(db *sql.DB, table *Table, blackList map[strin
|
|||||||
WHERE
|
WHERE
|
||||||
table_schema = database() AND table_name = ?`,
|
table_schema = database() AND table_name = ?`,
|
||||||
table.Name)
|
table.Name)
|
||||||
|
if err != nil {
|
||||||
|
logger.Fatalf("Could not query the database: %s", err)
|
||||||
|
}
|
||||||
defer colDefRows.Close()
|
defer colDefRows.Close()
|
||||||
|
|
||||||
for colDefRows.Next() {
|
for colDefRows.Next() {
|
||||||
// datatype as bytes so that SQL <null> values can be retrieved
|
// datatype as bytes so that SQL <null> values can be retrieved
|
||||||
var colNameBytes, dataTypeBytes, columnTypeBytes, isNullableBytes, columnDefaultBytes, extraBytes []byte
|
var colNameBytes, dataTypeBytes, columnTypeBytes, isNullableBytes, columnDefaultBytes, extraBytes []byte
|
||||||
if err := colDefRows.Scan(&colNameBytes, &dataTypeBytes, &columnTypeBytes, &isNullableBytes, &columnDefaultBytes, &extraBytes); err != nil {
|
if err := colDefRows.Scan(&colNameBytes, &dataTypeBytes, &columnTypeBytes, &isNullableBytes, &columnDefaultBytes, &extraBytes); err != nil {
|
||||||
ColorLog("[ERRO] Could not query INFORMATION_SCHEMA for column information\n")
|
logger.Fatal("Could not query INFORMATION_SCHEMA for column information")
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
colName, dataType, columnType, isNullable, columnDefault, extra :=
|
colName, dataType, columnType, isNullable, columnDefault, extra :=
|
||||||
string(colNameBytes), string(dataTypeBytes), string(columnTypeBytes), string(isNullableBytes), string(columnDefaultBytes), string(extraBytes)
|
string(colNameBytes), string(dataTypeBytes), string(columnTypeBytes), string(isNullableBytes), string(columnDefaultBytes), string(extraBytes)
|
||||||
|
|
||||||
// create a column
|
// create a column
|
||||||
col := new(Column)
|
col := new(Column)
|
||||||
col.Name = camelCase(colName)
|
col.Name = camelCase(colName)
|
||||||
col.Type = mysqlDB.GetGoDataType(dataType)
|
col.Type, err = mysqlDB.GetGoDataType(dataType)
|
||||||
|
if err != nil {
|
||||||
|
logger.Fatalf("%s", err)
|
||||||
|
}
|
||||||
|
|
||||||
// Tag info
|
// Tag info
|
||||||
tag := new(OrmTag)
|
tag := new(OrmTag)
|
||||||
tag.Column = colName
|
tag.Column = colName
|
||||||
@ -466,7 +461,10 @@ func (mysqlDB *MysqlDB) GetColumns(db *sql.DB, table *Table, blackList map[strin
|
|||||||
if isSQLSignedIntType(dataType) {
|
if isSQLSignedIntType(dataType) {
|
||||||
sign := extractIntSignness(columnType)
|
sign := extractIntSignness(columnType)
|
||||||
if sign == "unsigned" && extra != "auto_increment" {
|
if sign == "unsigned" && extra != "auto_increment" {
|
||||||
col.Type = mysqlDB.GetGoDataType(dataType + " " + sign)
|
col.Type, err = mysqlDB.GetGoDataType(dataType + " " + sign)
|
||||||
|
if err != nil {
|
||||||
|
logger.Fatalf("%s", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if isSQLStringType(dataType) {
|
if isSQLStringType(dataType) {
|
||||||
@ -500,15 +498,13 @@ func (mysqlDB *MysqlDB) GetColumns(db *sql.DB, table *Table, blackList map[strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetGoDataType maps an SQL data type to Golang data type
|
// GetGoDataType maps an SQL data type to Golang data type
|
||||||
func (*MysqlDB) GetGoDataType(sqlType string) (goType string) {
|
func (*MysqlDB) GetGoDataType(sqlType string) (string, error) {
|
||||||
var typeMapping = map[string]string{}
|
var typeMapping = map[string]string{}
|
||||||
typeMapping = typeMappingMysql
|
typeMapping = typeMappingMysql
|
||||||
if v, ok := typeMapping[sqlType]; ok {
|
if v, ok := typeMapping[sqlType]; ok {
|
||||||
return v
|
return v, nil
|
||||||
}
|
}
|
||||||
ColorLog("[ERRO] data type (%s) not found!\n", sqlType)
|
return "", fmt.Errorf("data type '%s' not found", sqlType)
|
||||||
os.Exit(2)
|
|
||||||
return goType
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTableNames for PostgreSQL
|
// GetTableNames for PostgreSQL
|
||||||
@ -519,16 +515,14 @@ func (*PostgresDB) GetTableNames(db *sql.DB) (tables []string) {
|
|||||||
table_type = 'BASE TABLE' AND
|
table_type = 'BASE TABLE' AND
|
||||||
table_schema NOT IN ('pg_catalog', 'information_schema')`)
|
table_schema NOT IN ('pg_catalog', 'information_schema')`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[ERRO] Could not show tables: %s\n", err)
|
logger.Fatalf("Could not show tables: %s", err)
|
||||||
ColorLog("[HINT] Check your connection string\n")
|
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var name string
|
var name string
|
||||||
if err := rows.Scan(&name); err != nil {
|
if err := rows.Scan(&name); err != nil {
|
||||||
ColorLog("[ERRO] Could not show tables\n")
|
logger.Fatalf("Could not show tables: %s", err)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
tables = append(tables, name)
|
tables = append(tables, name)
|
||||||
}
|
}
|
||||||
@ -558,14 +552,13 @@ func (*PostgresDB) GetConstraints(db *sql.DB, table *Table, blackList map[string
|
|||||||
AND u.table_name = $2`,
|
AND u.table_name = $2`,
|
||||||
table.Name, table.Name) // u.position_in_unique_constraint,
|
table.Name, table.Name) // u.position_in_unique_constraint,
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[ERRO] Could not query INFORMATION_SCHEMA for PK/UK/FK information: %s\n", err)
|
logger.Fatalf("Could not query INFORMATION_SCHEMA for PK/UK/FK information: %s", err)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var constraintTypeBytes, columnNameBytes, refTableSchemaBytes, refTableNameBytes, refColumnNameBytes, refOrdinalPosBytes []byte
|
var constraintTypeBytes, columnNameBytes, refTableSchemaBytes, refTableNameBytes, refColumnNameBytes, refOrdinalPosBytes []byte
|
||||||
if err := rows.Scan(&constraintTypeBytes, &columnNameBytes, &refTableSchemaBytes, &refTableNameBytes, &refColumnNameBytes, &refOrdinalPosBytes); err != nil {
|
if err := rows.Scan(&constraintTypeBytes, &columnNameBytes, &refTableSchemaBytes, &refTableNameBytes, &refColumnNameBytes, &refOrdinalPosBytes); err != nil {
|
||||||
ColorLog("[ERRO] Could not read INFORMATION_SCHEMA for PK/UK/FK information\n")
|
logger.Fatalf("Could not read INFORMATION_SCHEMA for PK/UK/FK information: %s", err)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
constraintType, columnName, refTableSchema, refTableName, refColumnName, refOrdinalPos :=
|
constraintType, columnName, refTableSchema, refTableName, refColumnName, refOrdinalPos :=
|
||||||
string(constraintTypeBytes), string(columnNameBytes), string(refTableSchemaBytes),
|
string(constraintTypeBytes), string(columnNameBytes), string(refTableSchemaBytes),
|
||||||
@ -595,7 +588,7 @@ func (*PostgresDB) GetConstraints(db *sql.DB, table *Table, blackList map[string
|
|||||||
// GetColumns for PostgreSQL
|
// GetColumns for PostgreSQL
|
||||||
func (postgresDB *PostgresDB) GetColumns(db *sql.DB, table *Table, blackList map[string]bool) {
|
func (postgresDB *PostgresDB) GetColumns(db *sql.DB, table *Table, blackList map[string]bool) {
|
||||||
// retrieve columns
|
// retrieve columns
|
||||||
colDefRows, _ := db.Query(
|
colDefRows, err := db.Query(
|
||||||
`SELECT
|
`SELECT
|
||||||
column_name,
|
column_name,
|
||||||
data_type,
|
data_type,
|
||||||
@ -614,20 +607,27 @@ func (postgresDB *PostgresDB) GetColumns(db *sql.DB, table *Table, blackList map
|
|||||||
table_catalog = current_database() AND table_schema NOT IN ('pg_catalog', 'information_schema')
|
table_catalog = current_database() AND table_schema NOT IN ('pg_catalog', 'information_schema')
|
||||||
AND table_name = $1`,
|
AND table_name = $1`,
|
||||||
table.Name)
|
table.Name)
|
||||||
|
if err != nil {
|
||||||
|
logger.Fatalf("Could not query INFORMATION_SCHEMA for column information: %s", err)
|
||||||
|
}
|
||||||
defer colDefRows.Close()
|
defer colDefRows.Close()
|
||||||
|
|
||||||
for colDefRows.Next() {
|
for colDefRows.Next() {
|
||||||
// datatype as bytes so that SQL <null> values can be retrieved
|
// datatype as bytes so that SQL <null> values can be retrieved
|
||||||
var colNameBytes, dataTypeBytes, columnTypeBytes, isNullableBytes, columnDefaultBytes, extraBytes []byte
|
var colNameBytes, dataTypeBytes, columnTypeBytes, isNullableBytes, columnDefaultBytes, extraBytes []byte
|
||||||
if err := colDefRows.Scan(&colNameBytes, &dataTypeBytes, &columnTypeBytes, &isNullableBytes, &columnDefaultBytes, &extraBytes); err != nil {
|
if err := colDefRows.Scan(&colNameBytes, &dataTypeBytes, &columnTypeBytes, &isNullableBytes, &columnDefaultBytes, &extraBytes); err != nil {
|
||||||
ColorLog("[ERRO] Could not query INFORMATION_SCHEMA for column information\n")
|
logger.Fatalf("Could not query INFORMATION_SCHEMA for column information: %s", err)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
colName, dataType, columnType, isNullable, columnDefault, extra :=
|
colName, dataType, columnType, isNullable, columnDefault, extra :=
|
||||||
string(colNameBytes), string(dataTypeBytes), string(columnTypeBytes), string(isNullableBytes), string(columnDefaultBytes), string(extraBytes)
|
string(colNameBytes), string(dataTypeBytes), string(columnTypeBytes), string(isNullableBytes), string(columnDefaultBytes), string(extraBytes)
|
||||||
// create a column
|
// Create a column
|
||||||
col := new(Column)
|
col := new(Column)
|
||||||
col.Name = camelCase(colName)
|
col.Name = camelCase(colName)
|
||||||
col.Type = postgresDB.GetGoDataType(dataType)
|
col.Type, err = postgresDB.GetGoDataType(dataType)
|
||||||
|
if err != nil {
|
||||||
|
logger.Fatalf("%s", err)
|
||||||
|
}
|
||||||
|
|
||||||
// Tag info
|
// Tag info
|
||||||
tag := new(OrmTag)
|
tag := new(OrmTag)
|
||||||
tag.Column = colName
|
tag.Column = colName
|
||||||
@ -690,13 +690,11 @@ func (postgresDB *PostgresDB) GetColumns(db *sql.DB, table *Table, blackList map
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetGoDataType returns the Go type from the mapped Postgres type
|
// GetGoDataType returns the Go type from the mapped Postgres type
|
||||||
func (*PostgresDB) GetGoDataType(sqlType string) (goType string) {
|
func (*PostgresDB) GetGoDataType(sqlType string) (string, error) {
|
||||||
if v, ok := typeMappingPostgres[sqlType]; ok {
|
if v, ok := typeMappingPostgres[sqlType]; ok {
|
||||||
return v
|
return v, nil
|
||||||
}
|
}
|
||||||
ColorLog("[ERRO] data type (%s) not found!\n", sqlType)
|
return "", fmt.Errorf("data type '%s' not found", sqlType)
|
||||||
os.Exit(2)
|
|
||||||
return goType
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// deleteAndRecreatePaths removes several directories completely
|
// deleteAndRecreatePaths removes several directories completely
|
||||||
@ -717,15 +715,15 @@ func createPaths(mode byte, paths *MvcPath) {
|
|||||||
// Newly geneated files will be inside these folders.
|
// Newly geneated files will be inside these folders.
|
||||||
func writeSourceFiles(pkgPath string, tables []*Table, mode byte, paths *MvcPath, selectedTables map[string]bool) {
|
func writeSourceFiles(pkgPath string, tables []*Table, mode byte, paths *MvcPath, selectedTables map[string]bool) {
|
||||||
if (OModel & mode) == OModel {
|
if (OModel & mode) == OModel {
|
||||||
ColorLog("[INFO] Creating model files...\n")
|
logger.Info("Creating model files...")
|
||||||
writeModelFiles(tables, paths.ModelPath, selectedTables)
|
writeModelFiles(tables, paths.ModelPath, selectedTables)
|
||||||
}
|
}
|
||||||
if (OController & mode) == OController {
|
if (OController & mode) == OController {
|
||||||
ColorLog("[INFO] Creating controller files...\n")
|
logger.Info("Creating controller files...")
|
||||||
writeControllerFiles(tables, paths.ControllerPath, selectedTables, pkgPath)
|
writeControllerFiles(tables, paths.ControllerPath, selectedTables, pkgPath)
|
||||||
}
|
}
|
||||||
if (ORouter & mode) == ORouter {
|
if (ORouter & mode) == ORouter {
|
||||||
ColorLog("[INFO] Creating router files...\n")
|
logger.Info("Creating router files...")
|
||||||
writeRouterFile(tables, paths.RouterPath, selectedTables, pkgPath)
|
writeRouterFile(tables, paths.RouterPath, selectedTables, pkgPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -746,21 +744,21 @@ func writeModelFiles(tables []*Table, mPath string, selectedTables map[string]bo
|
|||||||
var f *os.File
|
var f *os.File
|
||||||
var err error
|
var err error
|
||||||
if isExist(fpath) {
|
if isExist(fpath) {
|
||||||
ColorLog("[WARN] '%v' already exists. Do you want to overwrite it? [Yes|No] ", fpath)
|
logger.Warnf("'%s' already exists. Do you want to overwrite it? [Yes|No] ", fpath)
|
||||||
if askForConfirmation() {
|
if askForConfirmation() {
|
||||||
f, err = os.OpenFile(fpath, os.O_RDWR|os.O_TRUNC, 0666)
|
f, err = os.OpenFile(fpath, os.O_RDWR|os.O_TRUNC, 0666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[WARN] %v\n", err)
|
logger.Warnf("%s", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ColorLog("[WARN] Skipped create file '%s'\n", fpath)
|
logger.Warnf("Skipped create file '%s'", fpath)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
f, err = os.OpenFile(fpath, os.O_CREATE|os.O_RDWR, 0666)
|
f, err = os.OpenFile(fpath, os.O_CREATE|os.O_RDWR, 0666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[WARN] %v\n", err)
|
logger.Warnf("%s", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -773,7 +771,8 @@ func writeModelFiles(tables []*Table, mPath string, selectedTables map[string]bo
|
|||||||
fileStr := strings.Replace(template, "{{modelStruct}}", tb.String(), 1)
|
fileStr := strings.Replace(template, "{{modelStruct}}", tb.String(), 1)
|
||||||
fileStr = strings.Replace(fileStr, "{{modelName}}", camelCase(tb.Name), -1)
|
fileStr = strings.Replace(fileStr, "{{modelName}}", camelCase(tb.Name), -1)
|
||||||
fileStr = strings.Replace(fileStr, "{{tableName}}", tb.Name, -1)
|
fileStr = strings.Replace(fileStr, "{{tableName}}", tb.Name, -1)
|
||||||
// if table contains time field, import time.Time package
|
|
||||||
|
// If table contains time field, import time.Time package
|
||||||
timePkg := ""
|
timePkg := ""
|
||||||
importTimePkg := ""
|
importTimePkg := ""
|
||||||
if tb.ImportTimePkg {
|
if tb.ImportTimePkg {
|
||||||
@ -783,8 +782,7 @@ func writeModelFiles(tables []*Table, mPath string, selectedTables map[string]bo
|
|||||||
fileStr = strings.Replace(fileStr, "{{timePkg}}", timePkg, -1)
|
fileStr = strings.Replace(fileStr, "{{timePkg}}", timePkg, -1)
|
||||||
fileStr = strings.Replace(fileStr, "{{importTimePkg}}", importTimePkg, -1)
|
fileStr = strings.Replace(fileStr, "{{importTimePkg}}", importTimePkg, -1)
|
||||||
if _, err := f.WriteString(fileStr); err != nil {
|
if _, err := f.WriteString(fileStr); err != nil {
|
||||||
ColorLog("[ERRO] Could not write model file to %s\n", fpath)
|
logger.Fatalf("Could not write model file to '%s': %s", fpath, err)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
CloseFile(f)
|
CloseFile(f)
|
||||||
fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", fpath, "\x1b[0m")
|
fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", fpath, "\x1b[0m")
|
||||||
@ -797,7 +795,7 @@ func writeControllerFiles(tables []*Table, cPath string, selectedTables map[stri
|
|||||||
w := NewColorWriter(os.Stdout)
|
w := NewColorWriter(os.Stdout)
|
||||||
|
|
||||||
for _, tb := range tables {
|
for _, tb := range tables {
|
||||||
// if selectedTables map is not nil and this table is not selected, ignore it
|
// If selectedTables map is not nil and this table is not selected, ignore it
|
||||||
if selectedTables != nil {
|
if selectedTables != nil {
|
||||||
if _, selected := selectedTables[tb.Name]; !selected {
|
if _, selected := selectedTables[tb.Name]; !selected {
|
||||||
continue
|
continue
|
||||||
@ -811,29 +809,28 @@ func writeControllerFiles(tables []*Table, cPath string, selectedTables map[stri
|
|||||||
var f *os.File
|
var f *os.File
|
||||||
var err error
|
var err error
|
||||||
if isExist(fpath) {
|
if isExist(fpath) {
|
||||||
ColorLog("[WARN] '%v' already exists. Do you want to overwrite it? [Yes|No] ", fpath)
|
logger.Warnf("'%s' already exists. Do you want to overwrite it? [Yes|No] ", fpath)
|
||||||
if askForConfirmation() {
|
if askForConfirmation() {
|
||||||
f, err = os.OpenFile(fpath, os.O_RDWR|os.O_TRUNC, 0666)
|
f, err = os.OpenFile(fpath, os.O_RDWR|os.O_TRUNC, 0666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[WARN] %v\n", err)
|
logger.Warnf("%s", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ColorLog("[WARN] Skipped create file '%s'\n", fpath)
|
logger.Warnf("Skipped create file '%s'", fpath)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
f, err = os.OpenFile(fpath, os.O_CREATE|os.O_RDWR, 0666)
|
f, err = os.OpenFile(fpath, os.O_CREATE|os.O_RDWR, 0666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[WARN] %v\n", err)
|
logger.Warnf("%s", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fileStr := strings.Replace(CtrlTPL, "{{ctrlName}}", camelCase(tb.Name), -1)
|
fileStr := strings.Replace(CtrlTPL, "{{ctrlName}}", camelCase(tb.Name), -1)
|
||||||
fileStr = strings.Replace(fileStr, "{{pkgPath}}", pkgPath, -1)
|
fileStr = strings.Replace(fileStr, "{{pkgPath}}", pkgPath, -1)
|
||||||
if _, err := f.WriteString(fileStr); err != nil {
|
if _, err := f.WriteString(fileStr); err != nil {
|
||||||
ColorLog("[ERRO] Could not write controller file to %s\n", fpath)
|
logger.Fatalf("Could not write controller file to '%s': %s", fpath, err)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
CloseFile(f)
|
CloseFile(f)
|
||||||
fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", fpath, "\x1b[0m")
|
fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", fpath, "\x1b[0m")
|
||||||
@ -847,7 +844,7 @@ func writeRouterFile(tables []*Table, rPath string, selectedTables map[string]bo
|
|||||||
|
|
||||||
var nameSpaces []string
|
var nameSpaces []string
|
||||||
for _, tb := range tables {
|
for _, tb := range tables {
|
||||||
// if selectedTables map is not nil and this table is not selected, ignore it
|
// If selectedTables map is not nil and this table is not selected, ignore it
|
||||||
if selectedTables != nil {
|
if selectedTables != nil {
|
||||||
if _, selected := selectedTables[tb.Name]; !selected {
|
if _, selected := selectedTables[tb.Name]; !selected {
|
||||||
continue
|
continue
|
||||||
@ -856,63 +853,44 @@ func writeRouterFile(tables []*Table, rPath string, selectedTables map[string]bo
|
|||||||
if tb.Pk == "" {
|
if tb.Pk == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// add namespaces
|
// Add namespaces
|
||||||
nameSpace := strings.Replace(NamespaceTPL, "{{nameSpace}}", tb.Name, -1)
|
nameSpace := strings.Replace(NamespaceTPL, "{{nameSpace}}", tb.Name, -1)
|
||||||
nameSpace = strings.Replace(nameSpace, "{{ctrlName}}", camelCase(tb.Name), -1)
|
nameSpace = strings.Replace(nameSpace, "{{ctrlName}}", camelCase(tb.Name), -1)
|
||||||
nameSpaces = append(nameSpaces, nameSpace)
|
nameSpaces = append(nameSpaces, nameSpace)
|
||||||
}
|
}
|
||||||
// add export controller
|
// Add export controller
|
||||||
fpath := path.Join(rPath, "router.go")
|
fpath := path.Join(rPath, "router.go")
|
||||||
routerStr := strings.Replace(RouterTPL, "{{nameSpaces}}", strings.Join(nameSpaces, ""), 1)
|
routerStr := strings.Replace(RouterTPL, "{{nameSpaces}}", strings.Join(nameSpaces, ""), 1)
|
||||||
routerStr = strings.Replace(routerStr, "{{pkgPath}}", pkgPath, 1)
|
routerStr = strings.Replace(routerStr, "{{pkgPath}}", pkgPath, 1)
|
||||||
var f *os.File
|
var f *os.File
|
||||||
var err error
|
var err error
|
||||||
if isExist(fpath) {
|
if isExist(fpath) {
|
||||||
ColorLog("[WARN] '%v' already exists. Do you want to overwrite it? [Yes|No] ", fpath)
|
logger.Warnf("'%s' already exists. Do you want to overwrite it? [Yes|No] ", fpath)
|
||||||
if askForConfirmation() {
|
if askForConfirmation() {
|
||||||
f, err = os.OpenFile(fpath, os.O_RDWR|os.O_TRUNC, 0666)
|
f, err = os.OpenFile(fpath, os.O_RDWR|os.O_TRUNC, 0666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[WARN] %v\n", err)
|
logger.Warnf("%s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ColorLog("[WARN] Skipped create file '%s'\n", fpath)
|
logger.Warnf("Skipped create file '%s'", fpath)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
f, err = os.OpenFile(fpath, os.O_CREATE|os.O_RDWR, 0666)
|
f, err = os.OpenFile(fpath, os.O_CREATE|os.O_RDWR, 0666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[WARN] %v\n", err)
|
logger.Warnf("%s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if _, err := f.WriteString(routerStr); err != nil {
|
if _, err := f.WriteString(routerStr); err != nil {
|
||||||
ColorLog("[ERRO] Could not write router file to '%s'\n", fpath)
|
logger.Fatalf("Could not write router file to '%s': %s", fpath, err)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
CloseFile(f)
|
CloseFile(f)
|
||||||
fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", fpath, "\x1b[0m")
|
fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", fpath, "\x1b[0m")
|
||||||
formatSourceCode(fpath)
|
formatSourceCode(fpath)
|
||||||
}
|
}
|
||||||
|
|
||||||
// formatSourceCode formats source files
|
|
||||||
func formatSourceCode(filename string) {
|
|
||||||
cmd := exec.Command("gofmt", "-w", filename)
|
|
||||||
if err := cmd.Run(); err != nil {
|
|
||||||
ColorLog("[WARN] gofmt err: %s\n", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// camelCase converts a _ delimited string to camel case
|
|
||||||
// e.g. very_important_person => VeryImportantPerson
|
|
||||||
func camelCase(in string) string {
|
|
||||||
tokens := strings.Split(in, "_")
|
|
||||||
for i := range tokens {
|
|
||||||
tokens[i] = strings.Title(strings.Trim(tokens[i], " "))
|
|
||||||
}
|
|
||||||
return strings.Join(tokens, "")
|
|
||||||
}
|
|
||||||
|
|
||||||
func isSQLTemporalType(t string) bool {
|
func isSQLTemporalType(t string) bool {
|
||||||
return t == "date" || t == "datetime" || t == "timestamp" || t == "time"
|
return t == "date" || t == "datetime" || t == "timestamp" || t == "time"
|
||||||
}
|
}
|
||||||
@ -972,12 +950,12 @@ func getFileName(tbName string) (filename string) {
|
|||||||
|
|
||||||
func getPackagePath(curpath string) (packpath string) {
|
func getPackagePath(curpath string) (packpath string) {
|
||||||
gopath := os.Getenv("GOPATH")
|
gopath := os.Getenv("GOPATH")
|
||||||
Debugf("gopath:%s", gopath)
|
|
||||||
if gopath == "" {
|
if gopath == "" {
|
||||||
ColorLog("[ERRO] You should set GOPATH in the env")
|
logger.Fatal("GOPATH environment variable is not set or empty")
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger.Debugf("GOPATH: %s", gopath)
|
||||||
|
|
||||||
appsrcpath := ""
|
appsrcpath := ""
|
||||||
haspath := false
|
haspath := false
|
||||||
wgopath := filepath.SplitList(gopath)
|
wgopath := filepath.SplitList(gopath)
|
||||||
@ -993,13 +971,11 @@ func getPackagePath(curpath string) (packpath string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !haspath {
|
if !haspath {
|
||||||
ColorLog("[ERRO] Can't generate application code outside of GOPATH '%s'\n", gopath)
|
logger.Fatalf("Cannot generate application code outside of GOPATH '%s'", gopath)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if curpath == appsrcpath {
|
if curpath == appsrcpath {
|
||||||
ColorLog("[ERRO] Can't generate application code outside of application PATH \n")
|
logger.Fatal("Cannot generate application code outside of application path")
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
packpath = strings.Join(strings.Split(curpath[len(appsrcpath)+1:], string(filepath.Separator)), "/")
|
packpath = strings.Join(strings.Split(curpath[len(appsrcpath)+1:], string(filepath.Separator)), "/")
|
||||||
|
@ -21,9 +21,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// article
|
|
||||||
// cms/article
|
|
||||||
//
|
|
||||||
func generateController(cname, currpath string) {
|
func generateController(cname, currpath string) {
|
||||||
w := NewColorWriter(os.Stdout)
|
w := NewColorWriter(os.Stdout)
|
||||||
|
|
||||||
@ -36,15 +33,14 @@ func generateController(cname, currpath string) {
|
|||||||
packageName = p[i+1 : len(p)-1]
|
packageName = p[i+1 : len(p)-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorLog("[INFO] Using '%s' as controller name\n", controllerName)
|
logger.Infof("Using '%s' as controller name", controllerName)
|
||||||
ColorLog("[INFO] Using '%s' as package name\n", packageName)
|
logger.Infof("Using '%s' as package name", packageName)
|
||||||
|
|
||||||
fp := path.Join(currpath, "controllers", p)
|
fp := path.Join(currpath, "controllers", p)
|
||||||
if _, err := os.Stat(fp); os.IsNotExist(err) {
|
if _, err := os.Stat(fp); os.IsNotExist(err) {
|
||||||
// Create the controller's directory
|
// Create the controller's directory
|
||||||
if err := os.MkdirAll(fp, 0777); err != nil {
|
if err := os.MkdirAll(fp, 0777); err != nil {
|
||||||
ColorLog("[ERRO] Could not create controllers directory: %s\n", err)
|
logger.Fatalf("Could not create controllers directory: %s", err)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,7 +52,7 @@ func generateController(cname, currpath string) {
|
|||||||
|
|
||||||
var content string
|
var content string
|
||||||
if _, err := os.Stat(modelPath); err == nil {
|
if _, err := os.Stat(modelPath); err == nil {
|
||||||
ColorLog("[INFO] Using matching model '%s'\n", controllerName)
|
logger.Infof("Using matching model '%s'", controllerName)
|
||||||
content = strings.Replace(controllerModelTpl, "{{packageName}}", packageName, -1)
|
content = strings.Replace(controllerModelTpl, "{{packageName}}", packageName, -1)
|
||||||
pkgPath := getPackagePath(currpath)
|
pkgPath := getPackagePath(currpath)
|
||||||
content = strings.Replace(content, "{{pkgPath}}", pkgPath, -1)
|
content = strings.Replace(content, "{{pkgPath}}", pkgPath, -1)
|
||||||
@ -71,8 +67,7 @@ func generateController(cname, currpath string) {
|
|||||||
formatSourceCode(fpath)
|
formatSourceCode(fpath)
|
||||||
fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", fpath, "\x1b[0m")
|
fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", fpath, "\x1b[0m")
|
||||||
} else {
|
} else {
|
||||||
ColorLog("[ERRO] Could not create controller file: %s\n", err)
|
logger.Fatalf("Could not create controller file: %s", err)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
75
g_docs.go
75
g_docs.go
@ -26,7 +26,6 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"reflect"
|
"reflect"
|
||||||
"regexp"
|
"regexp"
|
||||||
"runtime"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"unicode"
|
"unicode"
|
||||||
@ -92,8 +91,7 @@ func parsePackagesFromDir(path string) {
|
|||||||
parsePackageFromDir(path)
|
parsePackageFromDir(path)
|
||||||
list, err := ioutil.ReadDir(path)
|
list, err := ioutil.ReadDir(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[ERRO] Can't read directory %s : %s\n", path, err)
|
logger.Fatalf("Cannot read directory '%s': %s", path, err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
for _, item := range list {
|
for _, item := range list {
|
||||||
if item.IsDir() && item.Name() != "vendor" {
|
if item.IsDir() && item.Name() != "vendor" {
|
||||||
@ -108,11 +106,10 @@ func parsePackageFromDir(path string) {
|
|||||||
name := info.Name()
|
name := info.Name()
|
||||||
return !info.IsDir() && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".go")
|
return !info.IsDir() && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".go")
|
||||||
}, parser.ParseComments)
|
}, parser.ParseComments)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[ERRO] the model %s parser.ParseDir error: %s\n", path, err)
|
logger.Fatalf("Error while parsing dir at '%s': %s", path, err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for k, v := range folderPkgs {
|
for k, v := range folderPkgs {
|
||||||
astPkgs[k] = v
|
astPkgs[k] = v
|
||||||
}
|
}
|
||||||
@ -124,13 +121,13 @@ func generateDocs(curpath string) {
|
|||||||
f, err := parser.ParseFile(fset, path.Join(curpath, "routers", "router.go"), nil, parser.ParseComments)
|
f, err := parser.ParseFile(fset, path.Join(curpath, "routers", "router.go"), nil, parser.ParseComments)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[ERRO] parse router.go error\n")
|
logger.Fatalf("Error while parsing router.go: %s", err)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rootapi.Infos = swagger.Information{}
|
rootapi.Infos = swagger.Information{}
|
||||||
rootapi.SwaggerVersion = "2.0"
|
rootapi.SwaggerVersion = "2.0"
|
||||||
//analysis API comments
|
|
||||||
|
// Analyse API comments
|
||||||
if f.Comments != nil {
|
if f.Comments != nil {
|
||||||
for _, c := range f.Comments {
|
for _, c := range f.Comments {
|
||||||
for _, s := range strings.Split(c.Text(), "\n") {
|
for _, s := range strings.Split(c.Text(), "\n") {
|
||||||
@ -168,13 +165,14 @@ func generateDocs(curpath string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// analisys controller package
|
|
||||||
|
// Analyse controller package
|
||||||
for _, im := range f.Imports {
|
for _, im := range f.Imports {
|
||||||
localName := ""
|
localName := ""
|
||||||
if im.Name != nil {
|
if im.Name != nil {
|
||||||
localName = im.Name.Name
|
localName = im.Name.Name
|
||||||
}
|
}
|
||||||
analisyscontrollerPkg(localName, im.Path.Value)
|
analyseControllerPkg(localName, im.Path.Value)
|
||||||
}
|
}
|
||||||
for _, d := range f.Decls {
|
for _, d := range f.Decls {
|
||||||
switch specDecl := d.(type) {
|
switch specDecl := d.(type) {
|
||||||
@ -184,11 +182,11 @@ func generateDocs(curpath string) {
|
|||||||
case *ast.AssignStmt:
|
case *ast.AssignStmt:
|
||||||
for _, l := range stmt.Rhs {
|
for _, l := range stmt.Rhs {
|
||||||
if v, ok := l.(*ast.CallExpr); ok {
|
if v, ok := l.(*ast.CallExpr); ok {
|
||||||
// analisys NewNamespace, it will return version and the subfunction
|
// Analyse NewNamespace, it will return version and the subfunction
|
||||||
if selName := v.Fun.(*ast.SelectorExpr).Sel.String(); selName != "NewNamespace" {
|
if selName := v.Fun.(*ast.SelectorExpr).Sel.String(); selName != "NewNamespace" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
version, params := analisysNewNamespace(v)
|
version, params := analyseNewNamespace(v)
|
||||||
if rootapi.BasePath == "" && version != "" {
|
if rootapi.BasePath == "" && version != "" {
|
||||||
rootapi.BasePath = version
|
rootapi.BasePath = version
|
||||||
}
|
}
|
||||||
@ -197,12 +195,12 @@ func generateDocs(curpath string) {
|
|||||||
case *ast.CallExpr:
|
case *ast.CallExpr:
|
||||||
controllerName := ""
|
controllerName := ""
|
||||||
if selname := pp.Fun.(*ast.SelectorExpr).Sel.String(); selname == "NSNamespace" {
|
if selname := pp.Fun.(*ast.SelectorExpr).Sel.String(); selname == "NSNamespace" {
|
||||||
s, params := analisysNewNamespace(pp)
|
s, params := analyseNewNamespace(pp)
|
||||||
for _, sp := range params {
|
for _, sp := range params {
|
||||||
switch pp := sp.(type) {
|
switch pp := sp.(type) {
|
||||||
case *ast.CallExpr:
|
case *ast.CallExpr:
|
||||||
if pp.Fun.(*ast.SelectorExpr).Sel.String() == "NSInclude" {
|
if pp.Fun.(*ast.SelectorExpr).Sel.String() == "NSInclude" {
|
||||||
controllerName = analisysNSInclude(s, pp)
|
controllerName = analyseNSInclude(s, pp)
|
||||||
if v, ok := controllerComments[controllerName]; ok {
|
if v, ok := controllerComments[controllerName]; ok {
|
||||||
rootapi.Tags = append(rootapi.Tags, swagger.Tag{
|
rootapi.Tags = append(rootapi.Tags, swagger.Tag{
|
||||||
Name: strings.Trim(s, "/"),
|
Name: strings.Trim(s, "/"),
|
||||||
@ -213,7 +211,7 @@ func generateDocs(curpath string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if selname == "NSInclude" {
|
} else if selname == "NSInclude" {
|
||||||
controllerName = analisysNSInclude("", pp)
|
controllerName = analyseNSInclude("", pp)
|
||||||
if v, ok := controllerComments[controllerName]; ok {
|
if v, ok := controllerComments[controllerName]; ok {
|
||||||
rootapi.Tags = append(rootapi.Tags, swagger.Tag{
|
rootapi.Tags = append(rootapi.Tags, swagger.Tag{
|
||||||
Name: controllerName, // if the NSInclude has no prefix, we use the controllername as the tag
|
Name: controllerName, // if the NSInclude has no prefix, we use the controllername as the tag
|
||||||
@ -250,8 +248,8 @@ func generateDocs(curpath string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// return version and the others params
|
// analyseNewNamespace returns version and the others params
|
||||||
func analisysNewNamespace(ce *ast.CallExpr) (first string, others []ast.Expr) {
|
func analyseNewNamespace(ce *ast.CallExpr) (first string, others []ast.Expr) {
|
||||||
for i, p := range ce.Args {
|
for i, p := range ce.Args {
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
switch pp := p.(type) {
|
switch pp := p.(type) {
|
||||||
@ -265,7 +263,7 @@ func analisysNewNamespace(ce *ast.CallExpr) (first string, others []ast.Expr) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func analisysNSInclude(baseurl string, ce *ast.CallExpr) string {
|
func analyseNSInclude(baseurl string, ce *ast.CallExpr) string {
|
||||||
cname := ""
|
cname := ""
|
||||||
for _, p := range ce.Args {
|
for _, p := range ce.Args {
|
||||||
x := p.(*ast.UnaryExpr).X.(*ast.CompositeLit).Type.(*ast.SelectorExpr)
|
x := p.(*ast.UnaryExpr).X.(*ast.CompositeLit).Type.(*ast.SelectorExpr)
|
||||||
@ -313,7 +311,7 @@ func analisysNSInclude(baseurl string, ce *ast.CallExpr) string {
|
|||||||
return cname
|
return cname
|
||||||
}
|
}
|
||||||
|
|
||||||
func analisyscontrollerPkg(localName, pkgpath string) {
|
func analyseControllerPkg(localName, pkgpath string) {
|
||||||
pkgpath = strings.Trim(pkgpath, "\"")
|
pkgpath = strings.Trim(pkgpath, "\"")
|
||||||
if isSystemPackage(pkgpath) {
|
if isSystemPackage(pkgpath) {
|
||||||
return
|
return
|
||||||
@ -329,7 +327,7 @@ func analisyscontrollerPkg(localName, pkgpath string) {
|
|||||||
}
|
}
|
||||||
gopath := os.Getenv("GOPATH")
|
gopath := os.Getenv("GOPATH")
|
||||||
if gopath == "" {
|
if gopath == "" {
|
||||||
panic("please set gopath")
|
logger.Fatal("GOPATH environment variable is not set or empty")
|
||||||
}
|
}
|
||||||
pkgRealpath := ""
|
pkgRealpath := ""
|
||||||
|
|
||||||
@ -347,18 +345,16 @@ func analisyscontrollerPkg(localName, pkgpath string) {
|
|||||||
}
|
}
|
||||||
pkgCache[pkgpath] = struct{}{}
|
pkgCache[pkgpath] = struct{}{}
|
||||||
} else {
|
} else {
|
||||||
ColorLog("[ERRO] the %s pkg not exist in gopath\n", pkgpath)
|
logger.Fatalf("Package '%s' does not exist in the GOPATH", pkgpath)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fileSet := token.NewFileSet()
|
fileSet := token.NewFileSet()
|
||||||
astPkgs, err := parser.ParseDir(fileSet, pkgRealpath, func(info os.FileInfo) bool {
|
astPkgs, err := parser.ParseDir(fileSet, pkgRealpath, func(info os.FileInfo) bool {
|
||||||
name := info.Name()
|
name := info.Name()
|
||||||
return !info.IsDir() && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".go")
|
return !info.IsDir() && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".go")
|
||||||
}, parser.ParseComments)
|
}, parser.ParseComments)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[ERRO] the %s pkg parser.ParseDir error: %s\n", pkgpath, err)
|
logger.Fatalf("Error while parsing dir at '%s': %s", pkgpath, err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
for _, pkg := range astPkgs {
|
for _, pkg := range astPkgs {
|
||||||
for _, fl := range pkg.Files {
|
for _, fl := range pkg.Files {
|
||||||
@ -367,7 +363,7 @@ func analisyscontrollerPkg(localName, pkgpath string) {
|
|||||||
case *ast.FuncDecl:
|
case *ast.FuncDecl:
|
||||||
if specDecl.Recv != nil && len(specDecl.Recv.List) > 0 {
|
if specDecl.Recv != nil && len(specDecl.Recv.List) > 0 {
|
||||||
if t, ok := specDecl.Recv.List[0].Type.(*ast.StarExpr); ok {
|
if t, ok := specDecl.Recv.List[0].Type.(*ast.StarExpr); ok {
|
||||||
// parse controller method
|
// Parse controller method
|
||||||
parserComments(specDecl.Doc, specDecl.Name.String(), fmt.Sprint(t.X), pkgpath)
|
parserComments(specDecl.Doc, specDecl.Name.String(), fmt.Sprint(t.X), pkgpath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -377,7 +373,7 @@ func analisyscontrollerPkg(localName, pkgpath string) {
|
|||||||
switch tp := s.(*ast.TypeSpec).Type.(type) {
|
switch tp := s.(*ast.TypeSpec).Type.(type) {
|
||||||
case *ast.StructType:
|
case *ast.StructType:
|
||||||
_ = tp.Struct
|
_ = tp.Struct
|
||||||
//parse controller definition comments
|
// Parse controller definition comments
|
||||||
if strings.TrimSpace(specDecl.Doc.Text()) != "" {
|
if strings.TrimSpace(specDecl.Doc.Text()) != "" {
|
||||||
controllerComments[pkgpath+s.(*ast.TypeSpec).Name.String()] = specDecl.Doc.Text()
|
controllerComments[pkgpath+s.(*ast.TypeSpec).Name.String()] = specDecl.Doc.Text()
|
||||||
}
|
}
|
||||||
@ -391,10 +387,11 @@ func analisyscontrollerPkg(localName, pkgpath string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func isSystemPackage(pkgpath string) bool {
|
func isSystemPackage(pkgpath string) bool {
|
||||||
goroot := runtime.GOROOT()
|
goroot := os.Getenv("GOROOT")
|
||||||
if goroot == "" {
|
if goroot == "" {
|
||||||
panic("goroot is empty, do you install Go right?")
|
logger.Fatalf("GOROOT environment variable is not set or empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
wg, _ := filepath.EvalSymlinks(filepath.Join(goroot, "src", "pkg", pkgpath))
|
wg, _ := filepath.EvalSymlinks(filepath.Join(goroot, "src", "pkg", pkgpath))
|
||||||
if utils.FileExists(wg) {
|
if utils.FileExists(wg) {
|
||||||
return true
|
return true
|
||||||
@ -460,8 +457,7 @@ func parserComments(comments *ast.CommentGroup, funcName, controllerName, pkgpat
|
|||||||
ss = strings.TrimSpace(ss[pos:])
|
ss = strings.TrimSpace(ss[pos:])
|
||||||
schemaName, pos := peekNextSplitString(ss)
|
schemaName, pos := peekNextSplitString(ss)
|
||||||
if schemaName == "" {
|
if schemaName == "" {
|
||||||
ColorLog("[ERRO][%s.%s] Schema must follow {object} or {array}\n", controllerName, funcName)
|
logger.Fatalf("[%s.%s] Schema must follow {object} or {array}", controllerName, funcName)
|
||||||
os.Exit(-1)
|
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(schemaName, "[]") {
|
if strings.HasPrefix(schemaName, "[]") {
|
||||||
schemaName = schemaName[2:]
|
schemaName = schemaName[2:]
|
||||||
@ -498,7 +494,7 @@ func parserComments(comments *ast.CommentGroup, funcName, controllerName, pkgpat
|
|||||||
para := swagger.Parameter{}
|
para := swagger.Parameter{}
|
||||||
p := getparams(strings.TrimSpace(t[len("@Param "):]))
|
p := getparams(strings.TrimSpace(t[len("@Param "):]))
|
||||||
if len(p) < 4 {
|
if len(p) < 4 {
|
||||||
panic(controllerName + "_" + funcName + "'s comments @Param at least should has 4 params")
|
logger.Fatal(controllerName + "_" + funcName + "'s comments @Param should have at least 4 params")
|
||||||
}
|
}
|
||||||
para.Name = p[0]
|
para.Name = p[0]
|
||||||
switch p[1] {
|
switch p[1] {
|
||||||
@ -513,7 +509,7 @@ func parserComments(comments *ast.CommentGroup, funcName, controllerName, pkgpat
|
|||||||
case "body":
|
case "body":
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
ColorLog("[WARN][%s.%s] Unknow param location: %s, Possible values are `query`, `header`, `path`, `formData` or `body`.\n", controllerName, funcName, p[1])
|
logger.Warnf("[%s.%s] Unknown param location: %s. Possible values are `query`, `header`, `path`, `formData` or `body`.\n", controllerName, funcName, p[1])
|
||||||
}
|
}
|
||||||
para.In = p[1]
|
para.In = p[1]
|
||||||
pp := strings.Split(p[2], ".")
|
pp := strings.Split(p[2], ".")
|
||||||
@ -544,7 +540,7 @@ func parserComments(comments *ast.CommentGroup, funcName, controllerName, pkgpat
|
|||||||
paraType = typeFormat[0]
|
paraType = typeFormat[0]
|
||||||
paraFormat = typeFormat[1]
|
paraFormat = typeFormat[1]
|
||||||
} else {
|
} else {
|
||||||
ColorLog("[WARN][%s.%s] Unknow param type: %s\n", controllerName, funcName, typ)
|
logger.Warnf("[%s.%s] Unknown param type: %s\n", controllerName, funcName, typ)
|
||||||
}
|
}
|
||||||
if isArray {
|
if isArray {
|
||||||
para.Type = "array"
|
para.Type = "array"
|
||||||
@ -697,7 +693,7 @@ func getModel(str string) (objectname string, m swagger.Schema, realTypes []stri
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if m.Title == "" {
|
if m.Title == "" {
|
||||||
ColorLog("[WARN]can't find the object: %s\n", str)
|
logger.Warnf("Cannot find the object: %s", str)
|
||||||
// TODO remove when all type have been supported
|
// TODO remove when all type have been supported
|
||||||
//os.Exit(1)
|
//os.Exit(1)
|
||||||
}
|
}
|
||||||
@ -712,8 +708,7 @@ func getModel(str string) (objectname string, m swagger.Schema, realTypes []stri
|
|||||||
func parseObject(d *ast.Object, k string, m *swagger.Schema, realTypes *[]string, astPkgs map[string]*ast.Package, packageName string) {
|
func parseObject(d *ast.Object, k string, m *swagger.Schema, realTypes *[]string, astPkgs map[string]*ast.Package, packageName string) {
|
||||||
ts, ok := d.Decl.(*ast.TypeSpec)
|
ts, ok := d.Decl.(*ast.TypeSpec)
|
||||||
if !ok {
|
if !ok {
|
||||||
ColorLog("Unknown type without TypeSec: %v\n", d)
|
logger.Fatalf("Unknown type without TypeSec: %v\n", d)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
// TODO support other types, such as `ArrayType`, `MapType`, `InterfaceType` etc...
|
// TODO support other types, such as `ArrayType`, `MapType`, `InterfaceType` etc...
|
||||||
st, ok := ts.Type.(*ast.StructType)
|
st, ok := ts.Type.(*ast.StructType)
|
||||||
@ -789,7 +784,7 @@ func parseObject(d *ast.Object, k string, m *swagger.Schema, realTypes *[]string
|
|||||||
mp.Default = str2RealType(res[1], realType)
|
mp.Default = str2RealType(res[1], realType)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ColorLog("[WARN] Invalid default value: %s\n", defaultValue)
|
logger.Warnf("Invalid default value: %s", defaultValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -933,7 +928,7 @@ func str2RealType(s string, typ string) interface{} {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[WARN] Invalid default value type(%s): %s\n", typ, s)
|
logger.Warnf("Invalid default value type '%s': %s", typ, s)
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,9 +38,7 @@ func generateHproseAppcode(driver, connStr, level, tables, currpath string) {
|
|||||||
case "3":
|
case "3":
|
||||||
mode = OModel | OController | ORouter
|
mode = OModel | OController | ORouter
|
||||||
default:
|
default:
|
||||||
ColorLog("[ERRO] Invalid 'level' option: %s\n", level)
|
logger.Fatal("Invalid 'level' option. Level must be either \"1\", \"2\" or \"3\"")
|
||||||
ColorLog("[HINT] Level must be either 1, 2 or 3\n")
|
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
var selectedTables map[string]bool
|
var selectedTables map[string]bool
|
||||||
if tables != "" {
|
if tables != "" {
|
||||||
@ -53,12 +51,9 @@ func generateHproseAppcode(driver, connStr, level, tables, currpath string) {
|
|||||||
case "mysql":
|
case "mysql":
|
||||||
case "postgres":
|
case "postgres":
|
||||||
case "sqlite":
|
case "sqlite":
|
||||||
ColorLog("[ERRO] Generating app code from SQLite database is not supported yet.\n")
|
logger.Fatal("Generating app code from SQLite database is not supported yet")
|
||||||
os.Exit(2)
|
|
||||||
default:
|
default:
|
||||||
ColorLog("[ERRO] Unknown database driver: %s\n", driver)
|
logger.Fatalf("Unknown database driver '%s'. Driver must be one of mysql, postgres or sqlite", driver)
|
||||||
ColorLog("[HINT] Driver must be one of mysql, postgres or sqlite\n")
|
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
genHprose(driver, connStr, mode, selectedTables, currpath)
|
genHprose(driver, connStr, mode, selectedTables, currpath)
|
||||||
}
|
}
|
||||||
@ -68,12 +63,11 @@ func generateHproseAppcode(driver, connStr, level, tables, currpath string) {
|
|||||||
func genHprose(dbms, connStr string, mode byte, selectedTableNames map[string]bool, currpath string) {
|
func genHprose(dbms, connStr string, mode byte, selectedTableNames map[string]bool, currpath string) {
|
||||||
db, err := sql.Open(dbms, connStr)
|
db, err := sql.Open(dbms, connStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[ERRO] Could not connect to %s database: %s, %s\n", dbms, connStr, err)
|
logger.Fatalf("Could not connect to '%s' database using '%s': %s", dbms, connStr, err)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
if trans, ok := dbDriver[dbms]; ok {
|
if trans, ok := dbDriver[dbms]; ok {
|
||||||
ColorLog("[INFO] Analyzing database tables...\n")
|
logger.Info("Analyzing database tables...")
|
||||||
tableNames := trans.GetTableNames(db)
|
tableNames := trans.GetTableNames(db)
|
||||||
tables := getTableObjects(tableNames, db, trans)
|
tables := getTableObjects(tableNames, db, trans)
|
||||||
mvcPath := new(MvcPath)
|
mvcPath := new(MvcPath)
|
||||||
@ -82,8 +76,7 @@ func genHprose(dbms, connStr string, mode byte, selectedTableNames map[string]bo
|
|||||||
pkgPath := getPackagePath(currpath)
|
pkgPath := getPackagePath(currpath)
|
||||||
writeHproseSourceFiles(pkgPath, tables, mode, mvcPath, selectedTableNames)
|
writeHproseSourceFiles(pkgPath, tables, mode, mvcPath, selectedTableNames)
|
||||||
} else {
|
} else {
|
||||||
ColorLog("[ERRO] Generating app code from %s database is not supported yet.\n", dbms)
|
logger.Fatalf("Generating app code from '%s' database is not supported yet", dbms)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,7 +85,7 @@ func genHprose(dbms, connStr string, mode byte, selectedTableNames map[string]bo
|
|||||||
// Newly geneated files will be inside these folders.
|
// Newly geneated files will be inside these folders.
|
||||||
func writeHproseSourceFiles(pkgPath string, tables []*Table, mode byte, paths *MvcPath, selectedTables map[string]bool) {
|
func writeHproseSourceFiles(pkgPath string, tables []*Table, mode byte, paths *MvcPath, selectedTables map[string]bool) {
|
||||||
if (OModel & mode) == OModel {
|
if (OModel & mode) == OModel {
|
||||||
ColorLog("[INFO] Creating model files...\n")
|
logger.Info("Creating model files...")
|
||||||
writeHproseModelFiles(tables, paths.ModelPath, selectedTables)
|
writeHproseModelFiles(tables, paths.ModelPath, selectedTables)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -113,21 +106,21 @@ func writeHproseModelFiles(tables []*Table, mPath string, selectedTables map[str
|
|||||||
var f *os.File
|
var f *os.File
|
||||||
var err error
|
var err error
|
||||||
if isExist(fpath) {
|
if isExist(fpath) {
|
||||||
ColorLog("[WARN] '%v' already exists. Do you want to overwrite it? [Yes|No] ", fpath)
|
logger.Warnf("'%s' already exists. Do you want to overwrite it? [Yes|No] ", fpath)
|
||||||
if askForConfirmation() {
|
if askForConfirmation() {
|
||||||
f, err = os.OpenFile(fpath, os.O_RDWR|os.O_TRUNC, 0666)
|
f, err = os.OpenFile(fpath, os.O_RDWR|os.O_TRUNC, 0666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[WARN] %v\n", err)
|
logger.Warnf("%s", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ColorLog("[WARN] Skipped create file '%s'\n", fpath)
|
logger.Warnf("Skipped create file '%s'", fpath)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
f, err = os.OpenFile(fpath, os.O_CREATE|os.O_RDWR, 0666)
|
f, err = os.OpenFile(fpath, os.O_CREATE|os.O_RDWR, 0666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[WARN] %v\n", err)
|
logger.Warnf("%s", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -150,8 +143,7 @@ func writeHproseModelFiles(tables []*Table, mPath string, selectedTables map[str
|
|||||||
fileStr = strings.Replace(fileStr, "{{timePkg}}", timePkg, -1)
|
fileStr = strings.Replace(fileStr, "{{timePkg}}", timePkg, -1)
|
||||||
fileStr = strings.Replace(fileStr, "{{importTimePkg}}", importTimePkg, -1)
|
fileStr = strings.Replace(fileStr, "{{importTimePkg}}", importTimePkg, -1)
|
||||||
if _, err := f.WriteString(fileStr); err != nil {
|
if _, err := f.WriteString(fileStr); err != nil {
|
||||||
ColorLog("[ERRO] Could not write model file to '%s'\n", fpath)
|
logger.Fatalf("Could not write model file to '%s'", fpath)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
CloseFile(f)
|
CloseFile(f)
|
||||||
fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", fpath, "\x1b[0m")
|
fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", fpath, "\x1b[0m")
|
||||||
|
@ -51,12 +51,12 @@ func (m mysqlDriver) generateSQLFromFields(fields string) string {
|
|||||||
for i, v := range fds {
|
for i, v := range fds {
|
||||||
kv := strings.SplitN(v, ":", 2)
|
kv := strings.SplitN(v, ":", 2)
|
||||||
if len(kv) != 2 {
|
if len(kv) != 2 {
|
||||||
ColorLog("[ERRO] Fields format is wrong. Should be: key:type,key:type " + v + "\n")
|
logger.Error("Fields format is wrong. Should be: key:type,key:type " + v)
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
typ, tag := m.getSQLType(kv[1])
|
typ, tag := m.getSQLType(kv[1])
|
||||||
if typ == "" {
|
if typ == "" {
|
||||||
ColorLog("[ERRO] Fields format is wrong. Should be: key:type,key:type " + v + "\n")
|
logger.Error("Fields format is wrong. Should be: key:type,key:type " + v)
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
if i == 0 && strings.ToLower(kv[0]) != "id" {
|
if i == 0 && strings.ToLower(kv[0]) != "id" {
|
||||||
@ -120,12 +120,12 @@ func (m postgresqlDriver) generateSQLFromFields(fields string) string {
|
|||||||
for i, v := range fds {
|
for i, v := range fds {
|
||||||
kv := strings.SplitN(v, ":", 2)
|
kv := strings.SplitN(v, ":", 2)
|
||||||
if len(kv) != 2 {
|
if len(kv) != 2 {
|
||||||
ColorLog("[ERRO] Fields format is wrong. Should be: key:type,key:type " + v + "\n")
|
logger.Error("Fields format is wrong. Should be: key:type,key:type " + v)
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
typ, tag := m.getSQLType(kv[1])
|
typ, tag := m.getSQLType(kv[1])
|
||||||
if typ == "" {
|
if typ == "" {
|
||||||
ColorLog("[ERRO] Fields format is wrong. Should be: key:type,key:type " + v + "\n")
|
logger.Error("Fields format is wrong. Should be: key:type,key:type " + v)
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
if i == 0 && strings.ToLower(kv[0]) != "id" {
|
if i == 0 && strings.ToLower(kv[0]) != "id" {
|
||||||
@ -177,7 +177,8 @@ func newDBDriver() DBDriver {
|
|||||||
case "postgres":
|
case "postgres":
|
||||||
return postgresqlDriver{}
|
return postgresqlDriver{}
|
||||||
default:
|
default:
|
||||||
panic("driver not supported")
|
logger.Fatal("Driver not supported")
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,8 +191,7 @@ func generateMigration(mname, upsql, downsql, curpath string) {
|
|||||||
if _, err := os.Stat(migrationFilePath); os.IsNotExist(err) {
|
if _, err := os.Stat(migrationFilePath); os.IsNotExist(err) {
|
||||||
// create migrations directory
|
// create migrations directory
|
||||||
if err := os.MkdirAll(migrationFilePath, 0777); err != nil {
|
if err := os.MkdirAll(migrationFilePath, 0777); err != nil {
|
||||||
ColorLog("[ERRO] Could not create migration directory: %s\n", err)
|
logger.Fatalf("Could not create migration directory: %s", err)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// create file
|
// create file
|
||||||
@ -208,8 +208,7 @@ func generateMigration(mname, upsql, downsql, curpath string) {
|
|||||||
formatSourceCode(fpath)
|
formatSourceCode(fpath)
|
||||||
fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", fpath, "\x1b[0m")
|
fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", fpath, "\x1b[0m")
|
||||||
} else {
|
} else {
|
||||||
ColorLog("[ERRO] Could not create migration file: %s\n", err)
|
logger.Fatalf("Could not create migration file: %s", err)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
13
g_model.go
13
g_model.go
@ -35,19 +35,17 @@ func generateModel(mname, fields, currpath string) {
|
|||||||
|
|
||||||
modelStruct, hastime, err := getStruct(modelName, fields)
|
modelStruct, hastime, err := getStruct(modelName, fields)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[ERRO] Could not generate the model struct: %s\n", err)
|
logger.Fatalf("Could not generate the model struct: %s", err)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorLog("[INFO] Using '%s' as model name\n", modelName)
|
logger.Infof("Using '%s' as model name", modelName)
|
||||||
ColorLog("[INFO] Using '%s' as package name\n", packageName)
|
logger.Infof("Using '%s' as package name", packageName)
|
||||||
|
|
||||||
fp := path.Join(currpath, "models", p)
|
fp := path.Join(currpath, "models", p)
|
||||||
if _, err := os.Stat(fp); os.IsNotExist(err) {
|
if _, err := os.Stat(fp); os.IsNotExist(err) {
|
||||||
// Create the model's directory
|
// Create the model's directory
|
||||||
if err := os.MkdirAll(fp, 0777); err != nil {
|
if err := os.MkdirAll(fp, 0777); err != nil {
|
||||||
ColorLog("[ERRO] Could not create the model directory: %s\n", err)
|
logger.Fatalf("Could not create the model directory: %s", err)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,8 +65,7 @@ func generateModel(mname, fields, currpath string) {
|
|||||||
formatSourceCode(fpath)
|
formatSourceCode(fpath)
|
||||||
fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", fpath, "\x1b[0m")
|
fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", fpath, "\x1b[0m")
|
||||||
} else {
|
} else {
|
||||||
ColorLog("[ERRO] Could not create model file: %s\n", err)
|
logger.Fatalf("Could not create model file: %s", err)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ package main
|
|||||||
import "strings"
|
import "strings"
|
||||||
|
|
||||||
func generateScaffold(sname, fields, currpath, driver, conn string) {
|
func generateScaffold(sname, fields, currpath, driver, conn string) {
|
||||||
ColorLog("[INFO] Do you want to create a '%v' model? [Yes|No] ", sname)
|
logger.Infof("Do you want to create a '%s' model? [Yes|No] ", sname)
|
||||||
|
|
||||||
// Generate the model
|
// Generate the model
|
||||||
if askForConfirmation() {
|
if askForConfirmation() {
|
||||||
@ -11,19 +11,19 @@ func generateScaffold(sname, fields, currpath, driver, conn string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate the controller
|
// Generate the controller
|
||||||
ColorLog("[INFO] Do you want to create a '%v' controller? [Yes|No] ", sname)
|
logger.Infof("Do you want to create a '%s' controller? [Yes|No] ", sname)
|
||||||
if askForConfirmation() {
|
if askForConfirmation() {
|
||||||
generateController(sname, currpath)
|
generateController(sname, currpath)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate the views
|
// Generate the views
|
||||||
ColorLog("[INFO] Do you want to create views for this '%v' resource? [Yes|No] ", sname)
|
logger.Infof("Do you want to create views for this '%s' resource? [Yes|No] ", sname)
|
||||||
if askForConfirmation() {
|
if askForConfirmation() {
|
||||||
generateView(sname, currpath)
|
generateView(sname, currpath)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate a migration
|
// Generate a migration
|
||||||
ColorLog("[INFO] Do you want to create a '%v' migration and schema for this resource? [Yes|No] ", sname)
|
logger.Infof("Do you want to create a '%s' migration and schema for this resource? [Yes|No] ", sname)
|
||||||
if askForConfirmation() {
|
if askForConfirmation() {
|
||||||
upsql := ""
|
upsql := ""
|
||||||
downsql := ""
|
downsql := ""
|
||||||
@ -40,9 +40,9 @@ func generateScaffold(sname, fields, currpath, driver, conn string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Run the migration
|
// Run the migration
|
||||||
ColorLog("[INFO] Do you want to migrate the database? [Yes|No] ")
|
logger.Infof("Do you want to migrate the database? [Yes|No] ")
|
||||||
if askForConfirmation() {
|
if askForConfirmation() {
|
||||||
migrateUpdate(currpath, driver, conn)
|
migrateUpdate(currpath, driver, conn)
|
||||||
}
|
}
|
||||||
ColorLog("[INFO] All done! Don't forget to add beego.Router(\"/%v\" ,&controllers.%vController{}) to routers/route.go\n", sname, strings.Title(sname))
|
logger.Successf("All done! Don't forget to add beego.Router(\"/%s\" ,&controllers.%sController{}) to routers/route.go\n", sname, strings.Title(sname))
|
||||||
}
|
}
|
||||||
|
17
g_views.go
17
g_views.go
@ -25,13 +25,12 @@ import (
|
|||||||
func generateView(viewpath, currpath string) {
|
func generateView(viewpath, currpath string) {
|
||||||
w := NewColorWriter(os.Stdout)
|
w := NewColorWriter(os.Stdout)
|
||||||
|
|
||||||
ColorLog("[INFO] Generating view...\n")
|
logger.Info("Generating view...")
|
||||||
|
|
||||||
absViewPath := path.Join(currpath, "views", viewpath)
|
absViewPath := path.Join(currpath, "views", viewpath)
|
||||||
err := os.MkdirAll(absViewPath, os.ModePerm)
|
err := os.MkdirAll(absViewPath, os.ModePerm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[ERRO] Could not create '%s' view: %s\n", viewpath, err)
|
logger.Fatalf("Could not create '%s' view: %s", viewpath, err)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cfile := path.Join(absViewPath, "index.tpl")
|
cfile := path.Join(absViewPath, "index.tpl")
|
||||||
@ -40,8 +39,7 @@ func generateView(viewpath, currpath string) {
|
|||||||
f.WriteString(cfile)
|
f.WriteString(cfile)
|
||||||
fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", cfile, "\x1b[0m")
|
fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", cfile, "\x1b[0m")
|
||||||
} else {
|
} else {
|
||||||
ColorLog("[ERRO] Could not create view file: %s\n", err)
|
logger.Fatalf("Could not create view file: %s", err)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cfile = path.Join(absViewPath, "show.tpl")
|
cfile = path.Join(absViewPath, "show.tpl")
|
||||||
@ -50,8 +48,7 @@ func generateView(viewpath, currpath string) {
|
|||||||
f.WriteString(cfile)
|
f.WriteString(cfile)
|
||||||
fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", cfile, "\x1b[0m")
|
fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", cfile, "\x1b[0m")
|
||||||
} else {
|
} else {
|
||||||
ColorLog("[ERRO] Could not create view file: %s\n", err)
|
logger.Fatalf("Could not create view file: %s", err)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cfile = path.Join(absViewPath, "create.tpl")
|
cfile = path.Join(absViewPath, "create.tpl")
|
||||||
@ -60,8 +57,7 @@ func generateView(viewpath, currpath string) {
|
|||||||
f.WriteString(cfile)
|
f.WriteString(cfile)
|
||||||
fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", cfile, "\x1b[0m")
|
fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", cfile, "\x1b[0m")
|
||||||
} else {
|
} else {
|
||||||
ColorLog("[ERRO] Could not create view file: %s\n", err)
|
logger.Fatalf("Could not create view file: %s", err)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cfile = path.Join(absViewPath, "edit.tpl")
|
cfile = path.Join(absViewPath, "edit.tpl")
|
||||||
@ -70,7 +66,6 @@ func generateView(viewpath, currpath string) {
|
|||||||
f.WriteString(cfile)
|
f.WriteString(cfile)
|
||||||
fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", cfile, "\x1b[0m")
|
fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", cfile, "\x1b[0m")
|
||||||
} else {
|
} else {
|
||||||
ColorLog("[ERRO] Could not create view file: %s\n", err)
|
logger.Fatalf("Could not create view file: %s", err)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
19
hproseapp.go
19
hproseapp.go
@ -65,7 +65,7 @@ var hproseMaingo = `package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
"{{.Appname}}/models"
|
"{{.Appname}}/models"
|
||||||
"github.com/hprose/hprose-golang/rpc"
|
"github.com/hprose/hprose-golang/rpc"
|
||||||
|
|
||||||
@ -90,7 +90,7 @@ func main() {
|
|||||||
// Create Http Server
|
// Create Http Server
|
||||||
service := rpc.NewHTTPService()
|
service := rpc.NewHTTPService()
|
||||||
|
|
||||||
// Use Logger Middleware
|
// Use Logger Middleware
|
||||||
service.AddInvokeHandler(logInvokeHandler)
|
service.AddInvokeHandler(logInvokeHandler)
|
||||||
|
|
||||||
// Publish Functions
|
// Publish Functions
|
||||||
@ -139,7 +139,7 @@ func main() {
|
|||||||
// Create Http Server
|
// Create Http Server
|
||||||
service := rpc.NewHTTPService()
|
service := rpc.NewHTTPService()
|
||||||
|
|
||||||
// Use Logger Middleware
|
// Use Logger Middleware
|
||||||
service.AddInvokeHandler(logInvokeHandler)
|
service.AddInvokeHandler(logInvokeHandler)
|
||||||
|
|
||||||
{{HproseFunctionList}}
|
{{HproseFunctionList}}
|
||||||
@ -314,8 +314,7 @@ func createhprose(cmd *Command, args []string) int {
|
|||||||
}
|
}
|
||||||
apppath, packpath, err := checkEnv(args[0])
|
apppath, packpath, err := checkEnv(args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
logger.Fatalf("%s", err)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
if driver == "" {
|
if driver == "" {
|
||||||
driver = "mysql"
|
driver = "mysql"
|
||||||
@ -323,7 +322,7 @@ func createhprose(cmd *Command, args []string) int {
|
|||||||
if conn == "" {
|
if conn == "" {
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorLog("[INFO] Creating Hprose application...\n")
|
logger.Info("Creating Hprose application...")
|
||||||
|
|
||||||
os.MkdirAll(apppath, 0755)
|
os.MkdirAll(apppath, 0755)
|
||||||
fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", apppath, "\x1b[0m")
|
fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", apppath, "\x1b[0m")
|
||||||
@ -334,9 +333,9 @@ func createhprose(cmd *Command, args []string) int {
|
|||||||
strings.Replace(hproseconf, "{{.Appname}}", args[0], -1))
|
strings.Replace(hproseconf, "{{.Appname}}", args[0], -1))
|
||||||
|
|
||||||
if conn != "" {
|
if conn != "" {
|
||||||
ColorLog("[INFO] Using '%s' as 'driver'\n", driver)
|
logger.Infof("Using '%s' as 'driver'", driver)
|
||||||
ColorLog("[INFO] Using '%s' as 'conn'\n", conn)
|
logger.Infof("Using '%s' as 'conn'", conn)
|
||||||
ColorLog("[INFO] Using '%s' as 'tables'\n", tables)
|
logger.Infof("Using '%s' as 'tables'", tables)
|
||||||
generateHproseAppcode(string(driver), string(conn), "1", string(tables), path.Join(curpath, args[0]))
|
generateHproseAppcode(string(driver), string(conn), "1", string(tables), path.Join(curpath, args[0]))
|
||||||
fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(apppath, "main.go"), "\x1b[0m")
|
fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(apppath, "main.go"), "\x1b[0m")
|
||||||
maingoContent := strings.Replace(hproseMainconngo, "{{.Appname}}", packpath, -1)
|
maingoContent := strings.Replace(hproseMainconngo, "{{.Appname}}", packpath, -1)
|
||||||
@ -369,6 +368,6 @@ func createhprose(cmd *Command, args []string) int {
|
|||||||
WriteToFile(path.Join(apppath, "main.go"),
|
WriteToFile(path.Join(apppath, "main.go"),
|
||||||
strings.Replace(hproseMaingo, "{{.Appname}}", packpath, -1))
|
strings.Replace(hproseMaingo, "{{.Appname}}", packpath, -1))
|
||||||
}
|
}
|
||||||
ColorLog("[SUCC] New Hprose application successfully created!\n")
|
logger.Success("New Hprose application successfully created!")
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
119
migrate.go
119
migrate.go
@ -16,14 +16,13 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path"
|
"path"
|
||||||
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
"runtime"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var cmdMigrate = &Command{
|
var cmdMigrate = &Command{
|
||||||
@ -69,18 +68,20 @@ func runMigration(cmd *Command, args []string) int {
|
|||||||
|
|
||||||
gps := GetGOPATHs()
|
gps := GetGOPATHs()
|
||||||
if len(gps) == 0 {
|
if len(gps) == 0 {
|
||||||
ColorLog("[ERRO] Fail to start[ %s ]\n", "GOPATH environment variable is not set or empty")
|
logger.Fatal("GOPATH environment variable is not set or empty")
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
gopath := gps[0]
|
|
||||||
Debugf("GOPATH: %s", gopath)
|
|
||||||
|
|
||||||
// load config
|
gopath := gps[0]
|
||||||
|
|
||||||
|
logger.Debugf("GOPATH: %s", gopath)
|
||||||
|
|
||||||
|
// Load the configuration
|
||||||
err := loadConfig()
|
err := loadConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[ERRO] Fail to parse bee.json[ %s ]\n", err)
|
logger.Errorf("Failed to load configuration: %s", err)
|
||||||
}
|
}
|
||||||
// getting command line arguments
|
|
||||||
|
// Getting command line arguments
|
||||||
if len(args) != 0 {
|
if len(args) != 0 {
|
||||||
cmd.Flag.Parse(args[1:])
|
cmd.Flag.Parse(args[1:])
|
||||||
}
|
}
|
||||||
@ -96,31 +97,30 @@ func runMigration(cmd *Command, args []string) int {
|
|||||||
mConn = "root:@tcp(127.0.0.1:3306)/test"
|
mConn = "root:@tcp(127.0.0.1:3306)/test"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ColorLog("[INFO] Using '%s' as 'driver'\n", mDriver)
|
logger.Infof("Using '%s' as 'driver'", mDriver)
|
||||||
ColorLog("[INFO] Using '%s' as 'conn'\n", mConn)
|
logger.Infof("Using '%s' as 'conn'", mConn)
|
||||||
driverStr, connStr := string(mDriver), string(mConn)
|
driverStr, connStr := string(mDriver), string(mConn)
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
// run all outstanding migrations
|
// run all outstanding migrations
|
||||||
ColorLog("[INFO] Running all outstanding migrations\n")
|
logger.Info("Running all outstanding migrations")
|
||||||
migrateUpdate(currpath, driverStr, connStr)
|
migrateUpdate(currpath, driverStr, connStr)
|
||||||
} else {
|
} else {
|
||||||
mcmd := args[0]
|
mcmd := args[0]
|
||||||
switch mcmd {
|
switch mcmd {
|
||||||
case "rollback":
|
case "rollback":
|
||||||
ColorLog("[INFO] Rolling back the last migration operation\n")
|
logger.Info("Rolling back the last migration operation")
|
||||||
migrateRollback(currpath, driverStr, connStr)
|
migrateRollback(currpath, driverStr, connStr)
|
||||||
case "reset":
|
case "reset":
|
||||||
ColorLog("[INFO] Reseting all migrations\n")
|
logger.Info("Reseting all migrations")
|
||||||
migrateReset(currpath, driverStr, connStr)
|
migrateReset(currpath, driverStr, connStr)
|
||||||
case "refresh":
|
case "refresh":
|
||||||
ColorLog("[INFO] Refreshing all migrations\n")
|
logger.Info("Refreshing all migrations")
|
||||||
migrateRefresh(currpath, driverStr, connStr)
|
migrateRefresh(currpath, driverStr, connStr)
|
||||||
default:
|
default:
|
||||||
ColorLog("[ERRO] Command is missing\n")
|
logger.Fatal("Command is missing")
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ColorLog("[SUCC] Migration successful!\n")
|
logger.Success("Migration successful!")
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,21 +146,21 @@ func migrateRefresh(currpath, driver, connStr string) {
|
|||||||
|
|
||||||
// migrate generates source code, build it, and invoke the binary who does the actual migration
|
// migrate generates source code, build it, and invoke the binary who does the actual migration
|
||||||
func migrate(goal, currpath, driver, connStr string) {
|
func migrate(goal, currpath, driver, connStr string) {
|
||||||
dir := path.Join(currpath, "database", "migrations")
|
dir := path.Join(currpath, "database", "migrations")
|
||||||
postfix := ""
|
postfix := ""
|
||||||
if runtime.GOOS == "windows" {
|
if runtime.GOOS == "windows" {
|
||||||
postfix = ".exe"
|
postfix = ".exe"
|
||||||
}
|
}
|
||||||
binary := "m" + postfix
|
binary := "m" + postfix
|
||||||
source := binary + ".go"
|
source := binary + ".go"
|
||||||
// connect to database
|
|
||||||
|
// Connect to database
|
||||||
db, err := sql.Open(driver, connStr)
|
db, err := sql.Open(driver, connStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[ERRO] Could not connect to %s: %s\n", driver, connStr)
|
logger.Fatalf("Could not connect to database using '%s': %s", connStr, err)
|
||||||
ColorLog("[ERRO] Error: %v", err.Error())
|
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
|
|
||||||
checkForSchemaUpdateTable(db, driver)
|
checkForSchemaUpdateTable(db, driver)
|
||||||
latestName, latestTime := getLatestMigration(db, goal)
|
latestName, latestTime := getLatestMigration(db, goal)
|
||||||
writeMigrationSourceFile(dir, source, driver, connStr, latestTime, latestName, goal)
|
writeMigrationSourceFile(dir, source, driver, connStr, latestTime, latestName, goal)
|
||||||
@ -175,50 +175,44 @@ func migrate(goal, currpath, driver, connStr string) {
|
|||||||
func checkForSchemaUpdateTable(db *sql.DB, driver string) {
|
func checkForSchemaUpdateTable(db *sql.DB, driver string) {
|
||||||
showTableSQL := showMigrationsTableSQL(driver)
|
showTableSQL := showMigrationsTableSQL(driver)
|
||||||
if rows, err := db.Query(showTableSQL); err != nil {
|
if rows, err := db.Query(showTableSQL); err != nil {
|
||||||
ColorLog("[ERRO] Could not show migrations table: %s\n", err)
|
logger.Fatalf("Could not show migrations table: %s", err)
|
||||||
os.Exit(2)
|
|
||||||
} else if !rows.Next() {
|
} else if !rows.Next() {
|
||||||
// no migrations table, create anew
|
// No migrations table, create new ones
|
||||||
createTableSQL := createMigrationsTableSQL(driver)
|
createTableSQL := createMigrationsTableSQL(driver)
|
||||||
ColorLog("[INFO] Creating 'migrations' table...\n")
|
|
||||||
|
logger.Infof("Creating 'migrations' table...")
|
||||||
|
|
||||||
if _, err := db.Query(createTableSQL); err != nil {
|
if _, err := db.Query(createTableSQL); err != nil {
|
||||||
ColorLog("[ERRO] Could not create migrations table: %s\n", err)
|
logger.Fatalf("Could not create migrations table: %s", err)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// checking that migrations table schema are expected
|
// Checking that migrations table schema are expected
|
||||||
selectTableSQL := selectMigrationsTableSQL(driver)
|
selectTableSQL := selectMigrationsTableSQL(driver)
|
||||||
if rows, err := db.Query(selectTableSQL); err != nil {
|
if rows, err := db.Query(selectTableSQL); err != nil {
|
||||||
ColorLog("[ERRO] Could not show columns of migrations table: %s\n", err)
|
logger.Fatalf("Could not show columns of migrations table: %s", err)
|
||||||
os.Exit(2)
|
|
||||||
} else {
|
} else {
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var fieldBytes, typeBytes, nullBytes, keyBytes, defaultBytes, extraBytes []byte
|
var fieldBytes, typeBytes, nullBytes, keyBytes, defaultBytes, extraBytes []byte
|
||||||
if err := rows.Scan(&fieldBytes, &typeBytes, &nullBytes, &keyBytes, &defaultBytes, &extraBytes); err != nil {
|
if err := rows.Scan(&fieldBytes, &typeBytes, &nullBytes, &keyBytes, &defaultBytes, &extraBytes); err != nil {
|
||||||
ColorLog("[ERRO] Could not read column information: %s\n", err)
|
logger.Fatalf("Could not read column information: %s", err)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
fieldStr, typeStr, nullStr, keyStr, defaultStr, extraStr :=
|
fieldStr, typeStr, nullStr, keyStr, defaultStr, extraStr :=
|
||||||
string(fieldBytes), string(typeBytes), string(nullBytes), string(keyBytes), string(defaultBytes), string(extraBytes)
|
string(fieldBytes), string(typeBytes), string(nullBytes), string(keyBytes), string(defaultBytes), string(extraBytes)
|
||||||
if fieldStr == "id_migration" {
|
if fieldStr == "id_migration" {
|
||||||
if keyStr != "PRI" || extraStr != "auto_increment" {
|
if keyStr != "PRI" || extraStr != "auto_increment" {
|
||||||
ColorLog("[ERRO] Column migration.id_migration type mismatch: KEY: %s, EXTRA: %s\n", keyStr, extraStr)
|
logger.Hint("Expecting KEY: PRI, EXTRA: auto_increment")
|
||||||
ColorLog("[HINT] Expecting KEY: PRI, EXTRA: auto_increment\n")
|
logger.Fatalf("Column migration.id_migration type mismatch: KEY: %s, EXTRA: %s", keyStr, extraStr)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
} else if fieldStr == "name" {
|
} else if fieldStr == "name" {
|
||||||
if !strings.HasPrefix(typeStr, "varchar") || nullStr != "YES" {
|
if !strings.HasPrefix(typeStr, "varchar") || nullStr != "YES" {
|
||||||
ColorLog("[ERRO] Column migration.name type mismatch: TYPE: %s, NULL: %s\n", typeStr, nullStr)
|
logger.Hint("Expecting TYPE: varchar, NULL: YES")
|
||||||
ColorLog("[HINT] Expecting TYPE: varchar, NULL: YES\n")
|
logger.Fatalf("Column migration.name type mismatch: TYPE: %s, NULL: %s", typeStr, nullStr)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if fieldStr == "created_at" {
|
} else if fieldStr == "created_at" {
|
||||||
if typeStr != "timestamp" || defaultStr != "CURRENT_TIMESTAMP" {
|
if typeStr != "timestamp" || defaultStr != "CURRENT_TIMESTAMP" {
|
||||||
ColorLog("[ERRO] Column migration.timestamp type mismatch: TYPE: %s, DEFAULT: %s\n", typeStr, defaultStr)
|
logger.Hint("Expecting TYPE: timestamp, DEFAULT: CURRENT_TIMESTAMP")
|
||||||
ColorLog("[HINT] Expecting TYPE: timestamp, DEFAULT: CURRENT_TIMESTAMP\n")
|
logger.Fatalf("Column migration.timestamp type mismatch: TYPE: %s, DEFAULT: %s", typeStr, defaultStr)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -262,26 +256,22 @@ func selectMigrationsTableSQL(driver string) string {
|
|||||||
func getLatestMigration(db *sql.DB, goal string) (file string, createdAt int64) {
|
func getLatestMigration(db *sql.DB, goal string) (file string, createdAt int64) {
|
||||||
sql := "SELECT name FROM migrations where status = 'update' ORDER BY id_migration DESC LIMIT 1"
|
sql := "SELECT name FROM migrations where status = 'update' ORDER BY id_migration DESC LIMIT 1"
|
||||||
if rows, err := db.Query(sql); err != nil {
|
if rows, err := db.Query(sql); err != nil {
|
||||||
ColorLog("[ERRO] Could not retrieve migrations: %s\n", err)
|
logger.Fatalf("Could not retrieve migrations: %s", err)
|
||||||
os.Exit(2)
|
|
||||||
} else {
|
} else {
|
||||||
if rows.Next() {
|
if rows.Next() {
|
||||||
if err := rows.Scan(&file); err != nil {
|
if err := rows.Scan(&file); err != nil {
|
||||||
ColorLog("[ERRO] Could not read migrations in database: %s\n", err)
|
logger.Fatalf("Could not read migrations in database: %s", err)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
createdAtStr := file[len(file)-15:]
|
createdAtStr := file[len(file)-15:]
|
||||||
if t, err := time.Parse("20060102_150405", createdAtStr); err != nil {
|
if t, err := time.Parse("20060102_150405", createdAtStr); err != nil {
|
||||||
ColorLog("[ERRO] Could not parse time: %s\n", err)
|
logger.Fatalf("Could not parse time: %s", err)
|
||||||
os.Exit(2)
|
|
||||||
} else {
|
} else {
|
||||||
createdAt = t.Unix()
|
createdAt = t.Unix()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// migration table has no 'update' record, no point rolling back
|
// migration table has no 'update' record, no point rolling back
|
||||||
if goal == "rollback" {
|
if goal == "rollback" {
|
||||||
ColorLog("[ERRO] There is nothing to rollback\n")
|
logger.Fatal("There is nothing to rollback")
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
file, createdAt = "", 0
|
file, createdAt = "", 0
|
||||||
}
|
}
|
||||||
@ -293,8 +283,7 @@ func getLatestMigration(db *sql.DB, goal string) (file string, createdAt int64)
|
|||||||
func writeMigrationSourceFile(dir, source, driver, connStr string, latestTime int64, latestName string, task string) {
|
func writeMigrationSourceFile(dir, source, driver, connStr string, latestTime int64, latestName string, task string) {
|
||||||
changeDir(dir)
|
changeDir(dir)
|
||||||
if f, err := os.OpenFile(source, os.O_CREATE|os.O_EXCL|os.O_RDWR, 0666); err != nil {
|
if f, err := os.OpenFile(source, os.O_CREATE|os.O_EXCL|os.O_RDWR, 0666); err != nil {
|
||||||
ColorLog("[ERRO] Could not create file: %s\n", err)
|
logger.Fatalf("Could not create file: %s", err)
|
||||||
os.Exit(2)
|
|
||||||
} else {
|
} else {
|
||||||
content := strings.Replace(MigrationMainTPL, "{{DBDriver}}", driver, -1)
|
content := strings.Replace(MigrationMainTPL, "{{DBDriver}}", driver, -1)
|
||||||
content = strings.Replace(content, "{{ConnStr}}", connStr, -1)
|
content = strings.Replace(content, "{{ConnStr}}", connStr, -1)
|
||||||
@ -302,8 +291,7 @@ func writeMigrationSourceFile(dir, source, driver, connStr string, latestTime in
|
|||||||
content = strings.Replace(content, "{{LatestName}}", latestName, -1)
|
content = strings.Replace(content, "{{LatestName}}", latestName, -1)
|
||||||
content = strings.Replace(content, "{{Task}}", task, -1)
|
content = strings.Replace(content, "{{Task}}", task, -1)
|
||||||
if _, err := f.WriteString(content); err != nil {
|
if _, err := f.WriteString(content); err != nil {
|
||||||
ColorLog("[ERRO] Could not write to file: %s\n", err)
|
logger.Fatalf("Could not write to file: %s", err)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
CloseFile(f)
|
CloseFile(f)
|
||||||
}
|
}
|
||||||
@ -314,7 +302,7 @@ func buildMigrationBinary(dir, binary string) {
|
|||||||
changeDir(dir)
|
changeDir(dir)
|
||||||
cmd := exec.Command("go", "build", "-o", binary)
|
cmd := exec.Command("go", "build", "-o", binary)
|
||||||
if out, err := cmd.CombinedOutput(); err != nil {
|
if out, err := cmd.CombinedOutput(); err != nil {
|
||||||
ColorLog("[ERRO] Could not build migration binary: %s\n", err)
|
logger.Errorf("Could not build migration binary: %s", err)
|
||||||
formatShellErrOutput(string(out))
|
formatShellErrOutput(string(out))
|
||||||
removeTempFile(dir, binary)
|
removeTempFile(dir, binary)
|
||||||
removeTempFile(dir, binary+".go")
|
removeTempFile(dir, binary+".go")
|
||||||
@ -328,7 +316,7 @@ func runMigrationBinary(dir, binary string) {
|
|||||||
cmd := exec.Command("./" + binary)
|
cmd := exec.Command("./" + binary)
|
||||||
if out, err := cmd.CombinedOutput(); err != nil {
|
if out, err := cmd.CombinedOutput(); err != nil {
|
||||||
formatShellOutput(string(out))
|
formatShellOutput(string(out))
|
||||||
ColorLog("[ERRO] Could not run migration binary: %s\n", err)
|
logger.Errorf("Could not run migration binary: %s", err)
|
||||||
removeTempFile(dir, binary)
|
removeTempFile(dir, binary)
|
||||||
removeTempFile(dir, binary+".go")
|
removeTempFile(dir, binary+".go")
|
||||||
os.Exit(2)
|
os.Exit(2)
|
||||||
@ -341,8 +329,7 @@ func runMigrationBinary(dir, binary string) {
|
|||||||
// It exits the system when encouter an error
|
// It exits the system when encouter an error
|
||||||
func changeDir(dir string) {
|
func changeDir(dir string) {
|
||||||
if err := os.Chdir(dir); err != nil {
|
if err := os.Chdir(dir); err != nil {
|
||||||
ColorLog("[ERRO] Could not find migration directory: %s\n", err)
|
logger.Fatalf("Could not find migration directory: %s", err)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -350,7 +337,7 @@ func changeDir(dir string) {
|
|||||||
func removeTempFile(dir, file string) {
|
func removeTempFile(dir, file string) {
|
||||||
changeDir(dir)
|
changeDir(dir)
|
||||||
if err := os.Remove(file); err != nil {
|
if err := os.Remove(file); err != nil {
|
||||||
ColorLog("[WARN] Could not remove temporary file: %s\n", err)
|
logger.Warnf("Could not remove temporary file: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -358,8 +345,7 @@ func removeTempFile(dir, file string) {
|
|||||||
func formatShellErrOutput(o string) {
|
func formatShellErrOutput(o string) {
|
||||||
for _, line := range strings.Split(o, "\n") {
|
for _, line := range strings.Split(o, "\n") {
|
||||||
if line != "" {
|
if line != "" {
|
||||||
ColorLog("[ERRO] -| ")
|
logger.Errorf("|> %s", line)
|
||||||
fmt.Println(line)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -368,13 +354,13 @@ func formatShellErrOutput(o string) {
|
|||||||
func formatShellOutput(o string) {
|
func formatShellOutput(o string) {
|
||||||
for _, line := range strings.Split(o, "\n") {
|
for _, line := range strings.Split(o, "\n") {
|
||||||
if line != "" {
|
if line != "" {
|
||||||
ColorLog("[INFO] -| ")
|
logger.Infof("|> %s", line)
|
||||||
fmt.Println(line)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// MigrationMainTPL migration main template
|
||||||
MigrationMainTPL = `package main
|
MigrationMainTPL = `package main
|
||||||
|
|
||||||
import(
|
import(
|
||||||
@ -414,6 +400,7 @@ func main(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
`
|
`
|
||||||
|
// MYSQLMigrationDDL MySQL migration SQL
|
||||||
MYSQLMigrationDDL = `
|
MYSQLMigrationDDL = `
|
||||||
CREATE TABLE migrations (
|
CREATE TABLE migrations (
|
||||||
id_migration int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'surrogate key',
|
id_migration int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'surrogate key',
|
||||||
@ -425,7 +412,7 @@ CREATE TABLE migrations (
|
|||||||
PRIMARY KEY (id_migration)
|
PRIMARY KEY (id_migration)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8
|
||||||
`
|
`
|
||||||
|
// POSTGRESMigrationDDL Postgres migration SQL
|
||||||
POSTGRESMigrationDDL = `
|
POSTGRESMigrationDDL = `
|
||||||
CREATE TYPE migrations_status AS ENUM('update', 'rollback');
|
CREATE TYPE migrations_status AS ENUM('update', 'rollback');
|
||||||
|
|
||||||
|
20
new.go
20
new.go
@ -58,7 +58,7 @@ func createApp(cmd *Command, args []string) int {
|
|||||||
ShowShortVersionBanner()
|
ShowShortVersionBanner()
|
||||||
w := NewColorWriter(os.Stdout)
|
w := NewColorWriter(os.Stdout)
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
ColorLog("[ERRO] Argument [appname] is missing\n")
|
logger.Error("Argument [appname] is missing")
|
||||||
os.Exit(2)
|
os.Exit(2)
|
||||||
}
|
}
|
||||||
apppath, packpath, err := checkEnv(args[0])
|
apppath, packpath, err := checkEnv(args[0])
|
||||||
@ -68,14 +68,14 @@ func createApp(cmd *Command, args []string) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if isExist(apppath) {
|
if isExist(apppath) {
|
||||||
ColorLog("[ERRO] Path (%s) already exists\n", apppath)
|
logger.Errorf("Path (%s) already exists", apppath)
|
||||||
ColorLog("[WARN] Do you want to overwrite it? [Yes|No] ")
|
logger.Warn("Do you want to overwrite it? [Yes|No] ")
|
||||||
if !askForConfirmation() {
|
if !askForConfirmation() {
|
||||||
os.Exit(2)
|
os.Exit(2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorLog("[INFO] Creating application...\n")
|
logger.Info("Creating application...")
|
||||||
|
|
||||||
os.MkdirAll(apppath, 0755)
|
os.MkdirAll(apppath, 0755)
|
||||||
fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", apppath+string(path.Separator), "\x1b[0m")
|
fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", apppath+string(path.Separator), "\x1b[0m")
|
||||||
@ -117,7 +117,7 @@ func createApp(cmd *Command, args []string) int {
|
|||||||
fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(apppath, "main.go"), "\x1b[0m")
|
fmt.Fprintf(w, "\t%s%screate%s\t %s%s\n", "\x1b[32m", "\x1b[1m", "\x1b[21m", path.Join(apppath, "main.go"), "\x1b[0m")
|
||||||
WriteToFile(path.Join(apppath, "main.go"), strings.Replace(maingo, "{{.Appname}}", packpath, -1))
|
WriteToFile(path.Join(apppath, "main.go"), strings.Replace(maingo, "{{.Appname}}", packpath, -1))
|
||||||
|
|
||||||
ColorLog("[SUCC] New application successfully created!\n")
|
logger.Success("New application successfully created!")
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,13 +302,3 @@ var indextpl = `<!DOCTYPE html>
|
|||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
`
|
`
|
||||||
|
|
||||||
// WriteToFile creates a file and writes content to it
|
|
||||||
func WriteToFile(filename, content string) {
|
|
||||||
f, err := os.Create(filename)
|
|
||||||
defer CloseFile(f)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
f.WriteString(content)
|
|
||||||
}
|
|
||||||
|
35
pack.go
35
pack.go
@ -104,11 +104,6 @@ func init() {
|
|||||||
w = NewColorWriter(os.Stdout)
|
w = NewColorWriter(os.Stdout)
|
||||||
}
|
}
|
||||||
|
|
||||||
func exitPrint(con string) {
|
|
||||||
fmt.Fprintln(os.Stderr, con)
|
|
||||||
os.Exit(2)
|
|
||||||
}
|
|
||||||
|
|
||||||
type walker interface {
|
type walker interface {
|
||||||
isExclude(string) bool
|
isExclude(string) bool
|
||||||
isEmpty(string) bool
|
isEmpty(string) bool
|
||||||
@ -397,10 +392,10 @@ func (wft *zipWalk) compress(name, fpath string, fi os.FileInfo) (bool, error) {
|
|||||||
func packDirectory(excludePrefix []string, excludeSuffix []string,
|
func packDirectory(excludePrefix []string, excludeSuffix []string,
|
||||||
excludeRegexp []*regexp.Regexp, includePath ...string) (err error) {
|
excludeRegexp []*regexp.Regexp, includePath ...string) (err error) {
|
||||||
|
|
||||||
ColorLog("Excluding relpath prefix: %s\n", strings.Join(excludePrefix, ":"))
|
logger.Infof("Excluding relpath prefix: %s", strings.Join(excludePrefix, ":"))
|
||||||
ColorLog("Excluding relpath suffix: %s\n", strings.Join(excludeSuffix, ":"))
|
logger.Infof("Excluding relpath suffix: %s", strings.Join(excludeSuffix, ":"))
|
||||||
if len(excludeRegexp) > 0 {
|
if len(excludeRegexp) > 0 {
|
||||||
ColorLog("Excluding filename regex: `%s`\n", strings.Join(excludeR, "`, `"))
|
logger.Infof("Excluding filename regex: `%s`", strings.Join(excludeR, "`, `"))
|
||||||
}
|
}
|
||||||
|
|
||||||
w, err := os.OpenFile(outputP, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
|
w, err := os.OpenFile(outputP, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
|
||||||
@ -477,17 +472,17 @@ func packApp(cmd *Command, args []string) int {
|
|||||||
|
|
||||||
thePath, err := path.Abs(appPath)
|
thePath, err := path.Abs(appPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
exitPrint(fmt.Sprintf("Wrong app path: %s", thePath))
|
logger.Fatalf("Wrong application path: %s", thePath)
|
||||||
}
|
}
|
||||||
if stat, err := os.Stat(thePath); os.IsNotExist(err) || stat.IsDir() == false {
|
if stat, err := os.Stat(thePath); os.IsNotExist(err) || stat.IsDir() == false {
|
||||||
exitPrint(fmt.Sprintf("App path does not exist: %s", thePath))
|
logger.Fatalf("Application path does not exist: %s", thePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
if isBeegoProject(thePath) == false {
|
if isBeegoProject(thePath) == false {
|
||||||
exitPrint(fmt.Sprintf("Bee does not support non Beego project"))
|
logger.Fatal("Bee does not support non Beego project")
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorLog("Packaging application: %s\n", thePath)
|
logger.Infof("Packaging application on '%s'...", thePath)
|
||||||
|
|
||||||
appName := path.Base(thePath)
|
appName := path.Base(thePath)
|
||||||
|
|
||||||
@ -507,7 +502,7 @@ func packApp(cmd *Command, args []string) int {
|
|||||||
os.Mkdir(tmpdir, 0700)
|
os.Mkdir(tmpdir, 0700)
|
||||||
|
|
||||||
if build {
|
if build {
|
||||||
ColorLog("Building application...\n")
|
logger.Info("Building application...")
|
||||||
var envs []string
|
var envs []string
|
||||||
for _, env := range buildEnvs {
|
for _, env := range buildEnvs {
|
||||||
parts := strings.SplitN(env, "=", 2)
|
parts := strings.SplitN(env, "=", 2)
|
||||||
@ -529,7 +524,7 @@ func packApp(cmd *Command, args []string) int {
|
|||||||
os.Setenv("GOOS", goos)
|
os.Setenv("GOOS", goos)
|
||||||
os.Setenv("GOARCH", goarch)
|
os.Setenv("GOARCH", goarch)
|
||||||
|
|
||||||
ColorLog("Env: GOOS=%s GOARCH=%s\n", goos, goarch)
|
logger.Infof("Using: GOOS=%s GOARCH=%s", goos, goarch)
|
||||||
|
|
||||||
binPath := path.Join(tmpdir, appName)
|
binPath := path.Join(tmpdir, appName)
|
||||||
if goos == "windows" {
|
if goos == "windows" {
|
||||||
@ -552,10 +547,10 @@ func packApp(cmd *Command, args []string) int {
|
|||||||
execmd.Dir = thePath
|
execmd.Dir = thePath
|
||||||
err = execmd.Run()
|
err = execmd.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
exitPrint(err.Error())
|
logger.Fatal(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorLog("Build successful\n")
|
logger.Success("Build successful!")
|
||||||
}
|
}
|
||||||
|
|
||||||
switch format {
|
switch format {
|
||||||
@ -573,7 +568,7 @@ func packApp(cmd *Command, args []string) int {
|
|||||||
if _, err := os.Stat(outputP); err != nil {
|
if _, err := os.Stat(outputP); err != nil {
|
||||||
err = os.MkdirAll(outputP, 0755)
|
err = os.MkdirAll(outputP, 0755)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
exitPrint(err.Error())
|
logger.Fatal(err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -595,7 +590,7 @@ func packApp(cmd *Command, args []string) int {
|
|||||||
for _, r := range excludeR {
|
for _, r := range excludeR {
|
||||||
if len(r) > 0 {
|
if len(r) > 0 {
|
||||||
if re, err := regexp.Compile(r); err != nil {
|
if re, err := regexp.Compile(r); err != nil {
|
||||||
exitPrint(err.Error())
|
logger.Fatal(err.Error())
|
||||||
} else {
|
} else {
|
||||||
exr = append(exr, re)
|
exr = append(exr, re)
|
||||||
}
|
}
|
||||||
@ -604,9 +599,9 @@ func packApp(cmd *Command, args []string) int {
|
|||||||
|
|
||||||
err = packDirectory(exp, exs, exr, tmpdir, thePath)
|
err = packDirectory(exp, exs, exr, tmpdir, thePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
exitPrint(err.Error())
|
logger.Fatal(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorLog("Writing to output: `%s`\n", outputP)
|
logger.Infof("Writing to output: %s", outputP)
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
34
run.go
34
run.go
@ -15,7 +15,6 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
path "path/filepath"
|
path "path/filepath"
|
||||||
@ -77,9 +76,8 @@ func runApp(cmd *Command, args []string) int {
|
|||||||
appname = path.Base(currpath)
|
appname = path.Base(currpath)
|
||||||
currentGoPath = _gopath
|
currentGoPath = _gopath
|
||||||
} else {
|
} else {
|
||||||
exitPrint(fmt.Sprintf("Bee does not support non Beego project: %s", currpath))
|
logger.Fatalf("No Beego application '%s' found in your GOPATH", currpath)
|
||||||
}
|
}
|
||||||
ColorLog("[INFO] Using '%s' as 'appname'\n", appname)
|
|
||||||
} else {
|
} else {
|
||||||
// Check if passed Bee application path/name exists in the GOPATH(s)
|
// Check if passed Bee application path/name exists in the GOPATH(s)
|
||||||
if found, _gopath, _path := SearchGOPATHs(args[0]); found {
|
if found, _gopath, _path := SearchGOPATHs(args[0]); found {
|
||||||
@ -87,35 +85,35 @@ func runApp(cmd *Command, args []string) int {
|
|||||||
currentGoPath = _gopath
|
currentGoPath = _gopath
|
||||||
appname = path.Base(currpath)
|
appname = path.Base(currpath)
|
||||||
} else {
|
} else {
|
||||||
exitPrint(fmt.Sprintf("No Beego application '%s' found in your GOPATH", args[0]))
|
logger.Fatalf("No Beego application '%s' found in your GOPATH", args[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorLog("[INFO] Using '%s' as 'appname'\n", appname)
|
|
||||||
|
|
||||||
if strings.HasSuffix(appname, ".go") && isExist(currpath) {
|
if strings.HasSuffix(appname, ".go") && isExist(currpath) {
|
||||||
ColorLog("[WARN] The appname is in conflict with currpath's file, do you want to build appname as %s\n", appname)
|
logger.Warnf("The appname is in conflict with file's current path. Do you want to build appname as '%s'", appname)
|
||||||
ColorLog("[INFO] Do you want to overwrite it? [yes|no]] ")
|
logger.Info("Do you want to overwrite it? [yes|no] ")
|
||||||
if !askForConfirmation() {
|
if !askForConfirmation() {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Debugf("current path:%s\n", currpath)
|
logger.Infof("Using '%s' as 'appname'", appname)
|
||||||
|
|
||||||
|
logger.Debugf("Current path: %s", currpath)
|
||||||
|
|
||||||
if runmode == "prod" || runmode == "dev" {
|
if runmode == "prod" || runmode == "dev" {
|
||||||
os.Setenv("BEEGO_RUNMODE", runmode)
|
os.Setenv("BEEGO_RUNMODE", runmode)
|
||||||
ColorLog("[INFO] Using '%s' as 'runmode'\n", os.Getenv("BEEGO_RUNMODE"))
|
logger.Infof("Using '%s' as 'runmode'", os.Getenv("BEEGO_RUNMODE"))
|
||||||
} else if runmode != "" {
|
} else if runmode != "" {
|
||||||
os.Setenv("BEEGO_RUNMODE", runmode)
|
os.Setenv("BEEGO_RUNMODE", runmode)
|
||||||
ColorLog("[WARN] Using '%s' as 'runmode'\n", os.Getenv("BEEGO_RUNMODE"))
|
logger.Warnf("Using '%s' as 'runmode'", os.Getenv("BEEGO_RUNMODE"))
|
||||||
} else if os.Getenv("BEEGO_RUNMODE") != "" {
|
} else if os.Getenv("BEEGO_RUNMODE") != "" {
|
||||||
ColorLog("[WARN] Using '%s' as 'runmode'\n", os.Getenv("BEEGO_RUNMODE"))
|
logger.Warnf("Using '%s' as 'runmode'", os.Getenv("BEEGO_RUNMODE"))
|
||||||
}
|
}
|
||||||
|
|
||||||
err := loadConfig()
|
err := loadConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[ERRO] Failed to load configuration [ %s ]\n", err)
|
logger.Fatalf("Failed to load configuration: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var paths []string
|
var paths []string
|
||||||
@ -143,10 +141,10 @@ func runApp(cmd *Command, args []string) int {
|
|||||||
}
|
}
|
||||||
if gendoc == "true" {
|
if gendoc == "true" {
|
||||||
NewWatcher(paths, files, true)
|
NewWatcher(paths, files, true)
|
||||||
Autobuild(files, true)
|
AutoBuild(files, true)
|
||||||
} else {
|
} else {
|
||||||
NewWatcher(paths, files, false)
|
NewWatcher(paths, files, false)
|
||||||
Autobuild(files, false)
|
AutoBuild(files, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
@ -202,16 +200,16 @@ func isExcluded(filePath string) bool {
|
|||||||
for _, p := range excludedPaths {
|
for _, p := range excludedPaths {
|
||||||
absP, err := path.Abs(p)
|
absP, err := path.Abs(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[ERROR] Can not get absolute path of [ %s ]\n", p)
|
logger.Errorf("Cannot get absolute path of '%s'", p)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
absFilePath, err := path.Abs(filePath)
|
absFilePath, err := path.Abs(filePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[ERROR] Can not get absolute path of [ %s ]\n", filePath)
|
logger.Errorf("Cannot get absolute path of '%s'", filePath)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(absFilePath, absP) {
|
if strings.HasPrefix(absFilePath, absP) {
|
||||||
ColorLog("[INFO] Excluding from watching [ %s ]\n", filePath)
|
logger.Infof("'%s' is not being watched", filePath)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
31
rundocs.go
31
rundocs.go
@ -17,7 +17,6 @@ import (
|
|||||||
"archive/zip"
|
"archive/zip"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
@ -63,18 +62,22 @@ func runDocs(cmd *Command, args []string) int {
|
|||||||
downloadFromURL(swaggerlink, "swagger.zip")
|
downloadFromURL(swaggerlink, "swagger.zip")
|
||||||
err := unzipAndDelete("swagger.zip")
|
err := unzipAndDelete("swagger.zip")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("has err exet unzipAndDelete", err)
|
logger.Errorf("Error while unzipping 'swagger.zip' file: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if docport == "" {
|
if docport == "" {
|
||||||
docport = "8089"
|
docport = "8089"
|
||||||
}
|
}
|
||||||
if _, err := os.Stat("swagger"); err != nil && os.IsNotExist(err) {
|
if _, err := os.Stat("swagger"); err != nil && os.IsNotExist(err) {
|
||||||
fmt.Println("there's no swagger, please use bee rundocs -isDownload=true downlaod first")
|
logger.Fatal("No Swagger dist found. Run: bee rundocs -isDownload=true")
|
||||||
os.Exit(2)
|
}
|
||||||
|
|
||||||
|
logger.Infof("Starting the docs server on: http://127.0.0.1:%s", docport)
|
||||||
|
|
||||||
|
err := http.ListenAndServe(":"+string(docport), http.FileServer(http.Dir("swagger")))
|
||||||
|
if err != nil {
|
||||||
|
logger.Fatalf("%s", err)
|
||||||
}
|
}
|
||||||
fmt.Println("start the docs server on: http://127.0.0.1:" + docport)
|
|
||||||
log.Fatal(http.ListenAndServe(":"+string(docport), http.FileServer(http.Dir("swagger"))))
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,36 +88,36 @@ func downloadFromURL(url, fileName string) {
|
|||||||
} else if fd.Size() == int64(0) {
|
} else if fd.Size() == int64(0) {
|
||||||
down = true
|
down = true
|
||||||
} else {
|
} else {
|
||||||
ColorLog("[%s] Filename %s already exist\n", INFO, fileName)
|
logger.Infof("'%s' already exists", fileName)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if down {
|
if down {
|
||||||
ColorLog("[%s]Downloading %s to %s\n", SUCC, url, fileName)
|
logger.Infof("Downloading '%s' to '%s'...", url, fileName)
|
||||||
output, err := os.Create(fileName)
|
output, err := os.Create(fileName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[%s]Error while creating %s: %s\n", ERRO, fileName, err)
|
logger.Errorf("Error while creating '%s': %s", fileName, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer output.Close()
|
defer output.Close()
|
||||||
|
|
||||||
response, err := http.Get(url)
|
response, err := http.Get(url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[%s]Error while downloading %s:%s\n", ERRO, url, err)
|
logger.Errorf("Error while downloading '%s': %s", url, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer response.Body.Close()
|
defer response.Body.Close()
|
||||||
|
|
||||||
n, err := io.Copy(output, response.Body)
|
n, err := io.Copy(output, response.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[%s]Error while downloading %s:%s\n", ERRO, url, err)
|
logger.Errorf("Error while downloading '%s': %s", url, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ColorLog("[%s] %d bytes downloaded.\n", SUCC, n)
|
logger.Successf("%d bytes downloaded!", n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func unzipAndDelete(src string) error {
|
func unzipAndDelete(src string) error {
|
||||||
ColorLog("[%s]start to unzip file from %s\n", INFO, src)
|
logger.Infof("Unzipping '%s'...", src)
|
||||||
r, err := zip.OpenReader(src)
|
r, err := zip.OpenReader(src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -146,6 +149,6 @@ func unzipAndDelete(src string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ColorLog("[%s]Start delete src file %s\n", INFO, src)
|
logger.Successf("Done! Deleting '%s'...", src)
|
||||||
return os.RemoveAll(src)
|
return os.RemoveAll(src)
|
||||||
}
|
}
|
||||||
|
26
test.go
26
test.go
@ -51,19 +51,19 @@ var started = make(chan bool)
|
|||||||
|
|
||||||
func testApp(cmd *Command, args []string) int {
|
func testApp(cmd *Command, args []string) int {
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
ColorLog("[ERRO] Cannot start running[ %s ]\n",
|
logger.Fatalf("Failed to start: %s", "argument 'appname' is missing")
|
||||||
"argument 'appname' is missing")
|
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
crupath, _ := os.Getwd()
|
|
||||||
Debugf("current path:%s\n", crupath)
|
currpath, _ := os.Getwd()
|
||||||
|
|
||||||
|
logger.Debugf("Current path: %s", currpath)
|
||||||
|
|
||||||
err := loadConfig()
|
err := loadConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[ERRO] Fail to parse bee.json[ %s ]\n", err)
|
logger.Fatalf("Failed to load configuration: %s", err)
|
||||||
}
|
}
|
||||||
var paths []string
|
var paths []string
|
||||||
readAppDirectories(crupath, &paths)
|
readAppDirectories(currpath, &paths)
|
||||||
|
|
||||||
NewWatcher(paths, nil, false)
|
NewWatcher(paths, nil, false)
|
||||||
appname = args[0]
|
appname = args[0]
|
||||||
@ -76,7 +76,7 @@ func testApp(cmd *Command, args []string) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func runTest() {
|
func runTest() {
|
||||||
ColorLog("[INFO] Start testing...\n")
|
logger.Info("Start testing...")
|
||||||
time.Sleep(time.Second * 1)
|
time.Sleep(time.Second * 1)
|
||||||
crupwd, _ := os.Getwd()
|
crupwd, _ := os.Getwd()
|
||||||
testDir := path.Join(crupwd, "tests")
|
testDir := path.Join(crupwd, "tests")
|
||||||
@ -88,14 +88,14 @@ func runTest() {
|
|||||||
icmd := exec.Command("go", "test")
|
icmd := exec.Command("go", "test")
|
||||||
icmd.Stdout = os.Stdout
|
icmd.Stdout = os.Stdout
|
||||||
icmd.Stderr = os.Stderr
|
icmd.Stderr = os.Stderr
|
||||||
ColorLog("[TRAC] ============== Test Begin ===================\n")
|
logger.Info("============== Test Begin ===================")
|
||||||
err = icmd.Run()
|
err = icmd.Run()
|
||||||
ColorLog("[TRAC] ============== Test End ===================\n")
|
logger.Info("============== Test End =====================")
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[ERRO] ============== Test failed ===================\n")
|
logger.Error("============== Test failed ===================")
|
||||||
ColorLog("[ERRO] %s", err)
|
logger.Errorf("Cause: %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ColorLog("[SUCC] Test finish\n")
|
logger.Success("Test Completed")
|
||||||
}
|
}
|
||||||
|
11
version.go
11
version.go
@ -78,7 +78,7 @@ func getBeegoVersion() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
if gopath == "" {
|
if gopath == "" {
|
||||||
err = fmt.Errorf("You should set GOPATH env variable")
|
err = fmt.Errorf("You need to set GOPATH environment variable")
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
wgopath := path.SplitList(gopath)
|
wgopath := path.SplitList(gopath)
|
||||||
@ -90,11 +90,11 @@ func getBeegoVersion() string {
|
|||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
ColorLog("[ERRO] Get `beego.go` has error\n")
|
logger.Error("Error while getting stats of 'beego.go'")
|
||||||
}
|
}
|
||||||
fd, err := os.Open(filename)
|
fd, err := os.Open(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[ERRO] Open `beego.go` has error\n")
|
logger.Error("Error while reading 'beego.go'")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
reader := bufio.NewReader(fd)
|
reader := bufio.NewReader(fd)
|
||||||
@ -114,7 +114,7 @@ func getBeegoVersion() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return "Beego not installed. Please install it first: https://github.com/astaxie/beego"
|
return "Beego is not installed. Please do consider installing it first: https://github.com/astaxie/beego"
|
||||||
}
|
}
|
||||||
|
|
||||||
func getGoVersion() string {
|
func getGoVersion() string {
|
||||||
@ -124,8 +124,7 @@ func getGoVersion() string {
|
|||||||
)
|
)
|
||||||
|
|
||||||
if cmdOut, err = exec.Command("go", "version").Output(); err != nil {
|
if cmdOut, err = exec.Command("go", "version").Output(); err != nil {
|
||||||
fmt.Fprintln(os.Stderr, "There was an error running go version command:", err)
|
logger.Fatalf("There was an error running go version command: %s", err)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
return strings.Split(string(cmdOut), " ")[2]
|
return strings.Split(string(cmdOut), " ")[2]
|
||||||
}
|
}
|
||||||
|
54
watch.go
54
watch.go
@ -16,7 +16,6 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
|
||||||
"github.com/howeyc/fsnotify"
|
"github.com/howeyc/fsnotify"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
@ -34,11 +33,11 @@ var (
|
|||||||
scheduleTime time.Time
|
scheduleTime time.Time
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// NewWatcher starts an fsnotify Watcher on the specified paths
|
||||||
func NewWatcher(paths []string, files []string, isgenerate bool) {
|
func NewWatcher(paths []string, files []string, isgenerate bool) {
|
||||||
watcher, err := fsnotify.NewWatcher()
|
watcher, err := fsnotify.NewWatcher()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[ERRO] Fail to create new Watcher[ %s ]\n", err)
|
logger.Fatalf("Failed to create watcher: %s", err)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
@ -57,14 +56,14 @@ func NewWatcher(paths []string, files []string, isgenerate bool) {
|
|||||||
|
|
||||||
mt := getFileModTime(e.Name)
|
mt := getFileModTime(e.Name)
|
||||||
if t := eventTime[e.Name]; mt == t {
|
if t := eventTime[e.Name]; mt == t {
|
||||||
ColorLog("[SKIP] # %s #\n", e.String())
|
logger.Infof(bold("Skipping: ")+"%s", e.String())
|
||||||
isbuild = false
|
isbuild = false
|
||||||
}
|
}
|
||||||
|
|
||||||
eventTime[e.Name] = mt
|
eventTime[e.Name] = mt
|
||||||
|
|
||||||
if isbuild {
|
if isbuild {
|
||||||
ColorLog("[EVEN] %s\n", e)
|
logger.Infof("Event fired: %s", e)
|
||||||
go func() {
|
go func() {
|
||||||
// Wait 1s before autobuild util there is no file change.
|
// Wait 1s before autobuild util there is no file change.
|
||||||
scheduleTime = time.Now().Add(1 * time.Second)
|
scheduleTime = time.Now().Add(1 * time.Second)
|
||||||
@ -76,22 +75,21 @@ func NewWatcher(paths []string, files []string, isgenerate bool) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
Autobuild(files, isgenerate)
|
AutoBuild(files, isgenerate)
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
case err := <-watcher.Error:
|
case err := <-watcher.Error:
|
||||||
ColorLog("[WARN] %s\n", err.Error()) // No need to exit here
|
logger.Warnf("Watcher error: %s", err.Error()) // No need to exit here
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
ColorLog("[INFO] Initializing watcher...\n")
|
logger.Info("Initializing watcher...")
|
||||||
for _, path := range paths {
|
for _, path := range paths {
|
||||||
ColorLog("[TRAC] Directory( %s )\n", path)
|
logger.Infof(bold("Watching: ")+"%s", path)
|
||||||
err = watcher.Watch(path)
|
err = watcher.Watch(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[ERRO] Fail to watch directory[ %s ]\n", err)
|
logger.Fatalf("Failed to watch directory: %s", err)
|
||||||
os.Exit(2)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,25 +100,26 @@ func getFileModTime(path string) int64 {
|
|||||||
path = strings.Replace(path, "\\", "/", -1)
|
path = strings.Replace(path, "\\", "/", -1)
|
||||||
f, err := os.Open(path)
|
f, err := os.Open(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[ERRO] Fail to open file[ %s ]\n", err)
|
logger.Errorf("Failed to open file on '%s': %s", path, err)
|
||||||
return time.Now().Unix()
|
return time.Now().Unix()
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
fi, err := f.Stat()
|
fi, err := f.Stat()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[ERRO] Fail to get file information[ %s ]\n", err)
|
logger.Errorf("Failed to get file stats: %s", err)
|
||||||
return time.Now().Unix()
|
return time.Now().Unix()
|
||||||
}
|
}
|
||||||
|
|
||||||
return fi.ModTime().Unix()
|
return fi.ModTime().Unix()
|
||||||
}
|
}
|
||||||
|
|
||||||
func Autobuild(files []string, isgenerate bool) {
|
// AutoBuild builds the specified set of files
|
||||||
|
func AutoBuild(files []string, isgenerate bool) {
|
||||||
state.Lock()
|
state.Lock()
|
||||||
defer state.Unlock()
|
defer state.Unlock()
|
||||||
|
|
||||||
ColorLog("[INFO] Start building...\n")
|
logger.Info("Start building...")
|
||||||
|
|
||||||
os.Chdir(currpath)
|
os.Chdir(currpath)
|
||||||
|
|
||||||
@ -162,7 +161,7 @@ func Autobuild(files []string, isgenerate bool) {
|
|||||||
icmd.Stdout = os.Stdout
|
icmd.Stdout = os.Stdout
|
||||||
icmd.Stderr = os.Stderr
|
icmd.Stderr = os.Stderr
|
||||||
icmd.Run()
|
icmd.Run()
|
||||||
ColorLog("============== generate docs ===================\n")
|
logger.Info("============== Generate Docs ===================")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@ -186,35 +185,38 @@ func Autobuild(files []string, isgenerate bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ColorLog("[ERRO] ============== Build failed ===================\n")
|
logger.Error("============== Build Failed ===================")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ColorLog("[SUCC] Build was successful\n")
|
logger.Success("Built Successfully!")
|
||||||
Restart(appname)
|
Restart(appname)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Kill kills the running command process
|
||||||
func Kill() {
|
func Kill() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Println("Kill.recover -> ", e)
|
logger.Infof("Kill recover: %s", e)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
if cmd != nil && cmd.Process != nil {
|
if cmd != nil && cmd.Process != nil {
|
||||||
err := cmd.Process.Kill()
|
err := cmd.Process.Kill()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Kill -> ", err)
|
logger.Errorf("Error while killing cmd process: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Restart kills the running command process and starts it again
|
||||||
func Restart(appname string) {
|
func Restart(appname string) {
|
||||||
Debugf("kill running process")
|
logger.Debugf("Kill running process")
|
||||||
Kill()
|
Kill()
|
||||||
go Start(appname)
|
go Start(appname)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Start starts the command process
|
||||||
func Start(appname string) {
|
func Start(appname string) {
|
||||||
ColorLog("[INFO] Restarting %s ...\n", appname)
|
logger.Infof("Restarting '%s'...", appname)
|
||||||
if strings.Index(appname, "./") == -1 {
|
if strings.Index(appname, "./") == -1 {
|
||||||
appname = "./" + appname
|
appname = "./" + appname
|
||||||
}
|
}
|
||||||
@ -226,17 +228,17 @@ func Start(appname string) {
|
|||||||
cmd.Env = append(os.Environ(), conf.Envs...)
|
cmd.Env = append(os.Environ(), conf.Envs...)
|
||||||
|
|
||||||
go cmd.Run()
|
go cmd.Run()
|
||||||
ColorLog("[INFO] %s is running...\n", appname)
|
logger.Successf("'%s' is running...", appname)
|
||||||
started <- true
|
started <- true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Should ignore filenames generated by
|
// shouldIgnoreFile ignores filenames generated by Emacs, Vim or SublimeText.
|
||||||
// Emacs, Vim or SublimeText
|
// It returns true if the file should be ignored, false otherwise.
|
||||||
func shouldIgnoreFile(filename string) bool {
|
func shouldIgnoreFile(filename string) bool {
|
||||||
for _, regex := range ignoredFilesRegExps {
|
for _, regex := range ignoredFilesRegExps {
|
||||||
r, err := regexp.Compile(regex)
|
r, err := regexp.Compile(regex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic("Could not compile the regex: " + regex)
|
logger.Fatalf("Could not compile regular expression: %s", err)
|
||||||
}
|
}
|
||||||
if r.MatchString(filename) {
|
if r.MatchString(filename) {
|
||||||
return true
|
return true
|
||||||
|
Loading…
Reference in New Issue
Block a user