Skip to content

Commit b6158da

Browse files
committed
chore: improve staged lint
1 parent 063089c commit b6158da

File tree

8 files changed

+236
-71
lines changed

8 files changed

+236
-71
lines changed

bin/cli.ts

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
#!/usr/bin/env bun
22
import process from 'node:process'
3+
import { Logger } from '@stacksjs/clarity'
34
import { CAC } from 'cac'
45
import { version } from '../package.json'
56
import { removeHooks, runStagedLint, setHooksFromConfig } from '../src/git-hooks'
67

78
const cli = new CAC('git-hooks')
9+
const log = new Logger('git-hooks', {
10+
showTags: true,
11+
})
812

913
// Check if installation should be skipped
1014
const { SKIP_INSTALL_GIT_HOOKS } = process.env
1115
if (['1', 'true'].includes(SKIP_INSTALL_GIT_HOOKS || '')) {
12-
console.log(`[INFO] SKIP_INSTALL_GIT_HOOKS is set to "${SKIP_INSTALL_GIT_HOOKS}", skipping installing hooks.`)
16+
log.info(`SKIP_INSTALL_GIT_HOOKS is set to "${SKIP_INSTALL_GIT_HOOKS}", skipping installing hooks.`)
1317
process.exit(0)
1418
}
1519

@@ -22,8 +26,8 @@ cli
2226
.action(async (configPath?: string, options?: { verbose?: boolean }) => {
2327
try {
2428
if (options?.verbose) {
25-
console.log('[DEBUG] Config path:', configPath || 'using default')
26-
console.log('[DEBUG] Working directory:', process.cwd())
29+
log.debug(`Config path: ${configPath || 'using default'}`)
30+
log.debug(`Working directory: ${process.cwd()}`)
2731
}
2832

2933
if (configPath) {
@@ -34,10 +38,10 @@ cli
3438
setHooksFromConfig(process.cwd())
3539
}
3640

37-
console.log('[INFO] Successfully set all git hooks')
41+
log.success('Successfully set all git hooks')
3842
}
3943
catch (err) {
40-
console.error('[ERROR] Was not able to set git hooks. Error:', err)
44+
log.error('Was not able to set git hooks. Error:', err)
4145
process.exit(1)
4246
}
4347
})
@@ -52,14 +56,14 @@ cli
5256
.action(async (options?: { verbose?: boolean }) => {
5357
try {
5458
if (options?.verbose) {
55-
console.log('[DEBUG] Removing hooks from:', process.cwd())
59+
log.debug(`Removing hooks from: ${process.cwd()}`)
5660
}
5761

5862
removeHooks(process.cwd(), options?.verbose)
59-
console.log('[INFO] Successfully removed all git hooks')
63+
log.success('Successfully removed all git hooks')
6064
}
6165
catch (err) {
62-
console.error('[ERROR] Was not able to remove git hooks. Error:', err)
66+
log.error('Was not able to remove git hooks. Error:', err)
6367
process.exit(1)
6468
}
6569
})
@@ -72,22 +76,22 @@ cli
7276
.action(async (hook: string, options?: { verbose?: boolean }) => {
7377
try {
7478
if (options?.verbose) {
75-
console.log('[DEBUG] Running staged lint for hook:', hook)
76-
console.log('[DEBUG] Working directory:', process.cwd())
79+
log.debug(`Running staged lint for hook: ${hook}`)
80+
log.debug(`Working directory: ${process.cwd()}`)
7781
}
7882

7983
const success = await runStagedLint(hook)
8084

8185
if (success) {
82-
console.log('[INFO] Staged lint completed successfully')
86+
log.success('Staged lint completed successfully')
8387
}
8488
else {
85-
console.error('[ERROR] Staged lint failed')
89+
log.error('Staged lint failed')
8690
process.exit(1)
8791
}
8892
}
8993
catch (err) {
90-
console.error('[ERROR] Was not able to run staged lint. Error:', err)
94+
log.error('Was not able to run staged lint. Error:', err)
9195
process.exit(1)
9296
}
9397
})

clarity.config.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import type { ClarityOptions } from '@stacksjs/clarity'
2+
3+
const config: ClarityOptions = {
4+
verbose: false,
5+
}
6+
7+
export default config

docs/config.md

Lines changed: 76 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,12 @@ import type { GitHooksConfig } from 'bun-git-hooks'
3333

