Skip to content

Commit 59454b8

Browse files
Copilotjfoshee
andcommitted
Implement multiple test environment files support
Co-authored-by: jfoshee <[email protected]>
1 parent 55bf81b commit 59454b8

File tree

3 files changed

+115
-6
lines changed

3 files changed

+115
-6
lines changed

extension/package.json

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1438,7 +1438,17 @@
14381438
"go.testEnvFile": {
14391439
"type": "string",
14401440
"default": null,
1441-
"description": "Absolute path to a file containing environment variables definitions. File contents should be of the form key=value.",
1441+
"description": "Absolute path to a file containing environment variables definitions. File contents should be of the form key=value. (Deprecated: Use go.testEnvFiles instead)",
1442+
"scope": "resource",
1443+
"deprecationMessage": "Use go.testEnvFiles instead"
1444+
},
1445+
"go.testEnvFiles": {
1446+
"type": "array",
1447+
"items": {
1448+
"type": "string"
1449+
},
1450+
"default": [],
1451+
"description": "Array of absolute paths to files containing environment variables definitions. File contents should be of the form key=value.",
14421452
"scope": "resource"
14431453
},
14441454
"go.testFlags": {

extension/src/testUtils.ts

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { getCurrentPackage } from './goModules';
1919
import { GoDocumentSymbolProvider } from './goDocumentSymbols';
2020
import { getNonVendorPackages } from './goPackages';
2121
import { getBinPath, getCurrentGoPath, getTempFilePath, LineBuffer, resolvePath } from './util';
22-
import { parseEnvFile } from './utils/envUtils';
22+
import { parseEnvFile, parseEnvFiles } from './utils/envUtils';
2323
import {
2424
getEnvPath,
2525
expandFilePathInOutput,
@@ -111,12 +111,28 @@ export function getTestEnvVars(config: vscode.WorkspaceConfiguration): any {
111111
const envVars = toolExecutionEnvironment();
112112
const testEnvConfig = config['testEnvVars'] || {};
113113

114-
let fileEnv: { [key: string]: any } = {};
115-
let testEnvFile = config['testEnvFile'];
114+
// Collect environment files from both settings
115+
const envFiles: string[] = [];
116+
117+
// Add files from the new testEnvFiles setting (array)
118+
const testEnvFiles = config['testEnvFiles'] || [];
119+
if (Array.isArray(testEnvFiles)) {
120+
envFiles.push(...testEnvFiles);
121+
}
122+
123+
// Add the deprecated testEnvFile setting (single file) for backward compatibility
124+
const testEnvFile = config['testEnvFile'];
116125
if (testEnvFile) {
117-
testEnvFile = resolvePath(testEnvFile);
126+
envFiles.push(testEnvFile);
127+
}
128+
129+
// Parse all environment files
130+
let fileEnv: { [key: string]: any } = {};
131+
if (envFiles.length > 0) {
118132
try {
119-
fileEnv = parseEnvFile(testEnvFile, envVars);
133+
// Resolve paths for all files
134+
const resolvedFiles = envFiles.map((file) => resolvePath(file));
135+
fileEnv = parseEnvFiles(resolvedFiles, envVars);
120136
} catch (e) {
121137
console.log(e);
122138
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*---------------------------------------------------------
2+
* Copyright (C) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See LICENSE in the project root for license information.
4+
*--------------------------------------------------------*/
5+
6+
import * as assert from 'assert';
7+
import * as path from 'path';
8+
import * as fs from 'fs';
9+
import * as os from 'os';
10+
import { parseEnvFiles } from '../../src/utils/envUtils';
11+
12+
suite('parseEnvFiles Tests', () => {
13+
let tmpDir: string;
14+
15+
setup(() => {
16+
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'go-test-env-'));
17+
});
18+
19+
teardown(() => {
20+
if (tmpDir && fs.existsSync(tmpDir)) {
21+
// Use rmdir for compatibility with older Node.js versions
22+
const rimraf = (dir: string) => {
23+
if (fs.existsSync(dir)) {
24+
fs.readdirSync(dir).forEach((file) => {
25+
const curPath = path.join(dir, file);
26+
if (fs.lstatSync(curPath).isDirectory()) {
27+
rimraf(curPath);
28+
} else {
29+
fs.unlinkSync(curPath);
30+
}
31+
});
32+
fs.rmdirSync(dir);
33+
}
34+
};
35+
rimraf(tmpDir);
36+
}
37+
});
38+
39+
test('should handle empty array', () => {
40+
const result = parseEnvFiles([]);
41+
assert.deepStrictEqual(result, {});
42+
});
43+
44+
test('should handle undefined input', () => {
45+
const result = parseEnvFiles(undefined);
46+
assert.deepStrictEqual(result, {});
47+
});
48+
49+
test('should handle single string input', () => {
50+
const envFile = path.join(tmpDir, 'single.env');
51+
fs.writeFileSync(envFile, 'SINGLE_VAR=single_value');
52+
53+
const result = parseEnvFiles(envFile);
54+
assert.strictEqual(result.SINGLE_VAR, 'single_value');
55+
});
56+
57+
test('should handle array of files', () => {
58+
const envFile1 = path.join(tmpDir, 'first.env');
59+
const envFile2 = path.join(tmpDir, 'second.env');
60+
61+
fs.writeFileSync(envFile1, 'VAR1=value1\nSHARED=from_first');
62+
fs.writeFileSync(envFile2, 'VAR2=value2\nSHARED=from_second');
63+
64+
const result = parseEnvFiles([envFile1, envFile2]);
65+
66+
assert.strictEqual(result.VAR1, 'value1');
67+
assert.strictEqual(result.VAR2, 'value2');
68+
// Later files should override earlier ones
69+
assert.strictEqual(result.SHARED, 'from_second');
70+
});
71+
72+
test('should handle mixed valid and invalid files', () => {
73+
const validFile = path.join(tmpDir, 'valid.env');
74+
const invalidFile = path.join(tmpDir, 'nonexistent.env');
75+
76+
fs.writeFileSync(validFile, 'VALID_VAR=valid_value');
77+
78+
// This should throw when trying to parse invalid file
79+
assert.throws(() => {
80+
parseEnvFiles([validFile, invalidFile]);
81+
});
82+
});
83+
});

0 commit comments

Comments
 (0)