Skip to content

Commit 20d1f1f

Browse files
chore: treat extension .env as optional (#11116)
1 parent 946ae80 commit 20d1f1f

File tree

2 files changed

+47
-7
lines changed

2 files changed

+47
-7
lines changed

src/__tests__/extension.spec.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ vi.mock("@dotenvx/dotenvx", () => ({
4646
config: vi.fn(),
4747
}))
4848

49+
// Mock fs so the extension module can safely check for optional .env.
50+
vi.mock("fs", () => ({
51+
existsSync: vi.fn().mockReturnValue(false),
52+
}))
53+
4954
const mockBridgeOrchestratorDisconnect = vi.fn().mockResolvedValue(undefined)
5055

5156
const mockCloudServiceInstance = {
@@ -238,6 +243,36 @@ describe("extension.ts", () => {
238243
authStateChangedHandler = undefined
239244
})
240245

246+
test("does not call dotenvx.config when optional .env does not exist", async () => {
247+
vi.resetModules()
248+
vi.clearAllMocks()
249+
250+
const fs = await import("fs")
251+
vi.mocked(fs.existsSync).mockReturnValue(false)
252+
253+
const dotenvx = await import("@dotenvx/dotenvx")
254+
255+
const { activate } = await import("../extension")
256+
await activate(mockContext)
257+
258+
expect(dotenvx.config).not.toHaveBeenCalled()
259+
})
260+
261+
test("calls dotenvx.config when optional .env exists", async () => {
262+
vi.resetModules()
263+
vi.clearAllMocks()
264+
265+
const fs = await import("fs")
266+
vi.mocked(fs.existsSync).mockReturnValue(true)
267+
268+
const dotenvx = await import("@dotenvx/dotenvx")
269+
270+
const { activate } = await import("../extension")
271+
await activate(mockContext)
272+
273+
expect(dotenvx.config).toHaveBeenCalledTimes(1)
274+
})
275+
241276
test("authStateChangedHandler calls BridgeOrchestrator.disconnect when logged-out event fires", async () => {
242277
const { CloudService, BridgeOrchestrator } = await import("@roo-code/cloud")
243278

src/extension.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
11
import * as vscode from "vscode"
22
import * as dotenvx from "@dotenvx/dotenvx"
3+
import * as fs from "fs"
34
import * as path from "path"
45

56
// Load environment variables from .env file
6-
try {
7-
// Specify path to .env file in the project root directory
8-
const envPath = path.join(__dirname, "..", ".env")
9-
dotenvx.config({ path: envPath })
10-
} catch (e) {
11-
// Silently handle environment loading errors
12-
console.warn("Failed to load environment variables:", e)
7+
// The extension-level .env is optional (not shipped in production builds).
8+
// Avoid calling dotenvx when the file doesn't exist, otherwise dotenvx emits
9+
// a noisy [MISSING_ENV_FILE] error to the extension host console.
10+
const envPath = path.join(__dirname, "..", ".env")
11+
if (fs.existsSync(envPath)) {
12+
try {
13+
dotenvx.config({ path: envPath })
14+
} catch (e) {
15+
// Best-effort only: never fail extension activation due to optional env loading.
16+
console.warn("Failed to load environment variables:", e)
17+
}
1318
}
1419

1520
import type { CloudUserInfo, AuthState } from "@roo-code/types"

0 commit comments

Comments
 (0)