Skip to content

Commit 1bbb26f

Browse files
committed
fix: load project staged-lint config
1 parent 3a1d632 commit 1bbb26f

5 files changed

Lines changed: 38 additions & 33 deletions

File tree

bin/cli.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import process from 'node:process'
33
import { CLI } from '@stacksjs/clapp'
44
import { Logger } from '@stacksjs/clarity'
55
import { version } from '../package.json'
6-
import { config } from '../src/config'
7-
import { removeHooks, setHooksFromConfig, getConfigFromPackageJson } from '../src/git-hooks'
6+
import { getConfig } from '../src/config'
7+
import { removeHooks, setHooksFromConfig } from '../src/git-hooks'
88
import { runStagedLint } from '../src/staged-lint'
99

1010
const cli = new CLI('git-hooks')
@@ -44,11 +44,12 @@ cli
4444
}
4545

4646
if (configPath) {
47-
const config = await import(configPath)
48-
setHooksFromConfig(process.cwd(), { configFile: config, verbose: options?.verbose ?? false })
47+
const importedConfig = await import(configPath)
48+
setHooksFromConfig(process.cwd(), { configFile: importedConfig.default ?? importedConfig, verbose: options?.verbose ?? false })
4949
}
5050
else {
51-
setHooksFromConfig(process.cwd(), { verbose: options?.verbose ?? false })
51+
const config = await getConfig()
52+
setHooksFromConfig(process.cwd(), { configFile: config, verbose: options?.verbose ?? false })
5253
}
5354

5455
log.success('Successfully set all git hooks')
@@ -101,8 +102,8 @@ cli
101102
}
102103
}
103104

104-
const effectiveConfig = getConfigFromPackageJson(process.cwd()) || config
105-
const success = await runStagedLint(hook, effectiveConfig, process.cwd(), options?.verbose ?? false, options?.autoRestage)
105+
const config = await getConfig()
106+
const success = await runStagedLint(hook, config, process.cwd(), options?.verbose ?? false, options?.autoRestage)
106107

107108
if (success) {
108109
log.success('Staged lint completed successfully')

git-hooks.config.ts

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

33
const config: GitHooksConfig = {
4-
// Hook-specific configuration (takes precedence)
54
'pre-commit': {
65
'staged-lint': {
7-
'**/*.{js,ts}': [
8-
'bunx --bun eslint --fix',
9-
'bunx --bun tsc --noEmit'
10-
]
11-
}
6+
'**/*.{js,ts,json,yaml,yml,md}': 'bunx --bun pickier {files} --fix',
7+
},
128
},
139
'commit-msg': 'bunx gitlint .git/COMMIT_EDITMSG',
14-
verbose: true
1510
}
1611

1712
export default config

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,10 @@
8686
"git-hooks": {
8787
"pre-commit": {
8888
"staged-lint": {
89-
"*.{js,ts,json,yaml,yml,md}": "bunx --bun pickier lint --fix"
89+
"*.{js,ts,json,yaml,yml,md}": "bunx --bun pickier {files} --fix"
9090
},
9191
"autoRestage": true
9292
},
93-
"commit-msg": "bunx gitlint --edit .git/COMMIT_EDITMSG"
93+
"commit-msg": "bunx gitlint .git/COMMIT_EDITMSG"
9494
}
9595
}

src/config.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,27 @@
11
import type { GitHooksConfig } from './types'
22
import process from 'node:process'
33
import { loadConfig } from 'bunfig'
4-
import defaultConfig from '../git-hooks.config.ts'
4+
import bundledDefaultConfig from '../git-hooks.config.ts'
55

66
// Lazy-loaded config to avoid top-level await (enables bun --compile)
77
let _config: GitHooksConfig | null = null
8+
const emptyConfig: GitHooksConfig = {}
89

