Skip to content

Commit 13750b6

Browse files
authored
Merge pull request #17 from prog-time/issues-16
Add missing linter hooks from claude-config-template
2 parents 0a54135 + e803f04 commit 13750b6

40 files changed

Lines changed: 1197 additions & 7 deletions

.github/workflows/tests.yml

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ jobs:
5757
- name: Checkout repository
5858
uses: actions/checkout@v4
5959

60+
- name: Install Python tools
61+
run: pip install ruff
62+
6063
- name: Prepare test environment
6164
run: |
6265
chmod +x python/*.sh
@@ -161,3 +164,68 @@ jobs:
161164
- name: Run YAML tests
162165
run: |
163166
for suite in tests/yml/*/run.sh; do "$suite"; done
167+
168+
simple-tests:
169+
name: Simple Tests
170+
runs-on: ubuntu-latest
171+
needs: shellcheck
172+
173+
steps:
174+
- name: Checkout repository
175+
uses: actions/checkout@v4
176+
177+
- name: Install codespell
178+
run: pip install codespell
179+
180+
- name: Prepare test environment
181+
run: |
182+
chmod +x simple/*.sh
183+
chmod +x tests/lib/*.bash
184+
find tests/simple -name "*.sh" -exec chmod +x {} +
185+
186+
- name: Run Simple tests
187+
run: |
188+
for suite in tests/simple/*/run.sh; do "$suite"; done
189+
190+
git-tests:
191+
name: Git Tests
192+
runs-on: ubuntu-latest
193+
needs: shellcheck
194+
195+
steps:
196+
- name: Checkout repository
197+
uses: actions/checkout@v4
198+
199+
- name: Prepare test environment
200+
run: |
201+
chmod +x git/*.sh
202+
chmod +x tests/lib/*.bash
203+
find tests/git -name "*.sh" -exec chmod +x {} +
204+
205+
- name: Run Git tests
206+
run: |
207+
for suite in tests/git/*/run.sh; do "$suite"; done
208+
209+
shell-tests:
210+
name: Shell Tests
211+
runs-on: ubuntu-latest
212+
needs: shellcheck
213+
214+
steps:
215+
- name: Checkout repository
216+
uses: actions/checkout@v4
217+
218+
- name: Install shfmt
219+
run: |
220+
curl -sS https://webi.sh/shfmt | sh
221+
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
222+
223+
- name: Prepare test environment
224+
run: |
225+
chmod +x shell/*.sh
226+
chmod +x tests/lib/*.bash
227+
find tests/shell -name "*.sh" -exec chmod +x {} +
228+
229+
- name: Run Shell tests
230+
run: |
231+
for suite in tests/shell/*/run.sh; do "$suite"; done

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,5 @@ tests/**/tmp/
2323
# Logs
2424
*.log
2525

26-
articles/
26+
articles/
27+
tasks/

CLAUDE.md

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## Project Overview
44

5-
A collection of reusable git hook scripts for automating code quality checks. Covers JavaScript/TypeScript, Python, PHP/Laravel, CSS, HTML, Markdown, YAML, Docker, and shell scripts.
5+
A collection of reusable git hook scripts for automating code quality checks. Covers JavaScript/TypeScript, Python, PHP/Laravel, CSS, HTML, Markdown, YAML, Docker, shell scripts, and general-purpose checks (spelling, JSON, secret detection, shell formatting).
66

77
## Directory Structure
88

