From 1d90ea9e28bdf8254e5f178297953ff50a2c8ca5 Mon Sep 17 00:00:00 2001 From: Bob Glickstein Date: Fri, 5 Dec 2025 11:38:07 -0800 Subject: [PATCH 1/2] Skip deprecated functions unless -deprecated is given. --- cmd/decouple/decouple_test.go | 6 +++--- cmd/decouple/main.go | 23 +++++++++++++++-------- decouple.go | 21 ++++++++++++++++++++- 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/cmd/decouple/decouple_test.go b/cmd/decouple/decouple_test.go index b26bd98..91d1cc9 100644 --- a/cmd/decouple/decouple_test.go +++ b/cmd/decouple/decouple_test.go @@ -14,7 +14,7 @@ import ( func TestRunJSON(t *testing.T) { buf := new(bytes.Buffer) - if err := run(buf, false, true, []string{"../.."}); err != nil { + if err := run2(buf, false, true, false, []string{"../.."}); err != nil { t.Fatal(err) } @@ -34,7 +34,7 @@ func TestRunJSON(t *testing.T) { want := []jtuple{{ PackageName: "main", FileName: "main.go", - Line: 106, + Line: 113, Column: 6, FuncName: "showJSON", Params: []jparam{{ @@ -52,7 +52,7 @@ func TestRunJSON(t *testing.T) { func TestRunPlain(t *testing.T) { buf := new(bytes.Buffer) - if err := run(buf, false, false, []string{"../.."}); err != nil { + if err := run2(buf, false, false, false, []string{"../.."}); err != nil { t.Fatal(err) } diff --git a/cmd/decouple/main.go b/cmd/decouple/main.go index 4e50f88..95b8e83 100644 --- a/cmd/decouple/main.go +++ b/cmd/decouple/main.go @@ -17,21 +17,27 @@ import ( ) func main() { + if err := run(); err != nil { + fmt.Fprintf(os.Stderr, "Error: %s\n", err) + os.Exit(1) + } +} + +func run() error { var ( - verbose bool - doJSON bool + deprecated bool + doJSON bool + verbose bool ) - flag.BoolVar(&verbose, "v", false, "verbose") + flag.BoolVar(&deprecated, "deprecated", false, "include deprecated functions in the analysis") flag.BoolVar(&doJSON, "json", false, "output in JSON format") + flag.BoolVar(&verbose, "v", false, "verbose") flag.Parse() - if err := run(os.Stdout, verbose, doJSON, flag.Args()); err != nil { - fmt.Fprintln(os.Stderr, err) - os.Exit(1) - } + return run2(os.Stdout, deprecated, doJSON, verbose, flag.Args()) } -func run(w io.Writer, verbose, doJSON bool, args []string) error { +func run2(w io.Writer, deprecated, doJSON, verbose bool, args []string) error { var dir string switch len(args) { case 0: @@ -46,6 +52,7 @@ func run(w io.Writer, verbose, doJSON bool, args []string) error { if err != nil { return errors.Wrapf(err, "creating checker for %s", dir) } + checker.Deprecated = deprecated checker.Verbose = verbose tuples, err := checker.Check() diff --git a/decouple.go b/decouple.go index e8a0229..37c13a1 100644 --- a/decouple.go +++ b/decouple.go @@ -21,9 +21,11 @@ const PkgMode = packages.NeedName | packages.NeedFiles | packages.NeedImports | // or a single such package, // or a function or function parameter in one. // +// Set Deprecated to include deprecated functions in the analysis, which are normally excluded. // Set Verbose to true to get (very) verbose debugging output. type Checker struct { - Verbose bool + Deprecated bool + Verbose bool pkgs []*packages.Package namedInterfaces map[*packages.Package]map[string]namedInterfacePair // pkg -> named interface type -> (method map, is alias) @@ -191,6 +193,10 @@ type MethodMap = map[string]*types.Signature // which should be one of the packages contained in the Checker. // The result is a map from parameter names eligible for decoupling to MethodMaps. func (ch Checker) CheckFunc(pkg *packages.Package, fndecl *ast.FuncDecl) (map[string]MethodMap, error) { + if !ch.Deprecated && isDeprecated(fndecl) { + return nil, nil + } + result := make(map[string]MethodMap) for _, field := range fndecl.Type.Params.List { for _, name := range field.Names { @@ -210,6 +216,19 @@ func (ch Checker) CheckFunc(pkg *packages.Package, fndecl *ast.FuncDecl) (map[st return result, nil } +func isDeprecated(fndecl *ast.FuncDecl) bool { + if fndecl.Doc == nil { + return false + } + pars := strings.Split(fndecl.Doc.Text(), "\n\n") + for _, par := range pars { + if strings.HasPrefix(par, "Deprecated:") { + return true + } + } + return false +} + // CheckParam checks a single named parameter in a given function declaration, // which must apepar in the given package, // which should be one of the packages in the Checker. From 9612953b06d06044219525311fdae99db699fad3 Mon Sep 17 00:00:00 2001 From: Bob Glickstein Date: Fri, 5 Dec 2025 14:46:47 -0800 Subject: [PATCH 2/2] Update items for release. --- .github/workflows/go.yml | 2 +- Readme.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index ffc8a1f..db73538 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -31,7 +31,7 @@ jobs: - name: Modver if: ${{ github.event_name == 'pull_request' }} - uses: bobg/modver@v2.12.1 + uses: bobg/modver@v2.12.2 with: github_token: ${{ secrets.GITHUB_TOKEN }} pull_request_url: https://github.com/${{ github.repository }}/pull/${{ github.event.number }} diff --git a/Readme.md b/Readme.md index f110c6c..8888881 100644 --- a/Readme.md +++ b/Readme.md @@ -3,7 +3,7 @@ [![Go Reference](https://pkg.go.dev/badge/github.com/bobg/decouple.svg)](https://pkg.go.dev/github.com/bobg/decouple) [![Go Report Card](https://goreportcard.com/badge/github.com/bobg/decouple)](https://goreportcard.com/report/github.com/bobg/decouple) [![Tests](https://github.com/bobg/decouple/actions/workflows/go.yml/badge.svg)](https://github.com/bobg/decouple/actions/workflows/go.yml) -[![Coverage Status](https://coveralls.io/repos/github.com/bobg/decouple/badge.svg?branch=main)](https://coveralls.io/github.com/bobg/decouple?branch=main) +[![Coverage Status](https://coveralls.io/repos/github/bobg/decouple/badge.svg?branch=main)](https://coveralls.io/github/bobg/decouple?branch=main) [![Mentioned in Awesome Go](https://awesome.re/mentioned-badge.svg)](https://github.com/avelino/awesome-go) This is decouple,