Skip to content

Commit

Permalink
feat(precommit): add tasks for registering and running precommit
Browse files Browse the repository at this point in the history
  • Loading branch information
sheldonhull committed Apr 16, 2022
1 parent eef1963 commit 4ad71c3
Show file tree
Hide file tree
Showing 10 changed files with 396 additions and 21 deletions.
68 changes: 68 additions & 0 deletions .examples/python3/installpython3.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
//go:build examples

// Overcomplicated example of installing python 3 with built in commands.
// Probably a much better way to do this with other packages, but I wanted to save this as one example.
// Additionally, I've reverted to using asdf or other tooling instead.
package main

import (
"fmt"
"os"
"os/exec"
"runtime"

"github.com/magefile/mage/sh"
"github.com/pterm/pterm"
)

//
// installPython3 is a setup helper to ensure python3 is setup on new systems for pre-commit tooling.
//
// Yes this should be done in Docker, or in OS, but in this case I'm trying to simplify bootstrap of a project and automatically handle pre-commit setup in case the environment doesn't have that already setup.
func installPython3() (string, error) { //nolint: cyclop // cyclop: acceptable as this is a cross platform installation function that tries to help setup a system with python if doesn't exist.
switch runtime.GOOS {
case "linux":
pterm.Info.Println("attempting to sudo install python3-pip")
_, err := os.Stat("apt-get")
if err != nil {
return "", fmt.Errorf(
"linux: automatic setup is only supported on debian based systems with apt-get command available: %w",
err,
)
}
if err := sh.RunV("sudo", "apt-get", "-yqq", "update"); err != nil {
pterm.Error.Println("running apt-get update")
return "", fmt.Errorf("linux: failed to apt-get update: %w", err)
}
pterm.Warning.Println("This can take 5-10 mins, depending on your system.")
if err := sh.RunV("sudo", "apt-get", "-yqq", "install", "python3-pip"); err != nil {
pterm.Error.Println("failed to sudo install python3-pip")
return "", fmt.Errorf("linux: failed to sudo install python3-pip: %w", err)
}
case "darwin":
pterm.Info.Println("will attempt to install with homebrew")
_, err := os.Stat("brew")
if err != nil {
return "", fmt.Errorf(
"darwin: automatic setup only works with homebrew installed. Try again after installing homebrew. https://docs.brew.sh/Installation: %w",
err,
)
}
if err := sh.RunV("brew", "install", "[email protected]"); err != nil {
return "", fmt.Errorf("failure on: brew install [email protected]: %w", err)
}
case "windows":
_, err := os.Stat("scoop")
if err != nil {
return "", fmt.Errorf(
"windows: automatic setup only works with Scoop installed. Try again after installing Scoop. https://github.com/ScoopInstaller/Scoop#installation: %w",
err,
)
}
if err := sh.RunV("scoop", "install", "python"); err != nil {
return "", fmt.Errorf("scoop install [email protected]: %w", err)
}
}
path, err := exec.LookPath("python3")
return path, err
}
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,5 @@ dist/
licensing/.licenses/
docker/.devcontainer
.artifacts/
precommit/.pre-commit.config.yaml
precommit/.pre-commit-config.yaml
6 changes: 4 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,11 @@ repos:
#entry: GOTESTS='slow' go test ./... -json -v -shuffle=on -race -tags integration | tparse -notests -smallscreen -pulse 1s
# no race conditions for this because we are doing build tasks here and not threadsafe to run parallel builds on every function
#entry: zsh -c "GOTESTS='superslow' go test ./... -json -v -shuffle=on -tags integration | tparse -notests -smallscreen -pulse 1s"
entry: zsh -c "(mkdir -p .artifacts/ || echo '.artifacts already exists') && GOTESTS='slow' GOTEST_FLAGS='--tags=integration' gotestsum --format pkgname --junitfile .artifacts/junit.xml --jsonfile
.artifacts/gotest.json -- -coverpkg=./... -coverprofile=.artifacts/cover.out -covermode atomic -shuffle=on -tags=integration ./..."
# entry: zsh -c "(mkdir -p .artifacts/ || echo '.artifacts already exists') && GOTESTS='slow' GOTEST_FLAGS='--tags=integration' gotestsum --format pkgname --junitfile .artifacts/junit.xml --jsonfile
# .artifacts/gotest.json -- -coverpkg=./... -coverprofile=.artifacts/cover.out -covermode atomic -shuffle=on -tags=integration ./..."
always_run: true # Always run full tests before push
entry: gotestsum
args: [./...]
stages: [commit]
types: [go]
language: golang
Expand Down
2 changes: 2 additions & 0 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
mage 1.13.0
golang 1.18.1
go-sdk 1.18.1
15 changes: 1 addition & 14 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,5 @@
"go.testEnvVars": {
"GOTESTS": "slow",
},
"workbench.colorCustomizations": {
"sash.hoverBorder": "#f1ba5b",
"statusBar.background": "#eda62c",
"statusBar.foreground": "#15202b",
"statusBarItem.hoverBackground": "#d48d12",
"statusBarItem.remoteBackground": "#eda62c",
"statusBarItem.remoteForeground": "#15202b",
"tab.activeBorder": "#f1ba5b",
"titleBar.activeBackground": "#eda62c",
"titleBar.activeForeground": "#15202b",
"titleBar.inactiveBackground": "#eda62c99",
"titleBar.inactiveForeground": "#15202b99"
},
"peacock.color": "#eda62c"
}
}
24 changes: 21 additions & 3 deletions gotools/gotools.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,19 @@ func (Go) Lint() error {
return nil
}

