Allow reviewer runtime with remote origins
This commit is contained in:
@@ -203,6 +203,13 @@ function readGitOutput(
|
|||||||
}).trim();
|
}).trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isRemoteGitOrigin(originUrl: string): boolean {
|
||||||
|
return (
|
||||||
|
/^(?:https?|ssh|git):\/\//i.test(originUrl) ||
|
||||||
|
/^[^/\\]+@[^:]+:.+/.test(originUrl)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export function assertReadonlyWorkspaceRepoConnectivity(
|
export function assertReadonlyWorkspaceRepoConnectivity(
|
||||||
baseEnv: NodeJS.ProcessEnv,
|
baseEnv: NodeJS.ProcessEnv,
|
||||||
enabled: boolean,
|
enabled: boolean,
|
||||||
@@ -227,6 +234,10 @@ export function assertReadonlyWorkspaceRepoConnectivity(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isRemoteGitOrigin(originUrl)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!path.isAbsolute(originUrl) || !fs.existsSync(originUrl)) {
|
if (!path.isAbsolute(originUrl) || !fs.existsSync(originUrl)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`EJClaw readonly runtime cannot access local git origin path: ${originUrl || '(missing)'}`,
|
`EJClaw readonly runtime cannot access local git origin path: ${originUrl || '(missing)'}`,
|
||||||
|
|||||||
@@ -167,6 +167,30 @@ describe('claude reviewer runtime guard', () => {
|
|||||||
expect(() => assertReadonlyWorkspaceRepoConnectivity(env, true)).not.toThrow();
|
expect(() => assertReadonlyWorkspaceRepoConnectivity(env, true)).not.toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it.each([
|
||||||
|
'https://github.com/EyeJoker-Internal/eyejoker-db.git',
|
||||||
|
'git@github.com:EyeJoker-Internal/eyejoker-db.git',
|
||||||
|
])(
|
||||||
|
'accepts remote origin %s without requiring a mounted local canonical path',
|
||||||
|
(originUrl) => {
|
||||||
|
const cwd = createTempRepo('ejclaw-reviewer-remote-origin-');
|
||||||
|
execFileSync('git', ['remote', 'add', 'origin', originUrl], {
|
||||||
|
cwd,
|
||||||
|
encoding: 'utf-8',
|
||||||
|
stdio: ['ignore', 'pipe', 'pipe'],
|
||||||
|
});
|
||||||
|
const env = buildReviewerGitGuardEnv(
|
||||||
|
{
|
||||||
|
PATH: process.env.PATH,
|
||||||
|
EJCLAW_WORK_DIR: cwd,
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(() => assertReadonlyWorkspaceRepoConnectivity(env, true)).not.toThrow();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
it('fails fast when the local origin path is not mounted as a git repo', () => {
|
it('fails fast when the local origin path is not mounted as a git repo', () => {
|
||||||
const cwd = createTempRepo('ejclaw-reviewer-workspace-');
|
const cwd = createTempRepo('ejclaw-reviewer-workspace-');
|
||||||
const missingOriginDir = path.join(
|
const missingOriginDir = path.join(
|
||||||
|
|||||||
@@ -200,6 +200,13 @@ function readGitOutput(
|
|||||||
}).trim();
|
}).trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isRemoteGitOrigin(originUrl: string): boolean {
|
||||||
|
return (
|
||||||
|
/^(?:https?|ssh|git):\/\//i.test(originUrl) ||
|
||||||
|
/^[^/\\]+@[^:]+:.+/.test(originUrl)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export function assertReadonlyWorkspaceRepoConnectivity(
|
export function assertReadonlyWorkspaceRepoConnectivity(
|
||||||
baseEnv: NodeJS.ProcessEnv,
|
baseEnv: NodeJS.ProcessEnv,
|
||||||
enabled: boolean,
|
enabled: boolean,
|
||||||
@@ -224,6 +231,10 @@ export function assertReadonlyWorkspaceRepoConnectivity(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isRemoteGitOrigin(originUrl)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!path.isAbsolute(originUrl) || !fs.existsSync(originUrl)) {
|
if (!path.isAbsolute(originUrl) || !fs.existsSync(originUrl)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`EJClaw readonly runtime cannot access local git origin path: ${originUrl || '(missing)'}`,
|
`EJClaw readonly runtime cannot access local git origin path: ${originUrl || '(missing)'}`,
|
||||||
|
|||||||
@@ -154,6 +154,30 @@ describe('codex reviewer runtime guard', () => {
|
|||||||
expect(() => assertReadonlyWorkspaceRepoConnectivity(env, true)).not.toThrow();
|
expect(() => assertReadonlyWorkspaceRepoConnectivity(env, true)).not.toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it.each([
|
||||||
|
'https://github.com/EyeJoker-Internal/eyejoker-db.git',
|
||||||
|
'git@github.com:EyeJoker-Internal/eyejoker-db.git',
|
||||||
|
])(
|
||||||
|
'accepts remote origin %s without requiring a mounted local canonical path',
|
||||||
|
(originUrl) => {
|
||||||
|
const cwd = createTempRepo('ejclaw-reviewer-remote-origin-');
|
||||||
|
execFileSync('git', ['remote', 'add', 'origin', originUrl], {
|
||||||
|
cwd,
|
||||||
|
encoding: 'utf-8',
|
||||||
|
stdio: ['ignore', 'pipe', 'pipe'],
|
||||||
|
});
|
||||||
|
const env = buildReviewerGitGuardEnv(
|
||||||
|
{
|
||||||
|
PATH: process.env.PATH,
|
||||||
|
EJCLAW_WORK_DIR: cwd,
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(() => assertReadonlyWorkspaceRepoConnectivity(env, true)).not.toThrow();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
it('fails fast when the local origin path is not mounted as a git repo', () => {
|
it('fails fast when the local origin path is not mounted as a git repo', () => {
|
||||||
const cwd = createTempRepo('ejclaw-reviewer-workspace-');
|
const cwd = createTempRepo('ejclaw-reviewer-workspace-');
|
||||||
const missingOriginDir = path.join(
|
const missingOriginDir = path.join(
|
||||||
|
|||||||
Reference in New Issue
Block a user