From 28580cf12c0afe6c972f2ca0cdb07efaf0448dd0 Mon Sep 17 00:00:00 2001 From: Tom Hale Date: Sat, 2 May 2026 21:16:46 +0700 Subject: [PATCH] fix(cli): use os.homedir() for home directory warning check The home directory warning incorrectly used the core homedir() helper which respects the GEMINI_CLI_HOME environment variable. When GEMINI_CLI_HOME is set to a non-home directory, the warning could fire in subdirectories or miss the actual home directory entirely. Switch to Node's native os.homedir() so the check always compares against the real OS home directory. Add test coverage for subdirectories, symlinked home directories, and GEMINI_CLI_HOME override scenarios. Fixes google-gemini/gemini-cli#22309 --- .../cli/src/utils/userStartupWarnings.test.ts | 57 ++++++++++++++++++- packages/cli/src/utils/userStartupWarnings.ts | 4 +- 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/packages/cli/src/utils/userStartupWarnings.test.ts b/packages/cli/src/utils/userStartupWarnings.test.ts index d255dc1d3a7..ed49c7104ad 100644 --- a/packages/cli/src/utils/userStartupWarnings.test.ts +++ b/packages/cli/src/utils/userStartupWarnings.test.ts @@ -29,10 +29,9 @@ vi.mock('os', async (importOriginal) => { vi.mock('@google/gemini-cli-core', async (importOriginal) => { const actual = - await importOriginal(); + await importOriginal(); return { ...actual, - homedir: () => os.homedir(), getCompatibilityWarnings: vi.fn().mockReturnValue([]), isHeadlessMode: vi.fn().mockReturnValue(false), WarningPriority: { @@ -108,6 +107,60 @@ describe('getUserStartupWarnings', () => { const warnings = await getUserStartupWarnings({}, homeDir); expect(warnings.find((w) => w.id === 'home-directory')).toBeUndefined(); }); + + it('should not return a warning when running in a subdirectory of home', async () => { + const subDir = path.join(homeDir, 'projects', 'my-app'); + await fs.mkdir(subDir, { recursive: true }); + const warnings = await getUserStartupWarnings({}, subDir); + expect(warnings.find((w) => w.id === 'home-directory')).toBeUndefined(); + }); + + it('should not return a warning when home directory is a symlink and running in a subdirectory', async () => { + const realHome = path.join(testRootDir, 'real-home'); + await fs.mkdir(realHome, { recursive: true }); + const symlinkedHome = path.join(testRootDir, 'symlinked-home'); + await fs.symlink(realHome, symlinkedHome); + vi.mocked(os.homedir).mockReturnValue(symlinkedHome); + + const subDir = path.join(symlinkedHome, 'projects'); + await fs.mkdir(subDir, { recursive: true }); + const warnings = await getUserStartupWarnings({}, subDir); + expect(warnings.find((w) => w.id === 'home-directory')).toBeUndefined(); + }); + + it('should return a warning when home directory is a symlink and running in it', async () => { + const realHome = path.join(testRootDir, 'real-home2'); + await fs.mkdir(realHome, { recursive: true }); + const symlinkedHome = path.join(testRootDir, 'symlinked-home2'); + await fs.symlink(realHome, symlinkedHome); + vi.mocked(os.homedir).mockReturnValue(symlinkedHome); + + const warnings = await getUserStartupWarnings({}, symlinkedHome); + expect(warnings).toContainEqual( + expect.objectContaining({ + id: 'home-directory', + message: expect.stringContaining( + 'Warning you are running Gemini CLI in your home directory', + ), + priority: WarningPriority.Low, + }), + ); + }); + + it('should not return a warning when GEMINI_CLI_HOME differs from os.homedir', async () => { + const projectDir = path.join(testRootDir, 'project'); + await fs.mkdir(projectDir, { recursive: true }); + vi.stubEnv('GEMINI_CLI_HOME', projectDir); + + const warnings = await getUserStartupWarnings({}, projectDir); + expect(warnings.find((w) => w.id === 'home-directory')).toBeUndefined(); + }); + }); + + afterEach(async () => { + await fs.rm(testRootDir, { recursive: true, force: true }); + vi.unstubAllEnvs(); + vi.restoreAllMocks(); }); describe('root directory check', () => { diff --git a/packages/cli/src/utils/userStartupWarnings.ts b/packages/cli/src/utils/userStartupWarnings.ts index 549b62f859d..75530b264fa 100644 --- a/packages/cli/src/utils/userStartupWarnings.ts +++ b/packages/cli/src/utils/userStartupWarnings.ts @@ -5,10 +5,10 @@ */ import fs from 'node:fs/promises'; +import { homedir as osHomedir } from 'node:os'; import path from 'node:path'; import process from 'node:process'; import { - homedir, getCompatibilityWarnings, WarningPriority, type StartupWarning, @@ -39,7 +39,7 @@ const homeDirectoryCheck: WarningCheck = { try { const [workspaceRealPath, homeRealPath] = await Promise.all([ fs.realpath(workspaceRoot), - fs.realpath(homedir()), + fs.realpath(osHomedir()), ]); if (workspaceRealPath === homeRealPath) {