@pleri/olam-cli 0.1.69 → 0.1.72
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/dist/cli-version.d.ts +16 -0
- package/dist/cli-version.d.ts.map +1 -0
- package/dist/cli-version.js +39 -0
- package/dist/cli-version.js.map +1 -0
- package/dist/commands/create.d.ts.map +1 -1
- package/dist/commands/create.js +2 -0
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/host-cp.d.ts.map +1 -1
- package/dist/commands/host-cp.js +10 -0
- package/dist/commands/host-cp.js.map +1 -1
- package/dist/commands/runbooks.d.ts +13 -0
- package/dist/commands/runbooks.d.ts.map +1 -0
- package/dist/commands/runbooks.js +189 -0
- package/dist/commands/runbooks.js.map +1 -0
- package/dist/commands/world-snapshot.d.ts +1 -0
- package/dist/commands/world-snapshot.d.ts.map +1 -1
- package/dist/commands/world-snapshot.js +126 -1
- package/dist/commands/world-snapshot.js.map +1 -1
- package/dist/commands/worldspec/compile.d.ts +20 -0
- package/dist/commands/worldspec/compile.d.ts.map +1 -0
- package/dist/commands/worldspec/compile.js +130 -0
- package/dist/commands/worldspec/compile.js.map +1 -0
- package/dist/commands/worldspec/index.d.ts +12 -0
- package/dist/commands/worldspec/index.d.ts.map +1 -0
- package/dist/commands/worldspec/index.js +23 -0
- package/dist/commands/worldspec/index.js.map +1 -0
- package/dist/commands/worldspec/init.d.ts +15 -0
- package/dist/commands/worldspec/init.d.ts.map +1 -0
- package/dist/commands/worldspec/init.js +166 -0
- package/dist/commands/worldspec/init.js.map +1 -0
- package/dist/commands/worldspec/schema.d.ts +11 -0
- package/dist/commands/worldspec/schema.d.ts.map +1 -0
- package/dist/commands/worldspec/schema.js +55 -0
- package/dist/commands/worldspec/schema.js.map +1 -0
- package/dist/commands/worldspec/validate.d.ts +15 -0
- package/dist/commands/worldspec/validate.d.ts.map +1 -0
- package/dist/commands/worldspec/validate.js +66 -0
- package/dist/commands/worldspec/validate.js.map +1 -0
- package/dist/exit-codes.d.ts +32 -0
- package/dist/exit-codes.d.ts.map +1 -1
- package/dist/exit-codes.js +32 -0
- package/dist/exit-codes.js.map +1 -1
- package/dist/image-digests.json +5 -5
- package/dist/index.js +4726 -1231
- package/dist/index.js.map +1 -1
- package/dist/mcp-server.js +1424 -321
- package/host-cp/compose.yaml +6 -0
- package/host-cp/src/global-config-source.mjs +71 -0
- package/host-cp/src/listening-server-poller.mjs +1 -1
- package/host-cp/src/plan-orchestrator.mjs +20 -1
- package/host-cp/src/port-bridge-manager.mjs +1 -1
- package/host-cp/src/server.mjs +46 -7
- package/host-cp/src/version-status.mjs +36 -0
- package/package.json +4 -2
- package/dist/__tests__/audit-publish-deps-contract.test.d.ts +0 -26
- package/dist/__tests__/audit-publish-deps-contract.test.d.ts.map +0 -1
- package/dist/__tests__/audit-publish-deps-contract.test.js +0 -86
- package/dist/__tests__/audit-publish-deps-contract.test.js.map +0 -1
- package/dist/__tests__/auth-status.test.d.ts +0 -2
- package/dist/__tests__/auth-status.test.d.ts.map +0 -1
- package/dist/__tests__/auth-status.test.js +0 -291
- package/dist/__tests__/auth-status.test.js.map +0 -1
- package/dist/__tests__/auth-upgrade.test.d.ts +0 -9
- package/dist/__tests__/auth-upgrade.test.d.ts.map +0 -1
- package/dist/__tests__/auth-upgrade.test.js +0 -397
- package/dist/__tests__/auth-upgrade.test.js.map +0 -1
- package/dist/__tests__/bootstrap-tag-mcp-auth.test.d.ts +0 -22
- package/dist/__tests__/bootstrap-tag-mcp-auth.test.d.ts.map +0 -1
- package/dist/__tests__/bootstrap-tag-mcp-auth.test.js +0 -63
- package/dist/__tests__/bootstrap-tag-mcp-auth.test.js.map +0 -1
- package/dist/__tests__/cli-mcp-revoke.test.d.ts +0 -8
- package/dist/__tests__/cli-mcp-revoke.test.d.ts.map +0 -1
- package/dist/__tests__/cli-mcp-revoke.test.js +0 -124
- package/dist/__tests__/cli-mcp-revoke.test.js.map +0 -1
- package/dist/__tests__/config.test.d.ts +0 -2
- package/dist/__tests__/config.test.d.ts.map +0 -1
- package/dist/__tests__/config.test.js +0 -95
- package/dist/__tests__/config.test.js.map +0 -1
- package/dist/__tests__/create-app-urls.test.d.ts +0 -2
- package/dist/__tests__/create-app-urls.test.d.ts.map +0 -1
- package/dist/__tests__/create-app-urls.test.js +0 -102
- package/dist/__tests__/create-app-urls.test.js.map +0 -1
- package/dist/__tests__/docker-host.test.d.ts +0 -14
- package/dist/__tests__/docker-host.test.d.ts.map +0 -1
- package/dist/__tests__/docker-host.test.js +0 -109
- package/dist/__tests__/docker-host.test.js.map +0 -1
- package/dist/__tests__/enter.test.d.ts +0 -2
- package/dist/__tests__/enter.test.d.ts.map +0 -1
- package/dist/__tests__/enter.test.js +0 -90
- package/dist/__tests__/enter.test.js.map +0 -1
- package/dist/__tests__/help-output.test.d.ts +0 -2
- package/dist/__tests__/help-output.test.d.ts.map +0 -1
- package/dist/__tests__/help-output.test.js +0 -74
- package/dist/__tests__/help-output.test.js.map +0 -1
- package/dist/__tests__/host-cp-gh-token.test.d.ts +0 -9
- package/dist/__tests__/host-cp-gh-token.test.d.ts.map +0 -1
- package/dist/__tests__/host-cp-gh-token.test.js +0 -119
- package/dist/__tests__/host-cp-gh-token.test.js.map +0 -1
- package/dist/__tests__/host-cp.test.d.ts +0 -9
- package/dist/__tests__/host-cp.test.d.ts.map +0 -1
- package/dist/__tests__/host-cp.test.js +0 -327
- package/dist/__tests__/host-cp.test.js.map +0 -1
- package/dist/__tests__/image-presence.test.d.ts +0 -2
- package/dist/__tests__/image-presence.test.d.ts.map +0 -1
- package/dist/__tests__/image-presence.test.js +0 -44
- package/dist/__tests__/image-presence.test.js.map +0 -1
- package/dist/__tests__/install-root.test.d.ts +0 -2
- package/dist/__tests__/install-root.test.d.ts.map +0 -1
- package/dist/__tests__/install-root.test.js +0 -119
- package/dist/__tests__/install-root.test.js.map +0 -1
- package/dist/__tests__/keys.test.d.ts +0 -9
- package/dist/__tests__/keys.test.d.ts.map +0 -1
- package/dist/__tests__/keys.test.js +0 -145
- package/dist/__tests__/keys.test.js.map +0 -1
- package/dist/__tests__/logs.test.d.ts +0 -9
- package/dist/__tests__/logs.test.d.ts.map +0 -1
- package/dist/__tests__/logs.test.js +0 -124
- package/dist/__tests__/logs.test.js.map +0 -1
- package/dist/__tests__/mcp-import.test.d.ts +0 -11
- package/dist/__tests__/mcp-import.test.d.ts.map +0 -1
- package/dist/__tests__/mcp-import.test.js +0 -134
- package/dist/__tests__/mcp-import.test.js.map +0 -1
- package/dist/__tests__/protocol-version.test.d.ts +0 -2
- package/dist/__tests__/protocol-version.test.d.ts.map +0 -1
- package/dist/__tests__/protocol-version.test.js +0 -170
- package/dist/__tests__/protocol-version.test.js.map +0 -1
- package/dist/__tests__/ps.test.d.ts +0 -2
- package/dist/__tests__/ps.test.d.ts.map +0 -1
- package/dist/__tests__/ps.test.js +0 -172
- package/dist/__tests__/ps.test.js.map +0 -1
- package/dist/__tests__/registry-allowlist.test.d.ts +0 -2
- package/dist/__tests__/registry-allowlist.test.d.ts.map +0 -1
- package/dist/__tests__/registry-allowlist.test.js +0 -129
- package/dist/__tests__/registry-allowlist.test.js.map +0 -1
- package/dist/__tests__/services.test.d.ts +0 -8
- package/dist/__tests__/services.test.d.ts.map +0 -1
- package/dist/__tests__/services.test.js +0 -185
- package/dist/__tests__/services.test.js.map +0 -1
- package/dist/__tests__/status-app-urls.test.d.ts +0 -2
- package/dist/__tests__/status-app-urls.test.d.ts.map +0 -1
- package/dist/__tests__/status-app-urls.test.js +0 -125
- package/dist/__tests__/status-app-urls.test.js.map +0 -1
- package/dist/__tests__/upgrade-gh-token-contract.test.d.ts +0 -19
- package/dist/__tests__/upgrade-gh-token-contract.test.d.ts.map +0 -1
- package/dist/__tests__/upgrade-gh-token-contract.test.js +0 -63
- package/dist/__tests__/upgrade-gh-token-contract.test.js.map +0 -1
- package/dist/__tests__/upgrade.test.d.ts +0 -9
- package/dist/__tests__/upgrade.test.d.ts.map +0 -1
- package/dist/__tests__/upgrade.test.js +0 -586
- package/dist/__tests__/upgrade.test.js.map +0 -1
- package/dist/commands/__tests__/__fixtures__/upgrade-helpers.d.ts +0 -6
- package/dist/commands/__tests__/__fixtures__/upgrade-helpers.d.ts.map +0 -1
- package/dist/commands/__tests__/__fixtures__/upgrade-helpers.js +0 -26
- package/dist/commands/__tests__/__fixtures__/upgrade-helpers.js.map +0 -1
- package/dist/commands/__tests__/begin.test.d.ts +0 -7
- package/dist/commands/__tests__/begin.test.d.ts.map +0 -1
- package/dist/commands/__tests__/begin.test.js +0 -72
- package/dist/commands/__tests__/begin.test.js.map +0 -1
- package/dist/commands/__tests__/bootstrap.test.d.ts +0 -2
- package/dist/commands/__tests__/bootstrap.test.d.ts.map +0 -1
- package/dist/commands/__tests__/bootstrap.test.js +0 -370
- package/dist/commands/__tests__/bootstrap.test.js.map +0 -1
- package/dist/commands/__tests__/carry-uncommitted.test.d.ts +0 -14
- package/dist/commands/__tests__/carry-uncommitted.test.d.ts.map +0 -1
- package/dist/commands/__tests__/carry-uncommitted.test.js +0 -83
- package/dist/commands/__tests__/carry-uncommitted.test.js.map +0 -1
- package/dist/commands/__tests__/clean.test.d.ts +0 -9
- package/dist/commands/__tests__/clean.test.d.ts.map +0 -1
- package/dist/commands/__tests__/clean.test.js +0 -105
- package/dist/commands/__tests__/clean.test.js.map +0 -1
- package/dist/commands/__tests__/crystallize.test.d.ts +0 -2
- package/dist/commands/__tests__/crystallize.test.d.ts.map +0 -1
- package/dist/commands/__tests__/crystallize.test.js +0 -133
- package/dist/commands/__tests__/crystallize.test.js.map +0 -1
- package/dist/commands/__tests__/diagnose.test.d.ts +0 -9
- package/dist/commands/__tests__/diagnose.test.d.ts.map +0 -1
- package/dist/commands/__tests__/diagnose.test.js +0 -108
- package/dist/commands/__tests__/diagnose.test.js.map +0 -1
- package/dist/commands/__tests__/openHostCpUrl.test.d.ts +0 -2
- package/dist/commands/__tests__/openHostCpUrl.test.d.ts.map +0 -1
- package/dist/commands/__tests__/openHostCpUrl.test.js +0 -63
- package/dist/commands/__tests__/openHostCpUrl.test.js.map +0 -1
- package/dist/commands/__tests__/refresh.test.d.ts +0 -13
- package/dist/commands/__tests__/refresh.test.d.ts.map +0 -1
- package/dist/commands/__tests__/refresh.test.js +0 -170
- package/dist/commands/__tests__/refresh.test.js.map +0 -1
- package/dist/commands/__tests__/status.test.d.ts +0 -8
- package/dist/commands/__tests__/status.test.d.ts.map +0 -1
- package/dist/commands/__tests__/status.test.js +0 -62
- package/dist/commands/__tests__/status.test.js.map +0 -1
- package/dist/commands/__tests__/stop.test.d.ts +0 -5
- package/dist/commands/__tests__/stop.test.d.ts.map +0 -1
- package/dist/commands/__tests__/stop.test.js +0 -30
- package/dist/commands/__tests__/stop.test.js.map +0 -1
- package/dist/commands/__tests__/update.test.d.ts +0 -7
- package/dist/commands/__tests__/update.test.d.ts.map +0 -1
- package/dist/commands/__tests__/update.test.js +0 -224
- package/dist/commands/__tests__/update.test.js.map +0 -1
- package/dist/commands/__tests__/upgrade.all-three.test.d.ts +0 -19
- package/dist/commands/__tests__/upgrade.all-three.test.d.ts.map +0 -1
- package/dist/commands/__tests__/upgrade.all-three.test.js +0 -80
- package/dist/commands/__tests__/upgrade.all-three.test.js.map +0 -1
- package/dist/commands/__tests__/upgrade.compose-path.test.d.ts +0 -20
- package/dist/commands/__tests__/upgrade.compose-path.test.d.ts.map +0 -1
- package/dist/commands/__tests__/upgrade.compose-path.test.js +0 -140
- package/dist/commands/__tests__/upgrade.compose-path.test.js.map +0 -1
- package/dist/commands/__tests__/upgrade.history.test.d.ts +0 -15
- package/dist/commands/__tests__/upgrade.history.test.d.ts.map +0 -1
- package/dist/commands/__tests__/upgrade.history.test.js +0 -199
- package/dist/commands/__tests__/upgrade.history.test.js.map +0 -1
- package/dist/commands/__tests__/upgrade.lock.test.d.ts +0 -15
- package/dist/commands/__tests__/upgrade.lock.test.d.ts.map +0 -1
- package/dist/commands/__tests__/upgrade.lock.test.js +0 -253
- package/dist/commands/__tests__/upgrade.lock.test.js.map +0 -1
- package/dist/commands/__tests__/upgrade.olam-tag.test.d.ts +0 -21
- package/dist/commands/__tests__/upgrade.olam-tag.test.d.ts.map +0 -1
- package/dist/commands/__tests__/upgrade.olam-tag.test.js +0 -114
- package/dist/commands/__tests__/upgrade.olam-tag.test.js.map +0 -1
- package/dist/commands/__tests__/upgrade.poll.test.d.ts +0 -14
- package/dist/commands/__tests__/upgrade.poll.test.d.ts.map +0 -1
- package/dist/commands/__tests__/upgrade.poll.test.js +0 -136
- package/dist/commands/__tests__/upgrade.poll.test.js.map +0 -1
- package/dist/commands/__tests__/upgrade.recreate.test.d.ts +0 -17
- package/dist/commands/__tests__/upgrade.recreate.test.d.ts.map +0 -1
- package/dist/commands/__tests__/upgrade.recreate.test.js +0 -83
- package/dist/commands/__tests__/upgrade.recreate.test.js.map +0 -1
- package/dist/commands/__tests__/upgrade.rollback.test.d.ts +0 -12
- package/dist/commands/__tests__/upgrade.rollback.test.d.ts.map +0 -1
- package/dist/commands/__tests__/upgrade.rollback.test.js +0 -255
- package/dist/commands/__tests__/upgrade.rollback.test.js.map +0 -1
- package/dist/commands/__tests__/upgrade.sha-capture.test.d.ts +0 -12
- package/dist/commands/__tests__/upgrade.sha-capture.test.d.ts.map +0 -1
- package/dist/commands/__tests__/upgrade.sha-capture.test.js +0 -63
- package/dist/commands/__tests__/upgrade.sha-capture.test.js.map +0 -1
- package/dist/commands/__tests__/upgrade.smoke.test.d.ts +0 -19
- package/dist/commands/__tests__/upgrade.smoke.test.d.ts.map +0 -1
- package/dist/commands/__tests__/upgrade.smoke.test.js +0 -87
- package/dist/commands/__tests__/upgrade.smoke.test.js.map +0 -1
- package/dist/commands/__tests__/upgrade.swap.test.d.ts +0 -19
- package/dist/commands/__tests__/upgrade.swap.test.d.ts.map +0 -1
- package/dist/commands/__tests__/upgrade.swap.test.js +0 -312
- package/dist/commands/__tests__/upgrade.swap.test.js.map +0 -1
- package/dist/commands/__tests__/world-upgrade.test.d.ts +0 -8
- package/dist/commands/__tests__/world-upgrade.test.d.ts.map +0 -1
- package/dist/commands/__tests__/world-upgrade.test.js +0 -73
- package/dist/commands/__tests__/world-upgrade.test.js.map +0 -1
- package/dist/lib/__tests__/symlink-reconcile.test.d.ts +0 -2
- package/dist/lib/__tests__/symlink-reconcile.test.d.ts.map +0 -1
- package/dist/lib/__tests__/symlink-reconcile.test.js +0 -106
- package/dist/lib/__tests__/symlink-reconcile.test.js.map +0 -1
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { spawnSync } from 'node:child_process';
|
|
2
|
-
import * as fs from 'node:fs';
|
|
3
|
-
import * as path from 'node:path';
|
|
4
|
-
export function findRepoRoot(start) {
|
|
5
|
-
let dir = start;
|
|
6
|
-
for (let i = 0; i < 10; i++) {
|
|
7
|
-
if (fs.existsSync(path.join(dir, 'packages', 'host-cp', 'compose.yaml')))
|
|
8
|
-
return dir;
|
|
9
|
-
const parent = path.dirname(dir);
|
|
10
|
-
if (parent === dir)
|
|
11
|
-
break;
|
|
12
|
-
dir = parent;
|
|
13
|
-
}
|
|
14
|
-
throw new Error(`Could not find repo root from ${start}`);
|
|
15
|
-
}
|
|
16
|
-
export function dockerAvailable() {
|
|
17
|
-
const result = spawnSync('docker', ['version', '--format', '{{.Server.Version}}'], {
|
|
18
|
-
encoding: 'utf-8',
|
|
19
|
-
stdio: ['ignore', 'pipe', 'ignore'],
|
|
20
|
-
});
|
|
21
|
-
return result.status === 0;
|
|
22
|
-
}
|
|
23
|
-
export const REPO_ROOT = findRepoRoot(process.cwd());
|
|
24
|
-
/** Shared fixture dir for Docker atomic-swap tests (swap + rollback suites). */
|
|
25
|
-
export const ATOMIC_SWAP_FIXTURE_DIR = path.join(REPO_ROOT, 'tests', 'fixtures', 'atomic-swap');
|
|
26
|
-
//# sourceMappingURL=upgrade-helpers.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"upgrade-helpers.js","sourceRoot":"","sources":["../../../../src/commands/__tests__/__fixtures__/upgrade-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,IAAI,GAAG,GAAG,KAAK,CAAC;IAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC;YAAE,OAAO,GAAG,CAAC;QACrF,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,MAAM,KAAK,GAAG;YAAE,MAAM;QAC1B,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,iCAAiC,KAAK,EAAE,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,MAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,qBAAqB,CAAC,EAAE;QACjF,QAAQ,EAAE,OAAO;QACjB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;KACpC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,CAAC,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;AAErD,gFAAgF;AAChF,MAAM,CAAC,MAAM,uBAAuB,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"begin.test.d.ts","sourceRoot":"","sources":["../../../src/commands/__tests__/begin.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for D1 — `olam begin` command (Phase D).
|
|
3
|
-
*
|
|
4
|
-
* Run: vitest run packages/cli/src/commands/__tests__/begin.test.ts
|
|
5
|
-
*/
|
|
6
|
-
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
7
|
-
// Cut the @olam/adapters transitive dependency that vitest can't resolve.
|
|
8
|
-
vi.mock('../host-cp.js', () => ({
|
|
9
|
-
startHostCp: vi.fn(),
|
|
10
|
-
readToken: vi.fn().mockReturnValue(null),
|
|
11
|
-
HOST_CP_PORT: 19000,
|
|
12
|
-
}));
|
|
13
|
-
vi.mock('@olam/core/src/util/open-url.js', () => ({
|
|
14
|
-
openUrl: vi.fn().mockReturnValue({ opened: false, reason: 'mocked' }),
|
|
15
|
-
}));
|
|
16
|
-
describe('doBegin (D1)', () => {
|
|
17
|
-
let prevExitCode;
|
|
18
|
-
beforeEach(() => {
|
|
19
|
-
prevExitCode = process.exitCode;
|
|
20
|
-
process.exitCode = undefined;
|
|
21
|
-
});
|
|
22
|
-
afterEach(() => {
|
|
23
|
-
process.exitCode = prevExitCode;
|
|
24
|
-
});
|
|
25
|
-
it('calls startFn with showToken=false by default', async () => {
|
|
26
|
-
const { doBegin } = await import('../begin.js');
|
|
27
|
-
const startFn = vi.fn().mockResolvedValue(undefined);
|
|
28
|
-
const openFn = vi.fn().mockReturnValue({ opened: false, reason: 'CI' });
|
|
29
|
-
await doBegin({ showToken: false, browser: true }, startFn, openFn);
|
|
30
|
-
expect(startFn).toHaveBeenCalledWith({ showToken: false });
|
|
31
|
-
});
|
|
32
|
-
it('calls startFn with showToken=true when passed', async () => {
|
|
33
|
-
const { doBegin } = await import('../begin.js');
|
|
34
|
-
const startFn = vi.fn().mockResolvedValue(undefined);
|
|
35
|
-
const openFn = vi.fn().mockReturnValue({ opened: false, reason: 'CI' });
|
|
36
|
-
await doBegin({ showToken: true, browser: false }, startFn, openFn);
|
|
37
|
-
expect(startFn).toHaveBeenCalledWith({ showToken: true });
|
|
38
|
-
});
|
|
39
|
-
it('returns true on success', async () => {
|
|
40
|
-
const { doBegin } = await import('../begin.js');
|
|
41
|
-
const startFn = vi.fn().mockResolvedValue(undefined);
|
|
42
|
-
const openFn = vi.fn().mockReturnValue({ opened: false, reason: 'CI' });
|
|
43
|
-
const result = await doBegin({ showToken: false, browser: false }, startFn, openFn);
|
|
44
|
-
expect(result).toBe(true);
|
|
45
|
-
});
|
|
46
|
-
it('returns false when startFn sets exitCode to 1', async () => {
|
|
47
|
-
const { doBegin } = await import('../begin.js');
|
|
48
|
-
const startFn = vi.fn().mockImplementation(async () => {
|
|
49
|
-
process.exitCode = 1;
|
|
50
|
-
});
|
|
51
|
-
const openFn = vi.fn().mockReturnValue({ opened: false, reason: 'CI' });
|
|
52
|
-
const result = await doBegin({ showToken: false, browser: true }, startFn, openFn);
|
|
53
|
-
expect(result).toBe(false);
|
|
54
|
-
});
|
|
55
|
-
it('does not call openFn when startFn fails', async () => {
|
|
56
|
-
const { doBegin } = await import('../begin.js');
|
|
57
|
-
const startFn = vi.fn().mockImplementation(async () => {
|
|
58
|
-
process.exitCode = 1;
|
|
59
|
-
});
|
|
60
|
-
const openFn = vi.fn().mockReturnValue({ opened: false, reason: 'CI' });
|
|
61
|
-
await doBegin({ showToken: false, browser: true }, startFn, openFn);
|
|
62
|
-
expect(openFn).not.toHaveBeenCalled();
|
|
63
|
-
});
|
|
64
|
-
it('does not call openFn when browser=false', async () => {
|
|
65
|
-
const { doBegin } = await import('../begin.js');
|
|
66
|
-
const startFn = vi.fn().mockResolvedValue(undefined);
|
|
67
|
-
const openFn = vi.fn().mockReturnValue({ opened: false, reason: 'no-browser' });
|
|
68
|
-
await doBegin({ showToken: false, browser: false }, startFn, openFn);
|
|
69
|
-
expect(openFn).not.toHaveBeenCalled();
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
//# sourceMappingURL=begin.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"begin.test.js","sourceRoot":"","sources":["../../../src/commands/__tests__/begin.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"bootstrap.test.d.ts","sourceRoot":"","sources":["../../../src/commands/__tests__/bootstrap.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,370 +0,0 @@
|
|
|
1
|
-
// C1 + C3 (Phase C — fresh-install self-bootstrap): `olam bootstrap`
|
|
2
|
-
// orchestrator. Closes the user goal end-to-end:
|
|
3
|
-
// `npm install -g @pleri/olam-cli && olam init && olam bootstrap`.
|
|
4
|
-
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
5
|
-
import { runBootstrap, pullImageWithRetry, loadImageDigests, } from '../bootstrap.js';
|
|
6
|
-
import { EXIT_BOOTSTRAP_PULL_FAILED, EXIT_GENERIC_ERROR, EXIT_PROTOCOL_MISMATCH, } from '../../exit-codes.js';
|
|
7
|
-
// ── Test helpers ──────────────────────────────────────────────────
|
|
8
|
-
function mkDigest(seed) {
|
|
9
|
-
// Build a 64-hex digest deterministically from a seed for readable test
|
|
10
|
-
// output. Real digests are sha256 hex of the manifest content; tests
|
|
11
|
-
// just need stable strings of the right shape.
|
|
12
|
-
const hex = (seed + 'a'.repeat(64)).replace(/[^a-f0-9]/g, '0').slice(0, 64);
|
|
13
|
-
return `sha256:${hex}`;
|
|
14
|
-
}
|
|
15
|
-
const FIXTURE_DIGESTS = {
|
|
16
|
-
'host-cp': mkDigest('host-cp-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),
|
|
17
|
-
auth: mkDigest('auth-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'),
|
|
18
|
-
devbox: mkDigest('devbox-ccccccccccccccccccccccccccccccccccccccccccccccccccccccc'),
|
|
19
|
-
$registry: 'ghcr.io/pleri',
|
|
20
|
-
$published_version: '0.1.15',
|
|
21
|
-
};
|
|
22
|
-
function ok(stdout = '') {
|
|
23
|
-
return { exitCode: 0, stdout, stderr: '' };
|
|
24
|
-
}
|
|
25
|
-
function err(stderr, exitCode = 1) {
|
|
26
|
-
return { exitCode, stdout: '', stderr };
|
|
27
|
-
}
|
|
28
|
-
function makeMockDocker(opts = {}) {
|
|
29
|
-
const calls = opts.calls ?? { pull: [], inspect: [] };
|
|
30
|
-
return {
|
|
31
|
-
info: vi.fn(async () => (opts.infoOk === false ? err('cannot connect to docker') : ok())),
|
|
32
|
-
pull: vi.fn(async (ref) => {
|
|
33
|
-
calls.pull.push(ref);
|
|
34
|
-
return opts.pullResults?.get(ref) ?? ok();
|
|
35
|
-
}),
|
|
36
|
-
inspectLabel: vi.fn(async (ref, label) => {
|
|
37
|
-
calls.inspect.push(`${ref}#${label}`);
|
|
38
|
-
const value = opts.inspectLabels?.get(ref) ?? '1';
|
|
39
|
-
return ok(`${value}\n`);
|
|
40
|
-
}),
|
|
41
|
-
tag: vi.fn(async () => ok()),
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
function silentSubprocess() {
|
|
45
|
-
const calls = [];
|
|
46
|
-
return {
|
|
47
|
-
calls,
|
|
48
|
-
runOlamSubcommand: (args) => {
|
|
49
|
-
calls.push([...args]);
|
|
50
|
-
return ok();
|
|
51
|
-
},
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
// Suppress real console output during tests — orchestrator uses ora +
|
|
55
|
-
// stdout/stderr writes that vitest reports as warnings otherwise.
|
|
56
|
-
beforeEach(() => {
|
|
57
|
-
vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
58
|
-
vi.spyOn(process.stderr, 'write').mockImplementation(() => true);
|
|
59
|
-
});
|
|
60
|
-
afterEach(() => {
|
|
61
|
-
vi.restoreAllMocks();
|
|
62
|
-
});
|
|
63
|
-
// ── pullImageWithRetry — unit ────────────────────────────────────
|
|
64
|
-
describe('pullImageWithRetry — coalesce + retry', () => {
|
|
65
|
-
it('returns first attempt success without retrying', async () => {
|
|
66
|
-
let calls = 0;
|
|
67
|
-
const docker = {
|
|
68
|
-
info: async () => ok(),
|
|
69
|
-
pull: async () => {
|
|
70
|
-
calls++;
|
|
71
|
-
return ok();
|
|
72
|
-
},
|
|
73
|
-
inspectLabel: async () => ok('1'),
|
|
74
|
-
tag: async () => ok(),
|
|
75
|
-
};
|
|
76
|
-
const result = await pullImageWithRetry('ghcr.io/test/img@sha256:xxx', docker);
|
|
77
|
-
expect(result.exitCode).toBe(0);
|
|
78
|
-
expect(calls).toBe(1);
|
|
79
|
-
});
|
|
80
|
-
it('retries once on transient (network) failure, then succeeds', async () => {
|
|
81
|
-
let calls = 0;
|
|
82
|
-
const docker = {
|
|
83
|
-
info: async () => ok(),
|
|
84
|
-
pull: async () => {
|
|
85
|
-
calls++;
|
|
86
|
-
if (calls === 1)
|
|
87
|
-
return err('connection refused', 1);
|
|
88
|
-
return ok();
|
|
89
|
-
},
|
|
90
|
-
inspectLabel: async () => ok('1'),
|
|
91
|
-
tag: async () => ok(),
|
|
92
|
-
};
|
|
93
|
-
const result = await pullImageWithRetry('ghcr.io/test/img@sha256:xxx', docker);
|
|
94
|
-
expect(result.exitCode).toBe(0);
|
|
95
|
-
expect(calls).toBe(2);
|
|
96
|
-
});
|
|
97
|
-
it('does NOT retry on a non-transient failure (e.g. manifest unknown)', async () => {
|
|
98
|
-
let calls = 0;
|
|
99
|
-
const docker = {
|
|
100
|
-
info: async () => ok(),
|
|
101
|
-
pull: async () => {
|
|
102
|
-
calls++;
|
|
103
|
-
return err('manifest unknown', 1);
|
|
104
|
-
},
|
|
105
|
-
inspectLabel: async () => ok('1'),
|
|
106
|
-
tag: async () => ok(),
|
|
107
|
-
};
|
|
108
|
-
const result = await pullImageWithRetry('ghcr.io/test/img@sha256:xxx', docker);
|
|
109
|
-
expect(result.exitCode).toBe(1);
|
|
110
|
-
expect(calls).toBe(1);
|
|
111
|
-
});
|
|
112
|
-
it('coalesces concurrent identical pulls into one in-flight promise', async () => {
|
|
113
|
-
let pullsStarted = 0;
|
|
114
|
-
const gate = new Promise((resolveGate) => setTimeout(resolveGate, 30));
|
|
115
|
-
const docker = {
|
|
116
|
-
info: async () => ok(),
|
|
117
|
-
pull: async () => {
|
|
118
|
-
pullsStarted++;
|
|
119
|
-
await gate;
|
|
120
|
-
return ok();
|
|
121
|
-
},
|
|
122
|
-
inspectLabel: async () => ok('1'),
|
|
123
|
-
tag: async () => ok(),
|
|
124
|
-
};
|
|
125
|
-
const ref = 'ghcr.io/test/img@sha256:dedupeme';
|
|
126
|
-
const [a, b, c] = await Promise.all([
|
|
127
|
-
pullImageWithRetry(ref, docker),
|
|
128
|
-
pullImageWithRetry(ref, docker),
|
|
129
|
-
pullImageWithRetry(ref, docker),
|
|
130
|
-
]);
|
|
131
|
-
expect(a.exitCode).toBe(0);
|
|
132
|
-
expect(b.exitCode).toBe(0);
|
|
133
|
-
expect(c.exitCode).toBe(0);
|
|
134
|
-
expect(pullsStarted).toBe(1); // coalesced
|
|
135
|
-
});
|
|
136
|
-
it('does not coalesce different image refs', async () => {
|
|
137
|
-
let pullsStarted = 0;
|
|
138
|
-
const docker = {
|
|
139
|
-
info: async () => ok(),
|
|
140
|
-
pull: async () => {
|
|
141
|
-
pullsStarted++;
|
|
142
|
-
return ok();
|
|
143
|
-
},
|
|
144
|
-
inspectLabel: async () => ok('1'),
|
|
145
|
-
tag: async () => ok(),
|
|
146
|
-
};
|
|
147
|
-
await Promise.all([
|
|
148
|
-
pullImageWithRetry('ghcr.io/a@sha256:111', docker),
|
|
149
|
-
pullImageWithRetry('ghcr.io/b@sha256:222', docker),
|
|
150
|
-
pullImageWithRetry('ghcr.io/c@sha256:333', docker),
|
|
151
|
-
]);
|
|
152
|
-
expect(pullsStarted).toBe(3);
|
|
153
|
-
});
|
|
154
|
-
});
|
|
155
|
-
// ── runBootstrap — orchestrator ───────────────────────────────────
|
|
156
|
-
describe('runBootstrap — happy path', () => {
|
|
157
|
-
it('exits 0 when daemon up + 3 pulls succeed + handshake passes + services start', async () => {
|
|
158
|
-
const docker = makeMockDocker();
|
|
159
|
-
const sub = silentSubprocess();
|
|
160
|
-
const result = await runBootstrap({ withSmoke: false, skipAuthLogin: true }, { docker, digests: FIXTURE_DIGESTS, runOlamSubcommand: sub.runOlamSubcommand });
|
|
161
|
-
expect(result.exitCode).toBe(0);
|
|
162
|
-
expect(sub.calls).toEqual([
|
|
163
|
-
['host-cp', 'start'],
|
|
164
|
-
['auth', 'up'],
|
|
165
|
-
]);
|
|
166
|
-
});
|
|
167
|
-
it('with --with-smoke, dispatches a smoke-test world create', async () => {
|
|
168
|
-
const docker = makeMockDocker();
|
|
169
|
-
const sub = silentSubprocess();
|
|
170
|
-
const result = await runBootstrap({ withSmoke: true, skipAuthLogin: true }, { docker, digests: FIXTURE_DIGESTS, runOlamSubcommand: sub.runOlamSubcommand });
|
|
171
|
-
expect(result.exitCode).toBe(0);
|
|
172
|
-
const lastCall = sub.calls[sub.calls.length - 1] ?? [];
|
|
173
|
-
expect(lastCall[0]).toBe('create');
|
|
174
|
-
expect(lastCall).toContain('--workspace');
|
|
175
|
-
expect(lastCall).toContain('smoke');
|
|
176
|
-
});
|
|
177
|
-
it('without --skip-auth-login (and OLAM_BOOTSTRAP_SKIP_AUTH_LOGIN unset), runs auth login', async () => {
|
|
178
|
-
const docker = makeMockDocker();
|
|
179
|
-
const sub = silentSubprocess();
|
|
180
|
-
delete process.env.OLAM_BOOTSTRAP_SKIP_AUTH_LOGIN;
|
|
181
|
-
const result = await runBootstrap({ withSmoke: false, skipAuthLogin: false }, { docker, digests: FIXTURE_DIGESTS, runOlamSubcommand: sub.runOlamSubcommand });
|
|
182
|
-
expect(result.exitCode).toBe(0);
|
|
183
|
-
expect(sub.calls).toContainEqual(['auth', 'login']);
|
|
184
|
-
});
|
|
185
|
-
});
|
|
186
|
-
describe('runBootstrap — failure paths', () => {
|
|
187
|
-
it('exits EXIT_GENERIC_ERROR (1) when docker daemon not reachable', async () => {
|
|
188
|
-
const docker = makeMockDocker({ infoOk: false });
|
|
189
|
-
const sub = silentSubprocess();
|
|
190
|
-
const result = await runBootstrap({ withSmoke: false, skipAuthLogin: true }, { docker, digests: FIXTURE_DIGESTS, runOlamSubcommand: sub.runOlamSubcommand });
|
|
191
|
-
expect(result.exitCode).toBe(EXIT_GENERIC_ERROR);
|
|
192
|
-
expect(result.summary).toContain('docker daemon not reachable');
|
|
193
|
-
// No subcommands run — bailed at step 1.
|
|
194
|
-
expect(sub.calls).toEqual([]);
|
|
195
|
-
});
|
|
196
|
-
it('exits EXIT_BOOTSTRAP_PULL_FAILED (3) when an image pull fails terminally', async () => {
|
|
197
|
-
const calls = { pull: [], inspect: [] };
|
|
198
|
-
const docker = makeMockDocker({
|
|
199
|
-
pullResults: new Map([
|
|
200
|
-
[`ghcr.io/pleri/olam-host-cp@${FIXTURE_DIGESTS['host-cp']}`, err('manifest unknown', 1)],
|
|
201
|
-
]),
|
|
202
|
-
calls,
|
|
203
|
-
});
|
|
204
|
-
const sub = silentSubprocess();
|
|
205
|
-
const result = await runBootstrap({ withSmoke: false, skipAuthLogin: true }, { docker, digests: FIXTURE_DIGESTS, runOlamSubcommand: sub.runOlamSubcommand });
|
|
206
|
-
expect(result.exitCode).toBe(EXIT_BOOTSTRAP_PULL_FAILED);
|
|
207
|
-
expect(result.summary).toContain('pull failed');
|
|
208
|
-
expect(sub.calls).toEqual([]);
|
|
209
|
-
});
|
|
210
|
-
it('exits EXIT_PROTOCOL_MISMATCH (4) when an image LABEL is missing', async () => {
|
|
211
|
-
const docker = makeMockDocker({
|
|
212
|
-
// Missing LABEL → docker inspect returns "<no value>".
|
|
213
|
-
inspectLabels: new Map([
|
|
214
|
-
[`ghcr.io/pleri/olam-devbox@${FIXTURE_DIGESTS.devbox}`, '<no value>'],
|
|
215
|
-
]),
|
|
216
|
-
});
|
|
217
|
-
const sub = silentSubprocess();
|
|
218
|
-
const result = await runBootstrap({ withSmoke: false, skipAuthLogin: true }, { docker, digests: FIXTURE_DIGESTS, runOlamSubcommand: sub.runOlamSubcommand });
|
|
219
|
-
expect(result.exitCode).toBe(EXIT_PROTOCOL_MISMATCH);
|
|
220
|
-
expect(result.summary).toContain('devbox');
|
|
221
|
-
});
|
|
222
|
-
it('exits EXIT_PROTOCOL_MISMATCH when an image LABEL declares non-overlapping versions', async () => {
|
|
223
|
-
const docker = makeMockDocker({
|
|
224
|
-
inspectLabels: new Map([
|
|
225
|
-
[`ghcr.io/pleri/olam-auth@${FIXTURE_DIGESTS.auth}`, '99'],
|
|
226
|
-
]),
|
|
227
|
-
});
|
|
228
|
-
const sub = silentSubprocess();
|
|
229
|
-
const result = await runBootstrap({ withSmoke: false, skipAuthLogin: true }, { docker, digests: FIXTURE_DIGESTS, runOlamSubcommand: sub.runOlamSubcommand });
|
|
230
|
-
expect(result.exitCode).toBe(EXIT_PROTOCOL_MISMATCH);
|
|
231
|
-
expect(result.summary).toContain('auth');
|
|
232
|
-
});
|
|
233
|
-
it('exits EXIT_GENERIC_ERROR when host-cp start fails', async () => {
|
|
234
|
-
const docker = makeMockDocker();
|
|
235
|
-
const calls = [];
|
|
236
|
-
const runOlamSubcommand = (args) => {
|
|
237
|
-
calls.push([...args]);
|
|
238
|
-
if (args[0] === 'host-cp')
|
|
239
|
-
return err('host-cp could not start', 1);
|
|
240
|
-
return ok();
|
|
241
|
-
};
|
|
242
|
-
const result = await runBootstrap({ withSmoke: false, skipAuthLogin: true }, { docker, digests: FIXTURE_DIGESTS, runOlamSubcommand });
|
|
243
|
-
expect(result.exitCode).toBe(EXIT_GENERIC_ERROR);
|
|
244
|
-
expect(result.summary).toContain('host-cp');
|
|
245
|
-
});
|
|
246
|
-
it('exits EXIT_GENERIC_ERROR when auth up fails', async () => {
|
|
247
|
-
const docker = makeMockDocker();
|
|
248
|
-
const runOlamSubcommand = (args) => {
|
|
249
|
-
if (args[0] === 'auth' && args[1] === 'up')
|
|
250
|
-
return err('auth-service docker port busy', 1);
|
|
251
|
-
return ok();
|
|
252
|
-
};
|
|
253
|
-
const result = await runBootstrap({ withSmoke: false, skipAuthLogin: true }, { docker, digests: FIXTURE_DIGESTS, runOlamSubcommand });
|
|
254
|
-
expect(result.exitCode).toBe(EXIT_GENERIC_ERROR);
|
|
255
|
-
expect(result.summary).toContain('auth up');
|
|
256
|
-
});
|
|
257
|
-
});
|
|
258
|
-
describe('runBootstrap — registry override + digest resolution', () => {
|
|
259
|
-
it('uses --registry flag when provided', async () => {
|
|
260
|
-
const calls = { pull: [], inspect: [] };
|
|
261
|
-
const docker = makeMockDocker({ calls });
|
|
262
|
-
const sub = silentSubprocess();
|
|
263
|
-
await runBootstrap({ withSmoke: false, skipAuthLogin: true, registry: 'localhost:5000/test' }, { docker, digests: FIXTURE_DIGESTS, runOlamSubcommand: sub.runOlamSubcommand });
|
|
264
|
-
expect(calls.pull[0]).toContain('localhost:5000/test/olam-host-cp');
|
|
265
|
-
});
|
|
266
|
-
it('falls back to digests.$registry when --registry not provided', async () => {
|
|
267
|
-
const calls = { pull: [], inspect: [] };
|
|
268
|
-
const docker = makeMockDocker({ calls });
|
|
269
|
-
const sub = silentSubprocess();
|
|
270
|
-
await runBootstrap({ withSmoke: false, skipAuthLogin: true }, {
|
|
271
|
-
docker,
|
|
272
|
-
digests: { ...FIXTURE_DIGESTS, $registry: 'ghcr.io/atlas-namespace' },
|
|
273
|
-
runOlamSubcommand: sub.runOlamSubcommand,
|
|
274
|
-
});
|
|
275
|
-
expect(calls.pull[0]).toContain('ghcr.io/atlas-namespace/olam-host-cp');
|
|
276
|
-
});
|
|
277
|
-
it('pulls all 3 images with the correct digest references', async () => {
|
|
278
|
-
const calls = { pull: [], inspect: [] };
|
|
279
|
-
const docker = makeMockDocker({ calls });
|
|
280
|
-
const sub = silentSubprocess();
|
|
281
|
-
await runBootstrap({ withSmoke: false, skipAuthLogin: true }, { docker, digests: FIXTURE_DIGESTS, runOlamSubcommand: sub.runOlamSubcommand });
|
|
282
|
-
expect(calls.pull).toHaveLength(3);
|
|
283
|
-
expect(calls.pull).toContain(`ghcr.io/pleri/olam-host-cp@${FIXTURE_DIGESTS['host-cp']}`);
|
|
284
|
-
expect(calls.pull).toContain(`ghcr.io/pleri/olam-auth@${FIXTURE_DIGESTS.auth}`);
|
|
285
|
-
expect(calls.pull).toContain(`ghcr.io/pleri/olam-devbox@${FIXTURE_DIGESTS.devbox}`);
|
|
286
|
-
});
|
|
287
|
-
});
|
|
288
|
-
// ── Regression: bootstrap compose-pull bare-name Docker Hub failure ──
|
|
289
|
-
//
|
|
290
|
-
// Bug: after step 2 (digest pull), bootstrap called `olam host-cp start`
|
|
291
|
-
// which ran `docker compose pull` against compose.yaml. When compose.yaml
|
|
292
|
-
// had `image: olam-host-cp:latest` (bare), Docker Hub rejected the pull
|
|
293
|
-
// with "pull access denied for olam-host-cp, repository does not exist".
|
|
294
|
-
//
|
|
295
|
-
// Fix: step 3b tags each pulled image with the canonical :latest name that
|
|
296
|
-
// compose.yaml expects, so `docker compose up` finds the image locally and
|
|
297
|
-
// does not need to pull from any registry. The tag target for host-cp MUST
|
|
298
|
-
// match compose.yaml's `image:` field exactly.
|
|
299
|
-
describe('runBootstrap — tag step aligns with compose.yaml (regression guard)', () => {
|
|
300
|
-
it('tags host-cp with the canonical registry-prefixed name (ghcr.io/pleri/olam-host-cp:latest)', async () => {
|
|
301
|
-
const tagCalls = [];
|
|
302
|
-
const docker = {
|
|
303
|
-
info: async () => ok(),
|
|
304
|
-
pull: async () => ok(),
|
|
305
|
-
inspectLabel: async () => ok('1\n'),
|
|
306
|
-
tag: async (from, to) => {
|
|
307
|
-
tagCalls.push({ from, to });
|
|
308
|
-
return ok();
|
|
309
|
-
},
|
|
310
|
-
};
|
|
311
|
-
const sub = silentSubprocess();
|
|
312
|
-
const result = await runBootstrap({ withSmoke: false, skipAuthLogin: true }, { docker, digests: FIXTURE_DIGESTS, runOlamSubcommand: sub.runOlamSubcommand });
|
|
313
|
-
expect(result.exitCode).toBe(0);
|
|
314
|
-
const hostCpTag = tagCalls.find((t) => t.to.includes('olam-host-cp'));
|
|
315
|
-
expect(hostCpTag).toBeDefined();
|
|
316
|
-
// This MUST match compose.yaml's `image:` field (`ghcr.io/pleri/olam-host-cp:latest`).
|
|
317
|
-
// If bootstrap tags as a bare name or a different registry, `compose up`
|
|
318
|
-
// won't find the locally-pulled image and will attempt a registry pull.
|
|
319
|
-
expect(hostCpTag.to).toBe('ghcr.io/pleri/olam-host-cp:latest');
|
|
320
|
-
// Must not be a bare image name — Docker Hub can't resolve it.
|
|
321
|
-
expect(hostCpTag.to).toMatch(/^[a-z0-9][\w.-]+\.[a-z]{2,}\//);
|
|
322
|
-
});
|
|
323
|
-
it('host-cp tag source is the digest-pinned ref, not a mutable :latest', async () => {
|
|
324
|
-
const tagCalls = [];
|
|
325
|
-
const docker = {
|
|
326
|
-
info: async () => ok(),
|
|
327
|
-
pull: async () => ok(),
|
|
328
|
-
inspectLabel: async () => ok('1\n'),
|
|
329
|
-
tag: async (from, to) => {
|
|
330
|
-
tagCalls.push({ from, to });
|
|
331
|
-
return ok();
|
|
332
|
-
},
|
|
333
|
-
};
|
|
334
|
-
const sub = silentSubprocess();
|
|
335
|
-
await runBootstrap({ withSmoke: false, skipAuthLogin: true }, { docker, digests: FIXTURE_DIGESTS, runOlamSubcommand: sub.runOlamSubcommand });
|
|
336
|
-
const hostCpTag = tagCalls.find((t) => t.to.includes('olam-host-cp'));
|
|
337
|
-
expect(hostCpTag).toBeDefined();
|
|
338
|
-
// The `from` ref must be the digest-pinned pull (sha256:...) — if it
|
|
339
|
-
// were `:latest`, the tag would alias whatever `:latest` the registry
|
|
340
|
-
// serves, defeating the whole point of digest-pinning in step 2.
|
|
341
|
-
expect(hostCpTag.from).toContain('@sha256:');
|
|
342
|
-
expect(hostCpTag.from).toContain(FIXTURE_DIGESTS['host-cp']);
|
|
343
|
-
});
|
|
344
|
-
it('with a custom registry, host-cp tag uses the registry-prefixed name', async () => {
|
|
345
|
-
const tagCalls = [];
|
|
346
|
-
const docker = {
|
|
347
|
-
info: async () => ok(),
|
|
348
|
-
pull: async () => ok(),
|
|
349
|
-
inspectLabel: async () => ok('1\n'),
|
|
350
|
-
tag: async (from, to) => {
|
|
351
|
-
tagCalls.push({ from, to });
|
|
352
|
-
return ok();
|
|
353
|
-
},
|
|
354
|
-
};
|
|
355
|
-
const sub = silentSubprocess();
|
|
356
|
-
await runBootstrap({ withSmoke: false, skipAuthLogin: true, registry: 'localhost:5000/myorg' }, { docker, digests: FIXTURE_DIGESTS, runOlamSubcommand: sub.runOlamSubcommand });
|
|
357
|
-
const hostCpTag = tagCalls.find((t) => t.to.includes('olam-host-cp'));
|
|
358
|
-
expect(hostCpTag).toBeDefined();
|
|
359
|
-
expect(hostCpTag.to).toBe('localhost:5000/myorg/olam-host-cp:latest');
|
|
360
|
-
// Custom registry is still a valid registry prefix (not bare).
|
|
361
|
-
expect(hostCpTag.to).not.toMatch(/^olam-host-cp/);
|
|
362
|
-
});
|
|
363
|
-
});
|
|
364
|
-
// ── loadImageDigests — unit ───────────────────────────────────────
|
|
365
|
-
describe('loadImageDigests', () => {
|
|
366
|
-
it('throws when image-digests.json is absent', () => {
|
|
367
|
-
expect(() => loadImageDigests('/tmp/no-such-install-' + Date.now())).toThrow(/image-digests\.json missing/);
|
|
368
|
-
});
|
|
369
|
-
});
|
|
370
|
-
//# sourceMappingURL=bootstrap.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"bootstrap.test.js","sourceRoot":"","sources":["../../../src/commands/__tests__/bootstrap.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Phase B B3 (olam-session-stability): unit tests for the
|
|
3
|
-
* --carry-uncommitted CLI flag.
|
|
4
|
-
*
|
|
5
|
-
* Strategy: programmatic commander parse + an in-memory listener that
|
|
6
|
-
* captures the parsed opts before the action handler's network calls
|
|
7
|
-
* fire. This sidesteps the heavy fixtures the action handler needs
|
|
8
|
-
* (host-cp, devbox image, world registry) — we only care that the flag
|
|
9
|
-
* is recognized + flows through to the createWorld opts shape.
|
|
10
|
-
*
|
|
11
|
-
* Run: `cd packages/cli && npx vitest run src/commands/__tests__/carry-uncommitted.test.ts`
|
|
12
|
-
*/
|
|
13
|
-
export {};
|
|
14
|
-
//# sourceMappingURL=carry-uncommitted.test.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"carry-uncommitted.test.d.ts","sourceRoot":"","sources":["../../../src/commands/__tests__/carry-uncommitted.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG"}
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Phase B B3 (olam-session-stability): unit tests for the
|
|
3
|
-
* --carry-uncommitted CLI flag.
|
|
4
|
-
*
|
|
5
|
-
* Strategy: programmatic commander parse + an in-memory listener that
|
|
6
|
-
* captures the parsed opts before the action handler's network calls
|
|
7
|
-
* fire. This sidesteps the heavy fixtures the action handler needs
|
|
8
|
-
* (host-cp, devbox image, world registry) — we only care that the flag
|
|
9
|
-
* is recognized + flows through to the createWorld opts shape.
|
|
10
|
-
*
|
|
11
|
-
* Run: `cd packages/cli && npx vitest run src/commands/__tests__/carry-uncommitted.test.ts`
|
|
12
|
-
*/
|
|
13
|
-
import { describe, it, expect } from 'vitest';
|
|
14
|
-
import { Command } from 'commander';
|
|
15
|
-
/**
|
|
16
|
-
* Build a minimal commander Command that mirrors the real `olam create`
|
|
17
|
-
* flag set + captures parsed opts via the action handler. We do NOT
|
|
18
|
-
* import the real `registerCreate` because it pulls in @olam/core +
|
|
19
|
-
* host-cp + ora; loading those drags ~2s of startup into the test for
|
|
20
|
-
* no extra signal. Instead we build a faithful copy of just the flag
|
|
21
|
-
* declarations under test.
|
|
22
|
-
*
|
|
23
|
-
* If the real flag set ever drifts from this fixture, the
|
|
24
|
-
* `recognizes the flag in the option chain` test should fail loudly
|
|
25
|
-
* (run-time `--help` mismatch).
|
|
26
|
-
*/
|
|
27
|
-
function buildTestCommand() {
|
|
28
|
-
const captured = { opts: null };
|
|
29
|
-
const program = new Command();
|
|
30
|
-
program.exitOverride(); // never call process.exit on parse error
|
|
31
|
-
program
|
|
32
|
-
.command('create')
|
|
33
|
-
.option('--name <name>', 'World name')
|
|
34
|
-
.option('--workspace <name>', 'Named workspace')
|
|
35
|
-
.option('--task <task>', 'Initial task')
|
|
36
|
-
.option('--carry-uncommitted', "Preserve operator's uncommitted edits in the world's worktree (B3)")
|
|
37
|
-
.action((opts) => {
|
|
38
|
-
captured.opts = opts;
|
|
39
|
-
});
|
|
40
|
-
return { program, captured };
|
|
41
|
-
}
|
|
42
|
-
describe('olam create --carry-uncommitted flag', () => {
|
|
43
|
-
it('parses to carryUncommitted:true when flag is passed', () => {
|
|
44
|
-
const { program, captured } = buildTestCommand();
|
|
45
|
-
program.parse(['create', '--carry-uncommitted'], { from: 'user' });
|
|
46
|
-
expect(captured.opts?.carryUncommitted).toBe(true);
|
|
47
|
-
});
|
|
48
|
-
it('parses to carryUncommitted:undefined (falsy) when flag is omitted', () => {
|
|
49
|
-
const { program, captured } = buildTestCommand();
|
|
50
|
-
program.parse(['create', '--name', 'foo'], { from: 'user' });
|
|
51
|
-
expect(captured.opts?.carryUncommitted).toBeFalsy();
|
|
52
|
-
});
|
|
53
|
-
it('coexists with other flags (--name, --workspace, --task) without conflict', () => {
|
|
54
|
-
const { program, captured } = buildTestCommand();
|
|
55
|
-
program.parse(['create', '--name', 'foo', '--workspace', 'atlas', '--task', 'do thing', '--carry-uncommitted'], { from: 'user' });
|
|
56
|
-
expect(captured.opts?.name).toBe('foo');
|
|
57
|
-
expect(captured.opts?.workspace).toBe('atlas');
|
|
58
|
-
expect(captured.opts?.task).toBe('do thing');
|
|
59
|
-
expect(captured.opts?.carryUncommitted).toBe(true);
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
describe('--carry-uncommitted maps to CreateWorldOpts.carryUncommitted', () => {
|
|
63
|
-
it('the createWorld opts shape includes carryUncommitted: <bool>', () => {
|
|
64
|
-
// Contract test: when the action handler builds its createWorld
|
|
65
|
-
// opts dict, `carryUncommitted: opts.carryUncommitted ?? false`
|
|
66
|
-
// must be present so the manager's conditional skip fires correctly.
|
|
67
|
-
// Mirror the build expression here so a future refactor that drops
|
|
68
|
-
// the field gets caught.
|
|
69
|
-
const cliOpts = { carryUncommitted: true };
|
|
70
|
-
const createWorldOpts = {
|
|
71
|
-
name: 'foo',
|
|
72
|
-
carryUncommitted: cliOpts.carryUncommitted ?? false,
|
|
73
|
-
};
|
|
74
|
-
expect(createWorldOpts.carryUncommitted).toBe(true);
|
|
75
|
-
const cliOptsNoFlag = {};
|
|
76
|
-
const createWorldOpts2 = {
|
|
77
|
-
name: 'foo',
|
|
78
|
-
carryUncommitted: cliOptsNoFlag.carryUncommitted ?? false,
|
|
79
|
-
};
|
|
80
|
-
expect(createWorldOpts2.carryUncommitted).toBe(false);
|
|
81
|
-
});
|
|
82
|
-
});
|
|
83
|
-
//# sourceMappingURL=carry-uncommitted.test.js.map
|