From 4ab2a6556a86b3ca2117cd995fd8fe32d143717c Mon Sep 17 00:00:00 2001 From: JackismyShephard Date: Wed, 6 Aug 2025 19:59:12 +0200 Subject: [PATCH] Add golangci-lint v2 hooks with formatting support --- .pre-commit-hooks.yaml | 131 +++++++++++++++++++++++++++++++++++ README.md | 82 ++++++++++++++++++++++ golangci-lint-v2-fmt-repo.sh | 3 + golangci-lint-v2-fmt.sh | 3 + golangci-lint-v2-mod.sh | 3 + golangci-lint-v2-pkg.sh | 3 + golangci-lint-v2-repo-mod.sh | 3 + golangci-lint-v2-repo-pkg.sh | 3 + golangci-lint-v2.sh | 3 + 9 files changed, 234 insertions(+) create mode 100755 golangci-lint-v2-fmt-repo.sh create mode 100755 golangci-lint-v2-fmt.sh create mode 100755 golangci-lint-v2-mod.sh create mode 100755 golangci-lint-v2-pkg.sh create mode 100755 golangci-lint-v2-repo-mod.sh create mode 100755 golangci-lint-v2-repo-pkg.sh create mode 100755 golangci-lint-v2.sh diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index a5703ea..446012a 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -837,3 +837,134 @@ language: 'script' description: "Run 'golangci-lint run [$ARGS] $FILE' for each staged .go file" pass_filenames: true + +# ============================================================================== +# golangci-lint-v2 +# * File-based +# * Executes if any .go files modified +# NOTES: +# `golangci-lint-v2` appears to work on single files when given them as args. +# This version uses golangci-lint v2 architecture which supports configuration +# files with `version: "2"` declarations. +# ============================================================================== +- id: golangci-lint-v2 + name: 'golangci-lint-v2' + entry: golangci-lint-v2.sh + types: [go] + exclude: '(^|/)vendor/' + language: 'script' + description: "Run 'golangci-lint-v2 run [$ARGS] $FILE' for each staged .go file" + pass_filenames: true + +# ============================================================================== +# golangci-lint-v2-mod +# * Folder-Based +# * Recursive +# * Targets first parent folder with a go.mod file +# * Executes if any .go files modified +# * Executes if go.mod modified +# NOTES: +# Uses golangci-lint v2 architecture which supports configuration +# files with `version: "2"` declarations. +# ============================================================================== +- id: golangci-lint-v2-mod + name: 'golangci-lint-v2-mod' + entry: golangci-lint-v2-mod.sh + files: '(\.go$)|(\bgo\.mod$)' + exclude: '(^|/)vendor/' + language: 'script' + description: "Run 'cd $(mod_root $FILE); golangci-lint-v2 run [$ARGS] ./...' for each staged .go file" + pass_filenames: true + require_serial: true + +# ============================================================================== +# golangci-lint-v2-pkg +# * Folder-Based +# * Targets folder containing staged file +# * Executes if any .go files modified +# NOTES: +# Uses golangci-lint v2 architecture which supports configuration +# files with `version: "2"` declarations. +# ============================================================================== +- id: golangci-lint-v2-pkg + name: 'golangci-lint-v2-pkg' + entry: golangci-lint-v2-pkg.sh + types: [go] + exclude: '(^|/)vendor/' + language: 'script' + description: "Run 'golangci-lint-v2 run [$ARGS] ./$(dirname $FILE)' for each staged .go file" + pass_filenames: true + require_serial: true + +# ============================================================================== +# golangci-lint-v2-repo-mod +# * Repo-Based +# * Recursive +# * Targets ALL folders with a go.mod file +# * Executes if any .go files modified +# * Executes if go.mod modified +# NOTES: +# Uses golangci-lint v2 architecture which supports configuration +# files with `version: "2"` declarations. +# ============================================================================== +- id: golangci-lint-v2-repo-mod + name: 'golangci-lint-v2-repo-mod' + entry: golangci-lint-v2-repo-mod.sh + files: '(\.go$)|(\bgo\.mod$)' + exclude: '(^|/)vendor/' + language: 'script' + description: "Run 'cd $(mod_root); golangci-lint-v2 run [$ARGS] ./...' for each module in the repo" + pass_filenames: false + +# ============================================================================== +# golangci-lint-v2-repo-pkg +# * Repo-Based +# * Recursive +# * Executes if any .go files modified +# NOTES: +# Uses golangci-lint v2 architecture which supports configuration +# files with `version: "2"` declarations. +# ============================================================================== +- id: golangci-lint-v2-repo-pkg + name: 'golangci-lint-v2-repo-pkg' + entry: golangci-lint-v2-repo-pkg.sh + types: [go] + exclude: '(^|/)vendor/' + language: 'script' + description: "Run 'golangci-lint-v2 run [$ARGS] ./...' in repo root folder" + pass_filenames: false + +# ============================================================================== +# golangci-lint-v2-fmt +# * File-based +# * Executes if any .go files modified +# NOTES: +# Uses golangci-lint v2's built-in fmt command which integrates with +# formatters configured in .golangci.yaml files with `version: "2"`. +# ============================================================================== +- id: golangci-lint-v2-fmt + name: 'golangci-lint-v2-fmt' + entry: golangci-lint-v2-fmt.sh + types: [go] + exclude: '(^|/)vendor/' + language: 'script' + description: "Run 'golangci-lint-v2 fmt [$ARGS] $FILE' for each staged .go file" + pass_filenames: true + +# ============================================================================== +# golangci-lint-v2-fmt-repo +# * Repo-based +# * Recursive +# * Executes if any .go files modified +# NOTES: +# Uses golangci-lint v2's built-in fmt command which integrates with +# formatters configured in .golangci.yaml files with `version: "2"`. +# ============================================================================== +- id: golangci-lint-v2-fmt-repo + name: 'golangci-lint-v2-fmt-repo' + entry: golangci-lint-v2-fmt-repo.sh + types: [go] + exclude: '(^|/)vendor/' + language: 'script' + description: "Run 'golangci-lint-v2 fmt [$ARGS] ./...' in repo root folder" + pass_filenames: false diff --git a/README.md b/README.md index b26e664..9e60370 100644 --- a/README.md +++ b/README.md @@ -120,6 +120,20 @@ You can copy/paste the following snippet into your `.pre-commit-config.yaml` fil - id: golangci-lint-repo-mod - id: golangci-lint-repo-pkg # + # GolangCI-Lint v2 + # - Fast Multi-Linter using v2 architecture + # - Supports config files with `version: "2"` + # - Includes built-in formatting command + # - Requires `golangci-lint-v2` binary + # + - id: golangci-lint-v2 + - id: golangci-lint-v2-mod + - id: golangci-lint-v2-pkg + - id: golangci-lint-v2-repo-mod + - id: golangci-lint-v2-repo-pkg + - id: golangci-lint-v2-fmt + - id: golangci-lint-v2-fmt-repo + # # Invoking Custom Go Tools # - Configured *entirely* through the `args` attribute, ie: # args: [ go, test, ./... ] @@ -416,6 +430,7 @@ This can be useful, for example, for hooks that display warnings, but don't gene - [go-revive](#go-revive) - GolangCI-Lint - [golangci-lint](#golangci-lint) + - [golangci-lint-v2](#golangci-lint-v2) - Invoking Custom Tools - [my-cmd](#my-cmd) @@ -820,6 +835,73 @@ bingo install github.com/golangci/golangci-lint/cmd/golangci-lint - https://github.com/golangci/golangci-lint#config-file - `golangci-lint config -h` +---------- +### golangci-lint-v2 +A FAST linter aggregator using golangci-lint v2 architecture, with enhanced colored output, fewer false-positives, and support for v2 yaml/toml configuration files. + + - Uses golangci-lint v2 architecture (supports `version: "2"` in config files) + - Manages multiple linters with improved performance + - Can replace many/most other hooks + - Can report only new issues (see `--new`) + - Can modify files (see `--fix`) + - Includes built-in formatting command (`fmt`) + +| Hook ID | Description | +|------------------------------|----------------------------------------------------------------------------------------------| +| `golangci-lint-v2` | Run `'golangci-lint-v2 run [$ARGS] $FILE'` for each staged .go file | +| `golangci-lint-v2-mod` | Run `'cd $(mod_root $FILE); golangci-lint-v2 run [$ARGS] ./...'` for each staged .go file | +| `golangci-lint-v2-pkg` | Run `'golangci-lint-v2 run [$ARGS] ./$(dirname $FILE)'` for each staged .go file | +| `golangci-lint-v2-repo-mod` | Run `'cd $(mod_root); golangci-lint-v2 run [$ARGS] ./...'` for each module in the repo | +| `golangci-lint-v2-repo-pkg` | Run `'golangci-lint-v2 run [$ARGS] ./...'` in repo root folder | +| `golangci-lint-v2-fmt` | Run `'golangci-lint-v2 fmt [$ARGS] $FILE'` for each staged .go file | +| `golangci-lint-v2-fmt-repo` | Run `'golangci-lint-v2 fmt [$ARGS] ./...'` in repo root folder | + +##### Install +``` +go install github.com/golangci/golangci-lint/cmd/golangci-lint-v2@latest +``` + +##### Configuration +The v2 hooks require a configuration file with `version: "2"` declared: +```yaml +# .golangci.yaml +version: "2" + +linters: + default: all # Enable all linters by default + settings: + staticcheck: + checks: ["all"] +formatters: + enable: + - goimports + - gofumpt +issues: + fix: true +``` + +##### Useful Args +``` + --config PATH : Specify config file (supports v2 format) + --disable linters : Disable specific linter(s) + --enable-all : Enable ALL linters + --enable linters : Enable specific linter(s) + --fast : Run only fast linters (from enabled linters sets) + --fix : Fix found issues (if supported by linter) + --new : Show only new issues (see help for further details) + --no-config : don't read config file + --presets presets : Enable presets of linters +``` + +##### Help + - https://github.com/golangci/golangci-lint#quick-start + - `golangci-lint-v2 run -h` + - `golangci-lint-v2 fmt -h` + +##### Config File Help: + - https://github.com/golangci/golangci-lint#config-file + - `golangci-lint-v2 config -h` + ---------- ### my-cmd diff --git a/golangci-lint-v2-fmt-repo.sh b/golangci-lint-v2-fmt-repo.sh new file mode 100755 index 0000000..ca5962a --- /dev/null +++ b/golangci-lint-v2-fmt-repo.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +cmd=(golangci-lint-v2 fmt) +. "$(dirname "${0}")/lib/cmd-repo-pkg.bash" \ No newline at end of file diff --git a/golangci-lint-v2-fmt.sh b/golangci-lint-v2-fmt.sh new file mode 100755 index 0000000..e97263b --- /dev/null +++ b/golangci-lint-v2-fmt.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +cmd=(golangci-lint-v2 fmt) +. "$(dirname "${0}")/lib/cmd-files.bash" \ No newline at end of file diff --git a/golangci-lint-v2-mod.sh b/golangci-lint-v2-mod.sh new file mode 100755 index 0000000..6ffda2d --- /dev/null +++ b/golangci-lint-v2-mod.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +cmd=(golangci-lint-v2 run) +. "$(dirname "${0}")/lib/cmd-mod.bash" \ No newline at end of file diff --git a/golangci-lint-v2-pkg.sh b/golangci-lint-v2-pkg.sh new file mode 100755 index 0000000..ed00543 --- /dev/null +++ b/golangci-lint-v2-pkg.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +cmd=(golangci-lint-v2 run) +. "$(dirname "${0}")/lib/cmd-pkg.bash" \ No newline at end of file diff --git a/golangci-lint-v2-repo-mod.sh b/golangci-lint-v2-repo-mod.sh new file mode 100755 index 0000000..4158f7a --- /dev/null +++ b/golangci-lint-v2-repo-mod.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +cmd=(golangci-lint-v2 run) +. "$(dirname "${0}")/lib/cmd-repo-mod.bash" \ No newline at end of file diff --git a/golangci-lint-v2-repo-pkg.sh b/golangci-lint-v2-repo-pkg.sh new file mode 100755 index 0000000..9c00c50 --- /dev/null +++ b/golangci-lint-v2-repo-pkg.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +cmd=(golangci-lint-v2 run) +. "$(dirname "${0}")/lib/cmd-repo-pkg.bash" \ No newline at end of file diff --git a/golangci-lint-v2.sh b/golangci-lint-v2.sh new file mode 100755 index 0000000..4d2acbe --- /dev/null +++ b/golangci-lint-v2.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +cmd=(golangci-lint-v2 run) +. "$(dirname "${0}")/lib/cmd-files.bash" \ No newline at end of file