# Conflicts:
#	generate/swaggergen/g_docs.go
This commit is contained in:
王迎宾 2018-07-25 18:25:45 +08:00
commit e56f6a4fe7
16 changed files with 213 additions and 112 deletions

View File

@ -1,8 +1,6 @@
language: go language: go
go: go:
- 1.6.3 - 1.10.3
- 1.7.3
- 1.8
install: install:
- export PATH=$PATH:$HOME/gopath/bin - export PATH=$PATH:$HOME/gopath/bin
- go get -u github.com/opennota/check/cmd/structcheck - go get -u github.com/opennota/check/cmd/structcheck

View File

@ -1,6 +1,7 @@
version: 0 version: 0
go_install: false go_install: false
watch_ext: [] watch_ext: [".go"]
watch_ext_static: [".html", ".tpl", ".js", ".css"]
dir_structure: dir_structure:
watch_all: false watch_all: false
controllers: "" controllers: ""

View File

@ -4,7 +4,8 @@ bee
Bee is a command-line tool facilitating development of Beego-based application. Bee is a command-line tool facilitating development of Beego-based application.
[![Build Status](https://drone.io/github.com/beego/bee/status.png)](https://drone.io/github.com/beego/bee/latest) [![Build Status](https://img.shields.io/travis/beego/bee.svg?branch=master&label=master)](https://travis-ci.org/beego/bee)
[![Build Status](https://img.shields.io/travis/beego/bee.svg?branch=develop&label=develop)](https://travis-ci.org/beego/bee)
## Requirements ## Requirements

View File

@ -1,7 +1,8 @@
{ {
"version": 0, "version": 0,
"go_install": false, "go_install": false,
"watch_ext": [], "watch_ext": [".go"],
"watch_ext_static": [".html", ".tpl", ".js", ".css"],
"dir_structure": { "dir_structure": {
"watch_all": false, "watch_all": false,
"controllers": "", "controllers": "",

View File

@ -166,6 +166,7 @@ func appCode(cmd *commands.Command, args []string, currpath string) {
beeLogger.Log.Infof("Using '%s' as 'Level'", generate.Level) beeLogger.Log.Infof("Using '%s' as 'Level'", generate.Level)
generate.GenerateAppcode(generate.SQLDriver.String(), generate.SQLConn.String(), generate.Level.String(), generate.Tables.String(), currpath) generate.GenerateAppcode(generate.SQLDriver.String(), generate.SQLConn.String(), generate.Level.String(), generate.Tables.String(), currpath)
} }
func migration(cmd *commands.Command, args []string, currpath string) { func migration(cmd *commands.Command, args []string, currpath string) {
if len(args) < 2 { if len(args) < 2 {
beeLogger.Log.Fatal("Wrong number of arguments. Run: bee help generate") beeLogger.Log.Fatal("Wrong number of arguments. Run: bee help generate")

View File

@ -196,6 +196,17 @@ func checkForSchemaUpdateTable(db *sql.DB, driver string) {
} }
} }
func driverImportStatement(driver string) string {
switch driver {
case "mysql":
return "github.com/go-sql-driver/mysql"
case "postgres":
return "github.com/lib/pq"
default:
return "github.com/go-sql-driver/mysql"
}
}
func showMigrationsTableSQL(driver string) string { func showMigrationsTableSQL(driver string) string {
switch driver { switch driver {
case "mysql": case "mysql":
@ -263,6 +274,7 @@ func writeMigrationSourceFile(dir, source, driver, connStr string, latestTime in
beeLogger.Log.Fatalf("Could not create file: %s", err) beeLogger.Log.Fatalf("Could not create file: %s", err)
} else { } else {
content := strings.Replace(MigrationMainTPL, "{{DBDriver}}", driver, -1) content := strings.Replace(MigrationMainTPL, "{{DBDriver}}", driver, -1)
content = strings.Replace(content, "{{DriverRepo}}", driverImportStatement(driver), -1)
content = strings.Replace(content, "{{ConnStr}}", connStr, -1) content = strings.Replace(content, "{{ConnStr}}", connStr, -1)
content = strings.Replace(content, "{{LatestTime}}", strconv.FormatInt(latestTime, 10), -1) content = strings.Replace(content, "{{LatestTime}}", strconv.FormatInt(latestTime, 10), -1)
content = strings.Replace(content, "{{LatestName}}", latestName, -1) content = strings.Replace(content, "{{LatestName}}", latestName, -1)
@ -346,8 +358,7 @@ import(
"github.com/astaxie/beego/orm" "github.com/astaxie/beego/orm"
"github.com/astaxie/beego/migration" "github.com/astaxie/beego/migration"
_ "github.com/go-sql-driver/mysql" _ "{{DriverRepo}}"
_ "github.com/lib/pq"
) )
func init(){ func init(){

View File

@ -58,6 +58,8 @@ var (
currentGoPath string currentGoPath string
// Current runmode // Current runmode
runmode string runmode string
// Extra args to run application
runargs string
// Extra directories // Extra directories
extraPackages utils.StrFlags extraPackages utils.StrFlags
) )
@ -71,6 +73,7 @@ func init() {
CmdRun.Flag.BoolVar(&vendorWatch, "vendor", false, "Enable watch vendor folder.") CmdRun.Flag.BoolVar(&vendorWatch, "vendor", false, "Enable watch vendor folder.")
CmdRun.Flag.StringVar(&buildTags, "tags", "", "Set the build tags. See: https://golang.org/pkg/go/build/") CmdRun.Flag.StringVar(&buildTags, "tags", "", "Set the build tags. See: https://golang.org/pkg/go/build/")
CmdRun.Flag.StringVar(&runmode, "runmode", "", "Set the Beego run mode.") CmdRun.Flag.StringVar(&runmode, "runmode", "", "Set the Beego run mode.")
CmdRun.Flag.StringVar(&runargs, "runargs", "", "Extra args to run application")
CmdRun.Flag.Var(&extraPackages, "ex", "List of extra package to watch.") CmdRun.Flag.Var(&extraPackages, "ex", "List of extra package to watch.")
exit = make(chan bool) exit = make(chan bool)
commands.AvailableCommands = append(commands.AvailableCommands, CmdRun) commands.AvailableCommands = append(commands.AvailableCommands, CmdRun)

View File

@ -36,13 +36,14 @@ var (
state sync.Mutex state sync.Mutex
eventTime = make(map[string]int64) eventTime = make(map[string]int64)
scheduleTime time.Time scheduleTime time.Time
watchExts = []string{".go"} watchExts = config.Conf.WatchExts
watchExtsStatic = []string{".html", ".tpl", ".js", ".css"} watchExtsStatic = config.Conf.WatchExtsStatic
ignoredFilesRegExps = []string{ ignoredFilesRegExps = []string{
`.#(\w+).go`, `.#(\w+).go`,
`.(\w+).go.swp`, `.(\w+).go.swp`,
`(\w+).go~`, `(\w+).go~`,
`(\w+).tmp`, `(\w+).tmp`,
`commentsRouter_controllers.go`,
} }
) )
@ -86,6 +87,12 @@ func NewWatcher(paths []string, files []string, isgenerate bool) {
scheduleTime = time.Now().Add(1 * time.Second) scheduleTime = time.Now().Add(1 * time.Second)
time.Sleep(scheduleTime.Sub(time.Now())) time.Sleep(scheduleTime.Sub(time.Now()))
AutoBuild(files, isgenerate) AutoBuild(files, isgenerate)
if config.Conf.EnableReload {
// Wait 100ms more before refreshing the browser
time.Sleep(100 * time.Millisecond)
sendReload(e.String())
}
}() }()
} }
case err := <-watcher.Errors: case err := <-watcher.Errors:
@ -141,9 +148,9 @@ func AutoBuild(files []string, isgenerate bool) {
} }
beeLogger.Log.Success("Docs generated!") beeLogger.Log.Success("Docs generated!")
} }
appName := appname
if err == nil { if err == nil {
appName := appname
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
appName += ".exe" appName += ".exe"
} }
@ -167,7 +174,7 @@ func AutoBuild(files []string, isgenerate bool) {
} }
beeLogger.Log.Success("Built Successfully!") beeLogger.Log.Success("Built Successfully!")
Restart(appname) Restart(appName)
} }
// Kill kills the running command process // Kill kills the running command process
@ -202,7 +209,13 @@ func Start(appname string) {
cmd = exec.Command(appname) cmd = exec.Command(appname)
cmd.Stdout = os.Stdout cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr cmd.Stderr = os.Stderr
cmd.Args = append([]string{appname}, config.Conf.CmdArgs...) if runargs != "" {
r := regexp.MustCompile("'.+'|\".+\"|\\S+")
m := r.FindAllString(runargs, -1)
cmd.Args = append([]string{appname}, m...)
} else {
cmd.Args = append([]string{appname}, config.Conf.CmdArgs...)
}
cmd.Env = append(os.Environ(), config.Conf.Envs...) cmd.Env = append(os.Environ(), config.Conf.Envs...)
go cmd.Run() go cmd.Run()

View File

@ -57,7 +57,7 @@ Prints the current Bee, Beego and Go version alongside the platform information.
} }
var outputFormat string var outputFormat string
const version = "1.9.1" const version = "1.10.0"
func init() { func init() {
fs := flag.NewFlagSet("version", flag.ContinueOnError) fs := flag.NewFlagSet("version", flag.ContinueOnError)

View File

@ -27,6 +27,8 @@ const confVer = 0
var Conf = struct { var Conf = struct {
Version int Version int
WatchExts []string `json:"watch_ext" yaml:"watch_ext"`
WatchExtsStatic []string `json:"watch_ext_static" yaml:"watch_ext_static"`
GoInstall bool `json:"go_install" yaml:"go_install"` // Indicates whether execute "go install" before "go build". GoInstall bool `json:"go_install" yaml:"go_install"` // Indicates whether execute "go install" before "go build".
DirStruct dirStruct `json:"dir_structure" yaml:"dir_structure"` DirStruct dirStruct `json:"dir_structure" yaml:"dir_structure"`
CmdArgs []string `json:"cmd_args" yaml:"cmd_args"` CmdArgs []string `json:"cmd_args" yaml:"cmd_args"`
@ -37,7 +39,9 @@ var Conf = struct {
EnableNotification bool `json:"enable_notification" yaml:"enable_notification"` EnableNotification bool `json:"enable_notification" yaml:"enable_notification"`
Scripts map[string]string `json:"scripts" yaml:"scripts"` Scripts map[string]string `json:"scripts" yaml:"scripts"`
}{ }{
GoInstall: true, WatchExts: []string{".go"},
WatchExtsStatic: []string{".html", ".tpl", ".js", ".css"},
GoInstall: true,
DirStruct: dirStruct{ DirStruct: dirStruct{
Others: []string{}, Others: []string{},
}, },

View File

@ -318,7 +318,7 @@ func gen(dbms, connStr string, mode byte, selectedTableNames map[string]bool, ap
mvcPath.RouterPath = path.Join(apppath, "routers") mvcPath.RouterPath = path.Join(apppath, "routers")
createPaths(mode, mvcPath) createPaths(mode, mvcPath)
pkgPath := getPackagePath(apppath) pkgPath := getPackagePath(apppath)
writeSourceFiles(pkgPath, tables, mode, mvcPath, selectedTableNames) writeSourceFiles(pkgPath, tables, mode, mvcPath)
} else { } else {
beeLogger.Log.Fatalf("Generating app code from '%s' database is not supported yet.", dbms) beeLogger.Log.Fatalf("Generating app code from '%s' database is not supported yet.", dbms)
} }
@ -728,32 +728,26 @@ func createPaths(mode byte, paths *MvcPath) {
// writeSourceFiles generates source files for model/controller/router // writeSourceFiles generates source files for model/controller/router
// It will wipe the following directories and recreate them:./models, ./controllers, ./routers // It will wipe the following directories and recreate them:./models, ./controllers, ./routers
// 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) {
if (OModel & mode) == OModel { if (OModel & mode) == OModel {
beeLogger.Log.Info("Creating model files...") beeLogger.Log.Info("Creating model files...")
writeModelFiles(tables, paths.ModelPath, selectedTables) writeModelFiles(tables, paths.ModelPath)
} }
if (OController & mode) == OController { if (OController & mode) == OController {
beeLogger.Log.Info("Creating controller files...") beeLogger.Log.Info("Creating controller files...")
writeControllerFiles(tables, paths.ControllerPath, selectedTables, pkgPath) writeControllerFiles(tables, paths.ControllerPath, pkgPath)
} }
if (ORouter & mode) == ORouter { if (ORouter & mode) == ORouter {
beeLogger.Log.Info("Creating router files...") beeLogger.Log.Info("Creating router files...")
writeRouterFile(tables, paths.RouterPath, selectedTables, pkgPath) writeRouterFile(tables, paths.RouterPath, pkgPath)
} }
} }
// writeModelFiles generates model files // writeModelFiles generates model files
func writeModelFiles(tables []*Table, mPath string, selectedTables map[string]bool) { func writeModelFiles(tables []*Table, mPath string) {
w := colors.NewColorWriter(os.Stdout) w := colors.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 != nil {
if _, selected := selectedTables[tb.Name]; !selected {
continue
}
}
filename := getFileName(tb.Name) filename := getFileName(tb.Name)
fpath := path.Join(mPath, filename+".go") fpath := path.Join(mPath, filename+".go")
var f *os.File var f *os.File
@ -806,16 +800,10 @@ func writeModelFiles(tables []*Table, mPath string, selectedTables map[string]bo
} }
// writeControllerFiles generates controller files // writeControllerFiles generates controller files
func writeControllerFiles(tables []*Table, cPath string, selectedTables map[string]bool, pkgPath string) { func writeControllerFiles(tables []*Table, cPath string, pkgPath string) {
w := colors.NewColorWriter(os.Stdout) w := colors.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 != nil {
if _, selected := selectedTables[tb.Name]; !selected {
continue
}
}
if tb.Pk == "" { if tb.Pk == "" {
continue continue
} }
@ -854,17 +842,11 @@ func writeControllerFiles(tables []*Table, cPath string, selectedTables map[stri
} }
// writeRouterFile generates router file // writeRouterFile generates router file
func writeRouterFile(tables []*Table, rPath string, selectedTables map[string]bool, pkgPath string) { func writeRouterFile(tables []*Table, rPath string, pkgPath string) {
w := colors.NewColorWriter(os.Stdout) w := colors.NewColorWriter(os.Stdout)
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 != nil {
if _, selected := selectedTables[tb.Name]; !selected {
continue
}
}
if tb.Pk == "" { if tb.Pk == "" {
continue continue
} }

View File

@ -37,6 +37,7 @@ import (
"github.com/astaxie/beego/utils" "github.com/astaxie/beego/utils"
"github.com/beego/bee/logger" "github.com/beego/bee/logger"
bu "github.com/beego/bee/utils" bu "github.com/beego/bee/utils"
"sort"
) )
const ( const (
@ -262,17 +263,8 @@ func GenerateDocs(curpath string) {
for _, l := range stmt.Rhs { for _, l := range stmt.Rhs {
if v, ok := l.(*ast.CallExpr); ok { if v, ok := l.(*ast.CallExpr); ok {
// Analyse 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
//}
if sel, ok := v.Fun.(*ast.SelectorExpr); ok {
if sel.Sel.String() != "NewNamespace" {
continue
}
} else if ident, ok := v.Fun.(*ast.Ident); ok {
if ident.String() != "NewNamespace" {
continue
}
} }
version, params := analyseNewNamespace(v) version, params := analyseNewNamespace(v)
if rootapi.BasePath == "" && version != "" { if rootapi.BasePath == "" && version != "" {
@ -443,20 +435,15 @@ func analyseControllerPkg(vendorPath, localName, pkgpath string) {
} }
fileSet := token.NewFileSet() fileSet := token.NewFileSet()
astPkg, 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 {
beeLogger.Log.Fatalf("Error while parsing dir at '%s': %s", pkgpath, err) beeLogger.Log.Fatalf("Error while parsing dir at '%s': %s", pkgpath, err)
} }
for _, pkg := range astPkg { for _, pkg := range astPkgs {
for _, fl := range pkg.Files { for _, fl := range pkg.Files {
for _, v := range fl.Imports {
for _, v1 := range gopaths {
parsePackageFromDir(filepath.Join(v1+"/src/", strings.Trim(v.Path.Value, "\"")))
}
}
for _, d := range fl.Decls { for _, d := range fl.Decls {
switch specDecl := d.(type) { switch specDecl := d.(type) {
case *ast.FuncDecl: case *ast.FuncDecl:
@ -572,20 +559,12 @@ func parserComments(f *ast.FuncDecl, controllerName, pkgpath string) error {
schema.Format = typeFormat[1] schema.Format = typeFormat[1]
} else { } else {
m, mod, realTypes := getModel(schemaName) m, mod, realTypes := getModel(schemaName)
if mod.Type != "object" { schema.Ref = "#/definitions/" + m
if sType, ok := basicTypes[mod.Type]; ok { if _, ok := modelsList[pkgpath+controllerName]; !ok {
typeFormat := strings.Split(sType, ":") modelsList[pkgpath+controllerName] = make(map[string]swagger.Schema)
schema.Type = typeFormat[0]
schema.Format = typeFormat[1]
}
} else {
schema.Ref = "#/definitions/" + m
if _, ok := modelsList[pkgpath+controllerName]; !ok {
modelsList[pkgpath+controllerName] = make(map[string]swagger.Schema)
}
modelsList[pkgpath+controllerName][schemaName] = mod
appendModels(pkgpath, controllerName, realTypes)
} }
modelsList[pkgpath+controllerName][schemaName] = mod
appendModels(pkgpath, controllerName, realTypes)
} }
if isArray { if isArray {
rs.Schema = &swagger.Schema{ rs.Schema = &swagger.Schema{
@ -636,7 +615,6 @@ func parserComments(f *ast.FuncDecl, controllerName, pkgpath string) error {
typ := pp[len(pp)-1] typ := pp[len(pp)-1]
if len(pp) >= 2 { if len(pp) >= 2 {
m, mod, realTypes := getModel(p[2]) m, mod, realTypes := getModel(p[2])
//TODO:这里可能还要对解析的参数进行处理
para.Schema = &swagger.Schema{ para.Schema = &swagger.Schema{
Ref: "#/definitions/" + m, Ref: "#/definitions/" + m,
} }
@ -797,10 +775,20 @@ func setParamType(para *swagger.Parameter, typ string, pkgpath, controllerName s
} }
} }
if isArray { if isArray {
para.Type = "array" if para.In == "body" {
para.Items = &swagger.ParameterItems{ para.Schema = &swagger.Schema{
Type: paraType, Type: "array",
Format: paraFormat, Items: &swagger.Schema{
Type: paraType,
Format: paraFormat,
},
}
} else {
para.Type = "array"
para.Items = &swagger.ParameterItems{
Type: paraType,
Format: paraFormat,
}
} }
} else { } else {
para.Type = paraType para.Type = paraType
@ -931,12 +919,117 @@ func parseObject(d *ast.Object, k string, m *swagger.Schema, realTypes *[]string
beeLogger.Log.Fatalf("Unknown type without TypeSec: %v\n", d) beeLogger.Log.Fatalf("Unknown type without TypeSec: %v\n", d)
} }
// 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) _, ok = ts.Type.(*ast.StructType)
if !ok { if !ok {
m.Title = fmt.Sprintf("%v", reflect.ValueOf(ts.Type)) m.Title = fmt.Sprintf("%v", reflect.ValueOf(ts.Type))
m.Type = fmt.Sprintf("%v", reflect.ValueOf(ts.Type)) m.Type = fmt.Sprintf("%v", reflect.ValueOf(ts.Type))
return return
switch t := ts.Type.(type) {
case *ast.ArrayType:
m.Title = k
m.Type = "array"
if isBasicType(fmt.Sprint(t.Elt)) {
typeFormat := strings.Split(basicTypes[fmt.Sprint(t.Elt)], ":")
m.Format = typeFormat[0]
} else {
objectName := packageName + "." + fmt.Sprint(t.Elt)
if _, ok := rootapi.Definitions[objectName]; !ok {
objectName, _, _ = getModel(objectName)
}
m.Items = &swagger.Schema{
Ref: "#/definitions/" + objectName,
}
}
case *ast.Ident:
parseIdent(t, k, m, astPkgs)
case *ast.StructType:
parseStruct(t, k, m, realTypes, astPkgs, packageName)
}
} }
}
// parse as enum, in the package, find out all consts with the same type
func parseIdent(st *ast.Ident, k string, m *swagger.Schema, astPkgs []*ast.Package) {
m.Title = k
basicType := fmt.Sprint(st)
if object, isStdLibObject := stdlibObject[basicType]; isStdLibObject {
basicType = object
}
if k, ok := basicTypes[basicType]; ok {
typeFormat := strings.Split(k, ":")
m.Type = typeFormat[0]
m.Format = typeFormat[1]
}
enums := make(map[int]string)
enumValues := make(map[int]interface{})
for _, pkg := range astPkgs {
for _, fl := range pkg.Files {
for _, obj := range fl.Scope.Objects {
if obj.Kind == ast.Con {
vs, ok := obj.Decl.(*ast.ValueSpec)
if !ok {
beeLogger.Log.Fatalf("Unknown type without ValueSpec: %v\n", vs)
}
ti, ok := vs.Type.(*ast.Ident)
if !ok {
// TODO type inference, iota not support yet
continue
}
// Only add the enums that are defined by the current identifier
if ti.Name != k {
continue
}
// For all names and values, aggregate them by it's position so that we can sort them later.
for i, val := range vs.Values {
v, ok := val.(*ast.BasicLit)
if !ok {
beeLogger.Log.Warnf("Unknown type without BasicLit: %v\n", v)
continue
}
enums[int(val.Pos())] = fmt.Sprintf("%s = %s", vs.Names[i].Name, v.Value)
switch v.Kind {
case token.INT:
vv, err := strconv.Atoi(v.Value)
if err != nil {
beeLogger.Log.Warnf("Unknown type with BasicLit to int: %v\n", v.Value)
continue
}
enumValues[int(val.Pos())] = vv
case token.FLOAT:
vv, err := strconv.ParseFloat(v.Value, 64)
if err != nil {
beeLogger.Log.Warnf("Unknown type with BasicLit to int: %v\n", v.Value)
continue
}
enumValues[int(val.Pos())] = vv
default:
enumValues[int(val.Pos())] = strings.Trim(v.Value, `"`)
}
}
}
}
}
}
// Sort the enums by position
if len(enums) > 0 {
var keys []int
for k := range enums {
keys = append(keys, k)
}
sort.Ints(keys)
for _, k := range keys {
m.Enum = append(m.Enum, enums[k])
}
// Automatically use the first enum value as the example.
m.Example = enumValues[keys[0]]
}
}
func parseStruct(st *ast.StructType, k string, m *swagger.Schema, realTypes *[]string, astPkgs []*ast.Package, packageName string) {
m.Title = k m.Title = k
if st.Fields.List != nil { if st.Fields.List != nil {
m.Properties = make(map[string]swagger.Propertie) m.Properties = make(map[string]swagger.Propertie)
@ -956,7 +1049,7 @@ func parseObject(d *ast.Object, k string, m *swagger.Schema, realTypes *[]string
mp := swagger.Propertie{} mp := swagger.Propertie{}
if isSlice { if isSlice {
mp.Type = "array" mp.Type = "array"
if isBasicType(strings.Replace(realType, "[]", "", -1)) { if sType, ok := basicTypes[(strings.Replace(realType, "[]", "", -1))]; ok {
typeFormat := strings.Split(sType, ":") typeFormat := strings.Split(sType, ":")
mp.Items = &swagger.Propertie{ mp.Items = &swagger.Propertie{
Type: typeFormat[0], Type: typeFormat[0],
@ -1046,19 +1139,7 @@ func parseObject(d *ast.Object, k string, m *swagger.Schema, realTypes *[]string
for _, fl := range pkg.Files { for _, fl := range pkg.Files {
for nameOfObj, obj := range fl.Scope.Objects { for nameOfObj, obj := range fl.Scope.Objects {
if obj.Name == fmt.Sprint(field.Type) { if obj.Name == fmt.Sprint(field.Type) {
nameOfObj = fmt.Sprintf("%s.%s",pkg.Name,nameOfObj) parseObject(obj, nameOfObj, m, realTypes, astPkgs, pkg.Name)
//m.Properties[obj.Name] = swagger.Propertie{
// Ref: "#/definitions/" + nameOfObj,
//}
m1,ok := rootapi.Definitions[nameOfObj]
if !ok {
_,m1,_ = getModel(nameOfObj)
}
if len(m1.Properties) > 0 {
for k,v := range m1.Properties {
m.Properties[k]=v
}
}
} }
} }
} }
@ -1084,6 +1165,9 @@ func typeAnalyser(f *ast.Field) (isSlice bool, realType, swaggerType string) {
switch t := f.Type.(type) { switch t := f.Type.(type) {
case *ast.StarExpr: case *ast.StarExpr:
basicType := fmt.Sprint(t.X) basicType := fmt.Sprint(t.X)
if object, isStdLibObject := stdlibObject[basicType]; isStdLibObject {
basicType = object
}
if k, ok := basicTypes[basicType]; ok { if k, ok := basicTypes[basicType]; ok {
return false, basicType, k return false, basicType, k
} }
@ -1160,6 +1244,12 @@ func urlReplace(src string) string {
} else if p[0] == '?' && p[1] == ':' { } else if p[0] == '?' && p[1] == ':' {
pt[i] = "{" + p[2:] + "}" pt[i] = "{" + p[2:] + "}"
} }
if pt[i][0] == '{' && strings.Contains(pt[i], ":") {
pt[i] = pt[i][:strings.Index(pt[i], ":")] + "}"
} else if pt[i][0] == '{' && strings.Contains(pt[i], "(") {
pt[i] = pt[i][:strings.Index(pt[i], "(")] + "}"
}
} }
} }
return strings.Join(pt, "/") return strings.Join(pt, "/")
@ -1172,6 +1262,8 @@ func str2RealType(s string, typ string) interface{} {
switch typ { switch typ {
case "int", "int64", "int32", "int16", "int8": case "int", "int64", "int32", "int16", "int8":
ret, err = strconv.Atoi(s) ret, err = strconv.Atoi(s)
case "uint", "uint64", "uint32", "uint16", "uint8":
ret, err = strconv.ParseUint(s, 10, 0)
case "bool": case "bool":
ret, err = strconv.ParseBool(s) ret, err = strconv.ParseBool(s)
case "float64": case "float64":

View File

@ -25,9 +25,15 @@ import (
"github.com/beego/bee/utils" "github.com/beego/bee/utils"
) )
var (
workspace = os.Getenv("BeeWorkspace")
)
func main() { func main() {
currentpath, _ := os.Getwd() currentpath, _ := os.Getwd()
if workspace != "" {
currentpath = workspace
}
flag.Usage = cmd.Usage flag.Usage = cmd.Usage
flag.Parse() flag.Parse()
log.SetFlags(0) log.SetFlags(0)
@ -66,7 +72,6 @@ func main() {
if utils.IsInGOPATH(currentpath) && cmd.IfGenerateDocs(c.Name(), args) { if utils.IsInGOPATH(currentpath) && cmd.IfGenerateDocs(c.Name(), args) {
swaggergen.ParsePackagesFromDir(currentpath) swaggergen.ParsePackagesFromDir(currentpath)
} }
os.Exit(c.Run(c, args)) os.Exit(c.Run(c, args))
return return
} }

View File

@ -1,13 +0,0 @@
Copyright 2014 astaxie
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -121,6 +121,8 @@ type Schema struct {
Type string `json:"type,omitempty" yaml:"type,omitempty"` Type string `json:"type,omitempty" yaml:"type,omitempty"`
Items *Schema `json:"items,omitempty" yaml:"items,omitempty"` Items *Schema `json:"items,omitempty" yaml:"items,omitempty"`
Properties map[string]Propertie `json:"properties,omitempty" yaml:"properties,omitempty"` Properties map[string]Propertie `json:"properties,omitempty" yaml:"properties,omitempty"`
Enum []interface{} `json:"enum,omitempty" yaml:"enum,omitempty"`
Example interface{} `json:"example,omitempty" yaml:"example,omitempty"`
} }
// Propertie are taken from the JSON Schema definition but their definitions were adjusted to the Swagger Specification // Propertie are taken from the JSON Schema definition but their definitions were adjusted to the Swagger Specification
@ -130,7 +132,7 @@ type Propertie struct {
Description string `json:"description,omitempty" yaml:"description,omitempty"` Description string `json:"description,omitempty" yaml:"description,omitempty"`
Default interface{} `json:"default,omitempty" yaml:"default,omitempty"` Default interface{} `json:"default,omitempty" yaml:"default,omitempty"`
Type string `json:"type,omitempty" yaml:"type,omitempty"` Type string `json:"type,omitempty" yaml:"type,omitempty"`
Example string `json:"example,omitempty" yaml:"example,omitempty"` Example interface{} `json:"example,omitempty" yaml:"example,omitempty"`
Required []string `json:"required,omitempty" yaml:"required,omitempty"` Required []string `json:"required,omitempty" yaml:"required,omitempty"`
Format string `json:"format,omitempty" yaml:"format,omitempty"` Format string `json:"format,omitempty" yaml:"format,omitempty"`
ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"`

6
vendor/vendor.json vendored
View File

@ -3,10 +3,10 @@
"ignore": "test", "ignore": "test",
"package": [ "package": [
{ {
"checksumSHA1": "OeOvZ+3A1tRBdMD8GuS6R9zcnqA=", "checksumSHA1": "/ffb74fNK251iTEebGjybfFBAbs=",
"path": "github.com/astaxie/beego/swagger", "path": "github.com/astaxie/beego/swagger",
"revision": "323a1c4214101331a4b71922c23d19b7409ac71f", "revision": "a09bafbf2ab483742b17bb352f95dbc0a597e720",
"revisionTime": "2017-03-06T13:59:04Z" "revisionTime": "2018-07-21T07:55:28Z"
}, },
{ {
"checksumSHA1": "epd3Y7nD7QVzTW0ppwK+q4pKo/4=", "checksumSHA1": "epd3Y7nD7QVzTW0ppwK+q4pKo/4=",