Skip to content

Commit 85ce216

Browse files
committed
chore(hooks): DRY API docs using shared helper; avoid direct process.exit in pre-commit
1 parent 90b108f commit 85ce216

File tree

4 files changed

+17
-36
lines changed

4 files changed

+17
-36
lines changed

booster/.husky/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ The hooks are designed to work seamlessly with DDEV.
8282

8383
You can control the behavior of the hooks using environment variables. These can be set in your shell or in a `.env` file.
8484

85+
Note: tool-specific skip variables are normalized to uppercase and non-alphanumeric characters are replaced with underscores. For example, a tool named `PHP Syntax Check` becomes `SKIP_PHP_SYNTAX_CHECK` and `api docs` becomes `SKIP_API_DOCS`.
86+
8587
| Variable | Description |
8688
| ------------------- | ---------------------------------------------------------------------------- |
8789
| `GIT_HOOKS_VERBOSE` | Set to `1` or `true` to enable verbose logging (shows executed commands). |

booster/.husky/pre-commit.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ await runHook(GitHook.PreCommit, async () => {
2323

2424
if (files.length === 0) {
2525
log.info('No files staged for commit. Skipping quality checks.')
26-
process.exit(0)
26+
return true
2727
}
2828

2929
log.info(`Found ${files.length} staged file(s): ${files.join(', ')}`)

booster/.husky/pre-push.ts

Lines changed: 8 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* - API Documentation generation
1010
*/
1111
import { $, fs } from 'zx'
12-
import { GitHook, log, runHook, runWithRunner } from './shared/index.ts'
12+
import { GitHook, isSkipped, log, runHook, runWithRunner, generateApiDocs } from './shared/index.ts'
1313

1414
const SKIP_COMMIT_MSG = 'chore: update API documentation'
1515

@@ -45,40 +45,14 @@ async function runTests(): Promise<boolean> {
4545
}
4646

4747
async function handleApiDocs(): Promise<boolean> {
48-
log.tool('API Documentation', 'Generating OpenAPI specification...')
49-
try {
50-
if (!(await fs.pathExists('vendor/zircote/swagger-php'))) {
51-
log.info('swagger-php not installed -> skipping API docs.')
52-
return true
53-
}
54-
55-
await runWithRunner(['composer', 'generate-api-spec'])
56-
57-
// Check if openapi.yml changed
58-
const diff = await $`git diff --name-only`
59-
if (!diff.stdout.includes('documentation/openapi.yml')) {
60-
log.success('API documentation check passed (no changes)')
61-
return true
62-
}
63-
64-
log.info('API spec changed, regenerating HTML...')
65-
await runWithRunner(['pnpm', 'generate:api-doc:html'])
66-
67-
// Check for changes in documentation files
68-
const status = await $`git status --porcelain documentation/openapi.html documentation/openapi.yml`
69-
if (status.stdout.trim() !== '') {
70-
log.info('API documentation is outdated. Updating and committing...')
71-
72-
await $`git add documentation/openapi.html documentation/openapi.yml`
73-
// Skip pre-commit (linting) but run commit-msg (ticket appending)
74-
await $`SKIP_PRECOMMIT=1 git commit -m ${SKIP_COMMIT_MSG}`
75-
76-
log.success('API documentation updated and committed.')
77-
log.warn('The new documentation commit was created AFTER the push started.')
78-
log.warn('Your code has been pushed, but you must run "git push" AGAIN to send the documentation update.')
79-
return true
80-
}
48+
// Allow skipping API docs generation explicitly via env var
49+
if (isSkipped('api_docs')) {
50+
log.info('Skipping API docs generation (SKIP_API_DOCS environment variable set)')
51+
return true
52+
}
8153

54+
try {
55+
await generateApiDocs()
8256
return true
8357
} catch (e) {
8458
log.error('API spec generation failed')

booster/.husky/shared/core.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,11 @@ export function formatDuration(ms: number): string {
115115
* @param name Name of the tool/check (will be converted to SKIP_<NAME>)
116116
*/
117117
export function isSkipped(name: string): boolean {
118-
const skipEnvVar = `SKIP_${name.toUpperCase()}`
118+
// Normalize name -> uppercase, replace non-alphanum with underscore, collapse multiple underscores
119+
const normalized = String(name)
120+
.toUpperCase()
121+
.replace(/[^A-Z0-9]+/g, '_')
122+
.replace(/^_+|_+$/g, '')
123+
const skipEnvVar = `SKIP_${normalized}`
119124
return process.env[skipEnvVar] === '1' || process.env[skipEnvVar] === 'true'
120125
}

0 commit comments

Comments
 (0)