Sweep active code, tests, identity files, public docs, CMS seed content, and stale handoffs so old assistant-name fixtures no longer leak into current Clawdie/system-namespace behavior. Keep the skills-memory SQL artifact unchanged per regeneration policy. --- Build: pass Tests: pass — 2197 passed (164 files) --- Build: pass | Tests: pass — 2197 passed (650 files)
235 lines
6 KiB
TypeScript
235 lines
6 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
|
|
const fsMocks = vi.hoisted(() => ({
|
|
mkdirSync: vi.fn(),
|
|
writeFileSync: vi.fn(),
|
|
existsSync: vi.fn(() => false),
|
|
readFileSync: vi.fn(() => ''),
|
|
appendFileSync: vi.fn(),
|
|
}));
|
|
|
|
const bastilleMocks = vi.hoisted(() => ({
|
|
bastille: vi.fn(),
|
|
bastilleTimed: vi.fn(),
|
|
jailExists: vi.fn(),
|
|
jailRoot: vi.fn(),
|
|
detectFreeBSDRelease: vi.fn(),
|
|
}));
|
|
|
|
const packageMocks = vi.hoisted(() => ({
|
|
loadPackageList: vi.fn(),
|
|
mountPkgCacheInJail: vi.fn(),
|
|
}));
|
|
|
|
const statusMocks = vi.hoisted(() => ({
|
|
emitStatus: vi.fn(),
|
|
}));
|
|
|
|
const childProcessMocks = vi.hoisted(() => ({
|
|
execSync: vi.fn(),
|
|
spawnSync: vi.fn(),
|
|
}));
|
|
|
|
const tailscaleMocks = vi.hoisted(() => ({
|
|
maybeEnableTailscaleInJail: vi.fn(),
|
|
}));
|
|
|
|
const envMocks = vi.hoisted(() => ({
|
|
readEnvFile: vi.fn(),
|
|
}));
|
|
|
|
vi.mock('child_process', () => childProcessMocks);
|
|
|
|
vi.mock('fs', async () => {
|
|
const actual = await vi.importActual<typeof import('fs')>('fs');
|
|
const mocked = { ...actual, ...fsMocks };
|
|
return { ...mocked, default: mocked };
|
|
});
|
|
|
|
vi.mock('./bastille-helpers.js', () => bastilleMocks);
|
|
|
|
vi.mock('./packages.js', () => packageMocks);
|
|
|
|
vi.mock('./status.js', () => statusMocks);
|
|
|
|
vi.mock('./tailscale.js', () => tailscaleMocks);
|
|
|
|
vi.mock('../src/env.js', () => envMocks);
|
|
|
|
vi.mock('./platform.js', () => ({
|
|
getPlatform: vi.fn(() => 'freebsd'),
|
|
}));
|
|
|
|
vi.mock('../src/logger.js', () => ({
|
|
logger: {
|
|
info: vi.fn(),
|
|
warn: vi.fn(),
|
|
error: vi.fn(),
|
|
debug: vi.fn(),
|
|
},
|
|
}));
|
|
|
|
function mockConfig(overrides: Record<string, unknown> = {}) {
|
|
vi.doMock('../src/config.js', () => ({
|
|
CODE_SERVICE_INTERNAL_DOMAIN: 'git.home.arpa',
|
|
CODE_HOSTING_MODE: 'local',
|
|
FEATURE_GIT: true,
|
|
GIT_DEFAULT_REPO_NAME: 'alpha-ai.git',
|
|
GIT_JAIL_NAME: 'alpha-git',
|
|
GIT_MIRROR_URLS: [],
|
|
GIT_JAIL_IP: '10.0.0.6',
|
|
GIT_STORAGE_ROOT: '/srv/git',
|
|
PLATFORM_RUNTIME_HOME: '/home/alpha',
|
|
REMOTE_GIT_URL: '',
|
|
SUBNET_BASE: '10.0.0',
|
|
...overrides,
|
|
}));
|
|
}
|
|
|
|
function ok(output = '') {
|
|
return { ok: true, output };
|
|
}
|
|
|
|
describe('setup/git.ts', () => {
|
|
beforeEach(() => {
|
|
vi.resetModules();
|
|
vi.clearAllMocks();
|
|
bastilleMocks.bastille.mockReturnValue(ok());
|
|
bastilleMocks.bastilleTimed.mockReturnValue(ok());
|
|
bastilleMocks.jailExists.mockReturnValue(true);
|
|
bastilleMocks.jailRoot.mockReturnValue('/jails/alpha-git/root');
|
|
bastilleMocks.detectFreeBSDRelease.mockReturnValue('15.0-RELEASE');
|
|
packageMocks.loadPackageList.mockReturnValue(['git', 'rsync']);
|
|
packageMocks.mountPkgCacheInJail.mockImplementation(() => {});
|
|
tailscaleMocks.maybeEnableTailscaleInJail.mockImplementation(() => {});
|
|
envMocks.readEnvFile.mockReturnValue({});
|
|
childProcessMocks.execSync.mockImplementation(() => Buffer.from(''));
|
|
fsMocks.existsSync.mockReturnValue(false);
|
|
});
|
|
|
|
it('skips when git feature is disabled', async () => {
|
|
mockConfig({ FEATURE_GIT: false });
|
|
const mod = await import('./git.js');
|
|
|
|
await mod.run([]);
|
|
|
|
expect(statusMocks.emitStatus).toHaveBeenCalledWith(
|
|
'SETUP_GIT',
|
|
expect.objectContaining({
|
|
STATUS: 'skipped',
|
|
REASON: 'feature_disabled',
|
|
}),
|
|
);
|
|
expect(bastilleMocks.bastille).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('falls back to git init --bare when mirror clone fails', async () => {
|
|
mockConfig({ REMOTE_GIT_URL: 'https://codeberg.org/Clawdie/pi.git' });
|
|
bastilleMocks.bastille.mockImplementation((...args: string[]) => {
|
|
if (
|
|
args[0] === 'cmd' &&
|
|
args[1] === 'alpha-git' &&
|
|
args[2] === 'test' &&
|
|
args[3] === '-d'
|
|
) {
|
|
return { ok: false, output: '' };
|
|
}
|
|
if (
|
|
args[0] === 'cmd' &&
|
|
args.includes('git') &&
|
|
args.includes('--version')
|
|
) {
|
|
return ok('git version 2.46.0');
|
|
}
|
|
if (args[0] === 'cmd' && args.includes('rev-parse')) {
|
|
return ok('true\n');
|
|
}
|
|
return ok();
|
|
});
|
|
bastilleMocks.bastilleTimed.mockReturnValue({
|
|
ok: false,
|
|
output: 'mirror failed',
|
|
});
|
|
|
|
const mod = await import('./git.js');
|
|
await mod.run([]);
|
|
|
|
expect(bastilleMocks.bastilleTimed).toHaveBeenCalledWith(
|
|
expect.any(Number),
|
|
'cmd',
|
|
'alpha-git',
|
|
'git',
|
|
'clone',
|
|
'--mirror',
|
|
'https://codeberg.org/Clawdie/pi.git',
|
|
'/srv/git/alpha-ai.git',
|
|
);
|
|
expect(bastilleMocks.bastille).toHaveBeenCalledWith(
|
|
'cmd',
|
|
'alpha-git',
|
|
'git',
|
|
'init',
|
|
'--bare',
|
|
'/srv/git/alpha-ai.git',
|
|
);
|
|
expect(statusMocks.emitStatus).toHaveBeenCalledWith(
|
|
'SETUP_GIT',
|
|
expect.objectContaining({ STATUS: 'success' }),
|
|
);
|
|
});
|
|
|
|
it('clones only unique extra mirror repos', async () => {
|
|
mockConfig({
|
|
REMOTE_GIT_URL: 'https://codeberg.org/Clawdie/pi.git',
|
|
GIT_MIRROR_URLS: [
|
|
'https://codeberg.org/Clawdie/pi.git',
|
|
'git@codeberg.org:Clawdie/docs.git',
|
|
],
|
|
});
|
|
bastilleMocks.bastille.mockImplementation((...args: string[]) => {
|
|
if (
|
|
args[0] === 'cmd' &&
|
|
args[1] === 'alpha-git' &&
|
|
args[2] === 'test' &&
|
|
args[3] === '-d'
|
|
) {
|
|
return { ok: false, output: '' };
|
|
}
|
|
if (
|
|
args[0] === 'cmd' &&
|
|
args.includes('git') &&
|
|
args.includes('--version')
|
|
) {
|
|
return ok('git version 2.46.0');
|
|
}
|
|
if (args[0] === 'cmd' && args.includes('rev-parse')) {
|
|
return ok('true\n');
|
|
}
|
|
return ok();
|
|
});
|
|
|
|
const mod = await import('./git.js');
|
|
await mod.run([]);
|
|
|
|
const cloneCalls = bastilleMocks.bastilleTimed.mock.calls;
|
|
expect(cloneCalls).toHaveLength(2);
|
|
expect(cloneCalls[0].slice(1)).toEqual([
|
|
'cmd',
|
|
'alpha-git',
|
|
'git',
|
|
'clone',
|
|
'--mirror',
|
|
'https://codeberg.org/Clawdie/pi.git',
|
|
'/srv/git/alpha-ai.git',
|
|
]);
|
|
expect(cloneCalls[1].slice(1)).toEqual([
|
|
'cmd',
|
|
'alpha-git',
|
|
'git',
|
|
'clone',
|
|
'--mirror',
|
|
'git@codeberg.org:Clawdie/docs.git',
|
|
'/srv/git/docs.git',
|
|
]);
|
|
});
|
|
});
|