diff --git a/extension/package-lock.json b/extension/package-lock.json index d15fff953b..648162322b 100644 --- a/extension/package-lock.json +++ b/extension/package-lock.json @@ -49,7 +49,7 @@ }, "engines": { "node": ">=16.14.2", - "vscode": "^1.75.0" + "vscode": "^1.90.0" } }, "node_modules/@babel/code-frame": { diff --git a/extension/package.json b/extension/package.json index 2d48b1fff8..f3e06d109a 100644 --- a/extension/package.json +++ b/extension/package.json @@ -1438,7 +1438,17 @@ "go.testEnvFile": { "type": "string", "default": null, - "description": "Absolute path to a file containing environment variables definitions. File contents should be of the form key=value.", + "description": "Absolute path to a file containing environment variables definitions. File contents should be of the form key=value. (Deprecated: Use go.testEnvFiles instead)", + "scope": "resource", + "deprecationMessage": "Use go.testEnvFiles instead" + }, + "go.testEnvFiles": { + "type": "array", + "items": { + "type": "string" + }, + "default": [], + "description": "Array of absolute paths to files containing environment variables definitions. File contents should be of the form key=value.", "scope": "resource" }, "go.testFlags": { diff --git a/extension/src/testUtils.ts b/extension/src/testUtils.ts index 4070f6e6d1..8a379be5c9 100644 --- a/extension/src/testUtils.ts +++ b/extension/src/testUtils.ts @@ -19,7 +19,7 @@ import { getCurrentPackage } from './goModules'; import { GoDocumentSymbolProvider } from './goDocumentSymbols'; import { getNonVendorPackages } from './goPackages'; import { getBinPath, getCurrentGoPath, getTempFilePath, LineBuffer, resolvePath } from './util'; -import { parseEnvFile } from './utils/envUtils'; +import { parseEnvFile, parseEnvFiles } from './utils/envUtils'; import { getEnvPath, expandFilePathInOutput, @@ -111,12 +111,28 @@ export function getTestEnvVars(config: vscode.WorkspaceConfiguration): any { const envVars = toolExecutionEnvironment(); const testEnvConfig = config['testEnvVars'] || {}; - let fileEnv: { [key: string]: any } = {}; - let testEnvFile = config['testEnvFile']; + // Collect environment files from both settings + const envFiles: string[] = []; + + // Add files from the new testEnvFiles setting (array) + const testEnvFiles = config['testEnvFiles'] || []; + if (Array.isArray(testEnvFiles)) { + envFiles.push(...testEnvFiles); + } + + // Add the deprecated testEnvFile setting (single file) for backward compatibility + const testEnvFile = config['testEnvFile']; if (testEnvFile) { - testEnvFile = resolvePath(testEnvFile); + envFiles.push(testEnvFile); + } + + // Parse all environment files + let fileEnv: { [key: string]: any } = {}; + if (envFiles.length > 0) { try { - fileEnv = parseEnvFile(testEnvFile, envVars); + // Resolve paths for all files + const resolvedFiles = envFiles.map((file) => resolvePath(file)); + fileEnv = parseEnvFiles(resolvedFiles, envVars); } catch (e) { console.log(e); } diff --git a/extension/test/unit/testEnvFiles.test.ts b/extension/test/unit/testEnvFiles.test.ts new file mode 100644 index 0000000000..c9cdcc7359 --- /dev/null +++ b/extension/test/unit/testEnvFiles.test.ts @@ -0,0 +1,61 @@ +/*--------------------------------------------------------- + * Copyright (C) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See LICENSE in the project root for license information. + *--------------------------------------------------------*/ + +import assert from 'assert'; +import path from 'path'; +import fs from 'fs'; +import os from 'os'; +import { parseEnvFiles } from '../../src/utils/envUtils'; + +suite('parseEnvFiles Tests', () => { + let tmpDir: string; + + setup(() => { + tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'go-test-env-')); + }); + + teardown(() => { + if (tmpDir && fs.existsSync(tmpDir)) { + fs.rmdirSync(tmpDir, { recursive: true }); + } + }); + + test('should handle empty array', () => { + const result = parseEnvFiles([]); + assert.deepStrictEqual(result, {}); + }); + + test('should handle undefined input', () => { + const result = parseEnvFiles(undefined); + assert.deepStrictEqual(result, {}); + }); + + test('should handle array of files', () => { + const envFile1 = path.join(tmpDir, 'first.env'); + const envFile2 = path.join(tmpDir, 'second.env'); + + fs.writeFileSync(envFile1, 'VAR1=value1\nSHARED=from_first'); + fs.writeFileSync(envFile2, 'VAR2=value2\nSHARED=from_second'); + + const result = parseEnvFiles([envFile1, envFile2]); + + assert.strictEqual(result.VAR1, 'value1'); + assert.strictEqual(result.VAR2, 'value2'); + // Later files should override earlier ones + assert.strictEqual(result.SHARED, 'from_second'); + }); + + test('should handle mixed valid and invalid files', () => { + const validFile = path.join(tmpDir, 'valid.env'); + const invalidFile = path.join(tmpDir, 'nonexistent.env'); + + fs.writeFileSync(validFile, 'VALID_VAR=valid_value'); + + // This should throw when trying to parse invalid file + assert.throws(() => { + parseEnvFiles([validFile, invalidFile]); + }); + }); +});