910
export async function getConfig(): Promise<GitHooksConfig> {
1011
if (!_config) {
11-
_config = await loadConfig({
12+
const loadedConfig = await loadConfig({
1213
name: 'git-hooks',
1314
cwd: process.cwd(),
14-
defaultConfig,
15+
defaultConfig: emptyConfig,
1516
})
17+
18+
_config = Object.keys(loadedConfig).length > 0
19+
? loadedConfig
20+
: bundledDefaultConfig
1621
}
22+
1723
return _config
1824
}
1925

2026
// For backwards compatibility - synchronous access with default fallback
21-
export const config: GitHooksConfig = defaultConfig
27+
export const config: GitHooksConfig = bundledDefaultConfig

src/git-hooks.ts

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
11
import fs from 'node:fs'
22
import path from 'node:path'
33
import process from 'node:process'
4-
import { config } from './config'
4+
import { config as defaultConfig } from './config'
55
import type { GitHooksConfig, StagedLintConfig, StagedLintTask, SetHooksFromConfigOptions } from './types'
66
import { exec } from 'node:child_process'
77
import { promisify } from 'node:util'
88
import { Logger, italic, bgRed, green, bgYellow } from '@stacksjs/clarity'
99

1010
const execAsync = promisify(exec)
11-
const log = new Logger('git-hooks', {
12-
showTags: true
13-
})
11+
let log: Logger | undefined
12+
13+
function getLog(): Logger {
14+
return log ??= new Logger('git-hooks', {
15+
showTags: true,
16+
})
17+
}
1418

1519
// Module-level verbose switch. Default: false
1620
let VERBOSE = false
@@ -194,12 +198,12 @@ export function areHooksInstalled(projectRootPath: string = process.cwd()): bool
194198
return false
195199
}
196200

197-
if (!config || Object.keys(config).length === 0) {
201+
if (!defaultConfig || Object.keys(defaultConfig).length === 0) {
198202
return false
199203
}
200204

201205
// Check if at least one configured hook exists and contains our script marker
202-
const configuredHooks = Object.keys(config).filter(key =>
206+
const configuredHooks = Object.keys(defaultConfig).filter(key =>
203207
VALID_GIT_HOOKS.includes(key as typeof VALID_GIT_HOOKS[number])
204208
)
205209

@@ -249,16 +253,15 @@ export function getConfigFromPackageJson(projectPath: string): GitHooksConfig |
249253
* Parses the config and sets git hooks
250254
*/
251255
export function setHooksFromConfig(projectRootPath: string = process.cwd(), options?: SetHooksFromConfigOptions): void {
252-
// Always use the provided configFile if available, otherwise try package.json in projectRoot, then cached config
253-
const configFile = options?.configFile || getConfigFromPackageJson(projectRootPath) || (config && Object.keys(config).length > 0 ? { ...config } : undefined)
256+
const configFile = options?.configFile || getConfigFromPackageJson(projectRootPath) || (defaultConfig && Object.keys(defaultConfig).length > 0 ? { ...defaultConfig } : undefined)
254257

255258
if (!configFile || Object.keys(configFile).length === 0)
256259
throw new Error('[ERROR] Config was not found! Please add `.git-hooks.config.{ts,js,mjs,cjs,json}` or `git-hooks.config.{ts,js,mjs,cjs,json}` or the `git-hooks` entry in package.json.\r\nCheck README for details')
257260

258261
// Set module verbosity strictly from options (CLI flag). Ignore config.verbose for logs.
259262
VERBOSE = Boolean(options?.verbose)
260263
if (VERBOSE) {
261-
log.config.level = 'debug'
264+
getLog().config.level = 'debug'
262265
}
263266

264267
_validateStagedLintConfig(configFile)
@@ -277,7 +280,7 @@ export function setHooksFromConfig(projectRootPath: string = process.cwd(), opti
277280
// For programmatic usage, fall back to config file setting
278281
const verbose = options?.verbose !== undefined ? options.verbose : (configFile.verbose ?? false)
279282
if (verbose) {
280-
log.debug(`Hook Keys: ${logKeys}`)
283+
getLog().debug(`Hook Keys: ${logKeys}`)
281284
}
282285
for (const hook of VALID_GIT_HOOKS) {
283286
if (Object.prototype.hasOwnProperty.call(configFile, hook)) {
@@ -347,7 +350,7 @@ else {
347350

348351
const addOrModify = fs.existsSync(hookPath) ? 'Modify' : 'Add'
349352
if (verbose) {
350-
log.debug(`${addOrModify} ${italic(hook)} hook`)
353+
getLog().debug(`${addOrModify} ${italic(hook)} hook`)
351354
}
352355

353356
fs.writeFileSync(hookPath, hookCommand, { mode: 0o755 })
@@ -369,12 +372,12 @@ function _removeHook(hook: string, projectRoot = process.cwd(), verbose = false)
369372
const hookPath = path.normalize(`${gitRoot}/hooks/${hook}`)
370373

371374
if (fs.existsSync(hookPath)){
372-
if (VERBOSE) log.debug(`Hook ${hook} is not set, removing!`)
375+
if (VERBOSE) getLog().debug(`Hook ${hook} is not set, removing!`)
373376
fs.unlinkSync(hookPath)
374377
}
375378

376379
if (verbose)
377-
log.success(`Successfully removed the ${hook} hook`)
380+
getLog().success(`Successfully removed the ${hook} hook`)
378381
}
379382

380383
/**

0 commit comments

Comments
 (0)