Skip to content

Commit c84b712

Browse files
committed
fix(hooks): respect Deptrac config in pre-push artifact generation
The pre-push hook now checks the .git-hooks.config.json tools section when deciding whether to generate the Deptrac image. Setting `"Deptrac": { "enabled": false }` will now skip both the static analysis (pre-commit) AND the image generation (pre-push). Skipping can also be done via: - SKIP_DEPTRAC=1 env var - SKIP_DEPTRAC_IMAGE=1 env var - skip.artifacts: true in config Also updated schema to include explicit tool name properties for better IDE autocomplete support.
1 parent 72836c0 commit c84b712

File tree

2 files changed

+65
-9
lines changed

2 files changed

+65
-9
lines changed

booster/.husky/pre-push.ts

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,34 @@ export async function runTests(): Promise<boolean> {
3737
return true
3838
}
3939

40-
export async function handleArtifacts(): Promise<void> {
40+
/**
41+
* Check if a tool is disabled in the config
42+
*/
43+
function isToolDisabled(toolName: string, config: Awaited<ReturnType<typeof loadConfig>>): boolean {
44+
if (!config.tools) return false
45+
46+
// Case-insensitive lookup
47+
const configKey = Object.keys(config.tools).find(
48+
key => key.toLowerCase() === toolName.toLowerCase()
49+
)
50+
51+
if (!configKey) return false
52+
return config.tools[configKey]?.enabled === false
53+
}
54+
55+
export async function handleArtifacts(config: Awaited<ReturnType<typeof loadConfig>>): Promise<void> {
4156
// Generate artifacts - these are informational and don't block the push
4257
// Developers should commit these manually if needed
4358

44-
if (!isSkipped('deptrac_image')) {
59+
// Check both env var and config file for Deptrac image
60+
if (!isSkipped('deptrac_image') && !isSkipped('deptrac') && !isToolDisabled('Deptrac', config)) {
4561
await generateDeptracImage()
62+
} else {
63+
log.skip('Deptrac image generation skipped')
4664
}
4765

48-
if (!isSkipped('api_docs')) {
66+
// Check both env var and config file for API docs
67+
if (!isSkipped('api_docs') && !isToolDisabled('API Docs', config)) {
4968
try {
5069
const result = await generateApiDocs()
5170
if (result.changed) {
@@ -55,6 +74,8 @@ export async function handleArtifacts(): Promise<void> {
5574
// API docs generation is optional, don't fail the push
5675
log.warn('API docs generation failed, but continuing with push')
5776
}
77+
} else {
78+
log.skip('API docs generation skipped')
5879
}
5980
}
6081

@@ -70,7 +91,7 @@ await runHook(GitHook.PrePush, async () => {
7091

7192
// Generate artifacts - informational only, don't block push
7293
if (!isHookSkippedByConfig('artifacts', config)) {
73-
await handleArtifacts()
94+
await handleArtifacts(config)
7495
} else {
7596
log.info('Skipping artifact generation (disabled in config)')
7697
}

booster/.husky/tests/pre-push.test.mjs

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ vi.mock('../shared/index.ts', () => ({
1616
success: vi.fn(),
1717
error: vi.fn(),
1818
warn: vi.fn(),
19+
skip: vi.fn(),
1920
},
2021
runHook: vi.fn(), // Prevent automatic execution
2122
exec: vi.fn(),
@@ -66,22 +67,24 @@ describe('Pre-push Hook', () => {
6667
})
6768

6869
describe('handleArtifacts', () => {
70+
const emptyConfig = {}
71+
6972
it('should generate both deptrac image and api docs', async () => {
7073
isSkipped.mockReturnValue(false)
7174
generateDeptracImage.mockResolvedValue({ generated: true, changed: true })
7275
generateApiDocs.mockResolvedValue({ generated: true, changed: false })
7376

74-
await handleArtifacts()
77+
await handleArtifacts(emptyConfig)
7578

7679
expect(generateDeptracImage).toHaveBeenCalled()
7780
expect(generateApiDocs).toHaveBeenCalled()
7881
})
7982

8083
it('should skip deptrac if env var is set', async () => {
81-
isSkipped.mockImplementation((name) => name === 'deptrac_image')
84+
isSkipped.mockImplementation((name) => name === 'deptrac_image' || name === 'deptrac')
8285
generateApiDocs.mockResolvedValue({ generated: true, changed: false })
8386

84-
await handleArtifacts()
87+
await handleArtifacts(emptyConfig)
8588

8689
expect(generateDeptracImage).not.toHaveBeenCalled()
8790
expect(generateApiDocs).toHaveBeenCalled()
@@ -91,7 +94,7 @@ describe('Pre-push Hook', () => {
9194
isSkipped.mockImplementation((name) => name === 'api_docs')
9295
generateDeptracImage.mockResolvedValue({ generated: true, changed: false })
9396

94-
await handleArtifacts()
97+
await handleArtifacts(emptyConfig)
9598

9699
expect(generateDeptracImage).toHaveBeenCalled()
97100
expect(generateApiDocs).not.toHaveBeenCalled()
@@ -103,7 +106,39 @@ describe('Pre-push Hook', () => {
103106
generateApiDocs.mockRejectedValue(new Error('Failed'))
104107

105108
// Should not throw
106-
await expect(handleArtifacts()).resolves.not.toThrow()
109+
await expect(handleArtifacts(emptyConfig)).resolves.not.toThrow()
110+
})
111+
112+
it('should skip deptrac if disabled in config', async () => {
113+
isSkipped.mockReturnValue(false)
114+
generateApiDocs.mockResolvedValue({ generated: true, changed: false })
115+
116+
const configWithDeptracDisabled = {
117+
tools: {
118+
Deptrac: { enabled: false }
119+
}
120+
}
121+
122+
await handleArtifacts(configWithDeptracDisabled)
123+
124+
expect(generateDeptracImage).not.toHaveBeenCalled()
125+
expect(generateApiDocs).toHaveBeenCalled()
126+
})
127+
128+
it('should skip deptrac if disabled with lowercase name in config', async () => {
129+
isSkipped.mockReturnValue(false)
130+
generateApiDocs.mockResolvedValue({ generated: true, changed: false })
131+
132+
const configWithDeptracDisabled = {
133+
tools: {
134+
deptrac: { enabled: false }
135+
}
136+
}
137+
138+
await handleArtifacts(configWithDeptracDisabled)
139+
140+
expect(generateDeptracImage).not.toHaveBeenCalled()
141+
expect(generateApiDocs).toHaveBeenCalled()
107142
})
108143
})
109144
})

0 commit comments

Comments
 (0)