From 12e7178bc05a23de029469cee0d246cd318e1fdd Mon Sep 17 00:00:00 2001 From: John Mulligan Date: Mon, 23 Aug 2021 13:47:34 -0400 Subject: [PATCH] implements: teach the implements tool to detect deprecated/preview funcs Teach the implements tool how to detect functions marked deprecated and marked preview in the go-ceph codebase. Especially helpful will be the JSON output which can, in the future, be added to a tool-chain that helps track when deprecated functions are to be removed and when preview functions should become stable. Note that this change ONLY implements the detection of preview/deprecated based on the doc comments. Signed-off-by: John Mulligan --- .../implements/internal/implements/gosrc.go | 25 ++++++++++++++----- .../internal/implements/inspector.go | 5 ++++ .../internal/implements/json_report.go | 20 +++++++++++++-- .../implements/internal/implements/report.go | 8 ++++++ 4 files changed, 50 insertions(+), 8 deletions(-) diff --git a/contrib/implements/internal/implements/gosrc.go b/contrib/implements/internal/implements/gosrc.go index f73ccea..d66b707 100644 --- a/contrib/implements/internal/implements/gosrc.go +++ b/contrib/implements/internal/implements/gosrc.go @@ -14,21 +14,34 @@ import ( type visitor struct { inFunction *ast.FuncDecl - callMap map[string]string - docMap map[string]string + callMap map[string]string + docMap map[string]string + deprecated map[string]string + preview map[string]string } func newVisitor() *visitor { return &visitor{ - callMap: map[string]string{}, - docMap: map[string]string{}, + callMap: map[string]string{}, + docMap: map[string]string{}, + deprecated: map[string]string{}, + preview: map[string]string{}, } } -func (v *visitor) checkDocImplements(fdec *ast.FuncDecl) { +func (v *visitor) checkDocComment(fdec *ast.FuncDecl) { dtext := fdec.Doc.Text() lines := strings.Split(dtext, "\n") for i := range lines { + if strings.Contains(lines[i], "DEPRECATED") { + v.deprecated[fdec.Name.Name] = dtext + logger.Printf("marked deprecated: %s\n", fdec.Name.Name) + } + if strings.Contains(lines[i], "PREVIEW") { + v.preview[fdec.Name.Name] = dtext + logger.Printf("marked preview: %s\n", fdec.Name.Name) + } + if lines[i] == "Implements:" { cfunc := cfuncFromComment(lines[i+1]) if cfunc == "" { @@ -67,7 +80,7 @@ func (v *visitor) Visit(node ast.Node) ast.Visitor { return v case *ast.FuncDecl: logger.Printf("checking function: %v\n", n.Name.Name) - v.checkDocImplements(n) + v.checkDocComment(n) v.inFunction = n return v case *ast.CallExpr: diff --git a/contrib/implements/internal/implements/inspector.go b/contrib/implements/internal/implements/inspector.go index 147f924..e5505c4 100644 --- a/contrib/implements/internal/implements/inspector.go +++ b/contrib/implements/internal/implements/inspector.go @@ -20,6 +20,9 @@ type Inspector struct { expected CFunctions found map[string]foundFlags deprecatedMissing int + + deprecated map[string]string + preview map[string]string } // SetExpected sets the expected C functions, asuming the supplied prefix. @@ -54,6 +57,8 @@ func (ii *Inspector) update() { } } } + ii.deprecated = ii.visitor.deprecated + ii.preview = ii.visitor.preview } // NewInspector returns a newly created code inspector object. diff --git a/contrib/implements/internal/implements/json_report.go b/contrib/implements/internal/implements/json_report.go index ce058d2..2c30334 100644 --- a/contrib/implements/internal/implements/json_report.go +++ b/contrib/implements/internal/implements/json_report.go @@ -39,6 +39,11 @@ type jrFunction struct { Refs []string `json:"referenced_by,omitempty"` } +type gFunc struct { + Name string `json:"name"` + Comment string `json:"comment,omitempty"` +} + type jrPackage struct { Name string `json:"name"` Summary struct { @@ -47,8 +52,10 @@ type jrPackage struct { Missing int `json:"missing"` Deprecated int `json:"deprecated"` } `json:"summary"` - Found []jrFunction `json:"found,omitempty"` - Missing []jrFunction `json:"missing,omitempty"` + Found []jrFunction `json:"found,omitempty"` + Missing []jrFunction `json:"missing,omitempty"` + Deprecated []gFunc `json:"deprecated_api,omitempty"` + Preview []gFunc `json:"preview_api,omitempty"` } type jrOut map[string]jrPackage @@ -105,6 +112,15 @@ func collectFuncs(jp *jrPackage, ii *Inspector) { jp.Missing = append(jp.Missing, jrFunction{cf.Name, flags, []string{}}) } + + for d, v := range ii.deprecated { + jp.Deprecated = append(jp.Deprecated, + gFunc{Name: d, Comment: v}) + } + for p, v := range ii.preview { + jp.Preview = append(jp.Preview, + gFunc{Name: p, Comment: v}) + } } func mkeys(m map[string]bool) []string { diff --git a/contrib/implements/internal/implements/report.go b/contrib/implements/internal/implements/report.go index 2645c15..6a63260 100644 --- a/contrib/implements/internal/implements/report.go +++ b/contrib/implements/internal/implements/report.go @@ -101,6 +101,14 @@ func (r *TextReport) Report(name string, ii *Inspector) error { } r.printf(" Missing: %s%s\n", cf.Name, d) } + r.printf("Deprecated by go-ceph:\n") + for d := range ii.deprecated { + r.printf(" %s\n", d) + } + r.printf("Preview in go-ceph:\n") + for p := range ii.preview { + r.printf(" %s\n", p) + } return nil }