Refactoring and code transformation tool for Go.

gopatch Go codecov

gopatch is a tool to match and transform Go code. It is meant to aid in refactoring and restyling.

Table of contents

Introduction

gopatch operates like the Unix patch tool: given a patch file and another file as input, it applies the changes specified in the patch to the provided file.

 .-------.                      .-------.
/_|      |.                    /_|      |.
|        ||.    +---------+    |        ||.
|   .go  |||>-->| gopatch |>-->|   .go  |||
|        |||    +---------+    |        |||
'--------'||      ^            '--------'||
 '--------'|      |             '--------'|
  '--------'      |              '--------'
     .-------.    |
    /_|      |    |
    |        +----'
    | .patch |
    |        |
    '--------'

What specifically differentiates it from patch is that unlike plain text transformations, it can be smarter because it understands Go syntax.

Getting started

Installation

Download a pre-built binary of gopatch from the Releases page or by running the following command in your terminal and place it on your $PATH.

VERSION=0.1.0
URL="https://github.com/uber-go/gopatch/releases/download/v$VERSION/gopatch_${VERSION}_$(uname -s)_$(uname -m).tar.gz"
curl -L "$URL" | tar xzv gopatch

Alternatively, if you have Go installed, build it from source and install it with the following command.

go install github.com/uber-go/gopatch@latest

Note: If you're using Go < 1.16, use go get github.com/uber-go/gopatch@latest instead.

Your first patch

Write your first patch.

$ cat > ~/s1028.patch
@@
@@
-import "errors"

-errors.New(fmt.Sprintf(...))
+fmt.Errorf(...)

This patch is a fix for staticcheck S1028. It searches for uses of fmt.Sprintf with errors.New, and simplifies them by replacing them with fmt.Errorf.

For example,

return errors.New(fmt.Sprintf("invalid port: %v", err))
// becomes
return fmt.Errorf("invalid port: %v", err)

Apply the patch

To apply the patch, cd to your Go project's directory.

$ cd ~/go/src/example.com/myproject

Run gopatch on the project, supplying the previously written patch with the -p flag.

$ gopatch -p ~/s1028.patch ./...

This will apply the patch on all Go code in your project.

Check if there were any instances of this issue in your code by running git diff.

Next steps

To learn how to write your own patches, move on to the Patches section. To dive deeper into patches, check out Patches in depth.

To experiment with other sample patches, check out the Examples section.

Usage

To use the gopatch command line tool, provide the following arguments.

gopatch [options] pattern ...

Where pattern specifies one or more Go files, or directories containing Go files. For directories, all Go code inside them and their descendants will be considered by gopatch.

Options

gopatch supports the following command line options.

  • -p file, --patch=file

    Path to a patch file specifying a transformation. Read more about the patch file format in Patches.

    Provide this flag multiple times to apply multiple patches in-order.

    $ gopatch -p foo.patch -p bar.patch path/to/my/project

    If this flag is omitted, a patch is expected on stdin.

    $ gopatch path/to/my/project << EOF
    @@
    @@
    -foo
    +bar
    EOF

Patches

Patch files are the input to gopatch that specify how to transform code. Each patch file contains one or more patches. This section provides an introduction to writing patches; look at Patches in depth for a more detailed explanation.

Each patch specifies a code transformation. These are formatted like unified diffs: lines prefixed with - specify matching code should be deleted, and lines prefixed with + specify that new code should be added.

Consider the following patch.

@@
@@
-foo
+bar

It specifies that we want to search for references to the identifier foo and replace them with references to bar. (Ignore the lines with @@ for now. We will cover those below.)

A more selective version of this patch will search for uses of foo where it is called as a function with specific arguments.

@@
@@
-foo(42)
+bar(42)

This will search for invocations of foo as a function with the specified argument, and replace only those with bar.

gopatch understands Go syntax, so the above is equivalent to the following.

