mirror of
https://github.com/affaan-m/ECC.git
synced 2026-08-28 10:49:45 +02:00
test(opencode): cover legacy upgrade edge cases
This commit is contained in:
@@ -62,6 +62,23 @@ function seedLegacyInstall(homeDir, options = {}) {
|
||||
scaffoldOnly: false,
|
||||
contentSha256: digest(sourceContent),
|
||||
};
|
||||
const operations = [operation];
|
||||
if (options.includeJsonOperation) {
|
||||
const configPath = path.join(targetRoot, 'opencode.json');
|
||||
fs.writeFileSync(configPath, JSON.stringify({ plugin: ['ecc'] }, null, 2) + '\n');
|
||||
operations.push({
|
||||
kind: 'merge-json',
|
||||
moduleId: 'opencode-plugin',
|
||||
sourceRelativePath: '.opencode/opencode.json',
|
||||
destinationPath: configPath,
|
||||
strategy: 'merge-json',
|
||||
ownership: 'managed',
|
||||
scaffoldOnly: false,
|
||||
mergePayload: { plugin: ['ecc'] },
|
||||
previousExists: false,
|
||||
previousContent: null,
|
||||
});
|
||||
}
|
||||
const state = createInstallState({
|
||||
adapter: { id: 'opencode-home', target: 'opencode', kind: 'home' },
|
||||
targetRoot,
|
||||
@@ -80,19 +97,20 @@ function seedLegacyInstall(homeDir, options = {}) {
|
||||
repoCommit: 'legacy-opencode-test',
|
||||
manifestVersion: require('../../manifests/install-modules.json').version,
|
||||
},
|
||||
operations: [operation],
|
||||
operations,
|
||||
});
|
||||
writeInstallState(installStatePath, state);
|
||||
return { targetRoot, installStatePath, destinationPath };
|
||||
}
|
||||
|
||||
function canonicalPlan(homeDir) {
|
||||
function canonicalPlan(homeDir, env) {
|
||||
return createManifestInstallPlan({
|
||||
sourceRoot: REPO_ROOT,
|
||||
target: 'opencode',
|
||||
moduleIds: ['workflow-quality'],
|
||||
projectRoot: homeDir,
|
||||
homeDir,
|
||||
...(env ? { env } : {}),
|
||||
exemptValidationCodes: ['opencode-plugin-not-built'],
|
||||
});
|
||||
}
|
||||
@@ -182,6 +200,55 @@ test('a canonical install migrates unchanged legacy ownership', () => {
|
||||
}
|
||||
});
|
||||
|
||||
test('a canonical install migrates legacy ownership when its config root is overridden', () => {
|
||||
const homeDir = fs.mkdtempSync(path.join(os.tmpdir(), 'opencode-legacy-custom-root-'));
|
||||
try {
|
||||
const legacy = seedLegacyInstall(homeDir);
|
||||
const configRoot = path.join(homeDir, 'custom', 'opencode');
|
||||
const result = applyInstallPlan(canonicalPlan(homeDir, {
|
||||
OPENCODE_CONFIG_DIR: configRoot,
|
||||
}));
|
||||
assert.ok(result.applied);
|
||||
assert.ok(fs.existsSync(path.join(configRoot, 'ecc-install-state.json')));
|
||||
assert.ok(!fs.existsSync(legacy.installStatePath));
|
||||
assert.ok(!fs.existsSync(legacy.destinationPath));
|
||||
} finally {
|
||||
fs.rmSync(homeDir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
test('legacy non-file operations do not block canonical cleanup or repair', () => {
|
||||
const applyHome = fs.mkdtempSync(path.join(os.tmpdir(), 'opencode-legacy-json-apply-'));
|
||||
const repairHome = fs.mkdtempSync(path.join(os.tmpdir(), 'opencode-legacy-json-repair-'));
|
||||
try {
|
||||
const legacyApply = seedLegacyInstall(applyHome, { includeJsonOperation: true });
|
||||
applyInstallPlan(canonicalPlan(applyHome));
|
||||
assert.ok(!fs.existsSync(legacyApply.installStatePath));
|
||||
assert.ok(fs.existsSync(path.join(legacyApply.targetRoot, 'opencode.json')));
|
||||
|
||||
const legacyRepair = seedLegacyInstall(repairHome, { includeJsonOperation: true });
|
||||
const result = repairInstalledStates({
|
||||
repoRoot: REPO_ROOT,
|
||||
homeDir: repairHome,
|
||||
projectRoot: repairHome,
|
||||
targets: ['opencode'],
|
||||
});
|
||||
const canonicalStatePath = path.join(
|
||||
repairHome,
|
||||
'.config',
|
||||
'opencode',
|
||||
'ecc-install-state.json'
|
||||
);
|
||||
assert.strictEqual(result.summary.errorCount, 0, JSON.stringify(result));
|
||||
assert.ok(fs.existsSync(canonicalStatePath));
|
||||
assert.ok(!fs.existsSync(legacyRepair.installStatePath));
|
||||
assert.ok(fs.existsSync(path.join(legacyRepair.targetRoot, 'opencode.json')));
|
||||
} finally {
|
||||
fs.rmSync(applyHome, { recursive: true, force: true });
|
||||
fs.rmSync(repairHome, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
test('repair migrates a legacy install while preserving modified legacy files', () => {
|
||||
const homeDir = fs.mkdtempSync(path.join(os.tmpdir(), 'opencode-legacy-repair-'));
|
||||
try {
|
||||
|
||||
@@ -502,6 +502,52 @@ function runTests() {
|
||||
}
|
||||
})) passed += 1; else failed += 1;
|
||||
|
||||
if (test('runAutoUpdate gives legacy-only OpenCode migration guidance', () => {
|
||||
const homeDir = createTempDir('auto-update-home-');
|
||||
const projectRoot = createTempDir('auto-update-project-');
|
||||
const repoRoot = createTempDir('auto-update-repo-');
|
||||
|
||||
try {
|
||||
ensureFakeRepo(repoRoot);
|
||||
const legacy = {
|
||||
...makeRecord({
|
||||
repoRoot,
|
||||
homeDir,
|
||||
projectRoot,
|
||||
adapter: { id: 'opencode-home', target: 'opencode', kind: 'home' },
|
||||
request: {
|
||||
profile: null,
|
||||
modules: ['workflow-quality'],
|
||||
includeComponents: [],
|
||||
excludeComponents: [],
|
||||
legacyLanguages: [],
|
||||
legacyMode: false,
|
||||
},
|
||||
resolution: { selectedModules: ['workflow-quality'], skippedModules: [] },
|
||||
operations: [],
|
||||
}),
|
||||
installStatePath: path.join(homeDir, '.opencode', 'ecc-install-state.json'),
|
||||
legacy: true,
|
||||
legacyLayout: 'opencode',
|
||||
};
|
||||
|
||||
const result = runAutoUpdate(
|
||||
{ homeDir, projectRoot, repoRoot, dryRun: true },
|
||||
{ discoverInstalledStates: () => [legacy] }
|
||||
);
|
||||
|
||||
assert.deepStrictEqual(result.results, []);
|
||||
assert.ok(result.warnings.some(warning => warning.includes(
|
||||
'Run the OpenCode installer once to migrate it to the configured OpenCode directory'
|
||||
)));
|
||||
assert.ok(result.warnings.every(warning => !warning.includes('Antigravity')));
|
||||
} finally {
|
||||
cleanup(homeDir);
|
||||
cleanup(projectRoot);
|
||||
cleanup(repoRoot);
|
||||
}
|
||||
})) passed += 1; else failed += 1;
|
||||
|
||||
console.log(`\nResults: Passed: ${passed}, Failed: ${failed}`);
|
||||
process.exit(failed > 0 ? 1 : 0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user