@afokapu/atdd-bun 0.10.109 → 0.10.110
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/integrity.json +2 -2
- package/package.json +1 -1
- package/src/hooks.ts +12 -1
package/integrity.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.10.
|
|
2
|
+
"version": "0.10.110",
|
|
3
3
|
"files": {
|
|
4
4
|
"HOOK_AUDIT.md": "5329d840db37671b1918f688ead26865473b87db73dbc75f7c8b2a8bbe8d6d43",
|
|
5
5
|
"README.md": "8aefceaa24bee498f39081b2aaf4c0d5c54bc1ed9849c20e1d98d1427df56eab",
|
|
@@ -1269,7 +1269,7 @@
|
|
|
1269
1269
|
"src/cli.ts": "395638ab87565bb10c2beb35988ff1acf686924d13515795156a2e8893b3da88",
|
|
1270
1270
|
"src/docs-capability.ts": "bdeeb414649049b1cd4fa8008cada3a576318be51c43bec91bfa46a8e250c270",
|
|
1271
1271
|
"src/enforce.ts": "c4811abe63efe4568f3cf26e21a152d1537e120cb3ce471daca32367cf6e2cda",
|
|
1272
|
-
"src/hooks.ts": "
|
|
1272
|
+
"src/hooks.ts": "fce67a102fe61c15b4100daddf842ce7264d9e0d0e79ec89c4ed4a0b188967b7",
|
|
1273
1273
|
"src/index.ts": "4081f8b08d1d3ee9e15a9964143e53d9cfb94a5616ab3e58a180d24cc16dc381",
|
|
1274
1274
|
"src/integrity.ts": "f1ede7cb04924ae88e11917047277e264af6596b9759e381bd9c497cd34a797d",
|
|
1275
1275
|
"src/journey-docs.ts": "994d229376244c84212cff951032823068a76565dd2fd427b9d44e341bd14853",
|
package/package.json
CHANGED
package/src/hooks.ts
CHANGED
|
@@ -345,7 +345,7 @@ type PrimaryPolicy = { policy: HookPolicy; source: { path: string; commit: strin
|
|
|
345
345
|
async function primaryPolicy(root: string): Promise<PrimaryPolicy> { const found = await primaryRoot(await realpath(resolve(root))); if (!found) return { policy: defaultHookPolicy, source: null }; const primary = await realpath(found), revision = await git(primary, ["rev-parse", "--verify", "HEAD^{commit}"]); if (revision.code || !revision.out) return { policy: defaultHookPolicy, source: null }; const source = { path: primary, commit: revision.out }, committed = await git(primary, ["show", `${source.commit}:atdd-bun.yaml`]); return { policy: committed.code ? defaultHookPolicy : parsePolicy(committed.out), source }; }
|
|
346
346
|
const disabledWorktreePolicy = (source: PrimaryPolicy["source"]) => bad(source ? `worktree policy is disabled in primary checkout ${source.path} at ${source.commit}; update the primary checkout and try again` : "worktree policy is disabled");
|
|
347
347
|
export type WorktreeLayout = { primary: string; worktreeRoot: string; current: string; branch: string };
|
|
348
|
-
async function layout(root: string, cfg: WorktreePolicy): Promise<WorktreeLayout | { error: string }> { const current = await realpath(resolve(root)), commonRoot = await primaryRoot(current); if (!commonRoot) return { error: "not inside a Git worktree" }; const primary = await realpath(commonRoot), expectedPrimary = cfg.primary_directory === "." ? primary : join(dirname(primary), cfg.primary_directory); if (primary !== expectedPrimary) return { error: `primary checkout must be ${expectedPrimary}, not ${primary}` }; const branch = (await git(primary, ["symbolic-ref", "--quiet", "--short", "HEAD"])).out; if (branch !== cfg.primary_branch) return { error: `primary checkout ${primary} must be on ${cfg.primary_branch}, not ${branch || "a detached HEAD"}` }; return { primary, worktreeRoot: resolve(primary, cfg.root.replaceAll("{repo}", basename(primary))), current, branch: (await git(current, ["symbolic-ref", "--quiet", "--short", "HEAD"])).out }; }
|
|
348
|
+
async function layout(root: string, cfg: WorktreePolicy): Promise<WorktreeLayout | { error: string }> { const current = await realpath(resolve(root)), commonRoot = await primaryRoot(current); if (!commonRoot) return { error: "not inside a Git worktree" }; const primary = await realpath(commonRoot), expectedPrimary = cfg.primary_directory === "." ? primary : join(dirname(primary), cfg.primary_directory); if (primary !== expectedPrimary) return { error: `primary checkout must be ${expectedPrimary}, not ${primary}` }; const branch = (await git(primary, ["symbolic-ref", "--quiet", "--short", "HEAD"])).out; if (branch !== cfg.primary_branch && !(await jjPrimaryOnBranch(primary, cfg.primary_branch))) return { error: `primary checkout ${primary} must be on ${cfg.primary_branch}, not ${branch || "a detached HEAD"}` }; return { primary, worktreeRoot: resolve(primary, cfg.root.replaceAll("{repo}", basename(primary))), current, branch: (await git(current, ["symbolic-ref", "--quiet", "--short", "HEAD"])).out }; }
|
|
349
349
|
async function worktreeCommitPolicy(root: string, cfg: WorktreePolicy): Promise<string | null> { if (!cfg.enabled || !cfg.require_linked_worktree) return null; const state = await layout(root, cfg); if ("error" in state) return state.error; if (state.current === state.primary) return `commits must use a linked worktree beneath ${state.worktreeRoot}; run: atdd-bun worktree start <branch>`; if (!inside(state.worktreeRoot, state.current)) return `linked worktree ${state.current} is outside required root ${state.worktreeRoot}`; if (!state.branch) return "commits require a named branch, not a detached HEAD"; return null; }
|
|
350
350
|
|
|
351
351
|
export async function runHook(event: HookEvent, root = process.cwd(), args: string[] = [], stdin = "") {
|
|
@@ -421,6 +421,17 @@ async function branchForCommit(root: string, commit: string, protectedBranches:
|
|
|
421
421
|
: { error: `current Jujutsu revision must have exactly one non-protected exported bookmark; found ${candidates.length}` };
|
|
422
422
|
}
|
|
423
423
|
|
|
424
|
+
// A JJ-colocated primary keeps Git HEAD detached at its working-copy parent, so JJ state decides:
|
|
425
|
+
// the parent must be exactly one commit and it must be the primary branch or its origin bookmark.
|
|
426
|
+
async function jjPrimaryOnBranch(primary: string, branch: string): Promise<boolean> {
|
|
427
|
+
if (!existsSync(join(primary, ".jj"))) return false;
|
|
428
|
+
const name = JSON.stringify(branch), lines = async (revset: string) => {
|
|
429
|
+
const result = await jj(primary, ["log", "--ignore-working-copy", "--no-graph", "-r", revset, "-T", 'commit_id ++ "\\n"']).catch(() => null);
|
|
430
|
+
return result && !result.code ? result.out.split("\n").filter(Boolean) : [];
|
|
431
|
+
};
|
|
432
|
+
return (await lines("@-")).length === 1 && (await lines(`@- & (bookmarks(exact:${name}) | remote_bookmarks(exact:${name}, exact:"origin"))`)).length === 1;
|
|
433
|
+
}
|
|
434
|
+
|
|
424
435
|
type Layout = { primary: string; worktreeRoot: string; current: string };
|
|
425
436
|
async function jjLayout(root: string, cfg: HookPolicy): Promise<Layout | { error: string }> {
|
|
426
437
|
const current = await realpath(resolve(root));
|