test(frontmatter-install-hook): isolate hooksPath assertion from developer global config

The "installHook writes ... and sets core.hooksPath" test asserted
`git config --get core.hooksPath` returns `.githooks`, which falls
back to the global scope when local is unset. Developers who set
`core.hooksPath` globally (common with dotfiles managers pointing at
~/.config/git/hooks) saw a deterministic FAIL because installHook
intentionally respects an existing global value and skips writing
the local one — exactly the documented contract.

Fix: read via `git config --local --get core.hooksPath` (scope-locked)
and branch the assertion on whether a global is already set. Both
clean-CI (local should be '.githooks') and developer-with-global
(local should be empty; installHook correctly didn't clobber) now
pass deterministically.

No API change. installHook behavior is unchanged.

Verified locally with the affected test passing under
`GIT_CONFIG_GLOBAL=~/.gitconfig` carrying `core.hooksPath=...`.
This commit is contained in:
Jeremy Knows
2026-05-12 10:06:02 -04:00
parent 17b190e227
commit 0e4da2cb38
+20 -3
View File
@@ -31,9 +31,26 @@ describe('frontmatter install-hook (B13)', () => {
const content = readFileSync(hookPath, 'utf8');
expect(content).toContain('gbrain frontmatter');
expect(content).toContain('git diff --cached');
// Configured hooksPath
const hooksPath = execFileSync('git', ['-C', tmp, 'config', '--get', 'core.hooksPath'], { encoding: 'utf8' }).trim();
expect(hooksPath).toBe('.githooks');
// installHook's contract is "set core.hooksPath unless it's already set
// elsewhere". Test BOTH branches deterministically by reading the local
// scope only: clean CI → local should be `.githooks`; developer with a
// global core.hooksPath (e.g. dotfiles → ~/.config/git/hooks) → local
// should be empty because installHook correctly skipped clobbering.
// Reading via `--get` without `--local` falls back to global scope when
// local is unset, which made this test environmentally fragile.
let globalHooksPath = '';
try {
globalHooksPath = execFileSync('git', ['config', '--global', '--get', 'core.hooksPath'], { encoding: 'utf8' }).trim();
} catch { /* unset is the expected clean-env case */ }
let localHooksPath = '';
try {
localHooksPath = execFileSync('git', ['-C', tmp, 'config', '--local', '--get', 'core.hooksPath'], { encoding: 'utf8' }).trim();
} catch { /* unset is fine when global was present */ }
if (globalHooksPath) {
expect(localHooksPath).toBe('');
} else {
expect(localHooksPath).toBe('.githooks');
}
});
test('installHook refuses to clobber existing hook without --force', () => {