diff --git a/g_docs.go b/g_docs.go index c4ee275..29541ae 100644 --- a/g_docs.go +++ b/g_docs.go @@ -26,6 +26,7 @@ import ( "path/filepath" "strconv" "strings" + "unicode" "github.com/astaxie/beego/swagger" "github.com/astaxie/beego/utils" @@ -82,6 +83,13 @@ func urlReplace(src string) string { ` +const ( + ajson = "application/json" + axml = "application/xml" + aplain = "text/plain" + ahtml = "text/html" +) + var pkgCache map[string]bool //pkg:controller:function:comments comments: key:value var controllerComments map[string]string var importlist map[string]string @@ -117,19 +125,19 @@ func generateDocs(curpath string) { for _, c := range f.Comments { for _, s := range strings.Split(c.Text(), "\n") { if strings.HasPrefix(s, "@APIVersion") { - rootapi.ApiVersion = s[len("@APIVersion "):] + rootapi.ApiVersion = strings.TrimSpace(s[len("@APIVersion"):]) } else if strings.HasPrefix(s, "@Title") { - rootapi.Infos.Title = s[len("@Title "):] + rootapi.Infos.Title = strings.TrimSpace(s[len("@Title"):]) } else if strings.HasPrefix(s, "@Description") { - rootapi.Infos.Description = s[len("@Description "):] + rootapi.Infos.Description = strings.TrimSpace(s[len("@Description"):]) } else if strings.HasPrefix(s, "@TermsOfServiceUrl") { - rootapi.Infos.TermsOfServiceUrl = s[len("@TermsOfServiceUrl "):] + rootapi.Infos.TermsOfServiceUrl = strings.TrimSpace(s[len("@TermsOfServiceUrl"):]) } else if strings.HasPrefix(s, "@Contact") { - rootapi.Infos.Contact = s[len("@Contact "):] + rootapi.Infos.Contact = strings.TrimSpace(s[len("@Contact"):]) } else if strings.HasPrefix(s, "@License") { - rootapi.Infos.License = s[len("@License "):] + rootapi.Infos.License = strings.TrimSpace(s[len("@License"):]) } else if strings.HasPrefix(s, "@LicenseUrl") { - rootapi.Infos.LicenseUrl = s[len("@LicenseUrl "):] + rootapi.Infos.LicenseUrl = strings.TrimSpace(s[len("@LicenseUrl"):]) } } } @@ -325,14 +333,45 @@ func parserComments(comments *ast.CommentGroup, funcName, controllerName, pkgpat opts.HttpMethod = "GET" } } else if strings.HasPrefix(t, "@Title") { - opts.Nickname = t[len("@Title "):] + opts.Nickname = strings.TrimSpace(t[len("@Title"):]) } else if strings.HasPrefix(t, "@Description") { - opts.Summary = t[len("@Description "):] + opts.Summary = strings.TrimSpace(t[len("@Description"):]) } else if strings.HasPrefix(t, "@Success") { + ss := strings.TrimSpace(t[len("@Success"):]) rs := swagger.ResponseMessage{} - st := strings.Split(t[len("@Success "):], " ") + st := make([]string, 3) + j := 0 + var tmp []rune + start := false + + for i, c := range ss { + if unicode.IsSpace(c) { + if !start && j < 2 { + continue + } + if j == 0 || j == 1 { + st[j] = string(tmp) + tmp = make([]rune, 0) + j += 1 + start = false + continue + } else { + st[j] = strings.TrimSpace(ss[i+1:]) + break + } + } else { + start = true + tmp = append(tmp, c) + } + } + if len(tmp) > 0 && st[2] == "" { + st[2] = strings.TrimSpace(string(tmp)) + } rs.Message = st[2] if st[1] == "{object}" { + if st[2] == "" { + panic(controllerName + " " + funcName + " has no object") + } m, mod := getModel(st[2]) rs.ResponseModel = m if _, ok := modelsList[pkgpath+controllerName]; ok { @@ -348,6 +387,9 @@ func parserComments(comments *ast.CommentGroup, funcName, controllerName, pkgpat } else if strings.HasPrefix(t, "@Param") { para := swagger.Parameter{} p := getparams(strings.TrimSpace(t[len("@Param "):])) + if len(p) < 4 { + panic(controllerName + "_" + funcName + "'s comments @Param at least should has 4 params") + } para.Name = p[0] para.ParamType = p[1] para.DataType = p[2] @@ -360,19 +402,43 @@ func parserComments(comments *ast.CommentGroup, funcName, controllerName, pkgpat opts.Parameters = append(opts.Parameters, para) } else if strings.HasPrefix(t, "@Failure") { rs := swagger.ResponseMessage{} - st := t[len("@Failure "):] + st := strings.TrimSpace(t[len("@Failure"):]) var cd []rune + var start bool for i, s := range st { - if s == ' ' { - rs.Message = st[i+1:] - break + if unicode.IsSpace(s) { + if start { + rs.Message = strings.TrimSpace(st[i+1:]) + break + } else { + continue + } } + start = true cd = append(cd, s) } rs.Code, _ = strconv.Atoi(string(cd)) opts.ResponseMessages = append(opts.ResponseMessages, rs) } else if strings.HasPrefix(t, "@Type") { - opts.Type = t[len("@Type "):] + opts.Type = strings.TrimSpace(t[len("@Type"):]) + } else if strings.HasPrefix(t, "@Accept") { + accepts := strings.Split(strings.TrimSpace(strings.TrimSpace(t[len("@Accept"):])), ",") + for _, a := range accepts { + switch a { + case "json": + opts.Consumes = append(opts.Consumes, ajson) + opts.Produces = append(opts.Produces, ajson) + case "xml": + opts.Consumes = append(opts.Consumes, axml) + opts.Produces = append(opts.Produces, axml) + case "plain": + opts.Consumes = append(opts.Consumes, aplain) + opts.Produces = append(opts.Produces, aplain) + case "html": + opts.Consumes = append(opts.Consumes, ahtml) + opts.Produces = append(opts.Produces, ahtml) + } + } } } } @@ -392,24 +458,24 @@ func parserComments(comments *ast.CommentGroup, funcName, controllerName, pkgpat // @Param query form string true "The email for login" // [query form string true "The email for login"] func getparams(str string) []string { - var s []byte + var s []rune var j int var start bool var r []string - for i, c := range []byte(str) { - if c == ' ' || c == '\t' || c == '\n' { + for i, c := range []rune(str) { + if unicode.IsSpace(c) { if !start { continue } else { if j == 3 { r = append(r, string(s)) - r = append(r, strings.Trim((str[i+1:]), " \"\t\n")) + r = append(r, strings.TrimSpace((str[i+1:]))) break } start = false j++ r = append(r, string(s)) - s = make([]byte, 0) + s = make([]rune, 0) continue } }