genesis-compiler 1.5.0 → 1.5.1
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/package.json +1 -1
- package/src/index/git.js +32 -10
package/package.json
CHANGED
package/src/index/git.js
CHANGED
|
@@ -2,30 +2,52 @@ import { realpath } from 'node:fs/promises';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
|
|
4
4
|
import { fail } from './errors.js';
|
|
5
|
-
import {
|
|
5
|
+
import { runGit } from './process.js';
|
|
6
6
|
|
|
7
7
|
/** Resolve the caller's working directory and the one Git repository that contains it. */
|
|
8
8
|
export async function gitContext(projectRoot = process.cwd()) {
|
|
9
9
|
let root;
|
|
10
10
|
try { root = await realpath(path.resolve(projectRoot)); } catch (error) {
|
|
11
|
-
fail('
|
|
12
|
-
|
|
11
|
+
fail('GIT_PROJECT_ROOT_UNAVAILABLE', `Cannot resolve project root: ${projectRoot}. ${error.message}`, {
|
|
12
|
+
stage: 'resolve-project-root',
|
|
13
|
+
projectRoot,
|
|
14
|
+
cause: error.code,
|
|
13
15
|
});
|
|
14
16
|
}
|
|
15
|
-
let
|
|
17
|
+
let discovery;
|
|
16
18
|
try {
|
|
17
|
-
|
|
19
|
+
discovery = await runGit(root, ['rev-parse', '--show-toplevel'], { env: { LC_ALL: 'C' } });
|
|
18
20
|
} catch (error) {
|
|
21
|
+
const details = { ...error.details, stage: 'discover-worktree', projectRoot: root };
|
|
19
22
|
if (/detected dubious ownership/iu.test(error?.details?.stderr || '')) {
|
|
20
|
-
fail('GIT_REPOSITORY_UNTRUSTED', `Git rejected ownership of the project worktree: ${projectRoot}. The caller must explicitly trust this shared repository.`,
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
fail('GIT_REPOSITORY_UNTRUSTED', `Git rejected ownership of the project worktree: ${projectRoot}. The caller must explicitly trust this shared repository.`, details);
|
|
24
|
+
}
|
|
25
|
+
if (error?.details?.status === 128 && /^fatal: (?:not a git repository|this operation must be run in a work tree)/mu.test(error.details.stderr || '')) {
|
|
26
|
+
fail('GIT_REPOSITORY_REQUIRED', `Project root is not inside a Git worktree: ${projectRoot}.`, details);
|
|
23
27
|
}
|
|
24
|
-
|
|
28
|
+
error.details = details;
|
|
29
|
+
throw error;
|
|
30
|
+
}
|
|
31
|
+
// Git terminates this path with one newline; whitespace can belong to the path.
|
|
32
|
+
const reportedRoot = discovery.stdout.toString('utf8').replace(/\n$/u, '');
|
|
33
|
+
if (!path.isAbsolute(reportedRoot)) {
|
|
34
|
+
fail('GIT_WORKTREE_PATH_INVALID', 'Git returned an empty or non-absolute worktree path.', {
|
|
35
|
+
stage: 'resolve-worktree', projectRoot: root, reportedRoot,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
let repositoryRoot;
|
|
39
|
+
try {
|
|
40
|
+
repositoryRoot = await realpath(reportedRoot);
|
|
41
|
+
} catch (error) {
|
|
42
|
+
fail('GIT_WORKTREE_PATH_UNAVAILABLE', `Cannot resolve the worktree reported by Git: ${reportedRoot}. ${error.message}`, {
|
|
43
|
+
stage: 'resolve-worktree', projectRoot: root, reportedRoot, cause: error.code,
|
|
44
|
+
});
|
|
25
45
|
}
|
|
26
46
|
const relative = path.relative(repositoryRoot, root);
|
|
27
47
|
if (relative === '..' || relative.startsWith(`..${path.sep}`)) {
|
|
28
|
-
fail('
|
|
48
|
+
fail('GIT_WORKTREE_PATH_INVALID', `Project root is outside its reported Git worktree: ${projectRoot}.`, {
|
|
49
|
+
stage: 'resolve-worktree', projectRoot: root, reportedRoot,
|
|
50
|
+
});
|
|
29
51
|
}
|
|
30
52
|
return { workingDirectory: root, repositoryRoot };
|
|
31
53
|
}
|