fix: respect env variables in .env for settings.json variable substitution (#3416)

This commit is contained in:
Jack Wotherspoon 2025-07-07 01:13:13 -04:00 committed by GitHub
parent 87a44ec468
commit b70fba5b09
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 40 additions and 44 deletions

View File

@ -5,7 +5,7 @@
*/ */
import { AuthType } from '@google/gemini-cli-core'; import { AuthType } from '@google/gemini-cli-core';
import { loadEnvironment } from './config.js'; import { loadEnvironment } from './settings.js';
export const validateAuthMethod = (authMethod: string): string | null => { export const validateAuthMethod = (authMethod: string): string | null => {
loadEnvironment(); loadEnvironment();

View File

@ -13,7 +13,6 @@ import {
setGeminiMdFilename as setServerGeminiMdFilename, setGeminiMdFilename as setServerGeminiMdFilename,
getCurrentGeminiMdFilename, getCurrentGeminiMdFilename,
ApprovalMode, ApprovalMode,
GEMINI_CONFIG_DIR as GEMINI_DIR,
DEFAULT_GEMINI_MODEL, DEFAULT_GEMINI_MODEL,
DEFAULT_GEMINI_EMBEDDING_MODEL, DEFAULT_GEMINI_EMBEDDING_MODEL,
FileDiscoveryService, FileDiscoveryService,
@ -23,10 +22,6 @@ import { Settings } from './settings.js';
import { Extension } from './extension.js'; import { Extension } from './extension.js';
import { getCliVersion } from '../utils/version.js'; import { getCliVersion } from '../utils/version.js';
import * as dotenv from 'dotenv';
import * as fs from 'node:fs';
import * as path from 'node:path';
import * as os from 'node:os';
import { loadSandboxConfig } from './sandboxConfig.js'; import { loadSandboxConfig } from './sandboxConfig.js';
// Simple console logger for now - replace with actual logger if available // Simple console logger for now - replace with actual logger if available
@ -166,8 +161,6 @@ export async function loadCliConfig(
extensions: Extension[], extensions: Extension[],
sessionId: string, sessionId: string,
): Promise<Config> { ): Promise<Config> {
loadEnvironment();
const argv = await parseArguments(); const argv = await parseArguments();
const debugMode = argv.debug || false; const debugMode = argv.debug || false;
@ -279,39 +272,3 @@ function mergeExcludeTools(
} }
return [...allExcludeTools]; return [...allExcludeTools];
} }
function findEnvFile(startDir: string): string | null {
let currentDir = path.resolve(startDir);
while (true) {
// prefer gemini-specific .env under GEMINI_DIR
const geminiEnvPath = path.join(currentDir, GEMINI_DIR, '.env');
if (fs.existsSync(geminiEnvPath)) {
return geminiEnvPath;
}
const envPath = path.join(currentDir, '.env');
if (fs.existsSync(envPath)) {
return envPath;
}
const parentDir = path.dirname(currentDir);
if (parentDir === currentDir || !parentDir) {
// check .env under home as fallback, again preferring gemini-specific .env
const homeGeminiEnvPath = path.join(os.homedir(), GEMINI_DIR, '.env');
if (fs.existsSync(homeGeminiEnvPath)) {
return homeGeminiEnvPath;
}
const homeEnvPath = path.join(os.homedir(), '.env');
if (fs.existsSync(homeEnvPath)) {
return homeEnvPath;
}
return null;
}
currentDir = parentDir;
}
}
export function loadEnvironment(): void {
const envFilePath = findEnvFile(process.cwd());
if (envFilePath) {
dotenv.config({ path: envFilePath, quiet: true });
}
}

View File

@ -7,8 +7,10 @@
import * as fs from 'fs'; import * as fs from 'fs';
import * as path from 'path'; import * as path from 'path';
import { homedir } from 'os'; import { homedir } from 'os';
import * as dotenv from 'dotenv';
import { import {
MCPServerConfig, MCPServerConfig,
GEMINI_CONFIG_DIR as GEMINI_DIR,
getErrorMessage, getErrorMessage,
BugCommandSettings, BugCommandSettings,
TelemetrySettings, TelemetrySettings,
@ -172,11 +174,48 @@ function resolveEnvVarsInObject<T>(obj: T): T {
return obj; return obj;
} }
function findEnvFile(startDir: string): string | null {
let currentDir = path.resolve(startDir);
while (true) {
// prefer gemini-specific .env under GEMINI_DIR
const geminiEnvPath = path.join(currentDir, GEMINI_DIR, '.env');
if (fs.existsSync(geminiEnvPath)) {
return geminiEnvPath;
}
const envPath = path.join(currentDir, '.env');
if (fs.existsSync(envPath)) {
return envPath;
}
const parentDir = path.dirname(currentDir);
if (parentDir === currentDir || !parentDir) {
// check .env under home as fallback, again preferring gemini-specific .env
const homeGeminiEnvPath = path.join(homedir(), GEMINI_DIR, '.env');
if (fs.existsSync(homeGeminiEnvPath)) {
return homeGeminiEnvPath;
}
const homeEnvPath = path.join(homedir(), '.env');
if (fs.existsSync(homeEnvPath)) {
return homeEnvPath;
}
return null;
}
currentDir = parentDir;
}
}
export function loadEnvironment(): void {
const envFilePath = findEnvFile(process.cwd());
if (envFilePath) {
dotenv.config({ path: envFilePath, quiet: true });
}
}
/** /**
* Loads settings from user and workspace directories. * Loads settings from user and workspace directories.
* Project settings override user settings. * Project settings override user settings.
*/ */
export function loadSettings(workspaceDir: string): LoadedSettings { export function loadSettings(workspaceDir: string): LoadedSettings {
loadEnvironment();
let userSettings: Settings = {}; let userSettings: Settings = {};
let workspaceSettings: Settings = {}; let workspaceSettings: Settings = {};
const settingsErrors: SettingsError[] = []; const settingsErrors: SettingsError[] = [];