diff --git a/cmd/web/restdoc/logger/logger.go b/cmd/web/restdoc/logger/logger.go index 926a384e..3464ee6b 100644 --- a/cmd/web/restdoc/logger/logger.go +++ b/cmd/web/restdoc/logger/logger.go @@ -14,9 +14,10 @@ import ( ) type Logger struct { - logs logs.Logs - p *message.Printer - count int + logs logs.Logs + p *message.Printer + count int + hasErr bool } func New(l logs.Logs, p *message.Printer) *Logger { @@ -35,6 +36,8 @@ func (l *Logger) Info(msg any) { l.log(logs.Info, msg, "", 0) } // Warning 输出警告信息 func (l *Logger) Warning(msg any) { l.log(logs.Warn, msg, "", 0) } +func (l *Logger) HasError() bool { return l.hasErr } + // Error 输出错误信息 // // 如果 msg 包含了定位信息,则 filename 和 line 将被忽略 @@ -75,6 +78,10 @@ func (l *Logger) log(lv logs.Level, msg any, filename string, line int) { l.count++ // 只有真正输出时,才需要+1。 + if !l.hasErr && (lv == logs.Error || lv == logs.Fatal) { + l.hasErr = true + } + mm := m.LocaleString(l.p) if filename != "" { mm = web.Phrase("%s at %s:%d", mm, filename, line).LocaleString(l.p) diff --git a/cmd/web/restdoc/logger/logger_test.go b/cmd/web/restdoc/logger/logger_test.go index 6295a5c9..86a4d4a6 100644 --- a/cmd/web/restdoc/logger/logger_test.go +++ b/cmd/web/restdoc/logger/logger_test.go @@ -31,7 +31,7 @@ func TestLogger(t *testing.T) { e1 := &scanner.Error{Pos: token.Position{Filename: "f1.go"}, Msg: "e1"} e2 := &scanner.Error{Pos: token.Position{Filename: "f1.go"}, Msg: "e2"} l.Error(e1, "f1.go", 0) - a.Equal(1, l.Count()).True(buf.Len() > 0) + a.Equal(1, l.Count()).True(buf.Len() > 0).True(l.HasError()) list := scanner.ErrorList{e1, e2} l.Error(list, "f1.go", 0) diff --git a/cmd/web/restdoc/parser/parser.go b/cmd/web/restdoc/parser/parser.go index 4e45fe86..019887fa 100644 --- a/cmd/web/restdoc/parser/parser.go +++ b/cmd/web/restdoc/parser/parser.go @@ -163,6 +163,10 @@ func (p *Parser) Parse(ctx context.Context) *openapi.OpenAPI { } wg.Wait() + if p.l.HasError() { + return nil + } + if err := t.Doc().Validate(ctx); err != nil { p.l.Error(err, "", 0) return nil diff --git a/cmd/web/restdoc/restdoc.go b/cmd/web/restdoc/restdoc.go index 5207ada2..f6039bf7 100644 --- a/cmd/web/restdoc/restdoc.go +++ b/cmd/web/restdoc/restdoc.go @@ -58,9 +58,9 @@ func Init(opt *cmdopt.CmdOpt, p *localeutil.Printer) { } l := logger.New(ls, p) - doc := parser.New(l, *urlPrefix, tags) + dp := parser.New(l, *urlPrefix, tags) for _, dir := range fs.Args() { - doc.AddDir(ctx, dir, *r) + dp.AddDir(ctx, dir, *r) if *d { modCache := filepath.Join(build.Default.GOPATH, "pkg", "mod") @@ -75,12 +75,15 @@ func Init(opt *cmdopt.CmdOpt, p *localeutil.Printer) { continue } modDir := filepath.Join(modCache, p.Mod.Path+"@"+p.Mod.Version) - doc.AddDir(ctx, modDir, *r) + dp.AddDir(ctx, modDir, *r) } } } - return doc.Parse(ctx).SaveAs(*o) + if doc := dp.Parse(ctx); doc != nil { + return doc.SaveAs(*o) + } + return nil } }) } diff --git a/cmd/web/restdoc/schema/search.go b/cmd/web/restdoc/schema/search.go index 47bc1f67..6f0c331a 100644 --- a/cmd/web/restdoc/schema/search.go +++ b/cmd/web/restdoc/schema/search.go @@ -212,7 +212,7 @@ func (f SearchFunc) fromTypeSpec(t *openapi.OpenAPI, currPath, tag string, file case *ast.IndexListExpr: // type x = G[int, float] return f.fromIndexListExprType(t, file, currPath, tag, ts) default: - msg := web.Phrase("%s can not convert to ast.StructType", s.Type) + msg := web.Phrase("%s can not convert to ast.StructType", s.Name.Name) return nil, newError(s.Pos(), msg) } } diff --git a/router_test.go b/router_test.go index fd032380..db4c3f11 100644 --- a/router_test.go +++ b/router_test.go @@ -8,6 +8,7 @@ import ( "net/http" "os" "testing" + "time" "github.com/issue9/assert/v3" "github.com/issue9/mux/v7" @@ -36,7 +37,7 @@ func TestServer_Routers(t *testing.T) { srv := newTestServer(a, nil) defer servertest.Run(a, srv)() - defer srv.Close(0) + defer srv.Close(500 * time.Millisecond) ver := group.NewHeaderVersion("ver", "v", log.Default(), "2") a.NotNil(ver) @@ -46,8 +47,11 @@ func TestServer_Routers(t *testing.T) { uu, err := r1.URL(false, "/posts/1", nil) a.NotError(err).Equal("https://example.com/posts/1", uu) - r1.Prefix("/p1").Delete("/path", buildHandler(http.StatusCreated)) - servertest.Delete(a, "http://localhost:8080/p1/path").Header("Accept", "application/json;v=2").Do(nil).Status(http.StatusCreated) + r1.Prefix("/p1").Delete("/path", buildHandler(http.StatusNoContent)) + servertest.Delete(a, "http://localhost:8080/p1/path"). + Header("Accept", "application/json;v=2"). + Do(nil). + Status(http.StatusNoContent) servertest.NewRequest(a, http.MethodOptions, "http://localhost:8080/p1/path"). Header("Accept", "application/json;v=2"). Do(nil).Status(http.StatusOK) @@ -72,7 +76,7 @@ func TestServer_FileServer(t *testing.T) { s.CatalogBuilder().SetString(language.MustParse("zh-CN"), "problem.404", "NOT FOUND") r := s.NewRouter("def", nil) defer servertest.Run(a, s)() - defer s.Close(0) + defer s.Close(500 * time.Millisecond) t.Run("problems", func(t *testing.T) { r.Get("/v1/{path}", s.FileServer(os.DirFS("./testdata"), "path", "index.html")) @@ -144,7 +148,7 @@ func TestMiddleware(t *testing.T) { prefix.Get("/path", buildHandler(201)) defer servertest.Run(a, srv)() - defer srv.Close(0) + defer srv.Close(500 * time.Millisecond) servertest.Get(a, "http://localhost:8080/p1/path"). Header("accept", "application/json"). diff --git a/web.go b/web.go index 2c82f5e5..067925e4 100644 --- a/web.go +++ b/web.go @@ -18,7 +18,7 @@ import ( ) // Version 当前框架的版本 -const Version = "0.84.0" +const Version = "0.85.0" type ( Logger = logs.Logger