diff --git a/packages/cli/src/config/trustedFolders.test.ts b/packages/cli/src/config/trustedFolders.test.ts index 446586719d..6676d3dbec 100644 --- a/packages/cli/src/config/trustedFolders.test.ts +++ b/packages/cli/src/config/trustedFolders.test.ts @@ -21,7 +21,7 @@ import stripJsonComments from 'strip-json-comments'; import * as path from 'node:path'; import { loadTrustedFolders, - USER_TRUSTED_FOLDERS_PATH, + getTrustedFoldersPath, TrustLevel, isWorkspaceTrusted, } from './trustedFolders.js'; @@ -80,10 +80,10 @@ describe('Trusted Folders Loading', () => { describe('isPathTrusted', () => { function setup({ config = {} as Record } = {}) { (mockFsExistsSync as Mock).mockImplementation( - (p) => p === USER_TRUSTED_FOLDERS_PATH, + (p) => p === getTrustedFoldersPath(), ); (fs.readFileSync as Mock).mockImplementation((p) => { - if (p === USER_TRUSTED_FOLDERS_PATH) return JSON.stringify(config); + if (p === getTrustedFoldersPath()) return JSON.stringify(config); return '{}'; }); @@ -124,7 +124,7 @@ describe('Trusted Folders Loading', () => { }); it('should load user rules if only user file exists', () => { - const userPath = USER_TRUSTED_FOLDERS_PATH; + const userPath = getTrustedFoldersPath(); (mockFsExistsSync as Mock).mockImplementation((p) => p === userPath); const userContent = { '/user/folder': TrustLevel.TRUST_FOLDER, @@ -142,7 +142,7 @@ describe('Trusted Folders Loading', () => { }); it('should handle JSON parsing errors gracefully', () => { - const userPath = USER_TRUSTED_FOLDERS_PATH; + const userPath = getTrustedFoldersPath(); (mockFsExistsSync as Mock).mockImplementation((p) => p === userPath); (fs.readFileSync as Mock).mockImplementation((p) => { if (p === userPath) return 'invalid json'; @@ -156,6 +156,31 @@ describe('Trusted Folders Loading', () => { expect(errors[0].message).toContain('Unexpected token'); }); + it('should use GEMINI_CLI_TRUSTED_FOLDERS_PATH env var if set', () => { + const customPath = '/custom/path/to/trusted_folders.json'; + process.env['GEMINI_CLI_TRUSTED_FOLDERS_PATH'] = customPath; + + (mockFsExistsSync as Mock).mockImplementation((p) => p === customPath); + const userContent = { + '/user/folder/from/env': TrustLevel.TRUST_FOLDER, + }; + (fs.readFileSync as Mock).mockImplementation((p) => { + if (p === customPath) return JSON.stringify(userContent); + return '{}'; + }); + + const { rules, errors } = loadTrustedFolders(); + expect(rules).toEqual([ + { + path: '/user/folder/from/env', + trustLevel: TrustLevel.TRUST_FOLDER, + }, + ]); + expect(errors).toEqual([]); + + delete process.env['GEMINI_CLI_TRUSTED_FOLDERS_PATH']; + }); + it('setValue should update the user config and save it', () => { const loadedFolders = loadTrustedFolders(); loadedFolders.setValue('/new/path', TrustLevel.TRUST_FOLDER); @@ -164,7 +189,7 @@ describe('Trusted Folders Loading', () => { TrustLevel.TRUST_FOLDER, ); expect(mockFsWriteFileSync).toHaveBeenCalledWith( - USER_TRUSTED_FOLDERS_PATH, + getTrustedFoldersPath(), JSON.stringify({ '/new/path': TrustLevel.TRUST_FOLDER }, null, 2), { encoding: 'utf-8', mode: 0o600 }, ); @@ -185,13 +210,13 @@ describe('isWorkspaceTrusted', () => { beforeEach(() => { vi.spyOn(process, 'cwd').mockImplementation(() => mockCwd); vi.spyOn(fs, 'readFileSync').mockImplementation((p) => { - if (p === USER_TRUSTED_FOLDERS_PATH) { + if (p === getTrustedFoldersPath()) { return JSON.stringify(mockRules); } return '{}'; }); vi.spyOn(fs, 'existsSync').mockImplementation( - (p) => p === USER_TRUSTED_FOLDERS_PATH, + (p) => p === getTrustedFoldersPath(), ); }); diff --git a/packages/cli/src/config/trustedFolders.ts b/packages/cli/src/config/trustedFolders.ts index 01119104f5..3a8943f464 100644 --- a/packages/cli/src/config/trustedFolders.ts +++ b/packages/cli/src/config/trustedFolders.ts @@ -18,10 +18,13 @@ 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_TRUSTED_FOLDERS_PATH = path.join( - USER_SETTINGS_DIR, - TRUSTED_FOLDERS_FILENAME, -); + +export function getTrustedFoldersPath(): string { + if (process.env['GEMINI_CLI_TRUSTED_FOLDERS_PATH']) { + return process.env['GEMINI_CLI_TRUSTED_FOLDERS_PATH']; + } + return path.join(USER_SETTINGS_DIR, TRUSTED_FOLDERS_FILENAME); +} export enum TrustLevel { TRUST_FOLDER = 'TRUST_FOLDER', @@ -110,7 +113,7 @@ export function loadTrustedFolders(): LoadedTrustedFolders { const errors: TrustedFoldersError[] = []; const userConfig: Record = {}; - const userPath = USER_TRUSTED_FOLDERS_PATH; + const userPath = getTrustedFoldersPath(); // Load user trusted folders try {