mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-28 23:11:19 -07:00
chore: Extract '.gemini' to GEMINI_DIR constant (#10540)
Co-authored-by: Richie Foreman <richie.foreman@gmail.com>
This commit is contained in:
committed by
GitHub
parent
7beaa368a9
commit
518caae62e
@@ -32,7 +32,7 @@ vi.mock('@google/gemini-cli-core', () => ({
|
||||
getWorkspaceSettingsPath: () => '/tmp/gemini/workspace-settings.json',
|
||||
getProjectTempDir: () => '/test/home/.gemini/tmp/mocked_hash',
|
||||
})),
|
||||
GEMINI_CONFIG_DIR: '.gemini',
|
||||
GEMINI_DIR: '.gemini',
|
||||
getErrorMessage: (e: unknown) => (e instanceof Error ? e.message : String(e)),
|
||||
}));
|
||||
vi.mock('@modelcontextprotocol/sdk/client/index.js');
|
||||
|
||||
@@ -11,6 +11,7 @@ import { removeCommand } from './remove.js';
|
||||
import * as fs from 'node:fs';
|
||||
import * as path from 'node:path';
|
||||
import * as os from 'node:os';
|
||||
import { GEMINI_DIR } from '@google/gemini-cli-core';
|
||||
|
||||
vi.mock('fs/promises', () => ({
|
||||
readFile: vi.fn(),
|
||||
@@ -80,7 +81,7 @@ describe('mcp remove command', () => {
|
||||
vi.restoreAllMocks();
|
||||
|
||||
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'mcp-remove-test-'));
|
||||
settingsDir = path.join(tempDir, '.gemini');
|
||||
settingsDir = path.join(tempDir, GEMINI_DIR);
|
||||
settingsPath = path.join(settingsDir, 'settings.json');
|
||||
fs.mkdirSync(settingsDir, { recursive: true });
|
||||
|
||||
|
||||
@@ -1171,7 +1171,10 @@ describe('Hierarchical Memory Loading (config.ts) - Placeholder Suite', () => {
|
||||
// 3. Spies on console functions (for logger output) are correctly set up if needed.
|
||||
// Example of a previously failing test structure:
|
||||
it.skip('should correctly use mocked homedir for global path', async () => {
|
||||
const MOCK_GEMINI_DIR_LOCAL = path.join('/mock/home/user', '.gemini');
|
||||
const MOCK_GEMINI_DIR_LOCAL = path.join(
|
||||
'/mock/home/user',
|
||||
ServerConfig.GEMINI_DIR,
|
||||
);
|
||||
const MOCK_GLOBAL_PATH_LOCAL = path.join(
|
||||
MOCK_GEMINI_DIR_LOCAL,
|
||||
'GEMINI.md',
|
||||
|
||||
@@ -9,7 +9,8 @@ import fs from 'node:fs';
|
||||
import os from 'node:os';
|
||||
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
||||
import { ExtensionEnablementManager, Override } from './extensionEnablement.js';
|
||||
import type { GeminiCLIExtension } from '@google/gemini-cli-core';
|
||||
|
||||
import { GEMINI_DIR, type GeminiCLIExtension } from '@google/gemini-cli-core';
|
||||
|
||||
// Helper to create a temporary directory for testing
|
||||
function createTestDir() {
|
||||
@@ -27,7 +28,7 @@ let manager: ExtensionEnablementManager;
|
||||
describe('ExtensionEnablementManager', () => {
|
||||
beforeEach(() => {
|
||||
testDir = createTestDir();
|
||||
configDir = path.join(testDir.path, '.gemini');
|
||||
configDir = path.join(testDir.path, GEMINI_DIR);
|
||||
manager = new ExtensionEnablementManager(configDir);
|
||||
});
|
||||
|
||||
|
||||
@@ -59,7 +59,6 @@ import {
|
||||
USER_SETTINGS_PATH, // This IS the mocked path.
|
||||
getSystemSettingsPath,
|
||||
getSystemDefaultsPath,
|
||||
SETTINGS_DIRECTORY_NAME, // This is from the original module, but used by the mock.
|
||||
migrateSettingsToV1,
|
||||
needsMigration,
|
||||
type Settings,
|
||||
@@ -70,10 +69,10 @@ import {
|
||||
import { FatalConfigError, GEMINI_DIR } from '@google/gemini-cli-core';
|
||||
|
||||
const MOCK_WORKSPACE_DIR = '/mock/workspace';
|
||||
// Use the (mocked) SETTINGS_DIRECTORY_NAME for consistency
|
||||
// Use the (mocked) GEMINI_DIR for consistency
|
||||
const MOCK_WORKSPACE_SETTINGS_PATH = pathActual.join(
|
||||
MOCK_WORKSPACE_DIR,
|
||||
SETTINGS_DIRECTORY_NAME,
|
||||
GEMINI_DIR,
|
||||
'settings.json',
|
||||
);
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import * as dotenv from 'dotenv';
|
||||
import process from 'node:process';
|
||||
import {
|
||||
FatalConfigError,
|
||||
GEMINI_CONFIG_DIR as GEMINI_DIR,
|
||||
GEMINI_DIR,
|
||||
getErrorMessage,
|
||||
Storage,
|
||||
} from '@google/gemini-cli-core';
|
||||
@@ -49,8 +49,6 @@ function getMergeStrategyForPath(path: string[]): MergeStrategy | undefined {
|
||||
|
||||
export type { Settings, MemoryImportFormat };
|
||||
|
||||
export const SETTINGS_DIRECTORY_NAME = '.gemini';
|
||||
|
||||
export const USER_SETTINGS_PATH = Storage.getGlobalSettingsPath();
|
||||
export const USER_SETTINGS_DIR = path.dirname(USER_SETTINGS_PATH);
|
||||
export const DEFAULT_EXCLUDED_ENV_VARS = ['DEBUG', 'DEBUG_MODE'];
|
||||
|
||||
@@ -12,13 +12,13 @@ import {
|
||||
getErrorMessage,
|
||||
isWithinRoot,
|
||||
ideContextStore,
|
||||
GEMINI_DIR,
|
||||
} from '@google/gemini-cli-core';
|
||||
import type { Settings } from './settings.js';
|
||||
import stripJsonComments from 'strip-json-comments';
|
||||
|
||||
export const TRUSTED_FOLDERS_FILENAME = 'trustedFolders.json';
|
||||
export const SETTINGS_DIRECTORY_NAME = '.gemini';
|
||||
export const USER_SETTINGS_DIR = path.join(homedir(), SETTINGS_DIRECTORY_NAME);
|
||||
export const USER_SETTINGS_DIR = path.join(homedir(), GEMINI_DIR);
|
||||
|
||||
export function getTrustedFoldersPath(): string {
|
||||
if (process.env['GEMINI_CLI_TRUSTED_FOLDERS_PATH']) {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
import * as path from 'node:path';
|
||||
import type { Config } from '@google/gemini-cli-core';
|
||||
import { Storage } from '@google/gemini-cli-core';
|
||||
import { GEMINI_DIR, Storage } from '@google/gemini-cli-core';
|
||||
import mock from 'mock-fs';
|
||||
import { FileCommandLoader } from './FileCommandLoader.js';
|
||||
import { assert, vi } from 'vitest';
|
||||
@@ -529,7 +529,9 @@ describe('FileCommandLoader', () => {
|
||||
).getProjectCommandsDir();
|
||||
const extensionDir = path.join(
|
||||
process.cwd(),
|
||||
'.gemini/extensions/test-ext',
|
||||
GEMINI_DIR,
|
||||
'extensions',
|
||||
'test-ext',
|
||||
);
|
||||
|
||||
mock({
|
||||
@@ -582,7 +584,9 @@ describe('FileCommandLoader', () => {
|
||||
).getProjectCommandsDir();
|
||||
const extensionDir = path.join(
|
||||
process.cwd(),
|
||||
'.gemini/extensions/test-ext',
|
||||
GEMINI_DIR,
|
||||
'extensions',
|
||||
'test-ext',
|
||||
);
|
||||
|
||||
mock({
|
||||
@@ -678,11 +682,15 @@ describe('FileCommandLoader', () => {
|
||||
it('only loads commands from active extensions', async () => {
|
||||
const extensionDir1 = path.join(
|
||||
process.cwd(),
|
||||
'.gemini/extensions/active-ext',
|
||||
GEMINI_DIR,
|
||||
'extensions',
|
||||
'active-ext',
|
||||
);
|
||||
const extensionDir2 = path.join(
|
||||
process.cwd(),
|
||||
'.gemini/extensions/inactive-ext',
|
||||
GEMINI_DIR,
|
||||
'extensions',
|
||||
'inactive-ext',
|
||||
);
|
||||
|
||||
mock({
|
||||
@@ -737,7 +745,9 @@ describe('FileCommandLoader', () => {
|
||||
it('handles missing extension commands directory gracefully', async () => {
|
||||
const extensionDir = path.join(
|
||||
process.cwd(),
|
||||
'.gemini/extensions/no-commands',
|
||||
GEMINI_DIR,
|
||||
'extensions',
|
||||
'no-commands',
|
||||
);
|
||||
|
||||
mock({
|
||||
@@ -769,7 +779,12 @@ describe('FileCommandLoader', () => {
|
||||
});
|
||||
|
||||
it('handles nested command structure in extensions', async () => {
|
||||
const extensionDir = path.join(process.cwd(), '.gemini/extensions/a');
|
||||
const extensionDir = path.join(
|
||||
process.cwd(),
|
||||
GEMINI_DIR,
|
||||
'extensions',
|
||||
'a',
|
||||
);
|
||||
|
||||
mock({
|
||||
[extensionDir]: {
|
||||
|
||||
@@ -11,7 +11,11 @@ import * as path from 'node:path';
|
||||
import { restoreCommand } from './restoreCommand.js';
|
||||
import { type CommandContext } from './types.js';
|
||||
import { createMockCommandContext } from '../../test-utils/mockCommandContext.js';
|
||||
import type { Config, GitService } from '@google/gemini-cli-core';
|
||||
import {
|
||||
GEMINI_DIR,
|
||||
type Config,
|
||||
type GitService,
|
||||
} from '@google/gemini-cli-core';
|
||||
|
||||
describe('restoreCommand', () => {
|
||||
let mockContext: CommandContext;
|
||||
@@ -26,7 +30,7 @@ describe('restoreCommand', () => {
|
||||
testRootDir = await fs.mkdtemp(
|
||||
path.join(os.tmpdir(), 'restore-command-test-'),
|
||||
);
|
||||
geminiTempDir = path.join(testRootDir, '.gemini');
|
||||
geminiTempDir = path.join(testRootDir, GEMINI_DIR);
|
||||
checkpointsDir = path.join(geminiTempDir, 'checkpoints');
|
||||
// The command itself creates this, but for tests it's easier to have it ready.
|
||||
// Some tests might remove it to test error paths.
|
||||
|
||||
@@ -11,10 +11,11 @@ import { theme } from '../semantic-colors.js';
|
||||
import { StreamingState } from '../types.js';
|
||||
import { UpdateNotification } from './UpdateNotification.js';
|
||||
|
||||
import { GEMINI_DIR } from '@google/gemini-cli-core';
|
||||
import { homedir } from 'node:os';
|
||||
import path from 'node:path';
|
||||
|
||||
const settingsPath = path.join(homedir(), '.gemini', 'settings.json');
|
||||
const settingsPath = path.join(homedir(), GEMINI_DIR, 'settings.json');
|
||||
|
||||
export const Notifications = () => {
|
||||
const { startupWarnings } = useAppContext();
|
||||
|
||||
@@ -19,6 +19,7 @@ vi.mock('../contexts/ConfigContext.js');
|
||||
vi.mock('../contexts/UIStateContext.js');
|
||||
vi.mock('@google/gemini-cli-core', () => ({
|
||||
recordFlickerFrame: vi.fn(),
|
||||
GEMINI_DIR: '.gemini',
|
||||
}));
|
||||
vi.mock('ink', async (importOriginal) => {
|
||||
const original = await importOriginal<typeof import('ink')>();
|
||||
|
||||
@@ -10,30 +10,34 @@ import * as fs from 'node:fs/promises';
|
||||
import * as path from 'node:path';
|
||||
import * as os from 'node:os';
|
||||
import * as crypto from 'node:crypto';
|
||||
import { GEMINI_DIR } from '@google/gemini-cli-core';
|
||||
|
||||
vi.mock('fs/promises', () => ({
|
||||
vi.mock('node:fs/promises', () => ({
|
||||
readFile: vi.fn(),
|
||||
writeFile: vi.fn(),
|
||||
mkdir: vi.fn(),
|
||||
}));
|
||||
vi.mock('os');
|
||||
vi.mock('crypto');
|
||||
vi.mock('fs', async (importOriginal) => {
|
||||
const actualFs = await importOriginal<typeof import('fs')>();
|
||||
vi.mock('node:os');
|
||||
vi.mock('node:crypto');
|
||||
vi.mock('node:fs', async (importOriginal) => {
|
||||
const actualFs = await importOriginal<typeof import('node:fs')>();
|
||||
return {
|
||||
...actualFs,
|
||||
mkdirSync: vi.fn(),
|
||||
};
|
||||
});
|
||||
vi.mock('@google/gemini-cli-core', () => {
|
||||
vi.mock('@google/gemini-cli-core', async (importOriginal) => {
|
||||
const actual =
|
||||
await importOriginal<typeof import('@google/gemini-cli-core')>();
|
||||
const path = await import('node:path');
|
||||
class Storage {
|
||||
getProjectTempDir(): string {
|
||||
return path.join('/test/home/', '.gemini', 'tmp', 'mocked_hash');
|
||||
return path.join('/test/home/', actual.GEMINI_DIR, 'tmp', 'mocked_hash');
|
||||
}
|
||||
getHistoryFilePath(): string {
|
||||
return path.join(
|
||||
'/test/home/',
|
||||
'.gemini',
|
||||
actual.GEMINI_DIR,
|
||||
'tmp',
|
||||
'mocked_hash',
|
||||
'shell_history',
|
||||
@@ -41,6 +45,7 @@ vi.mock('@google/gemini-cli-core', () => {
|
||||
}
|
||||
}
|
||||
return {
|
||||
...actual,
|
||||
isNodeError: (err: unknown): err is NodeJS.ErrnoException =>
|
||||
typeof err === 'object' && err !== null && 'code' in err,
|
||||
Storage,
|
||||
@@ -53,7 +58,7 @@ const MOCKED_PROJECT_HASH = 'mocked_hash';
|
||||
|
||||
const MOCKED_HISTORY_DIR = path.join(
|
||||
MOCKED_HOME_DIR,
|
||||
'.gemini',
|
||||
GEMINI_DIR,
|
||||
'tmp',
|
||||
MOCKED_PROJECT_HASH,
|
||||
);
|
||||
|
||||
@@ -11,13 +11,10 @@ import fs from 'node:fs';
|
||||
import { readFile } from 'node:fs/promises';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { quote, parse } from 'shell-quote';
|
||||
import {
|
||||
USER_SETTINGS_DIR,
|
||||
SETTINGS_DIRECTORY_NAME,
|
||||
} from '../config/settings.js';
|
||||
import { USER_SETTINGS_DIR } from '../config/settings.js';
|
||||
import { promisify } from 'node:util';
|
||||
import type { Config, SandboxConfig } from '@google/gemini-cli-core';
|
||||
import { FatalSandboxError } from '@google/gemini-cli-core';
|
||||
import { FatalSandboxError, GEMINI_DIR } from '@google/gemini-cli-core';
|
||||
import { ConsolePatcher } from '../ui/utils/ConsolePatcher.js';
|
||||
import { randomBytes } from 'node:crypto';
|
||||
|
||||
@@ -156,10 +153,7 @@ function entrypoint(workdir: string, cliArgs: string[]): string[] {
|
||||
shellCmds.push(`export PYTHONPATH="$PYTHONPATH${pythonPathSuffix}";`);
|
||||
}
|
||||
|
||||
const projectSandboxBashrc = path.join(
|
||||
SETTINGS_DIRECTORY_NAME,
|
||||
'sandbox.bashrc',
|
||||
);
|
||||
const projectSandboxBashrc = path.join(GEMINI_DIR, 'sandbox.bashrc');
|
||||
if (fs.existsSync(projectSandboxBashrc)) {
|
||||
shellCmds.push(`source ${getContainerPath(projectSandboxBashrc)};`);
|
||||
}
|
||||
@@ -211,10 +205,7 @@ export async function start_sandbox(
|
||||
);
|
||||
// if profile name is not recognized, then look for file under project settings directory
|
||||
if (!BUILTIN_SEATBELT_PROFILES.includes(profile)) {
|
||||
profileFile = path.join(
|
||||
SETTINGS_DIRECTORY_NAME,
|
||||
`sandbox-macos-${profile}.sb`,
|
||||
);
|
||||
profileFile = path.join(GEMINI_DIR, `sandbox-macos-${profile}.sb`);
|
||||
}
|
||||
if (!fs.existsSync(profileFile)) {
|
||||
throw new FatalSandboxError(
|
||||
@@ -359,7 +350,7 @@ export async function start_sandbox(
|
||||
const gcPath = fs.realpathSync(process.argv[1]);
|
||||
|
||||
const projectSandboxDockerfile = path.join(
|
||||
SETTINGS_DIRECTORY_NAME,
|
||||
GEMINI_DIR,
|
||||
'sandbox.Dockerfile',
|
||||
);
|
||||
const isCustomProjectSandbox = fs.existsSync(projectSandboxDockerfile);
|
||||
@@ -383,7 +374,7 @@ export async function start_sandbox(
|
||||
// if project folder has sandbox.Dockerfile under project settings folder, use that
|
||||
let buildArgs = '';
|
||||
const projectSandboxDockerfile = path.join(
|
||||
SETTINGS_DIRECTORY_NAME,
|
||||
GEMINI_DIR,
|
||||
'sandbox.Dockerfile',
|
||||
);
|
||||
if (isCustomProjectSandbox) {
|
||||
@@ -441,7 +432,7 @@ export async function start_sandbox(
|
||||
// note user/home changes inside sandbox and we mount at BOTH paths for consistency
|
||||
const userSettingsDirOnHost = USER_SETTINGS_DIR;
|
||||
const userSettingsDirInSandbox = getContainerPath(
|
||||
`/home/node/${SETTINGS_DIRECTORY_NAME}`,
|
||||
`/home/node/${GEMINI_DIR}`,
|
||||
);
|
||||
if (!fs.existsSync(userSettingsDirOnHost)) {
|
||||
fs.mkdirSync(userSettingsDirOnHost);
|
||||
@@ -665,10 +656,7 @@ export async function start_sandbox(
|
||||
?.toLowerCase()
|
||||
.startsWith(workdir.toLowerCase())
|
||||
) {
|
||||
const sandboxVenvPath = path.resolve(
|
||||
SETTINGS_DIRECTORY_NAME,
|
||||
'sandbox.venv',
|
||||
);
|
||||
const sandboxVenvPath = path.resolve(GEMINI_DIR, 'sandbox.venv');
|
||||
if (!fs.existsSync(sandboxVenvPath)) {
|
||||
fs.mkdirSync(sandboxVenvPath, { recursive: true });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user