@@ -16,6 +16,8 @@ docker/ # Docker-related hooks
1616
1717
git/ # Git workflow hooks
1818
├── check_branch_name.sh # Branch naming convention validator
19+
├── check_gitleaks.sh # Secret detection in staged changes (optional)
20+
├── check_gitleaks_all.sh # Secret detection in full repository history
1921
└── preparations/ # Commit message enhancers
2022
├── add_task_id_in_commit.sh
2123
└── prepare-commit-description.sh
@@ -54,10 +56,20 @@ python/ # Python hooks
5456
├── check_mypy_in_docker.sh # Mypy (Docker)
5557
├── check_pytest.sh # Pytest (local)
5658
├── check_pytest_in_docker.sh # Pytest (Docker)
59+
├── check_ruff.sh # Ruff linter for staged files
60+
├── check_ruff_all.sh # Ruff linter for entire project
5761
└── find_test.sh # Service test existence validator
5862
5963
shell/ # Shell script validation
60-
└── check_shellcheck.sh # ShellCheck via Docker
64+
├── check_shellcheck.sh # ShellCheck via Docker
65+
├── check_shfmt.sh # shfmt formatting check for staged files
66+
└── check_shfmt_all.sh # shfmt formatting check for entire project
67+
68+
simple/ # General-purpose hooks
69+
├── check_codespell.sh # Spelling check for staged files
70+
├── check_codespell_all.sh # Spelling check for entire project
71+
├── check_json_validate.sh # JSON syntax validation for staged files
72+
└── check_json_validate_all.sh # JSON syntax validation for entire project
6173
6274
scripts/ # Local utility scripts
6375
├── check_shellcheck.sh # ShellCheck (local execution)
@@ -71,11 +83,14 @@ tests/ # Test framework
7183
├── run_all.sh # Run all test suites
7284
├── lib/test_helper.bash # Test utilities and assertions
7385
├── css/ # CSS hook tests
86+
├── git/ # Git hook tests (gitleaks)
7487
├── html/ # HTML hook tests
7588
├── javascript/ # JavaScript hook tests
7689
├── markdown/ # Markdown hook tests
7790
├── php/ # PHP hook tests
78-
├── python/ # Python hook tests
91+
├── python/ # Python hook tests (flake8, mypy, ruff, pytest, find_test)
92+
├── shell/ # Shell hook tests (shfmt)
93+
├── simple/ # Simple hook tests (codespell, json_validate)
7994
└── yml/ # YAML hook tests
8095
```
8196

@@ -112,11 +127,15 @@ Every script must start with a description block after the shebang:
112127
- Bash 4.0+, Git, jq
113128
- Node.js with npx (for JavaScript/TypeScript, CSS, HTML hooks)
114129
- Python 3, Flake8, Mypy, Pytest (for Python hooks)
130+
- Ruff (`pip install ruff`) for `python/check_ruff.sh`
131+
- Codespell (`pip install codespell`) for `simple/check_codespell.sh`
115132
- PHP 8.1+, Composer (for PHPStan/Pint)
116133
- Stylelint via npx (for CSS hooks)
117134
- HTMLHint via npx (for HTML hooks)
118135
- markdownlint-cli (for Markdown hooks)
119136
- yamllint (for YAML hooks)
137+
- shfmt (`go install mvdan.cc/sh/v3/cmd/shfmt@latest` or `brew install shfmt`) for `shell/check_shfmt.sh`
138+
- gitleaks (optional, see [install guide](https://github.com/gitleaks/gitleaks#installing)) for `git/check_gitleaks.sh`
120139
- Docker (optional, for containerized checks)
121140
- ShellCheck (for shell validation)
122141

README.md

Lines changed: 78 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,16 @@ A collection of reusable git hook scripts for automating code quality checks and
55
## Features
66

77
- **JavaScript/TypeScript**: ESLint, Prettier, TypeScript type checking, Vitest test runner, test existence validation
8-
- **Python**: Flake8 linting, Mypy static analysis, Pytest runner, service test validation (local and Docker modes)
8+
- **Python**: Flake8 linting, Mypy static analysis, Ruff linting, Pytest runner, service test validation (local and Docker modes)
99
- **PHP/Laravel**: PHPStan analysis with progressive error reduction, Pint code style fixing, test coverage validation
1010
- **CSS/SCSS/Less**: Stylelint code style validation
1111
- **HTML**: HTMLHint linting
1212
- **Markdown**: markdownlint style validation
1313
- **YAML**: yamllint style validation
1414
- **Docker**: Dockerfile linting with Hadolint
15-
- **Shell**: Script validation with ShellCheck
16-
- **Git**: Branch naming conventions, automatic task ID injection in commits
15+
- **Shell**: Script validation with ShellCheck, shfmt formatting check
16+
- **Git**: Branch naming conventions, automatic task ID injection in commits, secret detection with gitleaks
17+
- **Simple**: Spelling check with codespell, JSON syntax validation
1718

1819
## Quick Start
1920

@@ -48,6 +49,8 @@ A collection of reusable git hook scripts for automating code quality checks and
4849
| `python/check_mypy_in_docker.sh` | Runs Mypy inside the Docker container, maps host/container paths. |
4950
| `python/check_pytest.sh` | Runs the full Pytest suite locally with `PYTHONPATH=./app`. |
5051
| `python/check_pytest_in_docker.sh` | Runs Pytest inside the Docker container, converts container paths to host paths. |
52+
| `python/check_ruff.sh` | Runs Ruff linter on staged Python files passed as arguments. |
53+
| `python/check_ruff_all.sh` | Runs Ruff linter on all Python files in the project. |
5154
| `python/find_test.sh` | Validates that each service in `app/services/` has exactly one corresponding test file. |
5255

5356
### PHP
@@ -92,6 +95,8 @@ A collection of reusable git hook scripts for automating code quality checks and
9295
| Script | Description |
9396
|--------|-------------|
9497
| `git/check_branch_name.sh` | Validates branch names match pattern: `{type}/{task-id}_{description}` |
98+
| `git/check_gitleaks.sh` | Scans staged changes for secrets using gitleaks (optional; exits 0 if not installed). |
99+
| `git/check_gitleaks_all.sh` | Scans full repository history for secrets using gitleaks. |
95100
| `git/preparations/add_task_id_in_commit.sh` | Prepends task ID from branch name to commit message. |
96101
| `git/preparations/prepare-commit-description.sh` | Appends list of changed files to commit message. |
97102

@@ -106,8 +111,19 @@ A collection of reusable git hook scripts for automating code quality checks and
106111
| Script | Description |
107112
|--------|-------------|
108113
| `shell/check_shellcheck.sh` | Validates shell scripts using ShellCheck (via Docker). |
114+
| `shell/check_shfmt.sh` | Checks shell script formatting using shfmt (`-i 2 -ci`). |
115+
| `shell/check_shfmt_all.sh` | Checks formatting of all `.sh` files in the project. |
109116
| `scripts/check_shellcheck.sh` | Validates shell scripts using ShellCheck (local). |
110117

118+
### Simple
119+
120+
| Script | Description |
121+
|--------|-------------|
122+
| `simple/check_codespell.sh` | Checks files for spelling mistakes using codespell. |
123+
| `simple/check_codespell_all.sh` | Checks all project files for spelling mistakes. |
124+
| `simple/check_json_validate.sh` | Validates JSON files for syntax correctness using `python3 -m json.tool`. |
125+
| `simple/check_json_validate_all.sh` | Validates all `*.json` files in the project. |
126+
111127
## Usage Examples
112128

113129
### JavaScript/TypeScript
@@ -210,6 +226,56 @@ A collection of reusable git hook scripts for automating code quality checks and
210226
./yml/check_yamllint_all.sh
211227
```
212228

