Skip to content

Commit 3594fc3

Browse files
authored
Merge pull request #1687 from Neon-White/upgrade-golangci-lint
Modify the `golangci-lint` pre-commit and Makefile flow
2 parents ffbbd4d + 7d37750 commit 3594fc3

File tree

3 files changed

+138
-46
lines changed

3 files changed

+138
-46
lines changed

.githooks/pre-commit

Lines changed: 7 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,11 @@
11
#!/bin/sh
2-
export PATH="$PATH:$(go env GOPATH)/bin"
32

4-
command -v golangci-lint >/dev/null 2>&1 || {
5-
echo "❌ golangci-lint not found – run 'make lint' to install it automatically"
6-
exit 1
7-
}
3+
# Pre-commit hook that runs golangci-lint on staged Go files
4+
# Uses the unified golangci-lint script
85

9-
# Get list of staged Go files
10-
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACMR | grep -E '\.go$' | sed 's| |\\ |g')
6+
# Get the directory of this script
7+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
8+
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
119

12-
# If there are no staged Go files, exit successfully
13-
if [ -z "$STAGED_FILES" ]; then
14-
echo "✅ No staged Go files were found, exiting"
15-
exit 0
16-
fi
17-
18-
# Run golangci-lint on staged files
19-
echo "Running golangci-lint on staged files..."
20-
BASE=$(git rev-parse --verify HEAD 2>/dev/null || echo "")
21-
if [ -z "$BASE" ]; then
22-
golangci-lint run $STAGED_FILES # initial commit – lint everything staged
23-
else
24-
golangci-lint run --new-from-rev="$BASE"
25-
fi
26-
27-
# Store the exit code
28-
LINT_EXIT_CODE=$?
29-
30-
# If golangci-lint found errors, exit with error
31-
if [ $LINT_EXIT_CODE -ne 0 ]; then
32-
echo "❌ golangci-lint found errors in staged files. Please fix them before committing."
33-
exit 1
34-
fi
35-
36-
echo "✅ golangci-lint passed!"
37-
38-
exit 0
10+
# Call the unified golangci-lint script in precommit mode
11+
exec "$PROJECT_ROOT/scripts/run-golangci-lint.sh" precommit

Makefile

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -184,18 +184,7 @@ test: lint test-go
184184
.PHONY: test
185185

186186
lint: gen
187-
@echo ""
188-
@if [ ! -f "$(GOBIN)/golangci-lint" ] || [ "v2.1.6" != "$$($(GOBIN)/golangci-lint --version 2>/dev/null | grep -o 'v[0-9]\+\.[0-9]\+\.[0-9]\+' || echo '')" ]; then \
189-
echo "Installing golangci-lint v2.1.6..."; \
190-
go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.1.6; \
191-
fi
192-
@if [ -n "$(FILES)" ]; then \
193-
echo "Running lint on changed files: $(FILES)"; \
194-
$(GOBIN)/golangci-lint run --config .golangci.yml $(FILES); \
195-
else \
196-
echo "Running lint on all files"; \
197-
$(GOBIN)/golangci-lint run --config .golangci.yml; \
198-
fi
187+
@./scripts/run-golangci-lint.sh makefile
199188
@echo "✅ lint"
200189
.PHONY: lint
201190

