├── .github └── FUNDING.yml ├── .pre-commit-config.yaml ├── .pre-commit-hooks.yaml ├── LICENSE ├── README.md ├── go-build-mod.sh ├── go-build-pkg.sh ├── go-build-repo-mod.sh ├── go-build-repo-pkg.sh ├── go-critic.sh ├── go-fmt-repo.sh ├── go-fmt.sh ├── go-fumpt-repo.sh ├── go-fumpt.sh ├── go-imports-repo.sh ├── go-imports.sh ├── go-lint.sh ├── go-mod-tidy-repo.sh ├── go-mod-tidy.sh ├── go-returns-repo.sh ├── go-returns.sh ├── go-revive-mod.sh ├── go-revive-repo-mod.sh ├── go-revive.sh ├── go-sec-mod.sh ├── go-sec-pkg.sh ├── go-sec-repo-mod.sh ├── go-sec-repo-pkg.sh ├── go-staticcheck-mod.sh ├── go-staticcheck-pkg.sh ├── go-staticcheck-repo-mod.sh ├── go-staticcheck-repo-pkg.sh ├── go-structslop-mod.sh ├── go-structslop-pkg.sh ├── go-structslop-repo-mod.sh ├── go-structslop-repo-pkg.sh ├── go-test-mod.sh ├── go-test-pkg.sh ├── go-test-repo-mod.sh ├── go-test-repo-pkg.sh ├── go-vet-mod.sh ├── go-vet-pkg.sh ├── go-vet-repo-mod.sh ├── go-vet-repo-pkg.sh ├── go-vet.sh ├── golangci-lint-mod.sh ├── golangci-lint-pkg.sh ├── golangci-lint-repo-mod.sh ├── golangci-lint-repo-pkg.sh ├── golangci-lint.sh ├── lib ├── cmd-files.bash ├── cmd-mod.bash ├── cmd-pkg.bash ├── cmd-repo-mod.bash ├── cmd-repo-pkg.bash ├── cmd-repo.bash ├── common.bash └── prepare-my-cmd.bash ├── my-cmd-mod.sh ├── my-cmd-pkg.sh ├── my-cmd-repo-mod.sh ├── my-cmd-repo-pkg.sh ├── my-cmd-repo.sh ├── my-cmd.sh └── sample-config.yaml /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [TekWizely] 4 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | # ============================================================================== 2 | # See https://pre-commit.com for more information 3 | # See https://pre-commit.com/hooks.html for more hooks 4 | # ============================================================================== 5 | repos: 6 | - repo: https://github.com/pre-commit/pre-commit-hooks 7 | rev: v2.0.0 8 | hooks: 9 | - id: check-merge-conflict 10 | - id: trailing-whitespace 11 | - id: end-of-file-fixer 12 | - id: check-yaml 13 | # Bash helper hooks (local) 14 | # 15 | - repo: local 16 | hooks: 17 | # shellcheck (aliased to shck) 18 | # 19 | - id: shellcheck 20 | name: Run static analysis (shellcheck) 21 | entry: shellcheck 22 | language: system 23 | files: \.(sh|bash)$ 24 | types: [file] 25 | alias: shck 26 | args: [ '-x', '-e', 'SC2034' ] 27 | # shfmt 28 | # 29 | - id: shfmt 30 | name: Run lint check (shfmt -d) 31 | entry: shfmt 32 | language: system 33 | files: \.(sh|bash)$ 34 | types: [file] 35 | args: [ '-i', '0', '-ci', '-sr', '-d' ] 36 | # shfmt -w (must manually invoke) 37 | # 38 | - id: shfmtw 39 | name: Auto-fix lint errors (shfmt -w) 40 | entry: shfmt 41 | language: system 42 | stages: [manual] 43 | files: \.(sh|bash)$ 44 | types: [file] 45 | args: [ '-i', '0', '-ci', '-sr', '-kp', '-w' ] 46 | -------------------------------------------------------------------------------- /.pre-commit-hooks.yaml: -------------------------------------------------------------------------------- 1 | # ============================================================================== 2 | # my-cmd 3 | # * File-based 4 | # * Executes if any .go files modified 5 | # ============================================================================== 6 | - id: my-cmd 7 | name: 'my-cmd' 8 | entry: my-cmd.sh 9 | types: [go] 10 | exclude: '(^|/)vendor/' 11 | language: 'script' 12 | description: "Run '$ARGS[0] [$ARGS[1:]] $FILE' for each staged .go file" 13 | pass_filenames: true 14 | 15 | # ============================================================================== 16 | # my-cmd-mod 17 | # * Folder-Based 18 | # * Recursive 19 | # * Targets first parent folder with a go.mod file 20 | # * Executes if any .go files modified 21 | # * Executes if go.mod modified 22 | # ============================================================================== 23 | - id: my-cmd-mod 24 | name: 'my-cmd-mod' 25 | entry: my-cmd-mod.sh 26 | files: '(\.go$)|(\bgo\.mod$)' 27 | exclude: '(^|/)vendor/' 28 | language: 'script' 29 | description: "Run 'cd $(mod_root $FILE); $ARGS[0] [$ARGS[1:]] ./...' for each staged .go file" 30 | pass_filenames: true 31 | require_serial: true 32 | 33 | # ============================================================================== 34 | # my-cmd-pkg 35 | # * Folder-Based 36 | # * Targets folder containing staged file 37 | # * Executes if any .go files modified 38 | # ============================================================================== 39 | - id: my-cmd-pkg 40 | name: 'my-cmd-pkg' 41 | entry: my-cmd-pkg.sh 42 | types: [go] 43 | exclude: '(^|/)vendor/' 44 | language: 'script' 45 | description: "Run '$ARGS[0] [$ARGS[1:]] ./$(dirname $FILE)' for each staged .go file" 46 | pass_filenames: true 47 | require_serial: true 48 | 49 | # ============================================================================== 50 | # my-cmd-repo 51 | # * Repo-Based 52 | # * Recursive 53 | # * Executes if any .go files modified 54 | # ============================================================================== 55 | - id: my-cmd-repo 56 | name: 'my-cmd-repo' 57 | entry: my-cmd-repo.sh 58 | types: [go] 59 | exclude: '(^|/)vendor/' 60 | language: 'script' 61 | description: "Run '$ARGS[0] [$ARGS[1:]]' in the repo root folder" 62 | pass_filenames: false 63 | 64 | # ============================================================================== 65 | # my-cmd-repo-mod 66 | # * Repo-Based 67 | # * Recursive 68 | # * Targets ALL folders with a go.mod file 69 | # * Executes if any .go files modified 70 | # * Executes if go.mod modified 71 | # ============================================================================== 72 | - id: my-cmd-repo-mod 73 | name: 'my-cmd-repo-mod' 74 | entry: my-cmd-repo-mod.sh 75 | files: '(\.go$)|(\bgo\.mod$)' 76 | exclude: '(^|/)vendor/' 77 | language: 'script' 78 | description: "Run 'cd $(mod_root); $ARGS[0] [$ARGS[1:]] /...' for each module in the repo" 79 | pass_filenames: false 80 | 81 | # ============================================================================== 82 | # my-cmd-repo-pkg 83 | # * Repo-Based 84 | # * Recursive 85 | # * Executes if any .go files modified 86 | # ============================================================================== 87 | - id: my-cmd-repo-pkg 88 | name: 'my-cmd-repo-pkg' 89 | entry: my-cmd-repo-pkg.sh 90 | types: [go] 91 | exclude: '(^|/)vendor/' 92 | language: 'script' 93 | description: "Run '$ARGS[0] [$ARGS[1:]] ./...' in repo root folder" 94 | pass_filenames: false 95 | 96 | # ============================================================================== 97 | # go-build-mod 98 | # * Folder-Based 99 | # * Recursive 100 | # * Targets first parent folder with a go.mod file 101 | # * Executes if any .go files modified 102 | # * Executes if go.mod modified 103 | # ============================================================================== 104 | - id: go-build-mod 105 | name: 'go-build-mod' 106 | entry: go-build-mod.sh 107 | files: '(\.go$)|(\bgo\.mod$)' 108 | exclude: '(^|/)vendor/' 109 | language: 'script' 110 | description: "Run 'cd $(mod_root $FILE); go build -o /dev/null [$ARGS] ./...' for each staged .go file" 111 | pass_filenames: true 112 | require_serial: true 113 | 114 | # ============================================================================== 115 | # go-build-pkg 116 | # * Folder-Based 117 | # * Targets folder containing staged file 118 | # * Executes if any .go files modified 119 | # ============================================================================== 120 | - id: go-build-pkg 121 | name: 'go-build-pkg' 122 | entry: go-build-pkg.sh 123 | types: [go] 124 | exclude: '(^|/)vendor/' 125 | language: 'script' 126 | description: "Run 'go build -o /dev/null [$ARGS] ./$(dirname $FILE)' for each staged .go file" 127 | pass_filenames: true 128 | require_serial: true 129 | 130 | # ============================================================================== 131 | # go-build-repo-mod 132 | # * Repo-Based 133 | # * Recursive 134 | # * Targets ALL folders with a go.mod file 135 | # * Executes if any .go files modified 136 | # * Executes if go.mod modified 137 | # ============================================================================== 138 | - id: go-build-repo-mod 139 | name: 'go-build-repo-mod' 140 | entry: go-build-repo-mod.sh 141 | files: '(\.go$)|(\bgo\.mod$)' 142 | exclude: '(^|/)vendor/' 143 | language: 'script' 144 | description: "Run 'cd $(mod_root); go build -o /dev/null [$ARGS] ./...' for each module in the repo" 145 | pass_filenames: false 146 | 147 | # ============================================================================== 148 | # go-build-repo-pkg 149 | # * Repo-Based 150 | # * Recursive 151 | # * Executes if any .go files modified 152 | # ============================================================================== 153 | - id: go-build-repo-pkg 154 | name: 'go-build-repo-pkg' 155 | entry: go-build-repo-pkg.sh 156 | types: [go] 157 | exclude: '(^|/)vendor/' 158 | language: 'script' 159 | description: "Run 'go build -o /dev/null [$ARGS] ./...' in repo root folder" 160 | pass_filenames: false 161 | 162 | # ============================================================================== 163 | # go-critic 164 | # * File-based 165 | # * Executes if any .go files modified 166 | # ============================================================================== 167 | - id: go-critic 168 | name: 'go-critic' 169 | entry: go-critic.sh 170 | types: [go] 171 | exclude: '(^|/)vendor/' 172 | language: 'script' 173 | description: "Run 'gocritic check [$ARGS] $FILE' for each staged .go file" 174 | pass_filenames: true 175 | 176 | # ============================================================================== 177 | # go-fmt 178 | # * File-based 179 | # * Executes if any .go files modified 180 | # NOTES: 181 | # `go fmt` delegates to `gofmt`, so we'll invote `gofmt` directly. 182 | # ============================================================================== 183 | - id: go-fmt 184 | name: 'go-fmt' 185 | entry: go-fmt.sh 186 | types: [go] 187 | exclude: '(^|/)vendor/' 188 | language: 'script' 189 | description: "Run 'gofmt -l -d [$ARGS] $FILE' for each staged .go file" 190 | pass_filenames: true 191 | 192 | # ============================================================================== 193 | # go-fmt-repo 194 | # * Repo-Based 195 | # * Recursive 196 | # * Executes if any .go files modified 197 | # NOTES: 198 | # `go fmt` delegates to `gofmt`, so we'll invote `gofmt` directly. 199 | # ============================================================================== 200 | - id: go-fmt-repo 201 | name: 'go-fmt-repo' 202 | entry: go-fmt-repo.sh 203 | types: [go] 204 | exclude: '(^|/)vendor/' 205 | language: 'script' 206 | description: "Run 'gofmt -l -d [$ARGS] .' in repo root folder" 207 | pass_filenames: false 208 | 209 | # ============================================================================== 210 | # go-fumpt 211 | # * File-based 212 | # * Executes if any .go files modified 213 | # NOTES: 214 | # Replaces go-fmt 215 | # ============================================================================== 216 | - id: go-fumpt 217 | name: 'go-fumpt' 218 | entry: go-fumpt.sh 219 | types: [go] 220 | exclude: '(^|/)vendor/' 221 | language: 'script' 222 | description: "Run 'fumpt -l -d [$ARGS] $FILE' for each staged .go file" 223 | pass_filenames: true 224 | 225 | # ============================================================================== 226 | # go-fumpt-repo 227 | # * Repo-Based 228 | # * Recursive 229 | # * Executes if any .go files modified 230 | # NOTES: 231 | # Replaces go-fmt-repo 232 | # ============================================================================== 233 | - id: go-fumpt-repo 234 | name: 'go-fumpt-repo' 235 | entry: go-fumpt-repo.sh 236 | types: [go] 237 | exclude: '(^|/)vendor/' 238 | language: 'script' 239 | description: "Run 'fumpt -l -d [$ARGS] .' in repo root folder" 240 | pass_filenames: false 241 | 242 | # ============================================================================== 243 | # go-imports 244 | # * File-based 245 | # * Executes if any .go files modified 246 | # NOTES: 247 | # Replaces go-fmt 248 | # ============================================================================== 249 | - id: go-imports 250 | name: 'go-imports' 251 | entry: go-imports.sh 252 | types: [go] 253 | exclude: '(^|/)vendor/' 254 | language: 'script' 255 | description: "Run 'goimports -l -d [$ARGS] $FILE' for each staged .go file" 256 | pass_filenames: true 257 | 258 | # ============================================================================== 259 | # go-imports-repo 260 | # * Repo-Based 261 | # * Recursive 262 | # * Executes if any .go files modified 263 | # NOTES: 264 | # Replaces go-fmt-repo 265 | # ============================================================================== 266 | - id: go-imports-repo 267 | name: 'go-imports-repo' 268 | entry: go-imports-repo.sh 269 | types: [go] 270 | exclude: '(^|/)vendor/' 271 | language: 'script' 272 | description: "Run 'goimports -l -d [$ARGS] .' in repo root folder" 273 | pass_filenames: false 274 | 275 | # ============================================================================== 276 | # go-lint 277 | # * File-based 278 | # * Executes if any .go files modified 279 | # ============================================================================== 280 | - id: go-lint 281 | name: 'go-lint' 282 | entry: go-lint.sh 283 | types: [go] 284 | exclude: '(^|/)vendor/' 285 | language: 'script' 286 | description: "Run 'golint -set_exit_status [$ARGS] $FILE' for each staged .go file" 287 | pass_filenames: true 288 | 289 | # ============================================================================== 290 | # go-mod-tidy 291 | # * Folder-Based 292 | # * Recursive 293 | # * Targets first parent folder with a go.mod file 294 | # * Executes if any .go files modified 295 | # * Executes if go.mod modified 296 | # ============================================================================== 297 | - id: go-mod-tidy 298 | name: 'go-mod-tidy' 299 | entry: go-mod-tidy.sh 300 | files: '(\.go$)|(\bgo\.mod$)' 301 | exclude: '(^|/)vendor/' 302 | language: 'script' 303 | description: "Run 'cd $(mod_root $FILE); go mod tidy [$ARGS]' for each staged .go file" 304 | pass_filenames: true 305 | require_serial: true 306 | 307 | # ============================================================================== 308 | # go-mod-tidy-repo 309 | # * Repo-Based 310 | # * Recursive 311 | # * Targets ALL folders with a go.mod file 312 | # * Executes if any .go files modified 313 | # * Executes if go.mod modified 314 | # ============================================================================== 315 | - id: go-mod-tidy-repo 316 | name: 'go-mod-tidy-repo' 317 | entry: go-mod-tidy-repo.sh 318 | files: '(\.go$)|(\bgo\.mod$)' 319 | exclude: '(^|/)vendor/' 320 | language: 'script' 321 | description: "Run 'cd $(mod_root); go mod tidy [$ARGS]' for each module in the repo" 322 | pass_filenames: false 323 | 324 | # ============================================================================== 325 | # go-returns 326 | # * File-based 327 | # * Executes if any .go files modified 328 | # NOTES: 329 | # Replaces go-imports & go-fmt 330 | # ============================================================================== 331 | - id: go-returns 332 | name: 'go-returns' 333 | entry: go-returns.sh 334 | types: [go] 335 | exclude: '(^|/)vendor/' 336 | language: 'script' 337 | description: "Run 'goreturns -l -d [$ARGS] $FILE' for each staged .go file" 338 | pass_filenames: true 339 | 340 | # ============================================================================== 341 | # go-returns-repo 342 | # * Repo-Based 343 | # * Recursive 344 | # * Executes if any .go files modified 345 | # NOTES: 346 | # Replaces go-imports-repo & go-fmt-repo 347 | # ============================================================================== 348 | - id: go-returns-repo 349 | name: 'go-returns-repo' 350 | entry: go-returns-repo.sh 351 | types: [go] 352 | exclude: '(^|/)vendor/' 353 | language: 'script' 354 | description: "Run 'goreturns -l -d [$ARGS] .' in repo root folder" 355 | pass_filenames: false 356 | 357 | # ============================================================================== 358 | # go-revive 359 | # * File-based 360 | # * Executes if any .go files modified 361 | # * Executes if revive.toml modified 362 | # * Adds arg '-config=revive.toml' if present 363 | # NOTE: Does nothing if ONLY revive.toml is modified (ie no .go files modified) 364 | # ============================================================================== 365 | - id: go-revive 366 | name: 'go-revive' 367 | entry: go-revive.sh 368 | files: '(\.go$)|(\brevive\.toml$)' 369 | exclude: '(^|/)vendor/' 370 | language: 'script' 371 | description: "Run 'revive [$ARGS] $FILE' for each staged .go file" 372 | pass_filenames: true 373 | 374 | # ============================================================================== 375 | # go-revive-mod 376 | # * Folder-Based 377 | # * Recursive 378 | # * Targets first parent folder with a go.mod file 379 | # * Executes if any .go files modified 380 | # * Executes if go.mod modified 381 | # * Executes if revive.toml modified 382 | # * Adds arg '-config=revive.toml' if present 383 | # ============================================================================== 384 | - id: go-revive-mod 385 | name: 'go-revive-mod' 386 | entry: go-revive-mod.sh 387 | files: '(\.go$)|(\bgo\.mod$)|(\brevive\.toml$)' 388 | exclude: '(^|/)vendor/' 389 | language: 'script' 390 | description: "Run 'cd $(mod_root $FILE); revive [$ARGS] ./...' for each staged .go file" 391 | pass_filenames: true 392 | require_serial: true 393 | 394 | # ============================================================================== 395 | # go-revive-repo-mod 396 | # * Repo-Based 397 | # * Recursive 398 | # * Targets ALL folders with a go.mod file 399 | # * Executes if any .go files modified 400 | # * Executes if go.mod modified 401 | # * Executes if revive.toml modified 402 | # * Adds arg '-config=revive.toml' if present 403 | # ============================================================================== 404 | - id: go-revive-repo-mod 405 | name: 'go-revive-repo-mod' 406 | entry: go-revive-repo-mod.sh 407 | files: '(\.go$)|(\bgo\.mod$)|(\brevive\.toml$)' 408 | exclude: '(^|/)vendor/' 409 | language: 'script' 410 | description: "Run 'cd $(mod_root); revive [$ARGS] ./...' for each module in the repo" 411 | pass_filenames: false 412 | 413 | # ============================================================================== 414 | # go-sec-mod 415 | # * Folder-Based 416 | # * Recursive 417 | # * Targets first parent folder with a go.mod file 418 | # * Executes if any .go files modified 419 | # * Executes if go.mod modified 420 | # ============================================================================== 421 | - id: go-sec-mod 422 | name: 'go-sec-mod' 423 | entry: go-sec-mod.sh 424 | files: '(\.go$)|(\bgo\.mod$)' 425 | exclude: '(^|/)vendor/' 426 | language: 'script' 427 | description: "Run 'cd $(mod_root $FILE); gosec [$ARGS] ./...' for each staged .go file" 428 | pass_filenames: true 429 | require_serial: true 430 | 431 | # ============================================================================== 432 | # go-sec-pkg 433 | # * Folder-Based 434 | # * Targets folder containing staged file 435 | # * Executes if any .go files modified 436 | # ============================================================================== 437 | - id: go-sec-pkg 438 | name: 'go-sec-pkg' 439 | entry: go-sec-pkg.sh 440 | types: [go] 441 | exclude: '(^|/)vendor/' 442 | language: 'script' 443 | description: "Run 'gosec [$ARGS] ./$(dirname $FILE)' for each staged .go file" 444 | pass_filenames: true 445 | require_serial: true 446 | 447 | # ============================================================================== 448 | # go-sec-repo-mod 449 | # * Repo-Based 450 | # * Recursive 451 | # * Targets ALL folders with a go.mod file 452 | # * Executes if any .go files modified 453 | # * Executes if go.mod modified 454 | # ============================================================================== 455 | - id: go-sec-repo-mod 456 | name: 'go-sec-repo-mod' 457 | entry: go-sec-repo-mod.sh 458 | files: '(\.go$)|(\bgo\.mod$)' 459 | exclude: '(^|/)vendor/' 460 | language: 'script' 461 | description: "Run 'cd $(mod_root); gosec [$ARGS] ./...' for each module in the repo" 462 | pass_filenames: false 463 | 464 | # ============================================================================== 465 | # go-sec-repo-pkg 466 | # * Repo-Based 467 | # * Recursive 468 | # * Executes if any .go files modified 469 | # ============================================================================== 470 | - id: go-sec-repo-pkg 471 | name: 'go-sec-repo-pkg' 472 | entry: go-sec-repo-pkg.sh 473 | types: [go] 474 | exclude: '(^|/)vendor/' 475 | language: 'script' 476 | description: "Run 'gosec [$ARGS] ./...' in repo root folder" 477 | pass_filenames: false 478 | 479 | # ============================================================================== 480 | # go-staticcheck-mod 481 | # * Folder-Based 482 | # * Recursive 483 | # * Targets first parent folder with a go.mod file 484 | # * Executes if any .go files modified 485 | # * Executes if go.mod modified 486 | # ============================================================================== 487 | - id: go-staticcheck-mod 488 | name: 'go-staticcheck-mod' 489 | entry: go-staticcheck-mod.sh 490 | files: '(\.go$)|(\bgo\.mod$)' 491 | exclude: '(^|/)vendor/' 492 | language: 'script' 493 | description: "Run 'cd $(mod_root $FILE); staticcheck [$ARGS] ./...' for each staged .go file" 494 | pass_filenames: true 495 | require_serial: true 496 | 497 | # ============================================================================== 498 | # go-staticcheck-pkg 499 | # * Folder-Based 500 | # * Targets folder containing staged file 501 | # * Executes if any .go files modified 502 | # ============================================================================== 503 | - id: go-staticcheck-pkg 504 | name: 'go-staticcheck-pkg' 505 | entry: go-staticcheck-pkg.sh 506 | types: [go] 507 | exclude: '(^|/)vendor/' 508 | language: 'script' 509 | description: "Run 'staticcheck [$ARGS] ./$(dirname $FILE)' for each staged .go file" 510 | pass_filenames: true 511 | require_serial: true 512 | 513 | # ============================================================================== 514 | # go-staticcheck-repo-mod 515 | # * Repo-Based 516 | # * Recursive 517 | # * Targets ALL folders with a go.mod file 518 | # * Executes if any .go files modified 519 | # * Executes if go.mod modified 520 | # ============================================================================== 521 | - id: go-staticcheck-repo-mod 522 | name: 'go-staticcheck-repo-mod' 523 | entry: go-staticcheck-repo-mod.sh 524 | files: '(\.go$)|(\bgo\.mod$)' 525 | exclude: '(^|/)vendor/' 526 | language: 'script' 527 | description: "Run 'cd $(mod_root); staticcheck [$ARGS] ./...' for each module in the repo" 528 | pass_filenames: false 529 | 530 | # ============================================================================== 531 | # go-staticcheck-repo-pkg 532 | # * Repo-Based 533 | # * Recursive 534 | # * Executes if any .go files modified 535 | # ============================================================================== 536 | - id: go-staticcheck-repo-pkg 537 | name: 'go-staticcheck-repo-pkg' 538 | entry: go-staticcheck-repo-pkg.sh 539 | types: [go] 540 | exclude: '(^|/)vendor/' 541 | language: 'script' 542 | description: "Run 'staticcheck [$ARGS] ./...' in repo root folder" 543 | pass_filenames: false 544 | 545 | # ============================================================================== 546 | # go-structslop-mod 547 | # * Folder-Based 548 | # * Recursive 549 | # * Targets first parent folder with a go.mod file 550 | # * Executes if any .go files modified 551 | # * Executes if go.mod modified 552 | # ============================================================================== 553 | - id: go-structslop-mod 554 | name: 'go-structslop-mod' 555 | entry: go-structslop-mod.sh 556 | files: '(\.go$)|(\bgo\.mod$)' 557 | exclude: '(^|/)vendor/' 558 | language: 'script' 559 | description: "Run 'cd $(mod_root $FILE); structslop [$ARGS] ./...' for each staged .go file" 560 | pass_filenames: true 561 | require_serial: true 562 | 563 | # ============================================================================== 564 | # go-structslop-pkg 565 | # * Folder-Based 566 | # * Targets folder containing staged file 567 | # * Executes if any .go files modified 568 | # ============================================================================== 569 | - id: go-structslop-pkg 570 | name: 'go-structslop-pkg' 571 | entry: go-structslop-pkg.sh 572 | types: [go] 573 | exclude: '(^|/)vendor/' 574 | language: 'script' 575 | description: "Run 'structslop [$ARGS] ./$(dirname $FILE)' for each staged .go file" 576 | pass_filenames: true 577 | require_serial: true 578 | 579 | # ============================================================================== 580 | # go-structslop-repo-mod 581 | # * Repo-Based 582 | # * Recursive 583 | # * Targets ALL folders with a go.mod file 584 | # * Executes if any .go files modified 585 | # * Executes if go.mod modified 586 | # ============================================================================== 587 | - id: go-structslop-repo-mod 588 | name: 'go-structslop-repo-mod' 589 | entry: go-structslop-repo-mod.sh 590 | files: '(\.go$)|(\bgo\.mod$)' 591 | exclude: '(^|/)vendor/' 592 | language: 'script' 593 | description: "Run 'cd $(mod_root); structslop [$ARGS] ./...' for each module in the repo" 594 | pass_filenames: false 595 | 596 | # ============================================================================== 597 | # go-structslop-repo-pkg 598 | # * Repo-Based 599 | # * Recursive 600 | # * Executes if any .go files modified 601 | # ============================================================================== 602 | - id: go-structslop-repo-pkg 603 | name: 'go-structslop-repo-pkg' 604 | entry: go-structslop-repo-pkg.sh 605 | types: [go] 606 | exclude: '(^|/)vendor/' 607 | language: 'script' 608 | description: "Run 'structslop [$ARGS] ./...' in repo root folder" 609 | pass_filenames: false 610 | 611 | # ============================================================================== 612 | # go-test-mod 613 | # * Folder-Based 614 | # * Recursive 615 | # * Targets first parent folder with a go.mod file 616 | # * Executes if any .go files modified 617 | # * Executes if go.mod modified 618 | # ============================================================================== 619 | - id: go-test-mod 620 | name: 'go-test-mod' 621 | entry: go-test-mod.sh 622 | files: '(\.go$)|(\bgo\.mod$)' 623 | exclude: '(^|/)vendor/' 624 | language: 'script' 625 | description: "Run 'cd $(mod_root $FILE); go test [$ARGS] ./...' for each staged .go file" 626 | pass_filenames: true 627 | require_serial: true 628 | 629 | # ============================================================================== 630 | # go-test-pkg 631 | # * Folder-Based 632 | # * Targets folder containing staged file 633 | # * Executes if any .go files modified 634 | # ============================================================================== 635 | - id: go-test-pkg 636 | name: 'go-test-pkg' 637 | entry: go-test-pkg.sh 638 | types: [go] 639 | exclude: '(^|/)vendor/' 640 | language: 'script' 641 | description: "Run 'go test [$ARGS] ./$(dirname $FILE)' for each staged .go file" 642 | pass_filenames: true 643 | require_serial: true 644 | 645 | # ============================================================================== 646 | # go-test-repo-mod 647 | # * Repo-Based 648 | # * Recursive 649 | # * Targets ALL folders with a go.mod file 650 | # * Executes if any .go files modified 651 | # * Executes if go.mod modified 652 | # ============================================================================== 653 | - id: go-test-repo-mod 654 | name: 'go-test-repo-mod' 655 | entry: go-test-repo-mod.sh 656 | files: '(\.go$)|(\bgo\.mod$)' 657 | exclude: '(^|/)vendor/' 658 | language: 'script' 659 | description: "Run 'cd $(mod_root); go test [$ARGS] ./...' for each module in the repo" 660 | pass_filenames: false 661 | 662 | # ============================================================================== 663 | # go-test-repo-pkg 664 | # * Repo-Based 665 | # * Recursive 666 | # * Executes if any .go files modified 667 | # ============================================================================== 668 | - id: go-test-repo-pkg 669 | name: 'go-test-repo-pkg' 670 | entry: go-test-repo-pkg.sh 671 | types: [go] 672 | exclude: '(^|/)vendor/' 673 | language: 'script' 674 | description: "Run 'go test [$ARGS] ./...' in repo root folder" 675 | pass_filenames: false 676 | 677 | # ============================================================================== 678 | # go-vet-mod 679 | # * Folder-Based 680 | # * Recursive 681 | # * Targets first parent folder with a go.mod file 682 | # * Executes if any .go files modified 683 | # * Executes if go.mod modified 684 | # ============================================================================== 685 | - id: go-vet-mod 686 | name: 'go-vet-mod' 687 | entry: go-vet-mod.sh 688 | files: '(\.go$)|(\bgo\.mod$)' 689 | exclude: '(^|/)vendor/' 690 | language: 'script' 691 | description: "Run 'cd $(mod_root $FILE); go vet [$ARGS] ./...' for each staged .go file" 692 | pass_filenames: true 693 | require_serial: true 694 | 695 | # ============================================================================== 696 | # go-vet-pkg 697 | # * Folder-Based 698 | # * Targets folder containing staged file 699 | # * Executes if any .go files modified 700 | # ============================================================================== 701 | - id: go-vet-pkg 702 | name: 'go-vet-pkg' 703 | entry: go-vet-pkg.sh 704 | types: [go] 705 | exclude: '(^|/)vendor/' 706 | language: 'script' 707 | description: "Run 'go vet [$ARGS] ./$(dirname $FILE)' for each staged .go file" 708 | pass_filenames: true 709 | require_serial: true 710 | 711 | # ============================================================================== 712 | # go-vet-repo-mod 713 | # * Repo-Based 714 | # * Recursive 715 | # * Targets ALL folders with a go.mod file 716 | # * Executes if any .go files modified 717 | # * Executes if go.mod modified 718 | # ============================================================================== 719 | - id: go-vet-repo-mod 720 | name: 'go-vet-repo-mod' 721 | entry: go-vet-repo-mod.sh 722 | files: '(\.go$)|(\bgo\.mod$)' 723 | exclude: '(^|/)vendor/' 724 | language: 'script' 725 | description: "Run 'cd $(mod_root); go vet [$ARGS] ./...' for each module in the repo" 726 | pass_filenames: false 727 | 728 | # ============================================================================== 729 | # go-vet-repo-pkg 730 | # * Repo-Based 731 | # * Recursive 732 | # * Executes if any .go files modified 733 | # ============================================================================== 734 | - id: go-vet-repo-pkg 735 | name: 'go-vet-repo-pkg' 736 | entry: go-vet-repo-pkg.sh 737 | types: [go] 738 | exclude: '(^|/)vendor/' 739 | language: 'script' 740 | description: "Run 'go vet [$ARGS] ./...' in repo root folder" 741 | pass_filenames: false 742 | 743 | # ============================================================================== 744 | # go-vet 745 | # * File-based 746 | # * Executes if any .go files modified 747 | # NOTES: 748 | # `go vet` appears to work on single files when given them as args. 749 | # ============================================================================== 750 | - id: go-vet 751 | name: 'go-vet' 752 | entry: go-vet.sh 753 | types: [go] 754 | exclude: '(^|/)vendor/' 755 | language: 'script' 756 | description: "Run 'go vet [$ARGS] $FILE' for each staged .go file" 757 | pass_filenames: true 758 | 759 | # ============================================================================== 760 | # golangci-lint-mod 761 | # * Folder-Based 762 | # * Recursive 763 | # * Targets first parent folder with a go.mod file 764 | # * Executes if any .go files modified 765 | # * Executes if go.mod modified 766 | # ============================================================================== 767 | - id: golangci-lint-mod 768 | name: 'golangci-lint-mod' 769 | entry: golangci-lint-mod.sh 770 | files: '(\.go$)|(\bgo\.mod$)' 771 | exclude: '(^|/)vendor/' 772 | language: 'script' 773 | description: "Run 'cd $(mod_root $FILE); golangci-lint run [$ARGS] ./...' for each staged .go file" 774 | pass_filenames: true 775 | require_serial: true 776 | 777 | # ============================================================================== 778 | # golangci-lint-pkg 779 | # * Folder-Based 780 | # * Targets folder containing staged file 781 | # * Executes if any .go files modified 782 | # ============================================================================== 783 | - id: golangci-lint-pkg 784 | name: 'golangci-lint-pkg' 785 | entry: golangci-lint-pkg.sh 786 | types: [go] 787 | exclude: '(^|/)vendor/' 788 | language: 'script' 789 | description: "Run 'golangci-lint run [$ARGS] ./$(dirname $FILE)' for each staged .go file" 790 | pass_filenames: true 791 | require_serial: true 792 | 793 | # ============================================================================== 794 | # golangci-lint-repo-mod 795 | # * Repo-Based 796 | # * Recursive 797 | # * Targets ALL folders with a go.mod file 798 | # * Executes if any .go files modified 799 | # * Executes if go.mod modified 800 | # ============================================================================== 801 | - id: golangci-lint-repo-mod 802 | name: 'golangci-lint-repo-mod' 803 | entry: golangci-lint-repo-mod.sh 804 | files: '(\.go$)|(\bgo\.mod$)' 805 | exclude: '(^|/)vendor/' 806 | language: 'script' 807 | description: "Run 'cd $(mod_root); golangci-lint run [$ARGS] ./...' for each module in the repo" 808 | pass_filenames: false 809 | 810 | # ============================================================================== 811 | # golangci-lint-repo-pkg 812 | # * Repo-Based 813 | # * Recursive 814 | # * Executes if any .go files modified 815 | # ============================================================================== 816 | - id: golangci-lint-repo-pkg 817 | name: 'golangci-lint-repo-pkg' 818 | entry: golangci-lint-repo-pkg.sh 819 | types: [go] 820 | exclude: '(^|/)vendor/' 821 | language: 'script' 822 | description: "Run 'golangci-lint run [$ARGS] ./...' in repo root folder" 823 | pass_filenames: false 824 | 825 | # ============================================================================== 826 | # golangci-lint 827 | # * File-based 828 | # * Executes if any .go files modified 829 | # NOTES: 830 | # `golangci-lint` appears to work on single files when given them as args. 831 | # ============================================================================== 832 | - id: golangci-lint 833 | name: 'golangci-lint' 834 | entry: golangci-lint.sh 835 | types: [go] 836 | exclude: '(^|/)vendor/' 837 | language: 'script' 838 | description: "Run 'golangci-lint run [$ARGS] $FILE' for each staged .go file" 839 | pass_filenames: true 840 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019-2021 TekWize.ly 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pre-Commit-GoLang [![MIT license](https://img.shields.io/badge/License-MIT-green.svg)](https://github.com/tekwizely/pre-commit-golang/blob/master/LICENSE) 2 | 3 | A set of git pre-commit hooks for Golang with support for multi-module monorepos, the ability to pass arguments and environment variables to all hooks, and the ability to invoke custom go tools. 4 | 5 | Requires the [Pre-Commit.com](https://pre-commit.com) Hook Management Framework. 6 | 7 | --------------- 8 | ## Installation 9 | 10 | You can copy/paste the following snippet into your `.pre-commit-config.yaml` file. 11 | 12 | **NOTE** A more fleshed-out version can be found in [`sample-config.yaml`](https://github.com/TekWizely/pre-commit-golang/blob/master/sample-config.yaml) 13 | 14 | ```yaml 15 | # ========================================================================== 16 | # Golang Pre-Commit Hooks | https://github.com/tekwizely/pre-commit-golang 17 | # 18 | # !! ALL Hooks enabled by default - Comment out hooks you are not using 19 | # 20 | # Visit the project home page to learn more about the available Hooks, 21 | # including useful arguments you might want to pass into them. 22 | # 23 | # NOTE: When passing options to hooks, if your options contain a reference 24 | # to an existing file, then you will need to use a trailing '--' 25 | # argument to separate the hook options from the modified-file list 26 | # that Pre-Commit passes into the hook. 27 | # For repo-based hooks, '--' is not needed. 28 | # 29 | # NOTE: You can pass environment variables to hooks using args with the 30 | # following format: 31 | # 32 | # --hook:env:NAME=VALUE 33 | # 34 | # Consider adding aliases to longer-named hooks for easier CLI usage. 35 | # ========================================================================== 36 | - repo: https://github.com/tekwizely/pre-commit-golang 37 | rev: master 38 | hooks: 39 | # 40 | # Go Build 41 | # 42 | - id: go-build-mod 43 | - id: go-build-pkg 44 | - id: go-build-repo-mod 45 | - id: go-build-repo-pkg 46 | # 47 | # Go Mod Tidy 48 | # 49 | - id: go-mod-tidy 50 | - id: go-mod-tidy-repo 51 | # 52 | # Go Test 53 | # 54 | - id: go-test-mod 55 | - id: go-test-pkg 56 | - id: go-test-repo-mod 57 | - id: go-test-repo-pkg 58 | # 59 | # Go Vet 60 | # 61 | - id: go-vet 62 | - id: go-vet-mod 63 | - id: go-vet-pkg 64 | - id: go-vet-repo-mod 65 | - id: go-vet-repo-pkg 66 | # 67 | # Revive 68 | # 69 | - id: go-revive 70 | - id: go-revive-mod 71 | - id: go-revive-repo-mod 72 | # 73 | # GoSec 74 | # 75 | - id: go-sec-mod 76 | - id: go-sec-pkg 77 | - id: go-sec-repo-mod 78 | - id: go-sec-repo-pkg 79 | # 80 | # StaticCheck 81 | # 82 | - id: go-staticcheck-mod 83 | - id: go-staticcheck-pkg 84 | - id: go-staticcheck-repo-mod 85 | - id: go-staticcheck-repo-pkg 86 | # 87 | # StructSlop 88 | # 89 | - id: go-structslop-mod 90 | - id: go-structslop-pkg 91 | - id: go-structslop-repo-mod 92 | - id: go-structslop-repo-pkg 93 | # 94 | # Formatters 95 | # 96 | - id: go-fmt 97 | - id: go-fmt-repo 98 | - id: go-fumpt # replaces go-fmt 99 | - id: go-fumpt-repo # replaces go-fmt-repo 100 | - id: go-imports # replaces go-fmt 101 | - id: go-imports-repo # replaces go-fmt-repo 102 | - id: go-returns # replaces go-imports & go-fmt 103 | - id: go-returns-repo # replaces go-imports-repo & go-fmt-repo 104 | # 105 | # Style Checkers 106 | # 107 | - id: go-lint 108 | - id: go-critic 109 | # 110 | # GolangCI-Lint 111 | # - Fast Multi-Linter 112 | # - Can be configured to replace MOST other hooks 113 | # - Supports repo config file for configuration 114 | # - https://github.com/golangci/golangci-lint 115 | # 116 | - id: golangci-lint 117 | - id: golangci-lint-mod 118 | - id: golangci-lint-pkg 119 | - id: golangci-lint-repo-mod 120 | - id: golangci-lint-repo-pkg 121 | # 122 | # Invoking Custom Go Tools 123 | # - Configured *entirely* through the `args` attribute, ie: 124 | # args: [ go, test, ./... ] 125 | # - Use arg `--hook:error-on-output` to indicate that any output from the tool 126 | # should be treated as an error. 127 | # - Use the `name` attribute to provide better messaging when the hook runs 128 | # - Use the `alias` attribute to be able to invoke your hook via `pre-commit run` 129 | # 130 | - id: my-cmd 131 | - id: my-cmd-mod 132 | - id: my-cmd-pkg 133 | - id: my-cmd-repo 134 | - id: my-cmd-repo-mod 135 | - id: my-cmd-repo-pkg 136 | ``` 137 | 138 | ----------- 139 | ## Overview 140 | 141 | ### Hook Targets 142 | 143 | #### File-Based Hooks 144 | Some hooks run against matching staged files individually. 145 | 146 | ##### Module-Based Hooks 147 | Some hooks work on a per-module basis. The hooks run against module root folders containing one or more matching staged files. 148 | 149 | _Module Root Folder:_ A folder containing a `go.mod` file. Discovered by walking up the folder path from the staged file. 150 | 151 | ###### Module Mode 152 | Module-based hooks enable module mode (`GO111MODULE=on`) before invoking their respective tools. 153 | 154 | ##### Package-Based Hooks 155 | Some hooks work on a per-package basis. The hooks run against folders containing one or more staged files. 156 | 157 | _Package Folder:_ A folder containing one or more `.go` files. 158 | 159 | ###### Package Mode 160 | Package-based hooks disable module mode (`GO111MODULE=off`) before invoking their respective tools. 161 | 162 | ##### Repo-Based Hooks 163 | Some hooks run against the entire repo. The hooks only run once (if any matching files are staged), and are NOT provided the list of staged files, 164 | 165 | ----------------- 166 | ### Hook Suffixes 167 | Hooks have suffixes in their name that indicate their targets: 168 | 169 | | Suffix | Target | Description | 170 | |-------------|--------------|---------------------------------------------------| 171 | | \ | Files | Targets staged files directly | 172 | | `-mod` | Module | Targets module root folders of staged `.go` files | 173 | | `-pkg` | Package | Targets folders containing staged `.go` files | 174 | | `-repo` | Repo Root | Targets the repo root folder | 175 | | `-repo-mod` | All Modules | Targets all module root folders in the repo | 176 | | `-repo-pkg` | All Packages | Targets all package folders in the repo | 177 | 178 | ----------------------------- 179 | ### Multiple Hook Invocations 180 | Due to OS command-line-length limits, Pre-Commit can invoke a hook multiple times if a large number of files are staged. 181 | 182 | For file and repo-based hooks, this isn't an issue, but for module and package-based hooks, there is a potential for the hook to run against the same module or package multiple times, duplicating any errors or warnings. 183 | 184 | ------------------------- 185 | ### Invoking Custom Tools 186 | While this project includes builtin hooks for many popular go tools, it's not possible to include builtin hooks for every tool that users might want to use. 187 | 188 | To help accommodate those users, this project includes the ability to invoke custom go tools. 189 | 190 | See the [my-cmd](#my-cmd) hooks for more information. 191 | 192 | -------------------------- 193 | ### Useful Hook Parameters 194 | ``` 195 | - id: hook-id 196 | args: [arg1, arg2, ..., '--'] # Pass options ('--' is optional) 197 | always_run: true # Run even if no matching files staged 198 | alias: hook-alias # Create an alias 199 | verbose: true # Display output, even if no errors 200 | ``` 201 | 202 | #### Passing Options To Hooks 203 | You can pass options into individual hooks to customize tool behavior. 204 | 205 | If your options contain a reference to an existing file, then you 206 | will need to use a trailing `'--'` argument to separate the hook options from 207 | the modified-file list that Pre-Commit passes into the hook. 208 | 209 | **NOTE:** For repo-based hooks, `'--'` is not needed. 210 | 211 | See each hook's description below for some popular options that you might want to use. 212 | 213 | Additionally, you can view each tool's individual home page or help settings to learn about all the available options. 214 | 215 | #### Passing Environment Variables To Hooks 216 | You can pass environment variables to hooks to customize tool behavior. 217 | 218 | **NOTE:** The Pre-Commit framework does not directly support the ability to pass environment variables to hooks. 219 | 220 | This feature is enabled via support for a specially-formatted argument: 221 | 222 | * `--hook:env:NAME=VALUE` 223 | 224 | The hook script will detect this argument and set the variable `NAME` to the value `VALUE` before invoking the configured tool. 225 | 226 | You can pass multiple `--hook:env:` arguments. 227 | 228 | The arguments can appear anywhere in the `args:` list. 229 | 230 | #### Always Run 231 | By default, hooks ONLY run when matching file types (usually `*.go`) are staged. 232 | 233 | When configured to `"always_run"`, a hook is executed as if EVERY matching file were staged. 234 | 235 | #### Aliases / Names 236 | 237 | pre-commit supports the ability to assign both an `alias` and a `name` to a configured hook: 238 | 239 | | config | description | 240 | |--------|---------------------------------------------------------------------------------------------------------| 241 | | alias | (optional) allows the hook to be referenced using an additional id when using `pre-commit run ` | 242 | | name | (optional) override the name of the hook - shown during hook execution | 243 | 244 | These are beneficial for a couple of reasons: 245 | 246 | * Creating short names for long-named hooks for easier CLI usage: 247 | ``` 248 | # ... 249 | hooks: 250 | - id: go-build-repo-mod 251 | alias: build 252 | ``` 253 | _usage_ 254 | ``` 255 | $ pre-commit run build 256 | ``` 257 | 258 | * Having variations of a given hook with different configurations: 259 | ``` 260 | # ... 261 | hooks: 262 | - id: go-fmt 263 | 264 | # Add a second go-fmt hook with -w enabled 265 | # Configure so it only runs when manually invoked 266 | - id: go-fmt 267 | args: [ -w ] 268 | alias: go-fmtw-alias 269 | name: go-fmtw-name 270 | stages: [manual] 271 | ``` 272 | **NOTE:** When creating variations, take note that the `alias` is used to execute the hook, but the the `name` is used in the hook report. 273 | 274 | _usage: alias vs name_ 275 | ``` 276 | $ pre-commit run --hook-stage manual go-fmtw-alias 277 | 278 | go-fmtw-name................................Passed 279 | ``` 280 | 281 | #### Verbose Hook Output 282 | When the `"verbose"` flag is enabled, all output generated by the hook will be displayed, even if there were no errors. 283 | 284 | This can be useful, for example, for hooks that display warnings, but don't generate error codes for them. 285 | 286 | -------- 287 | ## Hooks 288 | 289 | - Build Tools 290 | - [go-build](#go-build) 291 | - [go-mod-tidy](#go-mod-tidy) 292 | - Correctness Checkers 293 | - [go-test](#go-test) 294 | - [go-vet](#go-vet) 295 | - [go-sec](#go-sec) 296 | - [go-staticcheck](#go-staticcheck) 297 | - [go-structslop](#go-structslop) 298 | - Formatters 299 | - [go-fmt](#go-fmt) 300 | - [go-fumpt](#go-fumpt) 301 | - [go-imports](#go-imports) 302 | - [go-returns](#go-returns) 303 | - Style Checkers 304 | - [go-lint](#go-lint) 305 | - [go-critic](#go-critic) 306 | - [go-revive](#go-revive) 307 | - GolangCI-Lint 308 | - [golangci-lint](#golangci-lint) 309 | - Invoking Custom Tools 310 | - [my-cmd](#my-cmd) 311 | 312 | ------------ 313 | ### go-build 314 | Compiles packages, along with their dependencies, but does not install the results. 315 | 316 | | Hook ID | Description 317 | |---------------------|------------ 318 | | `go-build-mod` | Run `'cd $(mod_root $FILE); go build -o /dev/null [$ARGS] ./...'` for each staged .go file 319 | | `go-build-pkg` | Run `'go build -o /dev/null [$ARGS] ./$(dirname $FILE)'` for each staged .go file 320 | | `go-build-repo-mod` | Run `'cd $(mod_root); go build -o /dev/null [$ARGS] ./...'` for each module in the repo 321 | | `go-build-repo-pkg` | Run `'go build -o /dev/null [$ARGS] ./...'` in repo root folder 322 | 323 | ##### Install 324 | Comes with Golang ( [golang.org](https://golang.org/) ) 325 | 326 | ##### Help 327 | - https://golang.org/cmd/go/#hdr-Compile_packages_and_dependencies 328 | - `go help build` 329 | 330 | --------------- 331 | ### go-mod-tidy 332 | Makes sure `go.mod` matches the source code in the module. 333 | 334 | | Hook ID | Description 335 | |--------------------|------------ 336 | | `go-mod-tidy` | Run `'cd $(mod_root $FILE); go mod tidy [$ARGS] ./...'` for each staged .go file 337 | | `go-mod-tidy-repo` | Run `'cd $(mod_root); go mod tidy [$ARGS] ./...'` for each module in the repo 338 | 339 | ##### Install 340 | Comes with Golang ( [golang.org](https://golang.org/) ) 341 | 342 | ##### Help 343 | - https://golang.org/ref/mod#go-mod-tidy 344 | - `go mod help tidy` 345 | 346 | ----------- 347 | ### go-test 348 | Automates testing, printing a summary of test results. 349 | 350 | | Hook ID | Description 351 | |--------------------|------------ 352 | | `go-test-mod` | Run `'cd $(mod_root $FILE); go test [$ARGS] ./...'` for each staged .go file 353 | | `go-test-pkg` | Run `'go test [$ARGS] ./$(dirname $FILE)'` for each staged .go file 354 | | `go-test-repo-mod` | Run `'cd $(mod_root); go test [$ARGS] ./...'` for each module in the repo 355 | | `go-test-repo-pkg` | Run `'go test [$ARGS] ./...'` in repo root folder 356 | 357 | ##### Install 358 | Comes with Golang ( [golang.org](https://golang.org/) ) 359 | 360 | ##### Help 361 | - https://golang.org/cmd/go/#hdr-Test_packages 362 | - `go help test` 363 | 364 | ---------- 365 | ### go-sec 366 | Inspects source code for security problems by scanning the Go AST. 367 | 368 | | Hook ID | Description 369 | |-------------------|------------ 370 | | `go-sec-mod` | Run `'cd $(mod_root $FILE); gosec [$ARGS] ./...'` for each staged .go file 371 | | `go-sec-pkg` | Run `'gosec [$ARGS] ./$(dirname $FILE)'` for each staged .go file 372 | | `go-sec-repo-mod` | Run `'cd $(mod_root); gosec [$ARGS] ./...'` for each module in the repo 373 | | `go-sec-repo-pkg` | Run `'gosec [$ARGS] ./...'` in repo root folder 374 | 375 | ##### Install (via [bingo](https://github.com/TekWizely/bingo)) 376 | ``` 377 | bingo install github.com/securego/gosec/v2/cmd/gosec 378 | ``` 379 | 380 | ##### Help 381 | - https://github.com/securego/gosec#usage 382 | - `gosec (no args)` 383 | 384 | ------------------ 385 | ### go-staticcheck 386 | A state of the art linter for the Go programming language. Using static analysis, it finds bugs and performance issues, offers simplifications, and enforces style rules. 387 | 388 | | Hook ID | Description 389 | |---------------------------|------------ 390 | | `go-staticcheck-mod` | Run `'cd $(mod_root $FILE); staticcheck [$ARGS] ./...'` for each staged .go file 391 | | `go-staticcheck-pkg` | Run `'staticcheck [$ARGS] ./$(dirname $FILE)'` for each staged .go file 392 | | `go-staticcheck-repo-mod` | Run `'cd $(mod_root); staticcheck [$ARGS] ./...'` for each module in the repo 393 | | `go-staticcheck-repo-pkg` | Run `'staticcheck [$ARGS] ./...'` in repo root folder 394 | 395 | ##### Install (via [bingo](https://github.com/TekWizely/bingo)) 396 | ``` 397 | bingo install honnef.co/go/tools/cmd/staticcheck 398 | ``` 399 | 400 | ##### Help 401 | - https://staticcheck.io/ 402 | - `staticcheck -h` 403 | 404 | ----------------- 405 | ### go-structslop 406 | Recommends struct field rearrangements to provide for maximum space/allocation efficiency. 407 | 408 | - Can modify files (see `-apply`) 409 | 410 | | Hook ID | Description 411 | |--------------------------|------------ 412 | | `go-structslop-mod` | Run `'cd $(mod_root $FILE); structslop [$ARGS] ./...'` for each staged .go file 413 | | `go-structslop-pkg` | Run `'structslop [$ARGS] ./$(dirname $FILE)'` for each staged .go file 414 | | `go-structslop-repo-mod` | Run `'cd $(mod_root); structslop [$ARGS] ./...'` for each module in the repo 415 | | `go-structslop-repo-pkg` | Run `'structslop [$ARGS] ./...'` in repo root folder 416 | 417 | ##### Install (via [bingo](https://github.com/TekWizely/bingo)) 418 | ``` 419 | bingo install github.com/orijtech/structslop/cmd/structslop 420 | ``` 421 | 422 | ##### Useful Args 423 | ``` 424 | -apply : apply suggested fixes 425 | ``` 426 | 427 | ##### Help 428 | - https://github.com/orijtech/structslop#usage 429 | - `structslop -h` 430 | 431 | ---------- 432 | ### go-vet 433 | Examines Go source code and reports suspicious constructs, such as 434 | Printf calls whose arguments do not align with the format string. Vet uses 435 | heuristics that do not guarantee all reports are genuine problems, but it 436 | can find errors not caught by the compilers. 437 | 438 | | Hook ID | Description 439 | |-------------------|------------ 440 | | `go-vet` | Run `'go vet [$ARGS] $FILE'` for each staged .go file 441 | | `go-vet-mod` | Run `'cd $(mod_root $FILE); go vet [$ARGS] ./...'` for each staged .go file 442 | | `go-vet-pkg` | Run `'go vet [$ARGS] ./$(dirname $FILE)'` for each staged .go file 443 | | `go-vet-repo-mod` | Run `'cd $(mod_root); go vet [$ARGS] ./...'` for each module in the repo 444 | | `go-vet-repo-pkg` | Run `'go vet [$ARGS] ./...'` in repo root folder 445 | 446 | ##### Install 447 | Comes with Golang ( [golang.org](https://golang.org/) ) 448 | 449 | ##### Help 450 | - https://golang.org/cmd/go/#hdr-Report_likely_mistakes_in_packages 451 | - `go doc cmd/vet` 452 | 453 | ---------- 454 | ### go-fmt 455 | Formats Go programs. It uses tabs for indentation and blanks for alignment. Alignment assumes that an editor is using a fixed-width font. 456 | 457 | - Can modify files (see `-w`) 458 | 459 | | Hook ID | Description 460 | |---------------|------------ 461 | | `go-fmt` | Run `'gofmt -l -d [$ARGS] $FILE'` for each staged .go file 462 | | `go-fmt-repo` | Run `'gofmt -l -d [$ARGS] .'` in repo root folder 463 | 464 | ##### Install 465 | Comes with Golang ( [golang.org](https://golang.org/) ) 466 | 467 | ##### Useful Args 468 | ``` 469 | -d=false : Hide diffs 470 | -s : Try to simplify code 471 | -w : Update source file directly 472 | ``` 473 | 474 | ##### Help 475 | - https://godoc.org/github.com/golang/go/src/cmd/gofmt 476 | - `gofmt -h` 477 | 478 | ------------ 479 | ### go-fumpt 480 | Enforce a stricter format than `gofmt`, while being backwards compatible. 481 | 482 | - Replaces `go-fmt` 483 | - Can modify files (see `-w`) 484 | 485 | | Hook ID | Description 486 | |-----------------|------------ 487 | | `go-fumpt` | Run `'gofumpt -l -d [$ARGS] $FILE'` for each staged .go file 488 | | `go-fumpt-repo` | Run `'gofumpt -l -d [$ARGS] .'` in repo root folder 489 | 490 | ##### Install (via [bingo](https://github.com/TekWizely/bingo)) 491 | ``` 492 | bingo install mvdan.cc/gofumpt 493 | ``` 494 | 495 | ##### Useful Args 496 | ``` 497 | -d=false : Hide diffs 498 | -extra : Enable extra rules which should be vetted by a human 499 | -s : Try to simplify code 500 | -w : Update source file directly 501 | ``` 502 | 503 | ##### Help 504 | - https://pkg.go.dev/mvdan.cc/gofumpt 505 | - `gofumpt -h` 506 | 507 | -------------- 508 | ### go-imports 509 | Updates your Go import lines, adding missing ones and removing unreferenced ones. 510 | 511 | - Replaces `go-fmt` 512 | - Can modify files (see `-w`) 513 | 514 | | Hook ID | Description 515 | |-------------------|------------ 516 | | `go-imports` | Run `'goimports -l -d [$ARGS] $FILE'` for each staged .go file 517 | | `go-imports-repo` | Run `'goimports -l -d [$ARGS] .'` in repo root folder 518 | 519 | ##### Install (via [bingo](https://github.com/TekWizely/bingo)) 520 | ``` 521 | bingo install golang.org/x/tools/cmd/goimports 522 | ``` 523 | 524 | ##### Useful Args 525 | ``` 526 | -d=false : Hide diffs 527 | -format-only : Do not fix imports, act ONLY as go-fmt 528 | -local prefixes : Add imports matching prefix AFTER 3rd party packages 529 | (prefixes = comma-separated list) 530 | -v : Verbose logging 531 | -w : Update source file directly 532 | ``` 533 | 534 | ##### Help 535 | - https://godoc.org/golang.org/x/tools/cmd/goimports 536 | - `goimports -h` 537 | 538 | -------------- 539 | ### go-returns 540 | Implements a Go pretty-printer (like `go-fmt`) that also adds zero-value return values as necessary to incomplete return statements. 541 | 542 | - Replaces `go-fmt` and `go-imports` 543 | - Can modify files (see `-w`) 544 | 545 | | Hook ID | Description 546 | |-------------------|------------ 547 | | `go-returns` | Run `'goreturns -l -d [$ARGS] $FILE'` for each staged .go file 548 | | `go-returns-repo` | Run `'goreturns -l -d [$ARGS] .'` in repo root folder 549 | 550 | ##### Install (via [bingo](https://github.com/TekWizely/bingo)) 551 | ``` 552 | bingo install github.com/sqs/goreturns 553 | ``` 554 | 555 | ##### Useful Args 556 | ``` 557 | -b : Remove bare returns 558 | -d=false : Hide diffs 559 | -i=false : Disable go-imports 560 | -local prefixes : Add imports matching prefix AFTER 3rd party packages 561 | (prefixes = comma-separated list) 562 | -p : Print non-fatal type-checking errors to STDERR 563 | -s : Try to simplify code 564 | -w : Update source file directly 565 | ``` 566 | 567 | ##### Help 568 | - https://godoc.org/github.com/sqs/goreturns 569 | - `goreturns -h` 570 | 571 | ----------- 572 | ### go-lint 573 | A linter for Go source code, meant to carry out the stylistic conventions put forth in [Effective Go](https://golang.org/doc/effective_go.html) and [CodeReviewComments](https://golang.org/wiki/CodeReviewComments). 574 | 575 | | Hook ID | Description 576 | |-----------|------------ 577 | | `go-lint` | Run `'golint -set_exit_status [$ARGS] $FILE'` for each staged .go file 578 | 579 | ##### Install (via [bingo](https://github.com/TekWizely/bingo)) 580 | ``` 581 | bingo install golang.org/x/lint/golint 582 | ``` 583 | 584 | ##### Help 585 | - https://godoc.org/golang.org/x/lint 586 | - `golint -h` 587 | - https://golang.org/doc/effective_go.html 588 | - https://golang.org/wiki/CodeReviewComments 589 | 590 | ------------- 591 | ### go-revive 592 | \~6x faster, stricter, configurable, extensible, and beautiful drop-in replacement for golint. 593 | 594 | | Hook ID | Description 595 | |-----------|------------ 596 | | `go-revive` | Run `'revive [$ARGS] $FILE'` for each staged .go file 597 | | `go-revive-mod` | Run `'cd $(mod_root $FILE); revive [$ARGS] ./...'` for each staged .go file 598 | | `go-revive-repo-mod` | Run `'cd $(mod_root); revive [$ARGS] ./...'` for each module in the repo 599 | 600 | ##### Support for Repository-Level Config 601 | As of time of writing, revive only auto-checks for configs in `${HOME}/revive.toml`, and doesn't check the local folder (ie. `${REPO_ROOT}/revive.toml`). 602 | 603 | To make revive more useful, these hooks add built-in support for a repository-level config file. 604 | 605 | ###### Auto-Configured 606 | These hooks are configured to auto-add `-config=revive.toml` when the file is present in the repository root. 607 | 608 | ###### Triggerred When Modified 609 | These hooks are configured to run when the repo-level `revive.toml` file is modified (and staged). 610 | 611 | **NOTE:** Although configured to run, the file-based `go-revive` hook will, by default, effectively _do nothing_ if there are no staged `.go` files to run against. 612 | 613 | ##### Install (via [bingo](https://github.com/TekWizely/bingo)) 614 | ``` 615 | bingo install github.com/mgechev/revive 616 | ``` 617 | 618 | ##### Useful Args 619 | ``` 620 | -config [PATH] : Path to config file (TOML) 621 | -exclude [PATTERN] : Pattern for files/directories/packages to be excluded from linting 622 | -formatter [NAME] : formatter to be used for the output 623 | ``` 624 | 625 | ##### Displaying Warnings 626 | By default, `revive` doesn't generate errors on warnings, so warning messages may not be displayed if there are no accompanying error messages. 627 | 628 | You can use the `"verbose: true"` hook configuration to always show hook output. 629 | 630 | ##### Help 631 | - https://github.com/mgechev/revive#usage 632 | - `revive -h` 633 | 634 | ------------- 635 | ### go-critic 636 | The most opinionated Go source code linter for code audit. 637 | 638 | | Hook ID | Description 639 | |-------------|------------ 640 | | `go-critic` | Run `'gocritic check [$ARGS] $FILE'` for each staged .go file 641 | 642 | ##### Install 643 | https://github.com/go-critic/go-critic#installation 644 | 645 | ##### Useful Args 646 | ``` 647 | -enableAll : Enable ALL checkers 648 | -enable checkers : comma-separated list of checkers to be enabled 649 | (can include #tags) 650 | -disable checkers : comma-separated list of checkers to be disabled 651 | (can include #tags) 652 | ``` 653 | **Tags** 654 | - `#diagnostic` 655 | - `#style` 656 | - `#opinionated` 657 | - `#performance` 658 | - `#experimental` 659 | 660 | #### Help 661 | - https://go-critic.github.io/overview 662 | - `gocritic check -help` 663 | 664 | ----------------- 665 | ### golangci-lint 666 | A FAST linter aggregator, with colored output, fewer false-positives, and support for yaml/toml configuration. 667 | 668 | - Manages multiple linters 669 | - Can replace many/most other hooks 670 | - Can report only new issues (see `--new`) 671 | - Can modify files (see `--fix`) 672 | 673 | | Hook ID | Description 674 | |--------------------------|------------ 675 | | `golangci-lint` | Run `'golangci-lint run [$ARGS] $FILE'` for each staged .go file 676 | | `golangci-lint-mod` | Run `'cd $(mod_root $FILE); golangci-lint run [$ARGS] ./...'` for each staged .go file 677 | | `golangci-lint-pkg` | Run `'golangci-lint run [$ARGS] ./$(dirname $FILE)'` for each staged .go file 678 | | `golangci-lint-repo-mod` | Run `'cd $(mod_root); golangci-lint run [$ARGS] ./...'` for each module in the repo 679 | | `golangci-lint-repo-pkg` | Run `'golangci-lint run [$ARGS] ./...'` in repo root folder 680 | 681 | ##### Install (via [bingo](https://github.com/TekWizely/bingo)) 682 | ``` 683 | bingo install github.com/golangci/golangci-lint/cmd/golangci-lint 684 | ``` 685 | ##### Useful Args 686 | ``` 687 | --config PATH : Specify config file 688 | --disable linters : Disable specific linter(s) 689 | --enable-all : Enable ALL linters 690 | --enable linters : Enable specific linter(s) 691 | --fast : Run only fast linters (from enabled linters sets) 692 | --fix : Fix found issues (if supported by linter) 693 | --new : Show only new issues (see help for further details) 694 | --no-config : don't read config file 695 | --presets presets : Enable presets of linters 696 | ``` 697 | **Presets** 698 | - `bugs` 699 | - `complexity` 700 | - `format` 701 | - `performance` 702 | - `style` 703 | - `unused` 704 | 705 | ##### Help 706 | - https://github.com/golangci/golangci-lint#quick-start 707 | - `golangci-lint run -h` 708 | 709 | ##### Config File Help: 710 | - https://github.com/golangci/golangci-lint#config-file 711 | - `golangci-lint config -h` 712 | 713 | ---------- 714 | ### my-cmd 715 | 716 | Using the `my-cmd-*` hooks, you can invoke custom go tools in various contexts. 717 | 718 | | Hook ID | Description 719 | |-------------------|------------ 720 | | `my-cmd` | Run `'$ARGS[0] [$ARGS[1:]] $FILE'` for each staged .go file 721 | | `my-cmd-mod` | Run `'cd $(mod_root $FILE); GO111MODULE=on $ARGS[0] [$ARGS[1:]]'` for each staged .go file 722 | | `my-cmd-pkg` | Run `'GO111MODULE=off $ARGS[0] [$ARGS[1:]] ./$(dirname $FILE)'` for each staged .go file 723 | | `my-cmd-repo` | Run `'$ARGS[0] [$ARGS[1:]]'` in the repo root folder 724 | | `my-cmd-repo-mod` | Run `'cd $(mod_root); GO111MODULE=on $ARGS[0] [$ARGS[1:]]'` for each module in the repo 725 | | `my-cmd-repo-pkg` | Run `'GO111MODULE=off $ARGS[0] [$ARGS[1:]]` in repo root folder 726 | 727 | #### Configuring the hooks 728 | 729 | The my-cmd hooks are configured **entirely** through the pre-commit `args` attribute, including specifying which tool to run (ie `$ARGS[0]` above). 730 | 731 | This includes the need to manually add the `./...` target for module-based tools that require it. 732 | 733 | #### Examples 734 | 735 | Here's an example of what it would look like to use the my-cmd hooks to invoke `go test` if it wasn't already included: 736 | 737 | _.pre-commit-config.yaml_ 738 | ``` 739 | # ... 740 | hooks: 741 | # Run 'cd $(mod_root $FILE); go test ./...' for each staged .go file 742 | - id: my-cmd-mod 743 | name: go-test-mod 744 | alias: go-test-mod 745 | args: [ go, test, ./... ] 746 | ``` 747 | 748 | ##### Names & Aliases 749 | 750 | It is recommended that you use both `name` and `alias` attributes when defining my-cmd hooks. 751 | 752 | The name will provide better messaging when the hook runs. 753 | 754 | The alias will enable you to invoke the hook manually from the command-line when needed (see `pre-commit help run`) 755 | 756 | ##### error-on-output 757 | 758 | Some tools, like `gofmt`, `goimports`, and `goreturns`, don't generate error codes, but instead expect the presence of any output to indicate warning/error conditions. 759 | 760 | The my-cmd hooks accept a `--hook:error-on-output` argument to indicate this behavior. 761 | 762 | Here's an example of what it would look like to use the my-cmd hooks to invoke `gofmt` if it wasn't already included: 763 | 764 | _.pre-commit-config.yaml_ 765 | ``` 766 | # ... 767 | hooks: 768 | # Run 'gofmt -l -d $FILE' for each staged .go file 769 | # Treat any output as indication of failure 770 | - id: my-cmd 771 | name: go-fmt 772 | alias: go-fmt 773 | args: [ gofmt, -l, -d, --hook:error-on-output] 774 | ``` 775 | 776 | **NOTE:** The plain `--error-on-output` option is now deprecated, but still supported, as long as it's the **very first** entry in the `args:` list. 777 | 778 | ---------- 779 | ## License 780 | 781 | The `tekwizely/pre-commit-golang` project is released under the [MIT](https://opensource.org/licenses/MIT) License. See `LICENSE` file. 782 | -------------------------------------------------------------------------------- /go-build-mod.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cmd=(go build -o /dev/null) 3 | . "$(dirname "${0}")/lib/cmd-mod.bash" 4 | -------------------------------------------------------------------------------- /go-build-pkg.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cmd=(go build -o /dev/null) 3 | . "$(dirname "${0}")/lib/cmd-pkg.bash" 4 | -------------------------------------------------------------------------------- /go-build-repo-mod.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cmd=(go build -o /dev/null) 3 | . "$(dirname "${0}")/lib/cmd-repo-mod.bash" 4 | -------------------------------------------------------------------------------- /go-build-repo-pkg.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cmd=(go build -o /dev/null) 3 | . "$(dirname "${0}")/lib/cmd-repo-pkg.bash" 4 | -------------------------------------------------------------------------------- /go-critic.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cmd=(gocritic check) 3 | . "$(dirname "${0}")/lib/cmd-files.bash" 4 | -------------------------------------------------------------------------------- /go-fmt-repo.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | error_on_output=1 3 | cmd=(gofmt -l -d) 4 | target=(.) 5 | . "$(dirname "${0}")/lib/cmd-repo.bash" 6 | -------------------------------------------------------------------------------- /go-fmt.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | error_on_output=1 3 | cmd=(gofmt -l -d) 4 | . "$(dirname "${0}")/lib/cmd-files.bash" 5 | -------------------------------------------------------------------------------- /go-fumpt-repo.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | error_on_output=1 3 | cmd=(gofumpt -l -d) 4 | target=(.) 5 | . "$(dirname "${0}")/lib/cmd-repo.bash" 6 | -------------------------------------------------------------------------------- /go-fumpt.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | error_on_output=1 3 | cmd=(gofumpt -l -d) 4 | . "$(dirname "${0}")/lib/cmd-files.bash" 5 | -------------------------------------------------------------------------------- /go-imports-repo.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | error_on_output=1 3 | cmd=(goimports -l -d) 4 | target=(.) 5 | . "$(dirname "${0}")/lib/cmd-repo.bash" 6 | -------------------------------------------------------------------------------- /go-imports.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | error_on_output=1 3 | cmd=(goimports -l -d) 4 | . "$(dirname "${0}")/lib/cmd-files.bash" 5 | -------------------------------------------------------------------------------- /go-lint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cmd=(golint -set_exit_status) 3 | . "$(dirname "${0}")/lib/cmd-files.bash" 4 | -------------------------------------------------------------------------------- /go-mod-tidy-repo.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | use_dot_dot_dot=0 3 | cmd=(go mod tidy) 4 | . "$(dirname "${0}")/lib/cmd-repo-mod.bash" 5 | -------------------------------------------------------------------------------- /go-mod-tidy.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | use_dot_dot_dot=0 3 | cmd=(go mod tidy) 4 | . "$(dirname "${0}")/lib/cmd-mod.bash" 5 | -------------------------------------------------------------------------------- /go-returns-repo.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | error_on_output=1 3 | cmd=(goreturns -l -d) 4 | target=(.) 5 | . "$(dirname "${0}")/lib/cmd-repo.bash" 6 | -------------------------------------------------------------------------------- /go-returns.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | error_on_output=1 3 | cmd=(goreturns -l -d) 4 | . "$(dirname "${0}")/lib/cmd-files.bash" 5 | -------------------------------------------------------------------------------- /go-revive-mod.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cmd=(revive) 3 | if [ -f "revive.toml" ]; then 4 | cmd+=( "-config=revive.toml" ) 5 | fi 6 | . "$(dirname "${0}")/lib/cmd-mod.bash" 7 | -------------------------------------------------------------------------------- /go-revive-repo-mod.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cmd=(revive) 3 | if [ -f "revive.toml" ]; then 4 | cmd+=( "-config=revive.toml" ) 5 | fi 6 | . "$(dirname "${0}")/lib/cmd-repo-mod.bash" 7 | -------------------------------------------------------------------------------- /go-revive.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cmd=(revive) 3 | if [ -f "revive.toml" ]; then 4 | cmd+=( "-config=revive.toml" ) 5 | fi 6 | ignore_file_pattern_array=( "revive.toml" ) 7 | . "$(dirname "${0}")/lib/cmd-files.bash" 8 | -------------------------------------------------------------------------------- /go-sec-mod.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cmd=(gosec) 3 | . "$(dirname "${0}")/lib/cmd-mod.bash" 4 | -------------------------------------------------------------------------------- /go-sec-pkg.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cmd=(gosec) 3 | . "$(dirname "${0}")/lib/cmd-pkg.bash" 4 | -------------------------------------------------------------------------------- /go-sec-repo-mod.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cmd=(gosec) 3 | . "$(dirname "${0}")/lib/cmd-repo-mod.bash" 4 | -------------------------------------------------------------------------------- /go-sec-repo-pkg.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cmd=(gosec) 3 | . "$(dirname "${0}")/lib/cmd-repo-pkg.bash" 4 | -------------------------------------------------------------------------------- /go-staticcheck-mod.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cmd=(staticcheck) 3 | . "$(dirname "${0}")/lib/cmd-mod.bash" 4 | -------------------------------------------------------------------------------- /go-staticcheck-pkg.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cmd=(staticcheck) 3 | . "$(dirname "${0}")/lib/cmd-pkg.bash" 4 | -------------------------------------------------------------------------------- /go-staticcheck-repo-mod.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cmd=(staticcheck) 3 | . "$(dirname "${0}")/lib/cmd-repo-mod.bash" 4 | -------------------------------------------------------------------------------- /go-staticcheck-repo-pkg.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cmd=(staticcheck) 3 | . "$(dirname "${0}")/lib/cmd-repo-pkg.bash" 4 | -------------------------------------------------------------------------------- /go-structslop-mod.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cmd=(structslop) 3 | . "$(dirname "${0}")/lib/cmd-mod.bash" 4 | -------------------------------------------------------------------------------- /go-structslop-pkg.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cmd=(structslop) 3 | . "$(dirname "${0}")/lib/cmd-pkg.bash" 4 | -------------------------------------------------------------------------------- /go-structslop-repo-mod.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cmd=(structslop) 3 | . "$(dirname "${0}")/lib/cmd-repo-mod.bash" 4 | -------------------------------------------------------------------------------- /go-structslop-repo-pkg.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cmd=(structslop) 3 | . "$(dirname "${0}")/lib/cmd-repo-pkg.bash" 4 | -------------------------------------------------------------------------------- /go-test-mod.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cmd=(go test) 3 | . "$(dirname "${0}")/lib/cmd-mod.bash" 4 | -------------------------------------------------------------------------------- /go-test-pkg.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cmd=(go test) 3 | . "$(dirname "${0}")/lib/cmd-pkg.bash" 4 | -------------------------------------------------------------------------------- /go-test-repo-mod.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cmd=(go test) 3 | . "$(dirname "${0}")/lib/cmd-repo-mod.bash" 4 | -------------------------------------------------------------------------------- /go-test-repo-pkg.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cmd=(go test) 3 | . "$(dirname "${0}")/lib/cmd-repo-pkg.bash" 4 | -------------------------------------------------------------------------------- /go-vet-mod.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cmd=(go vet) 3 | . "$(dirname "${0}")/lib/cmd-mod.bash" 4 | -------------------------------------------------------------------------------- /go-vet-pkg.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cmd=(go vet) 3 | . "$(dirname "${0}")/lib/cmd-pkg.bash" 4 | -------------------------------------------------------------------------------- /go-vet-repo-mod.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cmd=(go vet) 3 | . "$(dirname "${0}")/lib/cmd-repo-mod.bash" 4 | -------------------------------------------------------------------------------- /go-vet-repo-pkg.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cmd=(go vet) 3 | . "$(dirname "${0}")/lib/cmd-repo-pkg.bash" 4 | -------------------------------------------------------------------------------- /go-vet.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cmd=(go vet) 3 | . "$(dirname "${0}")/lib/cmd-files.bash" 4 | -------------------------------------------------------------------------------- /golangci-lint-mod.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cmd=(golangci-lint run) 3 | . "$(dirname "${0}")/lib/cmd-mod.bash" 4 | -------------------------------------------------------------------------------- /golangci-lint-pkg.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cmd=(golangci-lint run) 3 | . "$(dirname "${0}")/lib/cmd-pkg.bash" 4 | -------------------------------------------------------------------------------- /golangci-lint-repo-mod.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cmd=(golangci-lint run) 3 | . "$(dirname "${0}")/lib/cmd-repo-mod.bash" 4 | -------------------------------------------------------------------------------- /golangci-lint-repo-pkg.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cmd=(golangci-lint run) 3 | . "$(dirname "${0}")/lib/cmd-repo-pkg.bash" 4 | -------------------------------------------------------------------------------- /golangci-lint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cmd=(golangci-lint run) 3 | . "$(dirname "${0}")/lib/cmd-files.bash" 4 | -------------------------------------------------------------------------------- /lib/cmd-files.bash: -------------------------------------------------------------------------------- 1 | # shellcheck shell=bash 2 | 3 | # shellcheck source=./common.bash 4 | . "$(dirname "${0}")/lib/common.bash" 5 | 6 | prepare_file_hook_cmd "$@" 7 | 8 | error_code=0 9 | for file in "${FILES[@]}"; do 10 | if [ "${error_on_output:-}" -eq 1 ]; then 11 | output=$(/usr/bin/env "${ENV_VARS[@]}" "${cmd[@]}" "${OPTIONS[@]}" "${file}" 2>&1) 12 | if [ -n "${output}" ]; then 13 | printf "%s\n" "${output}" 14 | error_code=1 15 | fi 16 | elif ! /usr/bin/env "${ENV_VARS[@]}" "${cmd[@]}" "${OPTIONS[@]}" "${file}"; then 17 | error_code=1 18 | fi 19 | done 20 | exit $error_code 21 | -------------------------------------------------------------------------------- /lib/cmd-mod.bash: -------------------------------------------------------------------------------- 1 | # shellcheck shell=bash 2 | 3 | # shellcheck source=./common.bash 4 | . "$(dirname "${0}")/lib/common.bash" 5 | 6 | prepare_file_hook_cmd "$@" 7 | 8 | if [ "${use_dot_dot_dot:-}" -eq 1 ]; then 9 | OPTIONS+=('./...') 10 | fi 11 | export GO111MODULE=on 12 | error_code=0 13 | # Assume parent folder of go.mod is module root folder 14 | # 15 | for sub in $(find_module_roots "${FILES[@]}" | sort -u); do 16 | pushd "${sub}" > /dev/null || exit 1 17 | if [ "${error_on_output:-}" -eq 1 ]; then 18 | output=$(/usr/bin/env "${ENV_VARS[@]}" "${cmd[@]}" "${OPTIONS[@]}" 2>&1) 19 | if [ -n "${output}" ]; then 20 | printf "%s\n" "${output}" 21 | error_code=1 22 | fi 23 | elif ! /usr/bin/env "${ENV_VARS[@]}" "${cmd[@]}" "${OPTIONS[@]}"; then 24 | error_code=1 25 | fi 26 | popd > /dev/null || exit 1 27 | done 28 | exit $error_code 29 | -------------------------------------------------------------------------------- /lib/cmd-pkg.bash: -------------------------------------------------------------------------------- 1 | # shellcheck shell=bash 2 | 3 | # shellcheck source=./common.bash 4 | . "$(dirname "${0}")/lib/common.bash" 5 | 6 | prepare_file_hook_cmd "$@" 7 | 8 | export GO111MODULE=off 9 | error_code=0 10 | for sub in $(printf "%q\n" "${FILES[@]}" | xargs -n1 dirname | sort -u); do 11 | if [ "${error_on_output:-}" -eq 1 ]; then 12 | output=$(/usr/bin/env "${ENV_VARS[@]}" "${cmd[@]}" "${OPTIONS[@]}" "./${sub}" 2>&1) 13 | if [ -n "${output}" ]; then 14 | printf "%s\n" "${output}" 15 | error_code=1 16 | fi 17 | elif ! /usr/bin/env "${ENV_VARS[@]}" "${cmd[@]}" "${OPTIONS[@]}" "./${sub}"; then 18 | error_code=1 19 | fi 20 | done 21 | exit $error_code 22 | -------------------------------------------------------------------------------- /lib/cmd-repo-mod.bash: -------------------------------------------------------------------------------- 1 | # shellcheck shell=bash 2 | 3 | # shellcheck source=./common.bash 4 | . "$(dirname "${0}")/lib/common.bash" 5 | 6 | prepare_repo_hook_cmd "$@" 7 | 8 | if [ "${use_dot_dot_dot:-}" -eq 1 ]; then 9 | OPTIONS+=('./...') 10 | fi 11 | export GO111MODULE=on 12 | error_code=0 13 | # Assume parent folder of go.mod is module root folder 14 | # 15 | for sub in $(find . -name go.mod -not -path '*/vendor/*' -exec dirname "{}" ';' | sort -u); do 16 | pushd "${sub}" > /dev/null || exit 1 17 | if [ "${error_on_output:-}" -eq 1 ]; then 18 | output=$(/usr/bin/env "${ENV_VARS[@]}" "${cmd[@]}" "${OPTIONS[@]}" 2>&1) 19 | if [ -n "${output}" ]; then 20 | printf "%s\n" "${output}" 21 | error_code=1 22 | fi 23 | elif ! /usr/bin/env "${ENV_VARS[@]}" "${cmd[@]}" "${OPTIONS[@]}"; then 24 | error_code=1 25 | fi 26 | popd > /dev/null || exit 1 27 | done 28 | exit $error_code 29 | -------------------------------------------------------------------------------- /lib/cmd-repo-pkg.bash: -------------------------------------------------------------------------------- 1 | # shellcheck shell=bash 2 | 3 | # shellcheck source=./common.bash 4 | . "$(dirname "${0}")/lib/common.bash" 5 | 6 | prepare_repo_hook_cmd "$@" 7 | 8 | if [ "${use_dot_dot_dot:-}" -eq 1 ]; then 9 | OPTIONS+=('./...') 10 | fi 11 | export GO111MODULE=off 12 | if [ "${error_on_output:-}" -eq 1 ]; then 13 | output=$(/usr/bin/env "${ENV_VARS[@]}" "${cmd[@]}" "${OPTIONS[@]}" 2>&1) 14 | if [ -n "${output}" ]; then 15 | printf "%s\n" "${output}" 16 | exit 1 17 | fi 18 | else 19 | /usr/bin/env "${ENV_VARS[@]}" "${cmd[@]}" "${OPTIONS[@]}" 20 | fi 21 | -------------------------------------------------------------------------------- /lib/cmd-repo.bash: -------------------------------------------------------------------------------- 1 | # shellcheck shell=bash 2 | 3 | # shellcheck source=./common.bash 4 | . "$(dirname "${0}")/lib/common.bash" 5 | 6 | prepare_repo_hook_cmd "$@" 7 | 8 | # Add target after options 9 | # 10 | if [[ ${#target[@]} -gt 0 ]]; then 11 | OPTIONS+=("${target[@]}") 12 | fi 13 | if [ "${error_on_output:-}" -eq 1 ]; then 14 | output=$(/usr/bin/env "${ENV_VARS[@]}" "${cmd[@]}" "${OPTIONS[@]}" 2>&1) 15 | if [ -n "${output}" ]; then 16 | printf "%s\n" "${output}" 17 | exit 1 18 | fi 19 | else 20 | /usr/bin/env "${ENV_VARS[@]}" "${cmd[@]}" "${OPTIONS[@]}" 21 | fi 22 | -------------------------------------------------------------------------------- /lib/common.bash: -------------------------------------------------------------------------------- 1 | # shellcheck shell=bash 2 | 3 | : "${use_dot_dot_dot:=1}" 4 | : "${error_on_output:=0}" 5 | : "${ignore_file_pattern_array:=}" 6 | 7 | ## 8 | # prepare_file_hook_cmd 9 | # 10 | function prepare_file_hook_cmd { 11 | verify_hook_cmd 12 | parse_file_hook_args "$@" 13 | } 14 | 15 | ## 16 | # prepare_repo_hook_cmd 17 | # 18 | function prepare_repo_hook_cmd { 19 | verify_hook_cmd 20 | parse_repo_hook_args "$@" 21 | } 22 | 23 | ## 24 | # verify_hook_cmd 25 | # 26 | function verify_hook_cmd { 27 | # shellcheck disable=SC2154 # Fails if not defined by caller 28 | if [[ ${#cmd[@]} -eq 0 ]]; then 29 | printf "error: no command provided" >&2 30 | exit 1 31 | fi 32 | if ! type "${cmd[0]}" &> /dev/null; then 33 | printf "error: command not found: %s" "${cmd[0]}" >&2 34 | exit 1 35 | fi 36 | } 37 | 38 | ## 39 | # parse_file_hook_args 40 | # Creates global vars: 41 | # ENV_VARS: List of variables to assign+export before invoking command 42 | # OPTIONS : List of options to pass to command 43 | # FILES : List of files to process, filtered against ignore_file_pattern_array 44 | # 45 | # NOTE: We consume the first (optional) '--' we encounter. 46 | # If you want to pass '--' to the command, you'll need to use 2 of them 47 | # in hook args, i.e. "args: [..., '--', '--']" 48 | # 49 | function parse_file_hook_args { 50 | # Look for '--hook:*' options up to the first (optional) '--' 51 | # Anything else (including '--' and after) gets saved and passed to next step 52 | # Positional order of saved arguments is preserved 53 | # 54 | local ENV_REGEX='^[a-zA-Z_][a-zA-Z0-9_]*=.*$' 55 | ENV_VARS=() 56 | local __ARGS=() 57 | while [ $# -gt 0 ] && [ "$1" != "--" ]; do 58 | case "$1" in 59 | --hook:env:*) 60 | local env_var="${1#--hook:env:}" 61 | if [[ "${env_var}" =~ ${ENV_REGEX} ]]; then 62 | ENV_VARS+=("${env_var}") 63 | else 64 | printf "ERROR: Invalid hook:env variable: '%s'\n" "${env_var}" >&2 65 | exit 1 66 | fi 67 | shift 68 | ;; 69 | --hook:*) 70 | printf "ERROR: Unknown hook option: '%s'\n" "${1}" >&2 71 | exit 1 72 | ;; 73 | *) # preserve positional arguments 74 | __ARGS+=("$1") 75 | shift 76 | ;; 77 | esac 78 | done 79 | set -- "${__ARGS[@]}" "${@}" 80 | unset __ARGS 81 | OPTIONS=() 82 | # If arg doesn't pass [ -f ] check, then it is assumed to be an option 83 | # 84 | while [ $# -gt 0 ] && [ "$1" != "--" ] && [ ! -f "$1" ]; do 85 | OPTIONS+=("$1") 86 | shift 87 | done 88 | 89 | local all_files 90 | all_files=() 91 | # Assume start of file list (may still be options) 92 | # 93 | while [ $# -gt 0 ] && [ "$1" != "--" ]; do 94 | all_files+=("$1") 95 | shift 96 | done 97 | 98 | # If '--' next, then files = options 99 | # NOTE: We consume the '--' here 100 | # 101 | if [ "$1" == "--" ]; then 102 | shift 103 | # Append to previous options 104 | # 105 | OPTIONS+=("${all_files[@]}") 106 | all_files=() 107 | fi 108 | 109 | # Any remaining arguments are assumed to be files 110 | # 111 | all_files+=("$@") 112 | 113 | # Filter out vendor entries and ignore_file_pattern_array 114 | # 115 | FILES=() 116 | local file pattern 117 | ignore_file_pattern_array+=( "vendor/*" "*/vendor/*" "*/vendor" ) 118 | for file in "${all_files[@]}"; do 119 | for pattern in "${ignore_file_pattern_array[@]}"; do 120 | if [[ "${file}" == ${pattern} ]] ; then # pattern => unquoted 121 | continue 2 122 | fi 123 | done 124 | FILES+=("${file}") 125 | done 126 | } 127 | 128 | ## 129 | # parse_repo_hook_args 130 | # Creates global vars: 131 | # ENV_VARS: List of variables to assign+export before invoking command 132 | # OPTIONS : List of options to pass to command 133 | # 134 | # NOTE: For consistency with file hooks, 135 | # we consume the first (optional) '--' we encounter. 136 | # If you want to pass '--' to the command, you'll need to use 2 of them 137 | # in hook args, i.e. "args: [..., '--', '--']" 138 | # 139 | function parse_repo_hook_args { 140 | # Look for '--hook:*' options up to the first (optional) '--' 141 | # Consumes the first '--', treating anything after as OPTIONS 142 | # Positional order of OPTIONS is preserved 143 | # 144 | local ENV_REGEX='^[a-zA-Z_][a-zA-Z0-9_]*=.*$' 145 | ENV_VARS=() 146 | OPTIONS=() 147 | while [ $# -gt 0 ]; do 148 | case "$1" in 149 | --hook:env:*) 150 | local env_var="${1#--hook:env:}" 151 | if [[ "${env_var}" =~ ${ENV_REGEX} ]]; then 152 | ENV_VARS+=("${env_var}") 153 | else 154 | printf "ERROR: Invalid hook:env variable: '%s'\n" "${env_var}" >&2 155 | exit 1 156 | fi 157 | shift 158 | ;; 159 | --hook:*) 160 | printf "ERROR: Unknown hook option: '%s'\n" "${1}" >&2 161 | exit 1 162 | ;; 163 | --) # consume '--' and stop loop 164 | shift 165 | break 166 | ;; 167 | *) # preserve positional arguments 168 | OPTIONS+=("$1") 169 | shift 170 | ;; 171 | esac 172 | done 173 | # Any remaining items also considered OPTIONS 174 | # 175 | OPTIONS+=("$@") 176 | } 177 | 178 | ## 179 | # find_module_roots 180 | # Walks up the file path looking for go.mod 181 | # Prunes paths with /vendor/ in them 182 | # 183 | function find_module_roots() { 184 | local path 185 | for path in "$@"; do 186 | if [[ "${path}" == "vendor/"* || "${path}" == *"/vendor/"* || "${path}" == *"/vendor" ]]; then 187 | continue 188 | fi 189 | if [ "${path}" == "" ]; then 190 | path="." 191 | elif [ -f "${path}" ]; then 192 | path=$(dirname "${path}") 193 | fi 194 | while [ "${path}" != "." ] && [ ! -f "${path}/go.mod" ]; do 195 | path=$(dirname "${path}") 196 | done 197 | if [ -f "${path}/go.mod" ]; then 198 | printf "%s\n" "${path}" 199 | fi 200 | done 201 | } 202 | -------------------------------------------------------------------------------- /lib/prepare-my-cmd.bash: -------------------------------------------------------------------------------- 1 | # shellcheck shell=bash 2 | use_dot_dot_dot=0 3 | # Check for error-on-output 4 | # '--error-on-output' can *only* appear at the FRONT 5 | # !! NOTE: This is DEPRECATED and will be removed in a future version !! 6 | # 7 | if [[ "${1:-}" == "--error-on-output" ]]; then 8 | error_on_output=1 9 | shift 10 | fi 11 | # '--hook:error-on-output' can appear anywhere before (the optional) '--' 12 | # Anything else (including '--' and after) gets saved and passed to next step 13 | # Positional order of saved arguments is preserved 14 | # 15 | _ARGS=() 16 | while [ $# -gt 0 ] && [ "$1" != "--" ]; do 17 | case "$1" in 18 | --hook:error-on-output) 19 | error_on_output=1 20 | # We continue (vs break) in order to consume multiple occurrences 21 | # of the arg. VERY unlikely but let's be safe. 22 | # 23 | shift 24 | ;; 25 | *) # preserve positional arguments 26 | __ARGS+=("$1") 27 | shift 28 | ;; 29 | esac 30 | done 31 | set -- "${__ARGS[@]}" "${@}" 32 | unset __ARGS 33 | 34 | cmd=() 35 | if [ -n "${1:-}" ]; then 36 | cmd+=("${1}") 37 | shift 38 | fi 39 | -------------------------------------------------------------------------------- /my-cmd-mod.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | . "$(dirname "${0}")/lib/prepare-my-cmd.bash" 3 | . "$(dirname "${0}")/lib/cmd-mod.bash" 4 | -------------------------------------------------------------------------------- /my-cmd-pkg.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | . "$(dirname "${0}")/lib/prepare-my-cmd.bash" 3 | . "$(dirname "${0}")/lib/cmd-pkg.bash" 4 | -------------------------------------------------------------------------------- /my-cmd-repo-mod.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | . "$(dirname "${0}")/lib/prepare-my-cmd.bash" 3 | . "$(dirname "${0}")/lib/cmd-repo-mod.bash" 4 | -------------------------------------------------------------------------------- /my-cmd-repo-pkg.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | . "$(dirname "${0}")/lib/prepare-my-cmd.bash" 3 | . "$(dirname "${0}")/lib/cmd-repo-pkg.bash" 4 | -------------------------------------------------------------------------------- /my-cmd-repo.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | . "$(dirname "${0}")/lib/prepare-my-cmd.bash" 3 | . "$(dirname "${0}")/lib/cmd-repo.bash" 4 | -------------------------------------------------------------------------------- /my-cmd.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | . "$(dirname "${0}")/lib/prepare-my-cmd.bash" 3 | . "$(dirname "${0}")/lib/cmd-files.bash" 4 | -------------------------------------------------------------------------------- /sample-config.yaml: -------------------------------------------------------------------------------- 1 | # !! Requires Pre-Commit 2 | # !! https://pre-commit.com 3 | # !! Config File: $GIT_REPO_ROOT/.pre-commit-config.yaml 4 | # !! Already have a config file present? 5 | # !! Copy/Paste everything below `repos:` into your existing file 6 | # !! Don't already have a config file? 7 | # !! Copy this whole file into your repo root (as '.pre-commit-config.yaml') 8 | # !! Delete this header section 9 | # !! Consider adding some built-in pre-commmit hooks to your project 10 | # !! (They're quite useful!) 11 | # !! ALL Hooks enabled by default - Comment out hooks you are not using 12 | repos: 13 | # ========================================================================== 14 | # Golang Pre-Commit Hooks | https://github.com/tekwizely/pre-commit-golang 15 | # 16 | # Visit the project home page to learn more about the available Hooks, 17 | # including useful arguments you might want to pass into them. 18 | # 19 | # File-Based Hooks: 20 | # Run against matching staged files individually. 21 | # 22 | # Module-Based Hooks: 23 | # Run against module root folders containing matching staged files. 24 | # 25 | # Package-Based Hooks: 26 | # Run against folders containing one or more staged files. 27 | # 28 | # Repo-Based Hooks: 29 | # Run against the entire repo. 30 | # The hooks only run once (if any matching files are staged), 31 | # and are NOT provided the list of staged files, 32 | # 33 | # My-Cmd-* Hooks 34 | # Allow you to invoke custom tools in various contexts. 35 | # Can be useful if your favorite tool(s) are not built-in (yet) 36 | # 37 | # Hook Suffixes 38 | # Hooks have suffixes in their name that indicate their targets: 39 | # 40 | # +-----------+--------------+ 41 | # | Suffix | Target | 42 | # |-----------+--------------+ 43 | # | | Files | 44 | # | -mod | Module | 45 | # | -pkg | Package | 46 | # | -repo | Repo Root | 47 | # | -repo-mod | All Modules | 48 | # | -repo-pkg | All Packages | 49 | # +-----------+--------------+ 50 | # 51 | # ! Multiple Hook Invocations 52 | # ! Due to OS command-line-length limits, Pre-Commit can invoke a hook 53 | # ! multiple times if a large number of files are staged. 54 | # ! For file and repo-based hooks, this isn't an issue, but for module 55 | # ! and package-based hooks, there is a potential for the hook to run 56 | # ! against the same module or package multiple times, duplicating any 57 | # ! errors or warnings. 58 | # 59 | # Useful Hook Parameters: 60 | # - id: hook-id 61 | # args: [arg1, arg2, ..., '--'] # Pass options ('--' is optional) 62 | # always_run: true # Run even if no matching files staged 63 | # alias: hook-alias # Create an alias 64 | # 65 | # Passing Options To Hooks: 66 | # If your options contain a reference to an existing file, then you will 67 | # need to use a trailing '--' argument to separate the hook options from 68 | # the modified-file list that Pre-Commit passes into the hook. 69 | # NOTE: For repo-based hooks, '--' is not needed. 70 | # 71 | # Passing Environment Variables to Hooks: 72 | # You can pass environment variables to hooks using args with the 73 | # following format: 74 | # 75 | # --hook:env:NAME=VALUE 76 | # 77 | # Always Run: 78 | # By default, hooks ONLY run when matching file types are staged. 79 | # When configured to "always_run", a hook is executed as if EVERY matching 80 | # file were staged. 81 | # 82 | # Aliases: 83 | # Consider adding aliases to longer-named hooks for easier CLI usage. 84 | # ========================================================================== 85 | - repo: https://github.com/tekwizely/pre-commit-golang 86 | rev: master 87 | hooks: 88 | # 89 | # Go Build 90 | # 91 | - id: go-build-mod 92 | - id: go-build-pkg 93 | - id: go-build-repo-mod 94 | - id: go-build-repo-pkg 95 | # 96 | # Go Mod Tidy 97 | # 98 | - id: go-mod-tidy 99 | - id: go-mod-tidy-repo 100 | # 101 | # Go Test 102 | # 103 | - id: go-test-mod 104 | - id: go-test-pkg 105 | - id: go-test-repo-mod 106 | - id: go-test-repo-pkg 107 | # 108 | # Go Vet 109 | # 110 | - id: go-vet 111 | - id: go-vet-mod 112 | - id: go-vet-pkg 113 | - id: go-vet-repo-mod 114 | - id: go-vet-repo-pkg 115 | # 116 | # Revive 117 | # 118 | - id: go-revive 119 | - id: go-revive-mod 120 | - id: go-revive-repo-mod 121 | # 122 | # GoSec 123 | # 124 | - id: go-sec-mod 125 | - id: go-sec-pkg 126 | - id: go-sec-repo-mod 127 | - id: go-sec-repo-pkg 128 | # 129 | # StaticCheck 130 | # 131 | - id: go-staticcheck-mod 132 | - id: go-staticcheck-pkg 133 | - id: go-staticcheck-repo-mod 134 | - id: go-staticcheck-repo-pkg 135 | # 136 | # StructSlop 137 | # 138 | - id: go-structslop-mod 139 | - id: go-structslop-pkg 140 | - id: go-structslop-repo-mod 141 | - id: go-structslop-repo-pkg 142 | # 143 | # Formatters 144 | # 145 | - id: go-fmt 146 | - id: go-fmt-repo 147 | - id: go-fumpt # replaces go-fmt 148 | - id: go-fumpt-repo # replaces go-fmt-repo 149 | - id: go-imports # replaces go-fmt 150 | - id: go-imports-repo # replaces go-fmt-repo 151 | - id: go-returns # replaces go-imports & go-fmt 152 | - id: go-returns-repo # replaces go-imports-repo & go-fmt-repo 153 | # 154 | # Style Checkers 155 | # 156 | - id: go-lint 157 | - id: go-critic 158 | # 159 | # GolangCI-Lint 160 | # - Fast Multi-Linter 161 | # - Can be configured to replace MOST other hooks 162 | # - Supports repo config file for configuration 163 | # - https://github.com/golangci/golangci-lint 164 | # 165 | - id: golangci-lint 166 | - id: golangci-lint-mod 167 | - id: golangci-lint-pkg 168 | - id: golangci-lint-repo-mod 169 | - id: golangci-lint-repo-pkg 170 | # 171 | # Invoking Custom Go Tools 172 | # - Configured *entirely* through the `args` attribute, ie: 173 | # args: [ go, test, ./... ] 174 | # - Use arg `--hook:error-on-output` to indicate that any output from the tool 175 | # should be treated as an error. 176 | # - Use the `name` attribute to provide better messaging when the hook runs 177 | # - Use the `alias` attribute to be able to invoke your hook via `pre-commit run` 178 | # 179 | - id: my-cmd 180 | - id: my-cmd-mod 181 | - id: my-cmd-pkg 182 | - id: my-cmd-repo 183 | - id: my-cmd-repo-mod 184 | - id: my-cmd-repo-pkg 185 | --------------------------------------------------------------------------------