* Revert changes * Unrap nested structure for doc code generation * Revert changes * Remove useless code * Remove useless code * Format code
This commit is contained in:
@@ -4,15 +4,15 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
_ "embed"
|
_ "embed"
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/format"
|
|
||||||
"html/template"
|
"html/template"
|
||||||
|
"io"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/stringx"
|
"github.com/zeromicro/go-zero/core/stringx"
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/api/gogen"
|
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/api/spec"
|
"github.com/zeromicro/go-zero/tools/goctl/api/spec"
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/api/util"
|
apiutil "github.com/zeromicro/go-zero/tools/goctl/api/util"
|
||||||
|
"github.com/zeromicro/go-zero/tools/goctl/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:embed markdown.tpl
|
//go:embed markdown.tpl
|
||||||
@@ -23,7 +23,7 @@ func genDoc(api *spec.ApiSpec, dir, filename string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
fp, _, err := util.MaybeCreateFile(dir, "", filename)
|
fp, _, err := apiutil.MaybeCreateFile(dir, "", filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -36,12 +36,12 @@ func genDoc(api *spec.ApiSpec, dir, filename string) error {
|
|||||||
routeComment = "N/A"
|
routeComment = "N/A"
|
||||||
}
|
}
|
||||||
|
|
||||||
requestContent, err := buildDoc(route.RequestType, api)
|
requestContent, err := buildDoc(route.RequestType, api.Types)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
responseContent, err := buildDoc(route.ResponseType, api)
|
responseContent, err := buildDoc(route.ResponseType, api.Types)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -61,6 +61,7 @@ func genDoc(api *spec.ApiSpec, dir, filename string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.Write(tmplBytes.Bytes())
|
builder.Write(tmplBytes.Bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,7 +69,7 @@ func genDoc(api *spec.ApiSpec, dir, filename string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildDoc(route spec.Type, api *spec.ApiSpec) (string, error) {
|
func buildDoc(route spec.Type, types []spec.Type) (string, error) {
|
||||||
if route == nil || len(route.Name()) == 0 {
|
if route == nil || len(route.Name()) == 0 {
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
@@ -78,15 +79,12 @@ func buildDoc(route spec.Type, api *spec.ApiSpec) (string, error) {
|
|||||||
if definedType, ok := route.(spec.DefineStruct); ok {
|
if definedType, ok := route.(spec.DefineStruct); ok {
|
||||||
associatedTypes(definedType, &tps)
|
associatedTypes(definedType, &tps)
|
||||||
}
|
}
|
||||||
value, err := gogen.BuildTypes(tps, api)
|
value, err := buildTypes(tps, types)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
formatted, err := format.Source([]byte(value))
|
|
||||||
if err != nil {
|
return fmt.Sprintf("\n\n```golang\n%s\n```\n", value), nil
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("\n\n```golang\n%s\n```\n", string(formatted)), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func associatedTypes(tp spec.DefineStruct, tps *[]spec.Type) {
|
func associatedTypes(tp spec.DefineStruct, tps *[]spec.Type) {
|
||||||
@@ -107,3 +105,82 @@ func associatedTypes(tp spec.DefineStruct, tps *[]spec.Type) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// buildTypes gen types to string
|
||||||
|
func buildTypes(types []spec.Type, all []spec.Type) (string, error) {
|
||||||
|
var builder strings.Builder
|
||||||
|
first := true
|
||||||
|
for _, tp := range types {
|
||||||
|
if first {
|
||||||
|
first = false
|
||||||
|
} else {
|
||||||
|
builder.WriteString("\n\n")
|
||||||
|
}
|
||||||
|
if err := writeType(&builder, tp, all); err != nil {
|
||||||
|
return "", apiutil.WrapErr(err, "Type "+tp.Name()+" generate error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeType(writer io.Writer, tp spec.Type, all []spec.Type) error {
|
||||||
|
fmt.Fprintf(writer, "type %s struct {\n", util.Title(tp.Name()))
|
||||||
|
if err := writerMembers(writer, tp, all); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Fprintf(writer, "}")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func writerMembers(writer io.Writer, tp spec.Type, all []spec.Type) error {
|
||||||
|
structType, ok := tp.(spec.DefineStruct)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("unspport struct type: %s", tp.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
getTargetType := func(tp string) spec.Type {
|
||||||
|
for _, v := range all {
|
||||||
|
if v.Name() == tp {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
for _, member := range structType.Members {
|
||||||
|
if member.IsInline {
|
||||||
|
inlineType := getTargetType(member.Type.Name())
|
||||||
|
if inlineType == nil {
|
||||||
|
if _, err := fmt.Fprintf(writer, "%s\n", strings.Title(member.Type.Name())); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if err := writerMembers(writer, inlineType, all); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := writeProperty(writer, member.Name, member.Tag, member.GetComment(), member.Type, 1); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeProperty(writer io.Writer, name, tag, comment string, tp spec.Type, indent int) error {
|
||||||
|
apiutil.WriteIndent(writer, indent)
|
||||||
|
var err error
|
||||||
|
if len(comment) > 0 {
|
||||||
|
comment = strings.TrimPrefix(comment, "//")
|
||||||
|
comment = "//" + comment
|
||||||
|
_, err = fmt.Fprintf(writer, "%s %s %s %s\n", strings.Title(name), tp.Name(), tag, comment)
|
||||||
|
} else {
|
||||||
|
_, err = fmt.Fprintf(writer, "%s %s %s\n", strings.Title(name), tp.Name(), tag)
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ const typesFile = "types"
|
|||||||
var typesTemplate string
|
var typesTemplate string
|
||||||
|
|
||||||
// BuildTypes gen types to string
|
// BuildTypes gen types to string
|
||||||
func BuildTypes(types []spec.Type, api *spec.ApiSpec) (string, error) {
|
func BuildTypes(types []spec.Type) (string, error) {
|
||||||
var builder strings.Builder
|
var builder strings.Builder
|
||||||
first := true
|
first := true
|
||||||
for _, tp := range types {
|
for _, tp := range types {
|
||||||
@@ -30,7 +30,7 @@ func BuildTypes(types []spec.Type, api *spec.ApiSpec) (string, error) {
|
|||||||
} else {
|
} else {
|
||||||
builder.WriteString("\n\n")
|
builder.WriteString("\n\n")
|
||||||
}
|
}
|
||||||
if err := writeType(&builder, tp, api); err != nil {
|
if err := writeType(&builder, tp); err != nil {
|
||||||
return "", apiutil.WrapErr(err, "Type "+tp.Name()+" generate error")
|
return "", apiutil.WrapErr(err, "Type "+tp.Name()+" generate error")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -39,7 +39,7 @@ func BuildTypes(types []spec.Type, api *spec.ApiSpec) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func genTypes(dir string, cfg *config.Config, api *spec.ApiSpec) error {
|
func genTypes(dir string, cfg *config.Config, api *spec.ApiSpec) error {
|
||||||
val, err := BuildTypes(api.Types, api)
|
val, err := BuildTypes(api.Types)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -68,7 +68,7 @@ func genTypes(dir string, cfg *config.Config, api *spec.ApiSpec) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeType(writer io.Writer, tp spec.Type, api *spec.ApiSpec) error {
|
func writeType(writer io.Writer, tp spec.Type) error {
|
||||||
structType, ok := tp.(spec.DefineStruct)
|
structType, ok := tp.(spec.DefineStruct)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("unspport struct type: %s", tp.Name())
|
return fmt.Errorf("unspport struct type: %s", tp.Name())
|
||||||
@@ -76,7 +76,15 @@ func writeType(writer io.Writer, tp spec.Type, api *spec.ApiSpec) error {
|
|||||||
|
|
||||||
fmt.Fprintf(writer, "type %s struct {\n", util.Title(tp.Name()))
|
fmt.Fprintf(writer, "type %s struct {\n", util.Title(tp.Name()))
|
||||||
for _, member := range structType.Members {
|
for _, member := range structType.Members {
|
||||||
if err := writeProperty(writer, member.Name, member.Tag, member.GetComment(), member.Type, 1, api); err != nil {
|
if member.IsInline {
|
||||||
|
if _, err := fmt.Fprintf(writer, "%s\n", strings.Title(member.Type.Name())); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := writeProperty(writer, member.Name, member.Tag, member.GetComment(), member.Type, 1); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
type Common {
|
|
||||||
Some string `json:"some"` // some imported type
|
|
||||||
}
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
import "./api_common.api"
|
|
||||||
type Resp {
|
|
||||||
R1 string `json:"r1"`
|
|
||||||
R2 bool `json:"r2"`
|
|
||||||
R3 Common `json:"r3"`
|
|
||||||
}
|
|
||||||
type CommonResponse {
|
|
||||||
Code int `json:"code"` // 100 | 200
|
|
||||||
Message string `json:"message"`
|
|
||||||
Common
|
|
||||||
Response Resp `json:"response"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type LoginResponseDto {
|
|
||||||
Id string `bson:"_id" json:"id"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
AccessToken string `json:"accessToken"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type UserCreateDto {
|
|
||||||
Id string `json:"id"`
|
|
||||||
}
|
|
||||||
type LoginRequest {
|
|
||||||
Username string `json:"username,optional"` // user name is optional
|
|
||||||
Password string `json:"password,optional"`
|
|
||||||
}
|
|
||||||
type LoginResponse {
|
|
||||||
*CommonResponse
|
|
||||||
Result *LoginResponseDto `json:"result"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type UserCreateRequest {
|
|
||||||
Username string `json:"username,optional"` // some dsada
|
|
||||||
Password string `json:"password,optional"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type UserCreateResponse {
|
|
||||||
*CommonResponse
|
|
||||||
Result *UserCreateDto `json:"result"` // result
|
|
||||||
}
|
|
||||||
|
|
||||||
service user-api {
|
|
||||||
@handler UserHandler
|
|
||||||
post /user/signin(UserCreateRequest) returns (UserCreateResponse)
|
|
||||||
|
|
||||||
@handler LoginHandler
|
|
||||||
post /user/login(LoginRequest) returns (LoginResponse)
|
|
||||||
}
|
|
||||||
@@ -4,7 +4,6 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
@@ -58,21 +57,15 @@ func genFile(c fileGenConfig) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeProperty(writer io.Writer, name, tag, comment string, tp spec.Type, indent int, api *spec.ApiSpec) error {
|
func writeProperty(writer io.Writer, name, tag, comment string, tp spec.Type, indent int) error {
|
||||||
util.WriteIndent(writer, indent)
|
util.WriteIndent(writer, indent)
|
||||||
var err error
|
var err error
|
||||||
var refPropertyName = tp.Name()
|
if len(comment) > 0 {
|
||||||
if isCustomType(refPropertyName) {
|
comment = strings.TrimPrefix(comment, "//")
|
||||||
strs := getRefProperty(api, refPropertyName, name)
|
comment = "//" + comment
|
||||||
_, err = fmt.Fprintf(writer, "%s\n", strs)
|
_, err = fmt.Fprintf(writer, "%s %s %s %s\n", strings.Title(name), tp.Name(), tag, comment)
|
||||||
} else {
|
} else {
|
||||||
if len(comment) > 0 {
|
_, err = fmt.Fprintf(writer, "%s %s %s\n", strings.Title(name), tp.Name(), tag)
|
||||||
comment = strings.TrimPrefix(comment, "//")
|
|
||||||
comment = "//" + comment
|
|
||||||
_, err = fmt.Fprintf(writer, "%s %s %s %s\n", strings.Title(name), tp.Name(), tag, comment)
|
|
||||||
} else {
|
|
||||||
_, err = fmt.Fprintf(writer, "%s %s %s\n", strings.Title(name), tp.Name(), tag)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
@@ -188,58 +181,3 @@ func golangExpr(ty spec.Type, pkg ...string) string {
|
|||||||
|
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func isCustomType(t string) bool {
|
|
||||||
var builtinType = []string{"string", "bool", "int", "uint", "uint8", "uint16", "uint32", "uint64", "int8", "int16", "int32", "int64", "float32", "float64", "uintptr", "complex64", "complex128"}
|
|
||||||
var is bool = true
|
|
||||||
for _, v := range builtinType {
|
|
||||||
if t == v {
|
|
||||||
is = false
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return is
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate nested types recursively
|
|
||||||
func getRefProperty(api *spec.ApiSpec, refPropertyName string, name string) string {
|
|
||||||
var str string = ""
|
|
||||||
for _, t := range api.Types {
|
|
||||||
if strings.TrimLeft(refPropertyName, "*") == t.Name() {
|
|
||||||
switch tm := t.(type) {
|
|
||||||
case spec.DefineStruct:
|
|
||||||
for _, m := range tm.Members {
|
|
||||||
if isCustomType(m.Type.Name()) {
|
|
||||||
// recursive
|
|
||||||
str += getRefProperty(api, m.Type.Name(), m.Name)
|
|
||||||
} else {
|
|
||||||
if len(m.Comment) > 0 {
|
|
||||||
comment := strings.TrimPrefix(m.Comment, "//")
|
|
||||||
comment = "//" + comment
|
|
||||||
str += fmt.Sprintf("%s %s %s %s\n\t", m.Name, m.Type.Name(), m.Tag, comment)
|
|
||||||
} else {
|
|
||||||
str += fmt.Sprintf("%s %s %s\n\t", m.Name, m.Type.Name(), m.Tag)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if name == "" {
|
|
||||||
temp := `${str}`
|
|
||||||
return os.Expand(temp, func(k string) string {
|
|
||||||
return str
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
temp := `${name} struct {
|
|
||||||
${str}}`
|
|
||||||
return os.Expand(temp, func(k string) string {
|
|
||||||
return map[string]string{
|
|
||||||
"name": name,
|
|
||||||
"str": str,
|
|
||||||
}[k]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user