Skip to content

Commit 611fca0

Browse files
Standing-Manhubcio
andauthored
fix(ci): honor staged file scope in lint hooks (#3188)
Co-authored-by: Hubert Gruszecki <h.gruszecki@gmail.com> d
1 parent 9a9254a commit 611fca0

6 files changed

Lines changed: 179 additions & 56 deletions

File tree

.pre-commit-config.yaml

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,18 @@ repos:
4343
- id: markdownlint
4444
name: markdownlint
4545
entry: ./scripts/ci/markdownlint.sh
46-
args: ["--fix", "--staged"]
46+
args: ["--fix"]
4747
language: system
4848
types: [markdown]
49-
pass_filenames: false
49+
pass_filenames: true
5050

5151
- id: shellcheck
5252
name: shellcheck
5353
entry: ./scripts/ci/shellcheck.sh
54-
args: ["--fix", "--staged"]
54+
args: ["--fix"]
5555
language: system
5656
types: [shell]
57-
pass_filenames: false
57+
pass_filenames: true
5858

5959
- id: license-headers
6060
name: license headers
@@ -106,41 +106,41 @@ repos:
106106
- id: trailing-whitespace
107107
name: trailing whitespace
108108
entry: ./scripts/ci/trailing-whitespace.sh
109-
args: ["--fix", "--staged"]
109+
args: ["--fix"]
110110
language: system
111111
types: [text]
112-
pass_filenames: false
112+
pass_filenames: true
113113

114114
- id: trailing-newline
115115
name: trailing newline
116116
entry: ./scripts/ci/trailing-newline.sh
117-
args: ["--fix", "--staged"]
117+
args: ["--fix"]
118118
language: system
119119
types: [text]
120-
pass_filenames: false
120+
pass_filenames: true
121121

122122
- id: binary-artifacts
123123
name: binary artifacts
124124
entry: ./scripts/ci/binary-artifacts.sh
125-
args: ["--check", "--staged"]
125+
args: ["--check"]
126126
language: system
127-
pass_filenames: false
127+
pass_filenames: true
128128

129129
- id: typos
130130
name: typos (spelling check)
131131
entry: typos
132132
args: [ "-w" ]
133133
language: system
134134
types: [ text ]
135-
pass_filenames: false
135+
pass_filenames: true
136136

137137
- id: taplo
138138
name: taplo (TOML format)
139139
entry: ./scripts/ci/taplo.sh
140-
args: ["--fix", "--staged"]
140+
args: ["--fix"]
141141
language: system
142142
types: [toml]
143-
pass_filenames: false
143+
pass_filenames: true
144144

145145
# Rust
146146
- repo: local

scripts/ci/markdownlint.sh

Lines changed: 58 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,73 @@
1818

1919
set -euo pipefail
2020

21-
# Parse arguments
2221
MODE="check"
23-
if [ $# -gt 0 ]; then
22+
FILE_MODE="all"
23+
FILES=()
24+
25+
# Accept mode flags plus optional file paths. In pre-commit, matching staged
26+
# markdown files are passed as positional arguments.
27+
while [[ $# -gt 0 ]]; do
2428
case "$1" in
2529
--check)
2630
MODE="check"
31+
shift
2732
;;
2833
--fix)
2934
MODE="fix"
35+
shift
3036
;;
31-
*)
32-
echo "Usage: $0 [--check|--fix]"
33-
echo " --check Check markdown files for issues (default)"
34-
echo " --fix Automatically fix markdown issues"
37+
--staged)
38+
FILE_MODE="staged"
39+
shift
40+
;;
41+
--all)
42+
FILE_MODE="all"
43+
shift
44+
;;
45+
--help|-h)
46+
echo "Usage: $0 [--check|--fix] [--staged|--all] [files...]"
47+
echo " --check Check markdown files for issues (default)"
48+
echo " --fix Automatically fix markdown issues"
49+
echo " --staged Check staged markdown files"
50+
echo " --all Check all markdown files (default)"
51+
exit 0
52+
;;
53+
-*)
54+
echo "Unknown option: $1"
55+
echo "Use --help for usage information"
3556
exit 1
3657
;;
58+
*)
59+
FILES+=("$1")
60+
shift
61+
;;
3762
esac
63+
done
64+
65+
# Files to ignore (in addition to .gitignore)
66+
# helm/charts/iggy/README.md is auto-generated by helm-docs
67+
IGNORE_ARGS=(--ignore "helm/charts/iggy/README.md")
68+
69+
# Keep --staged for manual runs; pre-commit normally passes matching staged
70+
# files directly through pass_filenames.
71+
if [ ${#FILES[@]} -eq 0 ] && [ "$FILE_MODE" = "staged" ]; then
72+
while IFS= read -r file; do
73+
[ -n "$file" ] && FILES+=("$file")
74+
done < <(git diff --cached --name-only --diff-filter=ACM -- '*.md')
75+
76+
if [ ${#FILES[@]} -eq 0 ]; then
77+
echo "✅ No staged markdown files to check"
78+
exit 0
79+
fi
80+
fi
81+
82+
# Default to the full repository for CI/manual runs, but use the explicit file
83+
# list when pre-commit or a caller passes paths directly.
84+
if [ ${#FILES[@]} -gt 0 ]; then
85+
TARGETS=("${FILES[@]}")
86+
else
87+
TARGETS=('**/*.md')
3888
fi
3989

4090
# Check if markdownlint is installed
@@ -44,17 +94,13 @@ if ! command -v markdownlint &> /dev/null; then
4494
exit 1
4595
fi
4696

47-
# Files to ignore (in addition to .gitignore)
48-
# helm/charts/iggy/README.md is auto-generated by helm-docs
49-
IGNORE_ARGS=(--ignore "helm/charts/iggy/README.md")
50-
5197
if [ "$MODE" = "fix" ]; then
5298
echo "🔧 Fixing markdown files..."
53-
markdownlint '**/*.md' --ignore-path .gitignore "${IGNORE_ARGS[@]}" --fix
99+
markdownlint "${TARGETS[@]}" --ignore-path .gitignore "${IGNORE_ARGS[@]}" --fix
54100
echo "✅ Markdown files have been fixed"
55101
else
56102
echo "🔍 Checking markdown files..."
57-
if markdownlint '**/*.md' --ignore-path .gitignore "${IGNORE_ARGS[@]}"; then
103+
if markdownlint "${TARGETS[@]}" --ignore-path .gitignore "${IGNORE_ARGS[@]}"; then
58104
echo "✅ All markdown files are properly formatted"
59105
else
60106
echo "❌ Markdown linting failed"

scripts/ci/shellcheck.sh

Lines changed: 96 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -20,36 +20,49 @@
2020

2121
set -euo pipefail
2222

23-
# Parse arguments
2423
MODE="check"
25-
if [ $# -gt 0 ]; then
24+
FILE_MODE="all"
25+
FILES=()
26+
27+
# Accept mode flags plus optional file paths. In pre-commit, matching staged
28+
# shell files are passed as positional arguments.
29+
while [[ $# -gt 0 ]]; do
2630
case "$1" in
2731
--check)
2832
MODE="check"
33+
shift
2934
;;
3035
--fix)
3136
MODE="fix"
37+
shift
3238
;;
33-
*)
34-
echo "Usage: $0 [--check|--fix]"
35-
echo " --check Check shell scripts for issues (default)"
36-
echo " --fix Show detailed suggestions for fixes"
39+
--staged)
40+
FILE_MODE="staged"
41+
shift
42+
;;
43+
--all)
44+
FILE_MODE="all"
45+
shift
46+
;;
47+
--help|-h)
48+
echo "Usage: $0 [--check|--fix] [--staged|--all] [files...]"
49+
echo " --check Check shell scripts for issues (default)"
50+
echo " --fix Show detailed suggestions for fixes"
51+
echo " --staged Check staged shell scripts"
52+
echo " --all Check all shell scripts (default)"
53+
exit 0
54+
;;
55+
-*)
56+
echo "Unknown option: $1"
57+
echo "Use --help for usage information"
3758
exit 1
3859
;;
60+
*)
61+
FILES+=("$1")
62+
shift
63+
;;
3964
esac
40-
fi
41-
42-
# Check if shellcheck is installed
43-
if ! command -v shellcheck &> /dev/null; then
44-
echo "❌ shellcheck command not found"
45-
echo "💡 Install it using:"
46-
echo " • Ubuntu/Debian: sudo apt-get install shellcheck"
47-
echo " • macOS: brew install shellcheck"
48-
echo " • Or visit: https://www.shellcheck.net/"
49-
exit 1
50-
fi
51-
52-
echo "shellcheck version: $(shellcheck --version)"
65+
done
5366

5467
# Get repository root
5568
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
@@ -75,22 +88,66 @@ for path in "${EXCLUDE_PATHS[@]}"; do
7588
FIND_EXCLUDE_ARGS+=("-not" "-path" "$path")
7689
done
7790

91+
# Keep --staged for manual runs; pre-commit normally passes matching staged
92+
# files directly through pass_filenames.
93+
if [ ${#FILES[@]} -eq 0 ] && [ "$FILE_MODE" = "staged" ]; then
94+
while IFS= read -r script; do
95+
if [ ! -f "$script" ]; then
96+
continue
97+
fi
98+
99+
# Match normal .sh files and executable scripts with shell shebangs.
100+
if [[ "$script" == *.sh ]] || head -n 1 "$script" | grep -qE '^#!.*[^[:alnum:]_](bash|dash|ksh|zsh|sh)([[:space:]]|$)'; then
101+
FILES+=("$script")
102+
fi
103+
done < <(git diff --cached --name-only --diff-filter=ACM)
104+
105+
if [ ${#FILES[@]} -eq 0 ]; then
106+
echo "✅ No staged shell scripts to check"
107+
exit 0
108+
fi
109+
fi
110+
111+
# Check if shellcheck is installed
112+
if ! command -v shellcheck &> /dev/null; then
113+
echo "❌ shellcheck command not found"
114+
echo "💡 Install it using:"
115+
echo " • Ubuntu/Debian: sudo apt-get install shellcheck"
116+
echo " • macOS: brew install shellcheck"
117+
echo " • Or visit: https://www.shellcheck.net/"
118+
exit 1
119+
fi
120+
121+
echo "shellcheck version: $(shellcheck --version)"
122+
78123
if [ "$MODE" = "fix" ]; then
79124
echo "🔧 Running shellcheck with detailed suggestions..."
80125
echo ""
81126
echo "Note: shellcheck does not support automatic fixing."
82127
echo "Please review the suggestions below and fix issues manually."
83128
echo ""
84129

85-
# Run with detailed format
86130
FAILED=0
87-
while IFS= read -r -d '' script; do
88-
echo "Checking: $script"
89-
if ! shellcheck -x -f gcc "$script"; then
90-
FAILED=1
91-
fi
92-
echo ""
93-
done < <(find . -type f -name "*.sh" "${FIND_EXCLUDE_ARGS[@]}" -print0)
131+
# Use staged or explicitly provided files when present; otherwise keep the
132+
# historical full-repository behavior for CI/manual all-file checks.
133+
if [ ${#FILES[@]} -gt 0 ]; then
134+
for script in "${FILES[@]}"; do
135+
[ -f "$script" ] || continue
136+
echo "Checking: $script"
137+
if ! shellcheck -x -f gcc "$script"; then
138+
FAILED=1
139+
fi
140+
echo ""
141+
done
142+
else
143+
while IFS= read -r -d '' script; do
144+
echo "Checking: $script"
145+
if ! shellcheck -x -f gcc "$script"; then
146+
FAILED=1
147+
fi
148+
echo ""
149+
done < <(find . -type f -name "*.sh" "${FIND_EXCLUDE_ARGS[@]}" -print0)
150+
fi
94151

95152
if [ $FAILED -eq 1 ]; then
96153
echo "❌ Found issues in shell scripts"
@@ -102,8 +159,18 @@ if [ "$MODE" = "fix" ]; then
102159
else
103160
echo "🔍 Checking shell scripts..."
104161

105-
# Run shellcheck on all shell scripts (checks all severities: error, warning, info, style)
106-
if find . -type f -name "*.sh" "${FIND_EXCLUDE_ARGS[@]}" -exec shellcheck -x {} +; then
162+
# Use staged or explicitly provided files when present; otherwise keep the
163+
# historical full-repository behavior for CI/manual all-file checks.
164+
if [ ${#FILES[@]} -gt 0 ]; then
165+
if shellcheck -x "${FILES[@]}"; then
166+
echo "✅ All shell scripts passed shellcheck"
167+
else
168+
echo ""
169+
echo "❌ Shellcheck found issues in shell scripts"
170+
echo "💡 Run '$0 --fix' to see detailed suggestions"
171+
exit 1
172+
fi
173+
elif find . -type f -name "*.sh" "${FIND_EXCLUDE_ARGS[@]}" -exec shellcheck -x {} +; then
107174
echo "✅ All shell scripts passed shellcheck"
108175
else
109176
echo ""

scripts/ci/trailing-whitespace.sh

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,9 @@ if [ "$MODE" = "fix" ]; then
150150

151151
echo "🔧 Removing trailing whitespace from ${#FILES_WITH_TRAILING[@]} file(s)..."
152152
for file in "${FILES_WITH_TRAILING[@]}"; do
153-
# Remove trailing whitespace (in-place)
154-
sed -i 's/[[:space:]]*$//' "$file"
153+
# Use a backup suffix so in-place editing works with both GNU and BSD sed.
154+
sed -i.bak 's/[[:space:]]*$//' "$file"
155+
rm -f "$file.bak"
155156
echo " Fixed: $file"
156157
done
157158
echo "✅ Trailing whitespace removed from ${#FILES_WITH_TRAILING[@]} file(s)"

scripts/ci/uv-lock-check.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,13 @@ fi
6363
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
6464
cd "$REPO_ROOT"
6565

66+
if ! command -v uv >/dev/null 2>&1; then
67+
echo -e "${RED}Error: uv is required but not installed${NC}"
68+
echo -e "${YELLOW}Install with: curl -LsSf https://astral.sh/uv/install.sh | sh${NC}"
69+
echo -e "${YELLOW}Or use: brew install uv${NC}"
70+
exit 127
71+
fi
72+
6673
PYTHON_DIRS=(
6774
"foreign/python"
6875
"bdd/python"

scripts/extract-version.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ NC='\033[0m'
6969
# Check for required tools
7070
if ! command -v yq &> /dev/null; then
7171
echo "Error: yq is required but not installed" >&2
72+
echo "Install with: brew install yq" >&2
73+
echo "Or download from: https://github.com/mikefarah/yq/releases" >&2
7274
exit 1
7375
fi
7476

0 commit comments

Comments
 (0)