From 3e9701861e9dc10fc6a28470069a63ebf6823c39 Mon Sep 17 00:00:00 2001 From: Shreya Keshive Date: Wed, 29 Oct 2025 13:23:35 -0700 Subject: [PATCH] refactor(core): Move getPackageJson utility to core package (#12224) --- package-lock.json | 1 + packages/cli/src/config/sandboxConfig.ts | 16 +++++--- packages/cli/src/ui/utils/updateCheck.test.ts | 6 ++- packages/cli/src/ui/utils/updateCheck.ts | 10 +++-- packages/cli/src/utils/package.ts | 38 ------------------- packages/cli/src/utils/version.ts | 9 ++++- packages/core/package.json | 1 + packages/core/src/index.ts | 1 + packages/core/src/utils/package.ts | 28 ++++++++++++++ 9 files changed, 61 insertions(+), 49 deletions(-) delete mode 100644 packages/cli/src/utils/package.ts create mode 100644 packages/core/src/utils/package.ts diff --git a/package-lock.json b/package-lock.json index 5ef0dfe882..6d285c400d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17868,6 +17868,7 @@ "mnemonist": "^0.40.3", "open": "^10.1.2", "picomatch": "^4.0.1", + "read-package-up": "^11.0.0", "shell-quote": "^1.8.3", "simple-git": "^3.28.0", "strip-ansi": "^7.1.0", diff --git a/packages/cli/src/config/sandboxConfig.ts b/packages/cli/src/config/sandboxConfig.ts index 8d2242c441..4e5088b30d 100644 --- a/packages/cli/src/config/sandboxConfig.ts +++ b/packages/cli/src/config/sandboxConfig.ts @@ -4,19 +4,25 @@ * SPDX-License-Identifier: Apache-2.0 */ -import type { SandboxConfig } from '@google/gemini-cli-core'; -import { FatalSandboxError } from '@google/gemini-cli-core'; +import { + getPackageJson, + type SandboxConfig, + FatalSandboxError, +} from '@google/gemini-cli-core'; import commandExists from 'command-exists'; import * as os from 'node:os'; -import { getPackageJson } from '../utils/package.js'; import type { Settings } from './settings.js'; +import { fileURLToPath } from 'node:url'; +import path from 'node:path'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); // This is a stripped-down version of the CliArgs interface from config.ts // to avoid circular dependencies. interface SandboxCliArgs { sandbox?: boolean | string; } - const VALID_SANDBOX_COMMANDS: ReadonlyArray = [ 'docker', 'podman', @@ -94,7 +100,7 @@ export async function loadSandboxConfig( const sandboxOption = argv.sandbox ?? settings.tools?.sandbox; const command = getSandboxCommand(sandboxOption); - const packageJson = await getPackageJson(); + const packageJson = await getPackageJson(__dirname); const image = process.env['GEMINI_SANDBOX_IMAGE'] ?? packageJson?.config?.sandboxImageUri; diff --git a/packages/cli/src/ui/utils/updateCheck.test.ts b/packages/cli/src/ui/utils/updateCheck.test.ts index 085fd2ea28..6ab29d6667 100644 --- a/packages/cli/src/ui/utils/updateCheck.test.ts +++ b/packages/cli/src/ui/utils/updateCheck.test.ts @@ -9,8 +9,12 @@ import { checkForUpdates } from './updateCheck.js'; import type { LoadedSettings } from '../../config/settings.js'; const getPackageJson = vi.hoisted(() => vi.fn()); -vi.mock('../../utils/package.js', () => ({ +const debugLogger = vi.hoisted(() => ({ + warn: vi.fn(), +})); +vi.mock('@google/gemini-cli-core', () => ({ getPackageJson, + debugLogger, })); const latestVersion = vi.hoisted(() => vi.fn()); diff --git a/packages/cli/src/ui/utils/updateCheck.ts b/packages/cli/src/ui/utils/updateCheck.ts index 6a6de8518d..000b37070d 100644 --- a/packages/cli/src/ui/utils/updateCheck.ts +++ b/packages/cli/src/ui/utils/updateCheck.ts @@ -6,9 +6,13 @@ import latestVersion from 'latest-version'; import semver from 'semver'; -import { getPackageJson } from '../../utils/package.js'; +import { getPackageJson, debugLogger } from '@google/gemini-cli-core'; import type { LoadedSettings } from '../../config/settings.js'; -import { debugLogger } from '@google/gemini-cli-core'; +import { fileURLToPath } from 'node:url'; +import path from 'node:path'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); export const FETCH_TIMEOUT_MS = 2000; @@ -54,7 +58,7 @@ export async function checkForUpdates( if (process.env['DEV'] === 'true') { return null; } - const packageJson = await getPackageJson(); + const packageJson = await getPackageJson(__dirname); if (!packageJson || !packageJson.name || !packageJson.version) { return null; } diff --git a/packages/cli/src/utils/package.ts b/packages/cli/src/utils/package.ts deleted file mode 100644 index e90376b69b..0000000000 --- a/packages/cli/src/utils/package.ts +++ /dev/null @@ -1,38 +0,0 @@ -/** - * @license - * Copyright 2025 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - -import { - readPackageUp, - type PackageJson as BasePackageJson, -} from 'read-package-up'; -import { fileURLToPath } from 'node:url'; -import path from 'node:path'; - -export type PackageJson = BasePackageJson & { - config?: { - sandboxImageUri?: string; - }; -}; - -const __filename = fileURLToPath(import.meta.url); -const __dirname = path.dirname(__filename); - -let packageJson: PackageJson | undefined; - -export async function getPackageJson(): Promise { - if (packageJson) { - return packageJson; - } - - const result = await readPackageUp({ cwd: __dirname }); - if (!result) { - // TODO: Maybe bubble this up as an error. - return; - } - - packageJson = result.packageJson; - return packageJson; -} diff --git a/packages/cli/src/utils/version.ts b/packages/cli/src/utils/version.ts index 0318f380be..82c55a1129 100644 --- a/packages/cli/src/utils/version.ts +++ b/packages/cli/src/utils/version.ts @@ -4,9 +4,14 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { getPackageJson } from './package.js'; +import { getPackageJson } from '@google/gemini-cli-core'; +import { fileURLToPath } from 'node:url'; +import path from 'node:path'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); export async function getCliVersion(): Promise { - const pkgJson = await getPackageJson(); + const pkgJson = await getPackageJson(__dirname); return process.env['CLI_VERSION'] || pkgJson?.version || 'unknown'; } diff --git a/packages/core/package.json b/packages/core/package.json index 307d2defa2..e4405060bd 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -58,6 +58,7 @@ "mnemonist": "^0.40.3", "open": "^10.1.2", "picomatch": "^4.0.1", + "read-package-up": "^11.0.0", "shell-quote": "^1.8.3", "simple-git": "^3.28.0", "strip-ansi": "^7.1.0", diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 8b95915bad..f9b2377d63 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -68,6 +68,7 @@ export * from './utils/thoughtUtils.js'; export * from './utils/debugLogger.js'; export * from './utils/events.js'; export * from './utils/extensionLoader.js'; +export * from './utils/package.js'; // Export services export * from './services/fileDiscoveryService.js'; diff --git a/packages/core/src/utils/package.ts b/packages/core/src/utils/package.ts new file mode 100644 index 0000000000..0ef7673f5d --- /dev/null +++ b/packages/core/src/utils/package.ts @@ -0,0 +1,28 @@ +/** + * @license + * Copyright 2025 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import { + readPackageUp, + type PackageJson as BasePackageJson, +} from 'read-package-up'; + +export type PackageJson = BasePackageJson & { + config?: { + sandboxImageUri?: string; + }; +}; + +export async function getPackageJson( + cwd: string, +): Promise { + const result = await readPackageUp({ cwd }); + if (!result) { + // TODO: Maybe bubble this up as an error. + return; + } + + return result.packageJson; +}