// 🔎 Run golangci-lint and apply any auto-fix.
func (Go) Fix() error {
magetoolsutils.CheckPtermDebug()

pterm.Info.Println("Running golangci-lint with --fix flag enabled.")
if err := sh.RunV("golangci-lint", "run", "--fix"); err != nil {
pterm.Error.WithShowLineNumber(true).WithLineNumberOffset(1).Println("golangci-lint failure")
return err
}
pterm.Success.Println("✅ Go Lint")
return nil
}

// ✨ Fmt runs gofumpt. Export SKIP_GOLINES=1 to skip golines.
// Important. Make sure golangci-lint config disables gci, goimports, and gofmt.
// This will perform all the sorting and other linters can cause conflicts in import ordering.
Expand Down Expand Up @@ -369,18 +382,23 @@ func (Go) LintConfig() error {
magetoolsutils.CheckPtermDebug()
pterm.DefaultHeader.Println("🏥 LintConfig Diagnostic Checks")
pterm.DefaultSection.Println("🔍 golangci-lint linters with --fast")
if err := sh.RunV("golangci-lint", "linters", "--fast"); err != nil {
var out string // using output instead of formatted colors straight to console so that test output with pterm can suppress.
var err error
out, err = sh.Output("golangci-lint", "linters", "--fast")
if err != nil {
pterm.Error.WithShowLineNumber(true).WithLineNumberOffset(1).Println("unable to run golangci-lint")
tracerr.PrintSourceColor(err)
return err
}
pterm.DefaultBox.Println(out)
pterm.DefaultSection.Println("🔍 golangci-lint linters with plain run")
if err := sh.RunV("golangci-lint", "linters"); err != nil {
out, err = sh.Output("golangci-lint", "linters")
if err != nil {
pterm.Error.WithShowLineNumber(true).WithLineNumberOffset(1).Println("unable to run golangci-lint")
tracerr.PrintSourceColor(err)
return err
}

pterm.DefaultBox.Println(out)
pterm.Success.Println("LintConfig Diagnostic Checks")
return nil
}
7 changes: 5 additions & 2 deletions magefiles/mage.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@ import (
"github.com/sheldonhull/magetools/fancy"

// mage:import
"github.com/sheldonhull/magetools/gotools"
"github.com/sheldonhull/magetools/gittools"

// mage:import
_ "github.com/sheldonhull/magetools/gittools" // gotools provides Git tooling to install git town and bit.
"github.com/sheldonhull/magetools/gotools"

// mage:import
_ "github.com/sheldonhull/magetools/licensing" // licensing provides a license checker and vendor tooling for the project
// mage:import
_ "github.com/sheldonhull/magetools/precommit"
)

// Default target to run when none is specified
Expand Down Expand Up @@ -65,6 +67,7 @@ func Init() { //nolint:deadcode // This is not dead code, and I find this insult
Clean,
createDirectories,
gotools.Go{}.Init,
gittools.Gittools{}.Init,
// tooling.SilentInstallTools(toolList),
)
}
Expand Down
149 changes: 149 additions & 0 deletions precommit/precommit.data.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
---
# IF ERROR ON INSTALL:
# brew uninstall pre-commit
# install with non-admin install this works on mac
# curl https://pre-commit.com/install-local.py | python -
# Setup: pre-commit install
# Upgrade: pre-commit autoupdate
# Run: pre-commit run --all-files
# https://pre-commit.com/hooks.html

default_language_version:
# force all unspecified python hooks to run python3
python: python3
exclude: (.terraform.lock.hcl)|(.devcontainer/)|(.cache/)|(.artifacts/)|(node_modules/)|(.yarn)|(ansible/)|(.licenses/)|(vendor/)
repos:

# https://github.com/jumanjihouse/pre-commit-hook-yamlfmt#override-defaults
# https://yaml.readthedocs.io/en/latest/example.html

- repo: https://github.com/jumanjihouse/pre-commit-hook-yamlfmt
rev: 0.1.0 # or specific tag
hooks:
- id: yamlfmt
args: [--mapping, '2', --sequence, '4', --offset, '2']
- repo: https://github.com/adrienverge/yamllint.git
rev: v1.26.3 # or higher tag
hooks:
- id: yamllint
args: [--format, parsable, --strict]

# Documentation on the arguments for these hooks https://github.com/pre-commit/pre-commit-hooks
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.0.1 # Use the ref you want to point at
hooks:
- id: trailing-whitespace
args: [--markdown-linebreak-ext=md]
- id: check-byte-order-marker
- id: check-case-conflict
- id: detect-aws-credentials
args: [--allow-missing-credentials]
- id: mixed-line-ending
args: [--fix=lf]
- id: pretty-format-json
exclude: ^.vscode/
args: [--autofix, --no-ensure-ascii]

- id: check-yaml
- id: detect-private-key
- id: end-of-file-fixer
- id: fix-byte-order-marker
- id: check-added-large-files
- id: check-merge-conflict
- id: forbid-new-submodules
- id: name-tests-test
- id: sort-simple-yaml
- id: no-commit-to-branch
args: [--branch, develop, --branch, master, --branch, main]
- id: requirements-txt-fixer
- id: check-toml
# Allows json to have comments which avoids a lot of false errors with things like vscode or other json configuration files.
- repo: https://gitlab.com/bmares/check-json5
rev: v1.0.0
hooks:
- id: check-json5

# https://pre-commit.com/#supported-languages
- repo: local
hooks:
- id: shellcheck
name: shellcheck
entry: zsh -c docker run --rm -v "${PWD}:/mnt" koalaman/shellcheck:stable --format=json
language: system

- repo: https://github.com/tchoedak/pre-commit-sql-format
rev: v0.0.3
hooks:
- id: format-sql

- repo: https://github.com/DavidAnson/markdownlint-cli2
rev: v0.3.2
hooks:
- id: markdownlint-cli2

- repo: local
hooks:
- id: gitleaks
name: gitleaks
entry: gitleaks --commit=latest --no-git --format json --path=. --report=.artifacts/gitleaks.json --quiet
language: system
pass_filenames: false
stages: [push]

# Go Local Hooks
- repo: local
hooks:
- id: golines
name: go-fmt
description: Run formatter against changed files
entry: mage go:wrap
types: [go]
language: golang
pass_filenames: true

- id: golangci-lint
name: golangci-lint
description: Run lint (normal) with fix applied.
entry: mage go:fix
types: [go]
language: golang
pass_filenames: false

# pre-commit run --hook-stage push
# This eventually needs to be tweaked to use the right tags and options for your environment.
# For example: -race might not be appropriate if doing Mage tests since they are designed to be run in parallel.
- id: gotest
name: go-test-all
description: Run integration tests for go
entry: zsh -c "GOTESTS='superslow' go test ./... -json -v -shuffle=on -race -tags integration | tparse -notests -smallscreen -pulse 1s"
always_run: true # Always run full tests before push
stages: [push]
types: [go]
language: golang
pass_filenames: false
verbose: true

# Can use mage task for go testing without integration flag and speed things up.
- id: gotest
name: go-test-fast
description: Run fast unit tests for go
entry: go test ./... -json -v -shuffle=on -race | tparse -notests -smallscreen -pulse 1s
stages: [commit]
types: [go]
language: golang
pass_filenames: false
verbose: true

- repo: local
hooks:
- id: gocover
name: gocover
entry: zsh -c 'go tool cover -func=".artifacts/cover.out" -o=".artifacts/coverage.out"'
language: system
stages: [commit]

- id: gobadge
name: gobadge
entry: gobadge -filename=.artifacts/coverage.out
language: system
stages: [commit]
Loading

0 comments on commit 4ad71c3

Please sign in to comment.