229+
### Ruff
230+
231+
```bash
232+
# Check staged files
233+
./python/check_ruff.sh app/services/user.py app/models/auth.py
234+
235+
# Check all Python files in the project
236+
./python/check_ruff_all.sh
237+
```
238+
239+
### Gitleaks
240+
241+
```bash
242+
# Check staged changes for secrets (optional: exits 0 if gitleaks not installed)
243+
./git/check_gitleaks.sh
244+
245+
# Scan full repository history for secrets
246+
./git/check_gitleaks_all.sh
247+
```
248+
249+
### shfmt
250+
251+
```bash
252+
# Check staged shell scripts for formatting
253+
./shell/check_shfmt.sh deploy.sh scripts/setup.sh
254+
255+
# Check all shell scripts in the project
256+
./shell/check_shfmt_all.sh
257+
```
258+
259+
### Codespell
260+
261+
```bash
262+
# Check specific files for spelling mistakes
263+
./simple/check_codespell.sh README.md src/utils.py
264+
265+
# Check all project files
266+
./simple/check_codespell_all.sh
267+
```
268+
269+
### JSON Validation
270+
271+
```bash
272+
# Validate specific JSON files
273+
./simple/check_json_validate.sh package.json .eslintrc.json
274+
275+
# Validate all JSON files in the project
276+
./simple/check_json_validate_all.sh
277+
```
278+
213279
### Branch Name Validation
214280

215281
```bash
@@ -290,6 +356,7 @@ SH_FILES=$(echo "$FILES" | grep '\.sh$' || true)
290356
./tests/javascript/vitest/run.sh
291357
./tests/python/flake8/run.sh
292358
./tests/python/mypy/run.sh
359+
./tests/python/ruff/run.sh
293360
./tests/python/find_test/run.sh
294361
./tests/css/stylelint/run.sh
295362
./tests/css/stylelint_all/run.sh
@@ -299,6 +366,10 @@ SH_FILES=$(echo "$FILES" | grep '\.sh$' || true)
299366
./tests/markdown/markdownlint_all/run.sh
300367
./tests/yml/yamllint/run.sh
301368
./tests/yml/yamllint_all/run.sh
369+
./tests/git/gitleaks/run.sh
370+
./tests/shell/shfmt/run.sh
371+
./tests/simple/codespell/run.sh
372+
./tests/simple/json_validate/run.sh
302373
```
303374