3434
const config: GitHooksConfig = {
3535
// Git hook commands
36-
'pre-commit': 'bun run lint && bun run test',
36+
'pre-commit': {
37+
'staged-lint': {
38+
'*.{js,ts}': 'bunx --bun eslint . --fix',
39+
'*.{css,scss}': 'stylelint --fix'
40+
}
41+
},
3742
'commit-msg': 'bun commitlint --edit $1',
3843
'pre-push': 'bun run build',
3944

@@ -50,7 +55,12 @@ export default config
5055
```json
5156
{
5257
"git-hooks": {
53-
"pre-commit": "bun run lint && bun run test",
58+
"pre-commit": {
59+
"staged-lint": {
60+
"*.{js,ts}": "bunx --bun eslint . --fix",
61+
"*.{css,scss}": "stylelint --fix"
62+
}
63+
},
5464
"commit-msg": "bun commitlint --edit $1",
5565
"pre-push": "bun run build",
5666
"verbose": true,
@@ -63,25 +73,72 @@ export default config
6373

6474
### Hook Commands
6575

66-
Any valid git hook can be configured with a command string:
76+
Any valid git hook can be configured with either a command string or a staged-lint configuration:
6777

6878
```ts
6979
const config: GitHooksConfig = {
70-
// Pre-commit phase
71-
'pre-commit': string, // Run before git commits the changes
72-
'prepare-commit-msg': string, // Modify commit message before editor
73-
'commit-msg': string, // Validate/modify commit message
74-
'post-commit': string, // Run after commit is created
75-
76-
// Push phase
77-
'pre-push': string, // Run before git pushes commits
78-
'post-push': string, // Run after git pushes commits
79-
80-
// Other hooks
81-
'post-merge': string, // Run after git merges
82-
'post-checkout': string, // Run after git checkout
83-
'pre-rebase': string, // Run before git rebase
84-
'post-rewrite': string // Run after git rewrite (rebase/commit --amend)
80+
// Simple command
81+
'pre-commit': 'bun run lint',
82+
83+
// Staged lint configuration
84+
'pre-commit': {
85+
'staged-lint': {
86+
'*.{js,ts}': 'bunx --bun eslint . --fix',
87+
'*.{css,scss}': 'stylelint --fix'
88+
}
89+
},
90+
91+
// Global staged lint configuration
92+
'staged-lint': {
93+
'*.{js,ts}': 'bunx --bun eslint . --fix',
94+
'*.{css,scss}': 'stylelint --fix'
95+
}
96+
}
97+
```
98+
99+
### Staged Lint Configuration
100+
101+
The `staged-lint` feature allows you to run specific commands on staged files matching certain patterns:
102+
103+
```ts
104+
const config: GitHooksConfig = {
105+
'pre-commit': {
106+
'staged-lint': {
107+
// Run ESLint on JavaScript and TypeScript files
108+
'*.{js,ts}': 'bunx --bun eslint . --fix',
109+
110+
// Run Stylelint on CSS and SCSS files
111+
'*.{css,scss}': 'stylelint --fix',
112+
113+
// Run multiple commands on TypeScript files
114+
'*.{ts,tsx}': [
115+
'eslint . --fix',
116+
'prettier --write'
117+
],
118+
119+
// Run Prettier on Markdown files
120+
'*.md': 'prettier --write'
121+
}
122+
}
123+
}
124+
```
125+
126+
You can also use `staged-lint` as a top-level configuration to apply the same rules to all hooks:
127+
128+
```ts
129+
const config: GitHooksConfig = {
130+
// Global staged lint configuration
131+
'staged-lint': {
132+
'*.{js,ts}': 'bunx --bun eslint . --fix',
133+
'*.{css,scss}': 'stylelint --fix'
134+
},
135+
136+
// Hook-specific staged lint configuration (takes precedence)
137+
'pre-commit': {
138+
'staged-lint': {
139+
'*.{js,ts}': 'bunx --bun eslint . --fix --max-warnings=0'
140+
}
141+
}
85142
}
86143
```
87144

@@ -162,3 +219,4 @@ If no configuration is found, an error will be thrown.
162219
4. **Preserve Critical Hooks**: Use `preserveUnused` for important custom hooks
163220
5. **Enable Verbose Mode**: When debugging hook issues
164221
6. **Use Exit Codes**: Hooks should exit with non-zero for failures
222+
7. **Use Staged Lint**: For efficient file-specific linting

docs/usage.md

Lines changed: 84 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,13 @@ Create a `git-hooks.config.{ts,js,mjs,cjs,json}` file in your project root:
1717
import type { GitHooksConfig } from 'bun-git-hooks'
1818

1919
const config: GitHooksConfig = {
20-
'pre-commit': 'bun run lint && bun run test',
20+
// Using staged-lint for efficient file-specific linting
21+
'pre-commit': {
22+
'staged-lint': {
23+
'*.{js,ts}': 'bunx --bun eslint . --fix',
24+
'*.{css,scss}': 'stylelint --fix'
25+
}
26+
},
2127
'commit-msg': 'bun commitlint --edit $1',
2228
'pre-push': 'bun run build',
2329
'verbose': true,
@@ -33,7 +39,12 @@ You can also use JSON format in your `package.json`:
3339
```json
3440
{
3541
"git-hooks": {
36-
"pre-commit": "bun run lint && bun run test",
42+
"pre-commit": {
43+
"staged-lint": {
44+
"*.{js,ts}": "bunx --bun eslint . --fix",
45+
"*.{css,scss}": "stylelint --fix"
46+
}
47+
},
3748
"commit-msg": "bun commitlint --edit $1",
3849
"pre-push": "bun run build"
3950
}
@@ -55,6 +66,68 @@ git-hooks remove # alias
5566

5667
# Enable verbose logging
5768
git-hooks --verbose
69+
70+
# Run staged lint for a specific hook
71+
git-hooks run-staged-lint pre-commit
72+
```
73+
74+
## Staged Lint Usage
75+
76+
The `staged-lint` feature allows you to run specific commands on staged files matching certain patterns. This is more efficient than running commands on all files.
77+
78+
### Basic Staged Lint
79+
80+
```ts
81+
const config: GitHooksConfig = {
82+
'pre-commit': {
83+
'staged-lint': {
84+
// Run ESLint on JavaScript and TypeScript files
85+
'*.{js,ts}': 'bunx --bun eslint . --fix',
86+
87+
// Run Stylelint on CSS and SCSS files
88+
'*.{css,scss}': 'stylelint --fix'
89+
}
90+
}
91+
}
92+
```
93+
94+
### Multiple Commands
95+
96+
You can run multiple commands on the same file pattern:
97+
98+
```ts
99+
const config: GitHooksConfig = {
100+
'pre-commit': {
101+
'staged-lint': {
102+
// Run both ESLint and Prettier on TypeScript files
103+
'*.{ts,tsx}': [
104+
'eslint . --fix',
105+
'prettier --write'
106+
]
107+
}
108+
}
109+
}
110+
```
111+
112+
### Global Staged Lint
113+
114+
You can define staged lint rules globally that apply to all hooks:
115+
116+
```ts
117+
const config: GitHooksConfig = {
118+
// Global staged lint configuration
119+
'staged-lint': {
120+
'*.{js,ts}': 'bunx --bun eslint . --fix',
121+
'*.{css,scss}': 'stylelint --fix'
122+
},
123+
124+
// Hook-specific configuration (takes precedence)
125+
'pre-commit': {
126+
'staged-lint': {
127+
'*.{js,ts}': 'bunx --bun eslint . --fix --max-warnings=0'
128+
}
129+
}
130+
}
58131
```
59132

60133
## Environment Variables
@@ -157,11 +230,18 @@ Full TypeScript support with detailed type definitions:
157230

158231
```ts
159232
interface GitHooksConfig {
160-
'pre-commit'?: string
233+
'pre-commit'?: string | {
234+
'staged-lint'?: {
235+
[pattern: string]: string | string[]
236+
}
237+
}
161238
'pre-push'?: string
162239
'commit-msg'?: string
163240
'post-merge'?: string
164241
// ... other git hooks
242+
'staged-lint'?: {
243+
[pattern: string]: string | string[]
244+
}
165245
'preserveUnused'?: Array<string> | boolean
166246
'verbose'?: boolean
167247
}
@@ -179,7 +259,7 @@ git add .
179259
git commit -m "test: checking if hooks work"
180260
```
181261

182-
3. Your pre-commit hook should run
262+
3. Your pre-commit hook should run staged linting on the changed files
183263
4. Your commit-msg hook should validate the message
184264
5. When pushing, your pre-push hook should run
185265

git-hooks.config.ts

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
import type { GitHooksConfig } from './src/types'
22

33
const config: GitHooksConfig = {
4+
5+
// Hook-specific configuration (takes precedence)
46
'pre-commit': {
5-
stagedLint: {
6-
'*.{js,ts,json,yaml,yml,md}': 'bunx --bun eslint . --fix',
7-
// '*.{ts,tsx}': ['eslint . --fix', 'prettier --write'],
8-
// '*.css': 'stylelint --fix',
9-
// '*.md': 'prettier --write'
7+
'staged-lint': {
8+
'*.{js,ts}': 'bunx --bun eslint . --fix --max-warnings=0'
109
}
1110
},
12-
// Example of a regular command hook
13-
'commit-msg': 'bun commitlint --edit $1',
14-
'verbose': true,
11+
verbose: true
1512
}
1613

1714
export default config

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
"zip:darwin-arm64": "zip -j bin/git-hooks-darwin-arm64.zip bin/git-hooks-darwin-arm64"
7474
},
7575
"devDependencies": {
76+
"@stacksjs/clarity": "0.3.14",
7677
"@stacksjs/docs": "^0.70.23",
7778
"@stacksjs/eslint-config": "^4.10.2-beta.3",
7879
"@types/bun": "^1.2.11",

0 commit comments

Comments
 (0)