Skip to content

Commit 2bd5a28

Browse files
committed
feat!: migrate git hooks to ZX
1 parent d4f8b08 commit 2bd5a28

28 files changed

+2090
-1054
lines changed

.github/copilot-instructions.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,10 @@ Copilot SHOULD NOT generate raw php-cs-fixer, phpstan, rector, or psalm command
5353

5454
---
5555
## 5. Git Hooks Architecture
56-
- Unified helper: `tools/commit-utils.py` handles: `--need-ticket`, `--footer-label`, `--extract-ticket`.
57-
- Common library: `tools/git-hooks/lib/common.sh` provides shared functionality and colored logging.
58-
- `commit-msg` hook validates branch, lints message, appends footer if needed.
59-
- Copilot SHOULD reference `commit-utils.py` and the common library instead of legacy scripts.
56+
- Native ZX implementation: All git hooks use Google ZX for secure, cross-platform execution.
57+
- Common library: `tools/git-hooks/shared/utils.mjs` provides shared functionality and colored logging.
58+
- `commit-msg` hook validates branch, lints message, appends footer if needed - all functionality integrated natively.
59+
- Copilot SHOULD reference the ZX-based hook system and shared utilities instead of legacy scripts.
6060

6161
---
6262
## 6. Configuration Files (Do Not Duplicate)
@@ -120,13 +120,13 @@ If user asks about improvements, Copilot may propose:
120120