@@
@@
-foo(
+bar(
  42,
 )

Metavariables

Searching for hard-coded exact parameters is limited. We should be able to generalize our patches.

The previously ignored @@ section of patches is referred to as the metavariable section. That is where we specify metavariables for the patch.

Metavariables will match any code, to be reproduced later. Think of them like holes to be filled by the code we match. For example,

@@
var x expression
@@
# rest of the patch

This specifies that x should match any Go expression and record its match for later reuse.

What is a Go expression?

Expressions usually refer to code that has value. You can pass these as arguments to functions. These include x, foo(), user.Name, etc.

Check the Identifiers vs expressions vs statements section of the appendix for more.

So the following patch will search for invocations of foo with a single argument---any argument---and replace them with invocations of bar with the same argument.

@@
var x expression
@@
-foo(x)
+bar(x)
Input Output
foo(42) bar(42)
foo(answer) bar(answer)
foo(getAnswer()) bar(getAnswer())

Metavariables hold the entire matched value, so we can add code around them without risk of breaking anything.

@@
var x expression
@@
-foo(x)
+bar(x + 3, true)
Input Output
foo(42) bar(42 + 3, true)
foo(answer) bar(answer + 3, true)
foo(getAnswer()) bar(getAnswer() + 3, true)

For more on metavariables see Patches in depth/Metavariables.

Statements

gopatch patches are not limited to transforming basic expressions. You can also transform statements.

What is a Go statements?

Statements are instructions to do things, and do not have value. They cannot be passed as parameters to other functions. These include assignments (foo := bar()), if statements (if foo { bar() }), variable declarations (var foo Bar), and so on.

Check the Identifiers vs expressions vs statements section of the appendix for more.

For example, consider the following patch.

@@
var f expression
var err identifier
@@
-err = f
-if err != nil {
+if err := f; err != nil {
   return err
 }

The patch declares two metavariables:

  • f: This represents an operation that possibly returns an error
  • err: This represents the name of the error variable

The patch will search for code that assigns to an error variable immediately before returning it, and inlines the assignment into the if statement. This effectively reduces the scope of the variable to just the if statement.

Input Output
err = foo(bar, baz)
if err != nil {
   return err
}
if err := foo(bar, baz); err != nil {
   return err
}
err = comment.Submit(ctx)
if err != nil {
  return err
}
if err := comment.Submit(ctx); err != nil {
  return err
}

For more on transforming statements, see Patches In Depth/Statements.

Elision

Matching a single argument is still too selective and we may want to match a wider criteria.

For this, gopatch supports elision of code by adding ... in many places. For example,

@@
@@
-foo(...)
+bar(...)

The patch above looks for all calls to the function foo and replaces them with calls to the function bar, regardless of the number of arguments they have.

Input Output
foo(42) bar(42)
foo(42, true, 1) bar(42, true, 1)
foo(getAnswer(), x(y())) bar(getAnswer(), x(y()))

Going back to the patch from Statements, we can instead write the following patch.

@@
var f expression
var err identifier
@@
-err = f
-if err != nil {
+if err := f; err != nil {
   return ..., err
 }

This patch is almost exactly the same as before except the return statement was changed to return ..., err. This will allow the patch to operate even on functions that return multiple values.

Input Output
err = foo()
if err != nil {
   return false, err
}
if err := foo(); err != nil {
   return false, err
}

For more on elision, see Patches in depth/Elision.

Examples

This section lists various example patches you can try in your code. Note that some of these patches are not perfect and may have false positives.

Project status

The project is currently is in a beta state. It works but significant features are planned that may result in breaking changes to the patch format.

Goals

gopatch aims to be a generic power tool that you can use in lieu of simple search-and-replace.

gopatch will attempt to do 80% of the work for you in a transformation, but it cannot guarantee 100% correctness or completeness. Part of this is owing to the decision that gopatch must be able to operate on code that doesn't yet compile, which can often be the case in the middle of a refactor. We may add features in the future that require compilable code, but we plan to always support transformation of partially-valid Go code.

Known issues

Beyond the known issues highlighted above, there are a handful of other issues with using gopatch today.

  • It's very quiet, so there's no indication of progress. #7
  • Error messages for invalid patch files are hard to decipher. #8
  • Matching elisions between the - and + sections does not always work in a desirable way. We may consider replacing anonymous ... elision with a different named elision syntax to address this issue. #9
  • When elision is used, gopatch stops replacing after the first instance in the given scope which is often not what you want. #10
  • Formatting of output generated by gopatch isn't always perfect.

Upcoming

Besides addressing the various limitations and issues we've already mentioned, we have a number of features planned for gopatch.

  • Contextual matching: match context (like a function declaration), and then run a transformation inside the function body repeatedly, at any depth. #11
  • Collateral changes: Match and capture values in one patch, and use those in a following patch in the same file.
  • Metavariable constraints: Specify constraints on metavariables, e.g. matching a string, or part of another metavariable.
  • Condition elision: An elision should match only if a specified condition is also true.

Contributing

If you'd like to contribute to gopatch, you may find the following documents useful:

  • HACKING documents the architecture, code organization, and other information necessary to contribute to the project.
  • RELEASE documents the process for releasing a new version of gopatch.

Similar Projects

  • rf is a refactoring tool with a custom DSL
  • gofmt rewrite rules support simple transformations on expressions
  • eg supports basic example-based refactoring
  • Coccinelle is a tool for C from which gopatch takes inspiration heavily
  • Semgrep is a cross-language semantic search tool
  • Comby is a language-agnostic search and transformation tool

Credits

gopatch is heavily inspired by Coccinelle.

Owner
Uber Go
Uber's open source software for Go development
Uber Go
Comments
  • Add feature to support Diff #20

    Add feature to support Diff #20

    Functionality to list matches without modifying the target files.

    User comments could be caught during the diff phase instead of their manual detection during the code review process. For example:

    - if err != nil {
    -     return err
    -   }
    -   return nil
    

    Could be replaced by

    + return err
    

    Current gopatch -p functionality completely modifies the target file and outputs nothing to the command line. There is no context on what is happening, what changes have been made or whether they have been made. This pull request extends gopatch to list matches and also display description comments if they exist, to give more context on what the patch does.
    Now -d flag turns on lint mode. Associating -d with call to the preview function which prints patch description comments and displays the matches. Otheriwse, (-d = false) associated with call to modify function which applied patch & modifies.

    Components Changed: Go.mod : added pkg/diff Go.sum : added pkg/diff main.go: added modify and preview functions and lint flag

    For reading description comments: internal/engine/change.go : adding comments to change struct internal/parse/change.go : read comment while parsing internal/parse/ast.go : adding comments to change struct internal/parse/section/section.go : read description comments Main.go : modify apply to return comments

    Added Test files for main_test.go

  • Add -v flag for verbose log to stdout

    Add -v flag for verbose log to stdout

    This implements #7. User can specify -v or --verbose flag to make gopatch print whether each file was patched or not to stdout.

    The -v short flag was being used for printing version number so I took it away from --version and put it on --verbose because that seems more conventional with CLI tools..

    Example output:

    ~/ > ./gopatch -v -p temp.patch ./tempdir/...
    [gopatch] /Users/sungyoonwhang/go/src/gopatch/tempdir/test1.go : Patch successfully applied.
    [gopatch] /Users/sungyoonwhang/go/src/gopatch/tempdir/test2.go : Couldn't patch. The file couldn't be parsed.
    [gopatch] /Users/sungyoonwhang/go/src/gopatch/tempdir/test3.go : Couldn't patch. Nothing was matched.
    [gopatch] /Users/sungyoonwhang/go/src/gopatch/tempdir/test4.go : Patch successfully applied.
    could not parse "/Users/sungyoonwhang/go/src/gopatch/tempdir/test2.go": /Users/sungyoonwhang/go/src/gopatch/tempdir/test2.go:2:1: expected 'package', found 'import' (and 1 more errors)
    
  • Add version support info to install step in readme

    Add version support info to install step in readme

    I got an error with the steps in the readme:

    $ go install github.com/uber-go/gopatch@latest
    can't load package: package github.com/uber-go/gopatch@latest: can only use path@version syntax with 'go get'
    

    Success after this fix:

    $ go get github.com/uber-go/gopatch@latest
    go: downloading github.com/uber-go/gopatch v0.0.2
    go: github.com/uber-go/gopatch latest => v0.0.2
    go: downloading github.com/google/go-intervals v0.0.0-20171120085516-250c62ad245e
    

    Edit: it's worth noting my go version:

    go version go1.14.4 darwin/amd64
    

    And that support for version suffixes on the install command was added in 1.16 So on some level, I guess this is a discussion about what versions of go the project supports!

  • build(deps): bump go.uber.org/multierr from 1.8.0 to 1.9.0

    build(deps): bump go.uber.org/multierr from 1.8.0 to 1.9.0

    Bumps go.uber.org/multierr from 1.8.0 to 1.9.0.

    Release notes

    Sourced from go.uber.org/multierr's releases.

    v1.9.0

    • Add AppendFunc that allow passsing functions to similar to AppendInvoke.

    • Bump up yaml.v3 dependency to 3.0.1.

    Changelog

    Sourced from go.uber.org/multierr's changelog.

    v1.9.0 (2022-12-12)

    • Add AppendFunc that allow passsing functions to similar to AppendInvoke.

    • Bump up yaml.v3 dependency to 3.0.1.

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
  • build(deps): bump golang.org/x/tools from 0.3.0 to 0.4.0

    build(deps): bump golang.org/x/tools from 0.3.0 to 0.4.0

    Bumps golang.org/x/tools from 0.3.0 to 0.4.0.

    Release notes

    Sourced from golang.org/x/tools's releases.

    gopls/v0.4.0

    • Improved support for working with modules (@​ridersofrohan). A detailed walk-through of the new features can be found here. A quick summary:
      • Use the -modfile flag to suggest which modules should be added/removed from the go.mod file, rather than editing it automatically.
      • Suggest dependency upgrades in-editor and provide additional language features, such as formatting, for the go.mod file.
    • Inverse implementations (@​muirdm). "Go to implementations" on a concrete type will show the interfaces it implements.
    • Completion improvements (@​muirdm). Specifically, improved completion for keywords. Also, offer if err != nil { return err } as a completion item.
    • Jumping to definition on an import statement returns all files as definition locations (@​danishprakash).
    • Support for running go generate through the editor, via a code lens (@​marwan-at-work).
    • Command-line support for workspace symbols (@​daisuzu).

    Opt-in:

    • Code actions suggesting gofmt -s-style simplifications (@​ridersofrohan). To get these on-save, add the following setting:
    "[go]": {
    	"editor.codeActionsOnSave": {
    		"source.fixAll": true,
    	}
    }
    
    • Code actions suggesting fixes for type errors, such as missing return values (goreturns-style), undeclared names, unused parameters, and assignment statements that should be converted from := to = (@​ridersofrohan). Add the following to your gopls settings to opt-in to these analyzers. In the future, they will be on by default and high-confidence suggested fixes may be applied on save. See additional documentation on analyzers here.
    "gopls": {
    	"analyses": {
    		"fillreturns": true,
                    "undeclaredname": true,
                    "unusedparams": true,
                    "nonewvars": true,
    	}
    }
    
    • Further improvements in the support for multiple concurrent clients (@​findleyr). See #34111 for all details.

    For a complete list of the issues resolved, see the gopls/v0.4.0 milestone.

    gopls/v0.3.4

    gopls/v0.3.3

    • Support for workspace symbols. (@​daisuzu)
    • Various completion improvements, including fixes for completion in code that doesn't parse. (@​muirdm)
    • Limit diagnostic concurrency, preventing huge spikes in memory usage that some users encountered. (@​heschik)
    • Improved handling for URIs containing escaped characters. (@​heschik)
    • Module versions from "go list" in pkg.go.dev links. (@​ridersofrohan)

    ... (truncated)

    Commits
    • aee3994 gopls/internal/lsp/fake: in (*Workdir).RenameFile, fall back to read + write
    • fe60148 go.mod: update golang.org/x dependencies
    • c9ea9a7 gopls/internal/regtest: add a test for the case when the renaming package's p...
    • bf5db81 gopls/internal/lsp/cache: improve ad-hoc warning for nested modules
    • aa9f4b2 go/analysis: document that facts are gob encoded in one gulp
    • bdcd082 internal/gcimporter: skip tests earlier when 'go build' is not available
    • 2ad6325 gopls/internal/lsp/cache: expand ImportPath!=PackagePath comment
    • 52c7b88 gopls/internal/robustio: only define ERROR_SHARING_VIOLATION on Windows
    • 4f69bf3 gopls/internal/lsp/cache: narrow reloadOrphanedFiles to open files
    • 6002d6e gopls/internal/regtest/misc: test Implementations + vendor
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
  • build(deps): bump golang.org/x/tools from 0.2.0 to 0.3.0

    build(deps): bump golang.org/x/tools from 0.2.0 to 0.3.0

    Bumps golang.org/x/tools from 0.2.0 to 0.3.0.

    Release notes

    Sourced from golang.org/x/tools's releases.

    gopls/v0.3.0

    Note: gopls now loads your entire workspace, where “workspace” is directory you opened in your editor.

    In module mode, you must open your module root (directory containing the go.mod file) or a subdirectory.

    In GOPATH mode, you must open your GOPATH/src or a directory within it. If you have a large GOPATH and you open your GOPATH as your workspace root, gopls may be very slow to load. Please see #36899 for further information.

    • Autocompletion from unimported packages is on by default. You will get completions for something like fmt.Printf even if “fmt” isn’t imported yet. (@​heschik)
    • Workspace-scoped references, rename, and go to implementation. These features use your workspace root as the search scope, so behavior will vary based on the directory you open in your editor. This may result in unexpected behavior. (@​muirdm, @​matloob)
    • Workspace-wide diagnostics. You will now see errors in your entire workspace, rather than just in your currently open files. Analysis errors will only be shown for packages with currently open files.
    • Watch file changes on disk. This allows users to switch branches without reloading their editors. Also, changing configurations no longer requires an editor reload.
    • GOPATH vendoring is fully supported. Previously, some features would ignore vendor directories, causing errors if packages weren't in GOPATH. (@​heschik)
    • New autocompletion suggestions for type conversions. Improved completions for literal candidates and variadic functions. Better rankings, including rankings for builtin functions and keywords. (@​muirdm)
    • Highlighting improvements: Highlighting now applies not only to variables, but also to fields, methods, types, and imports. Additional highlighting helps visualize control flow in loops and functions. Highlighting of single character variables has better support. (@​ridersofrohan)
    • Documentation on hover includes links to pkg.go.dev for exported symbols. (@​Southclaws)
    • Improved support for cgo dependencies. All features now work for packages that have cgo dependencies. Authoring cgo packages is still not supported, but improvements are scheduled for Go 1.15 (see #35721). (@​heschik)
    • Deep completions are now on by default. This feature of completion will search the fields and methods of all available candidates to see if there are any more candidates with the expected type. As an example, say you have imported the context package and are calling a function that takes a context.Context as a parameter. In the case that you don’t have a variable of that type in scope, deep completions will suggest context.Background() and context.TODO(). (@​muirdm)

    Opt-in:

    • staticcheck analyses remain opt-in and can be enabled by setting "staticcheck": true in your gopls settings.
    • Go 1.14 will support running the go command without modifying the user’s go.mod file. This new feature is used in gopls to show diagnostics and suggest edits in a user’s go.mod file rather than change the file without the user noticing. Currently, gopls will suggest removing unused dependencies and warn the user if there is a parse error in the go.mod file. Enable this behavior by using the go1.14 beta and setting "tempModfile": true in your gopls settings. (@​ridersofrohan)

    gopls/v0.2.2

    • Fix concurrent map read and write when a file is created (CL 210199).
    • Fix issue that caused errors to show up when a new file was created (CL 209978).

    gopls/v0.2.1

    • Fix for parse errors showing up as errors on the whole package (CL 206597).
    Commits
    • 502c634 go.mod: update golang.org/x dependencies
    • bd04e32 internal/jsonrpc2_v2: eliminate a potential Accept/Dial race in TestIdleTimeout
    • d41a43b internal/jsonrpc2_v2: fix a potential deadlock when (*Conn).Close is invoked ...
    • 3057465 gopls/doc: Add plugin for Lapce to gopls documentation
    • ba92ae1 internal/persistent: avoid incorrect map validation due to multiple keys
    • 9474ca3 gopls/doc: clarify go work use
    • 003fde1 internal/gcimporter: use nondeprecated go/packages mode bits
    • 5050657 gopls/fake: add semantic token modifiers to fake editor
    • 88a3548 gopls/coverage: repair coverage.go
    • 8e0240a internal/regtest/workspace: permanently skip TestDeleteModule_Interdependent
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
  • build(deps): bump github.com/stretchr/testify from 1.8.0 to 1.8.1

    build(deps): bump github.com/stretchr/testify from 1.8.0 to 1.8.1

    Bumps github.com/stretchr/testify from 1.8.0 to 1.8.1.

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
  • Add --print-only flag

    Add --print-only flag

    Copy of #66 by @lverma14 that I accidentally closed. It can't be reopened because its base branch doesn't exist anymore.

    Original PR message follows.


    Functionality to print the changed code to stdout. Doesn't modify the actual code. Current gopatch -p functionality completely modifies the target file and outputs nothing to the command line. There is no option which could show us what the modified code after applying the patch would look like which also doesn't actually modify the code.

    This pull request extends gopatch to display changed code to stdout. This would give more context and can be used for integrating gopatch into arclint.

    Now call to --print-only flag is associated with printing out the modified code to stdout, if the is patch applied. It also prints the description comments from the applied patch to the stderr.

    Components Changed: main.go: added --print-onlyflag and its functionality

  • test/e2e: Always check --diff output

    test/e2e: Always check --diff output

    Currently, the output of gopatch --diff is checked only if the test case included a .diff file. Long-term, it makes sense to verify this for all integration test cases.

    This changes the integration test to verify the output of --diff for all cases, backfilling output for all existing test cases that were missing entries.

  • add --print-only feature

    add --print-only feature

    Functionality to print the changed code to stdout. Doesn't modify the actual code. Current gopatch -p functionality completely modifies the target file and outputs nothing to the command line. There is no option which could show us what the modified code after applying the patch would look like which also doesn't actually modify the code.

    This pull request extends gopatch to display changed code to stdout. This would give more context and can be used for integrating gopatch into arclint.

    Now call to --print-only flag is associated with printing out the modified code to stdout, if the is patch applied. It also prints the description comments from the applied patch to the stderr.

    Components Changed: main.go: added --print-onlyflag and its functionality

  • build(deps): bump github.com/rogpeppe/go-internal from 1.8.1 to 1.9.0

    build(deps): bump github.com/rogpeppe/go-internal from 1.8.1 to 1.9.0

    Bumps github.com/rogpeppe/go-internal from 1.8.1 to 1.9.0.

    Release notes

    Sourced from github.com/rogpeppe/go-internal's releases.

    v1.9.0

    What's Changed

    New Contributors

    Full Changelog: https://github.com/rogpeppe/go-internal/compare/v1.8.1...v1.9.0

    Commits
    • 7a6a5f8 testscript: update docs on set variables
    • c16c0a2 testscript: remove leading newline before results
    • 0d96cbe Use 0o prefix for octal literals
    • 57a71e0 Trim '.txtar' extension from subtest name
    • 77fe68f testscript: fix RequireExplicitExec error messages
    • bb36173 testscript: fix RequireExplicitExec error messages
    • 2431384 testscript: add 'unix' condition
    • 8da7db8 imports: add 'UnixOS' list of Unix-like systems
    • 9d15b66 testscript: add Params.RequireExplicitExec
    • af73bbc all: add support for txtar extension and prefer it (#159)
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
  • Elision: match 1 or more returned types

    Elision: match 1 or more returned types

    (Edit: the below is using 10bff91)

    This patch

    @@
    @@
     func f() (...) {
    - fmt.Println("")
    + fmt.Println("hello")
      ...
     }
    

    will match against

    package foo
    
    func f() (string, error) {
      fmt.Println("")
      return "", nil
    }
    

    but not

    package foo
    
    func f() string {
      fmt.Println("")
      return ""
    }
    

    I thought the parentheses were forcing more than one return type, so I tried patching without them

    @@
    @@
     func f() ... {
    - return ""
    + return "hello"
     }
    

    however this is not a valid patch:

    load patch "repro": parse: repro/0.minus:1:11: found unexpected "..." inside *ast.FieldList

    This isn't a big deal -- I can repeat the patch for 1 return type and N return types.

    Intuitively, I would have thought "(...)" already represents "zero to N" return types, although I could also be totally misunderstanding the syntax!

  • Elision: Support

    Elision: Support "[...]" in function calls

    [...] in function calls should match any and all generic function instantiations.

    @@
    @@
    -foo[...](42)
    +bar[...](42)
    

    Should match:

    foo(42)
    foo[int](42)
    foo[MyInt](42)
    
  • Elision and variadic parameters

    Elision and variadic parameters

    Elision does not seem to match variadic parameters - which also use the ... notation. Below is a simple repro.

    Patch file (goal is to swap order of first 2 parameters only):

    @@
    var first expression
    var second expression
    @@
    -bar(second, first,...)
    +bar(first, second,...)
    

    Input:

    func foo() {
    	bar("b", "a")
    	bar("b", "a", "c")
    	bar("b", "a", []string{"c"}...)
    }
    

    Output:

    func foo() {
    	bar("a", "b")
    	bar("a", "b", "c")
            // Expected: bar("a", "b", []string{"c"}...)
    	bar("b", "a", []string{"c"}...)
    }
    
  • Metavariables for literals

    Metavariables for literals

    We should support metavariables to match on literals. That is, to match on "foo" and 42 below.

    x := "foo"
    const y = 42
    

    This will make it possible to write patches that detect, say, hard-coded strings and turn them into constants or optimize them (moving compilation of a hard-coded regex from a hot path to a top-level variable, for example).

  • Multiple top-level declarations

    Multiple top-level declarations

    It's currently impossible to have a patch that introduces a new top-level declaration while modifying another one.

    For example, given,

    func foo() {
      re := regexp.MustCompile("foo")
      // ...
    }
    

    We cannot build a patch that would turn it into the following.

    var re = regexp.MustCompile("foo")
    
    func foo() {
      // ...
    }
    

    That's because we don't yet support patches with multiple top-level declarations in them so the following will fail to parse.

    @@
    var f, re identifier
    var regex expression
    @@
    +var re = regexp.MustCompile(regex)
    
     func f() {
    -  re := regexp.MustCompile(regex)
       ...
     }
    

    See also #3, #4

octocov is a tool for collecting code metrics (code coverage, code to test ratio and test execution time).

octocov is a tool for collecting code metrics (code coverage, code to test ratio and test execution time).

Jan 9, 2023
A Golang tool that does static analysis, unit testing, code review and generate code quality report.
A Golang tool that does static analysis, unit testing, code review and generate code quality report.

goreporter A Golang tool that does static analysis, unit testing, code review and generate code quality report. This is a tool that concurrently runs

Jan 8, 2023
🐶 Automated code review tool integrated with any code analysis tools regardless of programming language
🐶 Automated code review tool integrated with any code analysis tools regardless of programming language

reviewdog - A code review dog who keeps your codebase healthy. reviewdog provides a way to post review comments to code hosting service, such as GitHu

Jan 2, 2023
🐶 Automated code review tool integrated with any code analysis tools regardless of programming language
🐶 Automated code review tool integrated with any code analysis tools regardless of programming language

reviewdog - A code review dog who keeps your codebase healthy. reviewdog provides a way to post review comments to code hosting service, such as GitHu

Jan 7, 2023
Sloc, Cloc and Code: scc is a very fast accurate code counter with complexity calculations and COCOMO estimates written in pure Go
Sloc, Cloc and Code: scc is a very fast accurate code counter with complexity calculations and COCOMO estimates written in pure Go

Sloc Cloc and Code (scc) A tool similar to cloc, sloccount and tokei. For counting physical the lines of code, blank lines, comment lines, and physica

Jan 4, 2023
The most opinionated Go source code linter for code audit.
The most opinionated Go source code linter for code audit.

go-critic Highly extensible Go source code linter providing checks currently missing from other linters. There is never too much static code analysis.

Jan 6, 2023
depth is tool to retrieve and visualize Go source code dependency trees.

depth is tool to retrieve and visualize Go source code dependency trees. Install Download the appropriate binary for your platform from the Rele

Dec 30, 2022
Tool to populate your code with traceable and secure error codes

Essential part of any project, especially customer facing is proper and secure error handling. When error happens and customer reports it, it would be nice to know the context of the error and where it exactly occured.

Sep 28, 2022
a tool for code clone detection

dupl dupl is a tool written in Go for finding code clones. So far it can find clones only in the Go source files. The method uses suffix tree for seri

Dec 12, 2022
a simple golang SSA viewer tool use for code analysis or make a linter
a simple golang SSA viewer tool use for code analysis or make a linter

ssaviewer A simple golang SSA viewer tool use for code analysis or make a linter ssa.html generate code modify from src/cmd/compile/internal/ssa/html.

May 17, 2022
Act as part of the business code and will report aqua scan report after application installed
Act as part of the business code and will report aqua scan report after application installed

starboard-report This repo aim to enrich the functionality of starboard. Starboard integrates security tools into the Kubernetes environment, so that

Nov 25, 2021
[mirror] This is a linter for Go source code.

Golint is a linter for Go source code. Installation Golint requires a supported release of Go. go get -u golang.org/x/lint/golint To find out where g

Dec 23, 2022
Run linters from Go code -

Lint - run linters from Go Lint makes it easy to run linters from Go code. This allows lint checks to be part of a regular go build + go test workflow

Sep 27, 2022
A static code analyzer for annotated TODO comments
A static code analyzer for annotated TODO comments

todocheck todocheck is a static code analyzer for annotated TODO comments. It let's you create actionable TODOs by annotating them with issues from an

Dec 7, 2022
A little fast cloc(Count Lines Of Code)

gocloc A little fast cloc(Count Lines Of Code), written in Go. Inspired by tokei. Installation $ go get -u github.com/hhatto/gocloc/cmd/gocloc Usage

Jan 6, 2023
🔒🌍 Security scanner for your Terraform code
🔒🌍 Security scanner for your Terraform code

????tfsec uses static analysis of your terraform templates to spot potential security issues.

Dec 30, 2022
Know when GC runs from inside your golang code

gcnotifier gcnotifier provides a way to receive notifications after every run of the garbage collector (GC). Knowing when GC runs is useful to instruc

Dec 26, 2022
a Go code to detect leaks in JS files via regex patterns

a Go code to detect leaks in JS files via regex patterns

Nov 13, 2022