304375
## Requirements
@@ -308,11 +379,15 @@ SH_FILES=$(echo "$FILES" | grep '\.sh$' || true)
308379
- jq
309380
- Node.js with npx (for JavaScript/TypeScript, CSS, HTML hooks)
310381
- Python 3, Flake8, Mypy, Pytest (for Python hooks)
382+
- Ruff (`pip install ruff`) for `python/check_ruff.sh`
383+
- Codespell (`pip install codespell`) for `simple/check_codespell.sh`
311384
- PHP 8.1+ with Composer (for PHP hooks)
312385
- Stylelint (`npm install -g stylelint`) or via `npx`
313386
- HTMLHint (`npm install -g htmlhint`) or via `npx`
314387
- markdownlint-cli (`npm install -g markdownlint-cli`)
315388
- yamllint (`pip install yamllint` or system package)
389+
- shfmt (`go install mvdan.cc/sh/v3/cmd/shfmt@latest` or `brew install shfmt`) for `shell/check_shfmt.sh`
390+
- gitleaks (optional, see [install guide](https://github.com/gitleaks/gitleaks#installing)) for `git/check_gitleaks.sh`
316391
- Docker (optional, for Docker-based hooks)
317392
- ShellCheck (for shell validation)
318393

git/check_gitleaks.sh

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#!/bin/bash
2+
# ------------------------------------------------------------------------------
3+
# Scans staged changes for secrets and tokens using gitleaks.
4+
# Runs gitleaks protect --staged --redact --exit-code 1.
5+
# Exits 0 with a warning if gitleaks is not installed (optional hook).
6+
# Exits 1 if any secrets are detected; exits 0 on clean scan.
7+
# ------------------------------------------------------------------------------
8+
9+
if ! command -v gitleaks > /dev/null 2>&1; then
10+
echo "WARNING: gitleaks is not installed. Skipping secret detection."
11+
echo "Install it with: https://github.com/gitleaks/gitleaks#installing"
12+
exit 0
13+
fi
14+
15+
OUTPUT=$(gitleaks protect --staged --redact --exit-code 1 2>&1)
16+
EXIT_CODE=$?
17+
18+
if [ $EXIT_CODE -ne 0 ]; then
19+
echo "ERROR: gitleaks detected secrets in staged changes!"
20+
echo "$OUTPUT"
21+
echo "Remove the secrets above before committing."
22+
exit 1
23+
fi
24+
25+
echo "gitleaks: no secrets detected in staged changes."
26+
exit 0

git/check_gitleaks_all.sh

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/bin/bash
2+
# ------------------------------------------------------------------------------
3+
# Scans the entire repository history for secrets using gitleaks detect.
4+
# Runs gitleaks detect --redact --exit-code 1 on the full git history.
5+
# Exits 0 with a warning if gitleaks is not installed (optional hook).
6+
# Exits 1 if any secrets are detected; exits 0 on clean scan.
7+
# ------------------------------------------------------------------------------
8+
9+
if ! command -v gitleaks > /dev/null 2>&1; then
10+
echo "WARNING: gitleaks is not installed. Skipping secret detection."
11+
echo "Install it with: https://github.com/gitleaks/gitleaks#installing"
12+
exit 0
13+
fi
14+
15+
OUTPUT=$(gitleaks detect --redact --exit-code 1 2>&1)
16+
EXIT_CODE=$?
17+
18+
if [ $EXIT_CODE -ne 0 ]; then
19+
echo "ERROR: gitleaks detected secrets in repository history!"
20+
echo "$OUTPUT"
21+
exit 1
22+
fi
23+
24+
echo "gitleaks: no secrets detected in repository history."
25+
exit 0

git/preparations/prepare-commit-description.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ PROMPT="git-agent desc commit en $STAGED_FILES"
2323
COMMIT_TEXT=$(printf "%s\n" "$PROMPT" | claude -p)
2424

2525
# Remove possible triple backticks ``` and empty lines
26+
# shellcheck disable=SC2016
2627
COMMIT_TEXT=$(echo "$COMMIT_TEXT" | sed 's/^```//; s/```$//' | sed '/^$/d')
2728

2829
# Exit if the generated text is empty

0 commit comments

Comments
 (0)