|
@@ -4,15 +4,15 @@ import (
|
|
|
"bytes"
|
|
|
_ "embed"
|
|
|
"fmt"
|
|
|
- "go/format"
|
|
|
"html/template"
|
|
|
+ "io"
|
|
|
"strconv"
|
|
|
"strings"
|
|
|
|
|
|
"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/util"
|
|
|
+ apiutil "github.com/zeromicro/go-zero/tools/goctl/api/util"
|
|
|
+ "github.com/zeromicro/go-zero/tools/goctl/util"
|
|
|
)
|
|
|
|
|
|
//go:embed markdown.tpl
|
|
@@ -23,7 +23,7 @@ func genDoc(api *spec.ApiSpec, dir, filename string) error {
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
- fp, _, err := util.MaybeCreateFile(dir, "", filename)
|
|
|
+ fp, _, err := apiutil.MaybeCreateFile(dir, "", filename)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
@@ -36,12 +36,12 @@ func genDoc(api *spec.ApiSpec, dir, filename string) error {
|
|
|
routeComment = "N/A"
|
|
|
}
|
|
|
|
|
|
- requestContent, err := buildDoc(route.RequestType, api)
|
|
|
+ requestContent, err := buildDoc(route.RequestType, api.Types)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
|
|
|
- responseContent, err := buildDoc(route.ResponseType, api)
|
|
|
+ responseContent, err := buildDoc(route.ResponseType, api.Types)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
@@ -61,6 +61,7 @@ func genDoc(api *spec.ApiSpec, dir, filename string) error {
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
+
|
|
|
builder.Write(tmplBytes.Bytes())
|
|
|
}
|
|
|
|
|
@@ -68,7 +69,7 @@ func genDoc(api *spec.ApiSpec, dir, filename string) error {
|
|
|
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 {
|
|
|
return "", nil
|
|
|
}
|
|
@@ -78,15 +79,12 @@ func buildDoc(route spec.Type, api *spec.ApiSpec) (string, error) {
|
|
|
if definedType, ok := route.(spec.DefineStruct); ok {
|
|
|
associatedTypes(definedType, &tps)
|
|
|
}
|
|
|
- value, err := gogen.BuildTypes(tps, api)
|
|
|
+ value, err := buildTypes(tps, types)
|
|
|
if err != nil {
|
|
|
return "", err
|
|
|
}
|
|
|
- formatted, err := format.Source([]byte(value))
|
|
|
- if err != nil {
|
|
|
- return "", err
|
|
|
- }
|
|
|
- return fmt.Sprintf("\n\n```golang\n%s\n```\n", string(formatted)), nil
|
|
|
+
|
|
|
+ return fmt.Sprintf("\n\n```golang\n%s\n```\n", value), nil
|
|
|
}
|
|
|
|
|
|
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
|
|
|
+}
|