Skip to content

kenyoni-software/go-multisplit

Repository files navigation

Go MultiSplit

maintained License: MIT Programming Language

Go report card

Go MultiSplit is a go/analysis-based linter that detects when multiple identifiers are declared, assigned or listed together (e.g. var a, b int or a, b := 1, 2). It recommends splitting these into separate declarations or assignments to improve clarity and reduce ambiguity.

Options

No fix will be suggested

  • if a declaration or statement has a comment attached, to avoid changing the intent of the comment
  • if a multiple declaration or statement uses an anonymous struct type, to avoid duplicate code

All *-to-block options rewrite declarations into a grouped block. Grouped blocks will never be unblocked.

  • assign (default: false) Split assignments with multiple targets into individual assignments.

    Before:

    a, b = 1, 2

    After:

    a = 1
    b = 2
  • const-decl-func (default: false) Split const declarations with multiple identifiers inside functions into individual declarations.
    If const-decl-func-to-block (default: false) is enabled, the individual declarations are placed inside a const block.

    Before:

    func f() {
        const x, y = 1, 2
    }

    After (with const-decl-func-to-block=true):

    func f() {
        const (
            x = 1
            y = 2
        )
    }

    After (with const-decl-func-to-block=false):

    func f() {
        const x = 1
        const y = 2
    }
  • const-decl-pkg (default: true) Split const declarations with multiple identifiers at package scope into individual declarations.
    If const-decl-pkg-to-block (default: true) is enabled, the individual declarations are placed inside a const block.

    Before:

    const a, b = 1, 2

    After (with const-decl-pkg-to-block=true):

    const (
        a = 1
        b = 2
    )

    After (with const-decl-pkg-to-block=false):

    const a = 1
    const b = 2
  • func-params (default: true) Split function parameters with multiple identifiers into individual parameters.

    Before:

    func f(a, b int) {}

    After:

    func f(a int, b int) {}
  • func-return-values (default: true) Split function return values with multiple identifiers into individual return values.

    Before:

    func f() (a, b int) { return }

    After:

    func f() (a int, b int) { return }
  • short-var-decl (default: false) Split short variable declarations with multiple identifiers into individual declarations.

    Before:

    a, b := 1, 2

    After:

    a := 1
    b := 2
  • struct-fields (default: true) Split struct field declarations with multiple identifiers into individual fields.

    Before:

    type S struct {
        a, b int
    }

    After:

    type S struct {
        a int
        b int
    }
  • var-decl-func (default: false) Split var declarations with multiple identifiers inside function bodies into individual declarations.
    If var-decl-func-to-block (default: false) is enabled, the individual declarations are placed inside a var block.

    Before:

    func f() {
        var x, y int
    }

    After (with var-decl-func-to-block=true):

    func f() {
        var (
            x int
            y int
        )
    }

    After (with var-decl-func-to-block=false):

    func f() {
        var x int
        var y int
    }
  • var-decl-pkg (default: true)
    Split var declarations with multiple identifiers at package scope into individual declarations.
    If var-decl-pkg-to-block (default: true) is enabled, the individual declarations are placed inside a var block.

    Before:

    var a, b int

    After (with var-decl-pkg-to-block=true):

    var (
        a int
        b int
    )

    After (with var-decl-pkg-to-block=false):

    var a int
    var b int
  • var-decl-init-func (default: false) Split multiple var declarations with multiple identifiers and initializers inside functions into individual declarations.
    If var-decl-init-func-to-block (default: false) is enabled, the individual declarations are placed inside a var block.
    If var-decl-init-func-to-short (default: true) is enabled and the declarations are not placed in a block, any declaration without an explicit type will be rewritten to a short variable declaration (:=). The short form takes precedence when applicable.

    Before:

    func f() {
        var x, y = 1, 2
    }

    After (with var-decl-init-func-to-block=true):

    func f() {
        var (
            x = 1
            y = 2
        )
    }

    After (with var-decl-init-func-to-block=false):

    func f() {
        var x = 1
        var y = 2
    }

    After (with var-decl-init-func-to-short=true):

    func f() {
        x := 1
        y := 2
    }
  • var-decl-init-pkg (default: true) Split var declarations with multiple identifiers and initializers at package scope into individual declarations.
    If var-decl-init-pkg-to-block (default: true) is enabled, the individual declarations are placed inside a var block.

    Before:

    var a, b = 1, 2

    After (with var-decl-init-pkg-to-block=true):

    var (
        a = 1
        b = 2
    )

    After (with var-decl-init-pkg-to-block=false):

    var a = 1
    var b = 2

golangci-lint

You can integrate Go MultiSplit with golangci-lint by using the module plugin system. Create the following file and run golangci-lint custom to build the custom linter. Then you can use the resulting binary custom-gcl to run the linter on the codebase.

The following configuration uses the main branch of golangci-lint, if another version is required, change it to an explicit version like v2.0.0.

.custom-gcl.yml

version: main
plugins:
  - module: "github.com/kenyoni-software/go-multisplit"
    import: "github.com/kenyoni-software/go-multisplit/golangci-plugin"
    version: v1.1.3

Add MultiSplit to the .golangci.yml configuration:

.golangci.yml

version: "2"
linters:
  settings:
    custom:
      multisplit:
        type: "module"
        settings:
          # The set of rules to apply. If empty, the default rules will be applied.
          # Default: const-decl-pkg, func-params, func-return-values, struct-fields, var-decl-init-pkg, var-decl-pkg
          rules:
            - assign
            - var-decl-func
            - var-decl-pkg

          # If enabled rewrite const declarations with multiple identifiers inside functions into a const block.
          # Default: false
          const-decl-func-to-block: true
          # If enabled rewrite const declarations with multiple identifiers at package scope into a const block.
          # Default: true
          const-decl-pkg-to-block: false
          # If enabled rewrite var declarations with multiple identifiers inside functions into a const block.
          # Default: false
          var-decl-func-to-block: true
          # If enabled rewrite var declarations with multiple identifiers at package scope into a var block.
          # Default: true
          var-decl-pkg-to-block: false
          # If enabled rewrite var declarations with multiple identifiers and initializers inside functions into a var block.
          # Default: false
          var-decl-init-func-to-block: true
          # If enabled rewrite untyped var declarations with multiple identifiers inside functions into short declarations.
          # Default: true
          var-decl-init-func-to-short: false
          # If enabled rewrite var declarations with multiple identifiers and initializers at package scope into a var block.
          # Default: false
          var-decl-init-pkg-to-block: false

About

Detect multiple declarations, assignments, struct fields and function parameters or return values.

Topics

Resources

License

Stars

Watchers

Forks

Contributors