Browse Source

fix(config-io): handle array-format plugin entries in getPinnedVersionFromConfig

Signed-off-by: Omar Mohamed <mohamed.omar67492@gmail.com>
Omar 2 months ago
parent
commit
e54d1c803a
2 changed files with 71 additions and 4 deletions
  1. 65 0
      src/cli/cache.test.ts
  2. 6 4
      src/cli/config-io.ts

+ 65 - 0
src/cli/cache.test.ts

@@ -469,6 +469,71 @@ describe('warmOpenCodePluginCache', () => {
     rmSync(tmpDir, { recursive: true, force: true });
   });
 
+  test('uses pinned version from array-format plugin entry', async () => {
+    const tmpDir = mkdirTemp();
+    const cacheHome = join(tmpDir, 'cache');
+    process.env.XDG_CACHE_HOME = cacheHome;
+
+    // Config uses array tuple format: [spec, options]
+    const configDir = join(tmpDir, 'config');
+    mkdirSync(configDir, { recursive: true });
+    const configPath = join(configDir, 'opencode.json');
+    writeFileSync(
+      configPath,
+      JSON.stringify({
+        plugin: [['oh-my-opencode-slim@1.2.3', { someOption: true }]],
+      }),
+    );
+
+    const pathsMod = await import('./paths');
+    const configPathSpy = spyOn(
+      pathsMod,
+      'getExistingConfigPath',
+    ).mockReturnValue(configPath);
+
+    try {
+      const packageRoot = join(
+        tmpDir,
+        'bunx-1000-oh-my-opencode-slim@latest',
+        'node_modules',
+        'oh-my-opencode-slim',
+      );
+      mkdirSync(join(packageRoot, 'dist', 'cli'), { recursive: true });
+      writeFileSync(
+        join(packageRoot, 'package.json'),
+        JSON.stringify({ name: 'oh-my-opencode-slim' }),
+      );
+      process.argv[1] = join(packageRoot, 'dist', 'cli', 'index.js');
+
+      const { warmOpenCodePluginCache } = await importFreshConfigIo();
+      const result = await warmOpenCodePluginCache();
+
+      const expectedCacheDir = join(
+        cacheHome,
+        'opencode',
+        'packages',
+        'oh-my-opencode-slim@1.2.3',
+      );
+
+      expect(result?.success).toBe(true);
+      expect(result?.configPath).toBe(expectedCacheDir);
+      expect(
+        JSON.parse(
+          readFileSync(join(expectedCacheDir, 'package.json'), 'utf-8'),
+        ),
+      ).toEqual({
+        name: 'oh-my-opencode-slim-cache',
+        private: true,
+        dependencies: {
+          'oh-my-opencode-slim': '1.2.3',
+        },
+      });
+    } finally {
+      configPathSpy.mockRestore();
+      rmSync(tmpDir, { recursive: true, force: true });
+    }
+  });
+
   test('pinned config version takes precedence over running version', async () => {
     const tmpDir = mkdirTemp();
     const cacheHome = join(tmpDir, 'cache');

+ 6 - 4
src/cli/config-io.ts

@@ -150,10 +150,12 @@ function getPinnedVersionFromConfig(): string | undefined {
   try {
     const { config } = parseConfig(getExistingConfigPath());
     if (!config) return undefined;
-    for (const entry of getPluginEntries(config)) {
-      if (entry === PACKAGE_NAME) return undefined;
-      if (entry.startsWith(`${PACKAGE_NAME}@`)) {
-        const version = entry.slice(PACKAGE_NAME.length + 1);
+    for (const entry of getPlugins(config)) {
+      const spec = getPluginSpec(entry);
+      if (!spec) continue;
+      if (spec === PACKAGE_NAME) return undefined;
+      if (spec.startsWith(`${PACKAGE_NAME}@`)) {
+        const version = spec.slice(PACKAGE_NAME.length + 1);
         if (version && version !== 'latest') return version;
       }
     }