121121
---
122122
## 13. Quick Reference Snippets
123-
Check ticket requirement:
123+
Check current branch and validation:
124124
```
125-
python3 tools/commit-utils.py --need-ticket
125+
git rev-parse --abbrev-ref HEAD
126126
```
127-
Extract ticket from current branch:
127+
Validate branch manually:
128128
```
129-
python3 tools/commit-utils.py --extract-ticket "$(git rev-parse --abbrev-ref HEAD)"
129+
./node_modules/.bin/validate-branch-name -t "$(git rev-parse --abbrev-ref HEAD)"
130130
```
131131
Run all analyzers (example if combined script exists, otherwise run individually):
132132
```

booster/.ddev/config.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,9 @@ timezone: Europe/Berlin
2121
hooks:
2222
pre-start:
2323
- exec-host: python3 .ddev/php/create-xdebug-local.py
24+
- exec-host: git config core.hooksPath tools/git-hooks/hooks
2425
post-start:
25-
- exec: bash ./tools/git-hooks/setup.sh
26+
- exec: yes | pnpm install
2627
- exec: composer install --prefer-dist --no-progress --no-interaction
2728
- exec: python3 .phpstorm/update_xdebug_config.py
2829
- exec: python3 .ddev/php/add-xdebug-trigger-to-nginx.py

booster/.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ vendor
22
.idea
33
node_modules
44
.pnpm-store
5-
.husky
65
coverage.xml
76
phpstan_sonar.json
87
psalm_sonar.json

booster/composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@
1717
},
1818
"scripts": {
1919
"post-install-cmd": [
20-
"bash ./tools/git-hooks/setup.sh"
20+
"yes | pnpm install"
2121
],
2222
"post-update-cmd": [
23-
"bash ./tools/git-hooks/setup.sh"
23+
"yes | pnpm install"
2424
],
2525
"generate-api-spec": "php documentation/api.php",
2626
"check-cs": "vendor/bin/ecs check --ansi",

booster/documentation/api.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,20 @@
99
// Change this to the paths of your API classes
1010
$scanPaths = glob('./src');
1111

12-
if (! is_array($scanPaths)) {
12+
if (!is_array($scanPaths)) {
1313
exit('No paths found to scan for OpenAPI documentation.');
1414
}
1515

16-
$openapi = Generator::scan($scanPaths);
16+
$generator = new Generator();
17+
18+
$openapi = $generator->generate($scanPaths);
1719

1820
if ($openapi === null) {
1921
exit('Failed to generate OpenAPI documentation.');
2022
}
2123

2224
$filename = 'documentation/openapi.yml';
23-
$content = $openapi->toYaml();
25+
$content = $openapi->toYaml();
2426

2527
if (file_put_contents($filename, $content) === false) {
2628
exit('Unable to write to file ' . $filename);

booster/integrate_booster.sh

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -292,33 +292,27 @@ function copy_files() {
292292
# Copy selected tool scripts instead of entire tools directory
293293
local tools_src="${BOOSTER_INTERNAL_PATH}/tools"
294294
if [ -d "$tools_src" ]; then
295-
mkdir -p tools/git-hooks/hooks
296-
# List of tool files to copy (public runtime helpers only)
297-
local tool_files=(
298-
"runner.sh"
299-
"commit-utils.py"
300-
"git-hooks"
301-
)
302-
for f in "${tool_files[@]}"; do
303-
if [ -f "$tools_src/$f" ]; then
304-
log " Copying tool '$f'"
305-
cp "$tools_src/$f" tools/
306-
# Set execute permissions for shell scripts and Python files
307-
if [[ "$f" == *.sh ]] || [[ "$f" == *.py ]]; then
308-
chmod +x "tools/$f"
309-
fi
310-
elif [ -d "$tools_src/$f" ]; then
311-
log " Copying tool directory '$f'"
312-
cp -R "$tools_src/$f" tools/
313-
# Set execute permissions for shell scripts in the directory
314-
find "tools/$f" -name "*.sh" -exec chmod +x {} \;
315-
find "tools/$f" -name "*.bash" -exec chmod +x {} \;
316-
else
317-
warn " Expected tool file missing: $f"
318-
fi
319-
done
320-
295+
mkdir -p tools/git-hooks
296+
297+
# Copy git-hooks/hooks directory
298+
if [ -d "$tools_src/git-hooks/hooks" ]; then
299+
log " Copying git-hooks/hooks directory"
300+
cp -R "$tools_src/git-hooks/hooks" tools/git-hooks/
301+
# Set execute permissions for all scripts in hooks directory
302+
find "tools/git-hooks/hooks" -type f \( -name "*.sh" -o -name "*.bash" -o -name "*.mjs" \) -exec chmod +x {} \;
303+
else
304+
warn " Expected tool directory missing: git-hooks/hooks"
305+
fi
321306

307+
# Copy git-hooks/shared directory
308+
if [ -d "$tools_src/git-hooks/shared" ]; then
309+
log " Copying git-hooks/shared directory"
310+
cp -R "$tools_src/git-hooks/shared" tools/git-hooks/
311+
# Set execute permissions for scripts in shared directory
312+
find "tools/git-hooks/shared" -type f \( -name "*.sh" -o -name "*.bash" -o -name "*.mjs" \) -exec chmod +x {} \;
313+
else
314+
warn " Expected tool directory missing: git-hooks/shared"
315+
fi
322316
else
323317
warn " Booster tools directory not found; skipping tools copy."
324318
fi
@@ -358,7 +352,8 @@ function update_package_json() {
358352
.[0] as $proj | .[1] as $booster |
359353
$proj * {
360354
scripts: (($proj.scripts // {}) + ($booster.scripts // {})),
361-
devDependencies: (($proj.devDependencies // {}) + ($booster.devDependencies // {}))
355+
devDependencies: (($proj.devDependencies // {}) + ($booster.devDependencies // {})),
356+
husky: (($proj.husky // {}) + ($booster.husky // {}))
362357
}
363358
' "$project_pkg" "$booster_pkg" >"$tmp_pkg" || error "Failed to merge package.json using jq."
364359

booster/package.json

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,24 @@
44
"type": "module",
55
"version": "0.6.0",
66
"scripts": {
7-
"prepare": "husky",
87
"commit": "commit",
9-
"generate:api-doc:html": "redocly build-docs documentation/openapi.yml --output=documentation/openapi.html"
8+
"generate:api-doc:html": "redocly build-docs documentation/openapi.yml --output=documentation/openapi.html",
9+
"test:hooks": "vitest run tools/git-hooks",
10+
"test:hooks:watch": "vitest watch tools/git-hooks"
11+
},
12+
"husky": {
13+
"hooksPath": "tools/git-hooks/hooks"
1014
},
1115
"devDependencies": {
1216
"@commitlint/cli": "^19.8.1",
1317
"@commitlint/config-conventional": "^19.8.1",
1418
"@commitlint/prompt-cli": "^19.8.1",
1519
"@commitlint/types": "^19.8.1",
16-
"@redocly/cli": "^2.0.2",
20+
"@redocly/cli": "^2.1.3",
1721
"husky": "^9.1.7",
18-
"validate-branch-name": "^1.3.2"
22+
"validate-branch-name": "^1.3.2",
23+
"zx": "^8.8.1",
24+
"vitest": "^3.2.4"
1925
},
2026
"packageManager": "pnpm@10.16.1"
2127
}

0 commit comments

Comments
 (0)