mirror of
https://github.com/zeromicro/go-zero.git
synced 2025-02-03 00:38:40 +08:00
optimized goctl format (#336)
* fix format * refactor * refactor * optimized * refactor * refactor * refactor * add js path prefix
This commit is contained in:
parent
01060cf16d
commit
12e235efb0
@ -4,6 +4,7 @@ import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"fmt"
|
||||
"go/format"
|
||||
"go/scanner"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
@ -13,6 +14,7 @@ import (
|
||||
"github.com/tal-tech/go-zero/core/errorx"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/api/parser"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/api/util"
|
||||
ctlutil "github.com/tal-tech/go-zero/tools/goctl/util"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
@ -103,24 +105,108 @@ func apiFormat(data string) (string, error) {
|
||||
var builder strings.Builder
|
||||
s := bufio.NewScanner(strings.NewReader(data))
|
||||
var tapCount = 0
|
||||
var newLineCount = 0
|
||||
var preLine string
|
||||
for s.Scan() {
|
||||
line := strings.TrimSpace(s.Text())
|
||||
if len(line) == 0 {
|
||||
if newLineCount > 0 {
|
||||
continue
|
||||
}
|
||||
newLineCount++
|
||||
} else {
|
||||
if preLine == rightBrace {
|
||||
builder.WriteString(ctlutil.NL)
|
||||
}
|
||||
newLineCount = 0
|
||||
}
|
||||
|
||||
if tapCount == 0 {
|
||||
format, err := formatGoTypeDef(line, s, &builder)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if format {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
noCommentLine := util.RemoveComment(line)
|
||||
if noCommentLine == rightParenthesis || noCommentLine == rightBrace {
|
||||
tapCount -= 1
|
||||
}
|
||||
if tapCount < 0 {
|
||||
line = strings.TrimSuffix(line, rightBrace)
|
||||
line := strings.TrimSuffix(noCommentLine, rightBrace)
|
||||
line = strings.TrimSpace(line)
|
||||
if strings.HasSuffix(line, leftBrace) {
|
||||
tapCount += 1
|
||||
}
|
||||
}
|
||||
util.WriteIndent(&builder, tapCount)
|
||||
builder.WriteString(line + "\n")
|
||||
builder.WriteString(line + ctlutil.NL)
|
||||
if strings.HasSuffix(noCommentLine, leftParenthesis) || strings.HasSuffix(noCommentLine, leftBrace) {
|
||||
tapCount += 1
|
||||
}
|
||||
preLine = line
|
||||
}
|
||||
return strings.TrimSpace(builder.String()), nil
|
||||
}
|
||||
|
||||
func formatGoTypeDef(line string, scanner *bufio.Scanner, builder *strings.Builder) (bool, error) {
|
||||
noCommentLine := util.RemoveComment(line)
|
||||
tokenCount := 0
|
||||
if strings.HasPrefix(noCommentLine, "type") && (strings.HasSuffix(noCommentLine, leftParenthesis) ||
|
||||
strings.HasSuffix(noCommentLine, leftBrace)) {
|
||||
var typeBuilder strings.Builder
|
||||
typeBuilder.WriteString(mayInsertStructKeyword(line, &tokenCount) + ctlutil.NL)
|
||||
for scanner.Scan() {
|
||||
noCommentLine := util.RemoveComment(scanner.Text())
|
||||
typeBuilder.WriteString(mayInsertStructKeyword(scanner.Text(), &tokenCount) + ctlutil.NL)
|
||||
if noCommentLine == rightBrace || noCommentLine == rightParenthesis {
|
||||
tokenCount--
|
||||
}
|
||||
if tokenCount == 0 {
|
||||
ts, err := format.Source([]byte(typeBuilder.String()))
|
||||
if err != nil {
|
||||
return false, errors.New("error format \n" + typeBuilder.String())
|
||||
}
|
||||
|
||||
result := strings.ReplaceAll(string(ts), " struct ", " ")
|
||||
result = strings.ReplaceAll(result, "type ()", "")
|
||||
builder.WriteString(result)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func mayInsertStructKeyword(line string, token *int) string {
|
||||
insertStruct := func() string {
|
||||
if strings.Contains(line, " struct") {
|
||||
return line
|
||||
}
|
||||
index := strings.Index(line, leftBrace)
|
||||
return line[:index] + " struct " + line[index:]
|
||||
}
|
||||
|
||||
noCommentLine := util.RemoveComment(line)
|
||||
if strings.HasSuffix(noCommentLine, leftBrace) {
|
||||
*token++
|
||||
return insertStruct()
|
||||
}
|
||||
if strings.HasSuffix(noCommentLine, rightBrace) {
|
||||
noCommentLine = strings.TrimSuffix(noCommentLine, rightBrace)
|
||||
noCommentLine = util.RemoveComment(noCommentLine)
|
||||
if strings.HasSuffix(noCommentLine, leftBrace) {
|
||||
return insertStruct()
|
||||
}
|
||||
}
|
||||
if strings.HasSuffix(noCommentLine, leftParenthesis) {
|
||||
*token++
|
||||
}
|
||||
return line
|
||||
}
|
||||
|
@ -24,11 +24,11 @@ handler: GreetHandler
|
||||
}
|
||||
`
|
||||
|
||||
formattedStr = `type Request struct {
|
||||
formattedStr = `type Request {
|
||||
Name string
|
||||
}
|
||||
|
||||
type Response struct {
|
||||
type Response {
|
||||
Message string
|
||||
}
|
||||
|
||||
@ -40,7 +40,7 @@ service A-api {
|
||||
}`
|
||||
)
|
||||
|
||||
func TestInlineTypeNotExist(t *testing.T) {
|
||||
func TestFormat(t *testing.T) {
|
||||
r, err := apiFormat(notFormattedStr)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, r, formattedStr)
|
||||
|
@ -90,6 +90,12 @@ func writeType(writer io.Writer, tp spec.Type, types []spec.Type) error {
|
||||
|
||||
func writeMembers(writer io.Writer, types []spec.Type, members []spec.Member, allMembers *[]spec.Member, indent int) error {
|
||||
for _, member := range members {
|
||||
if !member.IsInline {
|
||||
_, err := member.GetPropertyName()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if !member.IsBodyMember() {
|
||||
continue
|
||||
}
|
||||
|
@ -63,10 +63,6 @@ func (m Member) IsOmitempty() bool {
|
||||
|
||||
func (m Member) GetPropertyName() (string, error) {
|
||||
tags := m.Tags()
|
||||
if len(tags) == 0 {
|
||||
return "", errors.New("json property name not exist, member: " + m.Name)
|
||||
}
|
||||
|
||||
for _, tag := range tags {
|
||||
if stringx.Contains(definedKeys, tag.Key) {
|
||||
if tag.Name == "-" {
|
||||
|
@ -85,7 +85,7 @@ func genHandler(dir, webApi, caller string, api *spec.ApiSpec, unwrapApi bool) e
|
||||
imports += fmt.Sprintf(`import * as components from "%s"`, "./"+outputFile)
|
||||
}
|
||||
|
||||
apis, err := genApi(api, localTypes, caller, prefixForType)
|
||||
apis, err := genApi(api, caller, prefixForType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -119,32 +119,34 @@ func genTypes(localTypes []spec.Type, inlineType func(string) (*spec.Type, error
|
||||
return types, nil
|
||||
}
|
||||
|
||||
func genApi(api *spec.ApiSpec, localTypes []spec.Type, caller string, prefixForType func(string) string) (string, error) {
|
||||
func genApi(api *spec.ApiSpec, caller string, prefixForType func(string) string) (string, error) {
|
||||
var builder strings.Builder
|
||||
for _, route := range api.Service.Routes() {
|
||||
handler, ok := apiutil.GetAnnotationValue(route.Annotations, "server", "handler")
|
||||
if !ok {
|
||||
return "", fmt.Errorf("missing handler annotation for route %q", route.Path)
|
||||
}
|
||||
handler = util.Untitle(handler)
|
||||
handler = strings.Replace(handler, "Handler", "", 1)
|
||||
comment := commentForRoute(route)
|
||||
if len(comment) > 0 {
|
||||
fmt.Fprintf(&builder, "%s\n", comment)
|
||||
}
|
||||
fmt.Fprintf(&builder, "export function %s(%s) {\n", handler, paramsForRoute(route, prefixForType))
|
||||
writeIndent(&builder, 1)
|
||||
responseGeneric := "<null>"
|
||||
if len(route.ResponseType.Name) > 0 {
|
||||
val, err := goTypeToTs(route.ResponseType.Name, prefixForType)
|
||||
if err != nil {
|
||||
return "", err
|
||||
for _, group := range api.Service.Groups {
|
||||
for _, route := range group.Routes {
|
||||
handler, ok := apiutil.GetAnnotationValue(route.Annotations, "server", "handler")
|
||||
if !ok {
|
||||
return "", fmt.Errorf("missing handler annotation for route %q", route.Path)
|
||||
}
|
||||
responseGeneric = fmt.Sprintf("<%s>", val)
|
||||
handler = util.Untitle(handler)
|
||||
handler = strings.Replace(handler, "Handler", "", 1)
|
||||
comment := commentForRoute(route)
|
||||
if len(comment) > 0 {
|
||||
fmt.Fprintf(&builder, "%s\n", comment)
|
||||
}
|
||||
fmt.Fprintf(&builder, "export function %s(%s) {\n", handler, paramsForRoute(route, prefixForType))
|
||||
writeIndent(&builder, 1)
|
||||
responseGeneric := "<null>"
|
||||
if len(route.ResponseType.Name) > 0 {
|
||||
val, err := goTypeToTs(route.ResponseType.Name, prefixForType)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
responseGeneric = fmt.Sprintf("<%s>", val)
|
||||
}
|
||||
fmt.Fprintf(&builder, `return %s.%s%s(%s)`, caller, strings.ToLower(route.Method),
|
||||
util.Title(responseGeneric), callParamsForRoute(route, group))
|
||||
builder.WriteString("\n}\n\n")
|
||||
}
|
||||
fmt.Fprintf(&builder, `return %s.%s%s(%s)`, caller, strings.ToLower(route.Method),
|
||||
util.Title(responseGeneric), callParamsForRoute(route))
|
||||
builder.WriteString("\n}\n\n")
|
||||
}
|
||||
|
||||
apis := builder.String()
|
||||
@ -188,21 +190,28 @@ func commentForRoute(route spec.Route) string {
|
||||
return builder.String()
|
||||
}
|
||||
|
||||
func callParamsForRoute(route spec.Route) string {
|
||||
func callParamsForRoute(route spec.Route, group spec.Group) string {
|
||||
hasParams := pathHasParams(route)
|
||||
hasBody := hasRequestBody(route)
|
||||
if hasParams && hasBody {
|
||||
return fmt.Sprintf("%s, %s, %s", pathForRoute(route), "params", "req")
|
||||
return fmt.Sprintf("%s, %s, %s", pathForRoute(route, group), "params", "req")
|
||||
} else if hasParams {
|
||||
return fmt.Sprintf("%s, %s", pathForRoute(route), "params")
|
||||
return fmt.Sprintf("%s, %s", pathForRoute(route, group), "params")
|
||||
} else if hasBody {
|
||||
return fmt.Sprintf("%s, %s", pathForRoute(route), "req")
|
||||
return fmt.Sprintf("%s, %s", pathForRoute(route, group), "req")
|
||||
}
|
||||
return pathForRoute(route)
|
||||
return pathForRoute(route, group)
|
||||
}
|
||||
|
||||
func pathForRoute(route spec.Route) string {
|
||||
return "\"" + route.Path + "\""
|
||||
func pathForRoute(route spec.Route, group spec.Group) string {
|
||||
value, ok := apiutil.GetAnnotationValue(group.Annotations, "server", pathPrefix)
|
||||
if !ok {
|
||||
return "\"" + route.Path + "\""
|
||||
} else {
|
||||
value = strings.TrimPrefix(value, `"`)
|
||||
value = strings.TrimSuffix(value, `"`)
|
||||
return fmt.Sprintf(`"%s/%s"`, value, strings.TrimPrefix(route.Path, "/"))
|
||||
}
|
||||
}
|
||||
|
||||
func pathHasParams(route spec.Route) bool {
|
||||
|
@ -2,4 +2,5 @@ package tsgen
|
||||
|
||||
const (
|
||||
packagePrefix = "components."
|
||||
pathPrefix = "pathPrefix"
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user