scripts/run-golangci-lint.sh

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
#!/bin/sh
2+
3+
# Unified golangci-lint runner script
4+
# Usage: ./scripts/run-golangci-lint.sh <mode>
5+
# Modes: precommit, makefile
6+
7+
# Uncomment this to see the commands being run
8+
# Note: We don't use 'set -e' because we need to handle golangci-lint's
9+
# exit codes manually to distinguish between linting issues and other errors
10+
# set -x
11+
12+
# Exit code used by golangci-lint when linting issues are found
13+
# Allows us to distinguish between linting issues and other errors
14+
readonly ISSUES_EXIT_CODE=42
15+
16+
MODE="${1}"
17+
18+
# Safely check whether Go is installed and set the GOPATH
19+
# Also check for GOBIN and add it to the PATH in case the binary was installed to a non-standard location
20+
if command -v go >/dev/null 2>&1; then
21+
GOBIN="$(go env GOBIN)"
22+
GOPATH_BIN="$(go env GOPATH)/bin"
23+
[ -n "${GOBIN}" ] && export PATH="${PATH}:${GOBIN}"
24+
export PATH="${PATH}:${GOPATH_BIN}"
25+
fi
26+
27+
# Function to install golangci-lint (for makefile mode)
28+
install_golangci_lint() {
29+
echo "Installing the latest golangci-lint with local toolchain"
30+
if ! go install -a "github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest"
31+
then
32+
echo "⚠️ Failed to install golangci-lint"
33+
exit 0
34+
fi
35+
}
36+
37+
# Function to run golangci-lint in precommit mode
38+
run_precommit_lint() {
39+
echo "Running golangci-lint in precommit mode..."
40+
41+
# Check if golangci-lint is available - exit gracefully if it isn't
42+
if ! command -v golangci-lint >/dev/null 2>&1
43+
then
44+
echo "⚠️ golangci-lint not found – run 'make lint' to install it automatically"
45+
exit 0
46+
fi
47+
48+
# Collect staged Go files as positional args
49+
# cached: retrieve only staged files
50+
# name-only: retrieve only the names of the files
51+
# diff-filter=ACMR: retrieve only the files that have been added, copied, modified, or renamed
52+
# grep -E '\.go$': retrieve only the files that end with .go
53+
# || true: if there are no staged Go files, return a zero-status exit code
54+
set -- $(git diff --cached --name-only --diff-filter=ACMR | grep -E '\.go$' || true)
55+
# If there are no staged Go files, exit successfully
56+
if [ "$#" -eq 0 ]; then
57+
echo "✅ No staged Go files were found, exiting"
58+
exit 0
59+
fi
60+
61+
echo "Running golangci-lint on staged files..."
62+
BASE=$(git rev-parse --verify HEAD 2>/dev/null || echo "")
63+
64+
if [ -z "${BASE}" ]
65+
then
66+
# Initial commit – lint only staged files
67+
golangci-lint run --issues-exit-code=${ISSUES_EXIT_CODE} --config .golangci.yml "${@}"
68+
else
69+
# Lint only staged changes vs HEAD
70+
golangci-lint run --issues-exit-code=${ISSUES_EXIT_CODE} --config .golangci.yml --new-from-rev="${BASE}" "${@}"
71+
fi
72+
73+
# Store the exit code
74+
LINT_EXIT_CODE=${?}
75+
76+
# Handle exit codes properly
77+
if [ ${LINT_EXIT_CODE} -eq ${ISSUES_EXIT_CODE} ]
78+
then
79+
echo "❌ golangci-lint found linting issues in staged files. Please fix them before committing."
80+
exit 1
81+
elif [ ${LINT_EXIT_CODE} -ne 0 ]
82+
then
83+
echo "⚠️ golangci-lint encountered an error (exit code: ${LINT_EXIT_CODE})"
84+
exit 0
85+
fi
86+
87+
echo "✅ golangci-lint passed!"
88+
}
89+
90+
# Function to run golangci-lint in makefile mode
91+
run_makefile_lint() {
92+
echo "Running golangci-lint in makefile mode..."
93+
94+
# Install golangci-lint if needed
95+
install_golangci_lint
96+
97+
echo "Running lint on all files"
98+
golangci-lint run --issues-exit-code=${ISSUES_EXIT_CODE} --config .golangci.yml
99+
100+
# Store the exit code
101+
LINT_EXIT_CODE=${?}
102+
103+
# Handle exit codes properly
104+
if [ ${LINT_EXIT_CODE} -eq ${ISSUES_EXIT_CODE} ]
105+
then
106+
echo "❌ golangci-lint found linting issues. Please fix them."
107+
exit 1
108+
elif [ ${LINT_EXIT_CODE} -ne 0 ]
109+
then
110+
echo "⚠️ golangci-lint encountered an error (exit code: ${LINT_EXIT_CODE})"
111+
exit 0
112+
fi
113+
114+
echo "✅ golangci-lint passed!"
115+
}
116+
117+
# Main logic
118+
case "${MODE}" in
119+
"precommit")
120+
run_precommit_lint
121+
;;
122+
"makefile")
123+
run_makefile_lint
124+
;;
125+
*)
126+
echo "Usage: ${0} <mode>"
127+
echo "Modes: precommit, makefile"
128+
exit 1
129+
;;
130+
esac

0 commit comments

Comments
 (0)