src/utils/envUtils.ts: add parseEnvFiles

parseEnvFiles reads one or more .env files and returns
the merged environment variable collection.

Change-Id: Ia6c23fc3ea3a39737ec61ad82817df4a8ffa881e
Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/248658
Run-TryBot: Hyang-Ah Hana Kim <hyangah@gmail.com>
TryBot-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Polina Sokolova <polina@google.com>
diff --git a/src/debugAdapter/goDebug.ts b/src/debugAdapter/goDebug.ts
index 98accc8..b6dd86e 100644
--- a/src/debugAdapter/goDebug.ts
+++ b/src/debugAdapter/goDebug.ts
@@ -29,7 +29,7 @@
 	Thread
 } from 'vscode-debugadapter';
 import { DebugProtocol } from 'vscode-debugprotocol';
-import { parseEnvFile } from '../utils/envUtils';
+import { parseEnvFiles } from '../utils/envUtils';
 import {
 	envPath,
 	fixDriveCasingInWindows,
@@ -424,23 +424,14 @@
 				}
 
 				// read env from disk and merge into env variables
-				const fileEnvs = [];
 				try {
-					if (typeof launchArgs.envFile === 'string') {
-						fileEnvs.push(parseEnvFile(launchArgs.envFile));
-					}
-					if (Array.isArray(launchArgs.envFile)) {
-						launchArgs.envFile.forEach((envFile) => {
-							fileEnvs.push(parseEnvFile(envFile));
-						});
-					}
+					const fileEnvs = parseEnvFiles(launchArgs.envFile);
+					const launchArgsEnv = launchArgs.env || {};
+					env = Object.assign({}, process.env, fileEnvs, launchArgsEnv);
 				} catch (e) {
-					return reject(e);
+					return reject(`failed to process 'envFile' and 'env' settings: ${e}`);
 				}
 
-				const launchArgsEnv = launchArgs.env || {};
-				env = Object.assign({}, process.env, ...fileEnvs, launchArgsEnv);
-
 				const dirname = isProgramDirectory ? program : path.dirname(program);
 				if (!env['GOPATH'] && (mode === 'debug' || mode === 'test')) {
 					// If no GOPATH is set, then infer it from the file/package path
diff --git a/src/debugAdapter2/goDlvDebug.ts b/src/debugAdapter2/goDlvDebug.ts
index 461c27c..c861f81 100644
--- a/src/debugAdapter2/goDlvDebug.ts
+++ b/src/debugAdapter2/goDlvDebug.ts
@@ -20,7 +20,7 @@
 	TerminatedEvent
 } from 'vscode-debugadapter';
 import { DebugProtocol } from 'vscode-debugprotocol';
-import { parseEnvFile } from '../utils/envUtils';
+import { parseEnvFiles } from '../utils/envUtils';
 import { envPath, getBinPathWithPreferredGopathGoroot } from '../utils/goPath';
 import { killProcessTree } from '../utils/processUtils';
 
@@ -611,18 +611,9 @@
 		}
 
 		// Read env from disk and merge into env variables.
-		const fileEnvs = [];
-		if (typeof launchArgs.envFile === 'string') {
-			fileEnvs.push(parseEnvFile(launchArgs.envFile));
-		}
-		if (Array.isArray(launchArgs.envFile)) {
-			launchArgs.envFile.forEach((envFile) => {
-				fileEnvs.push(parseEnvFile(envFile));
-			});
-		}
-
+		const fileEnvs = parseEnvFiles(launchArgs.envFile);
 		const launchArgsEnv = launchArgs.env || {};
-		const programEnv = Object.assign({}, process.env, ...fileEnvs, launchArgsEnv);
+		const programEnv = Object.assign({}, process.env, fileEnvs, launchArgsEnv);
 
 		log(`Current working directory: ${dirname}`);
 		const goExe = getBinPathWithPreferredGopathGoroot('go', []);
diff --git a/src/utils/envUtils.ts b/src/utils/envUtils.ts
index 0270207..bdb8cf4 100644
--- a/src/utils/envUtils.ts
+++ b/src/utils/envUtils.ts
@@ -41,3 +41,16 @@
 		throw new Error(`Cannot load environment variables from file ${envFilePath}`);
 	}
 }
+
+export function parseEnvFiles(envFiles: string[]|string): { [key: string]: string } {
+	const fileEnvs = [];
+	if (typeof envFiles === 'string') {
+		fileEnvs.push(parseEnvFile(envFiles));
+	}
+	if (Array.isArray(envFiles)) {
+		envFiles.forEach((envFile) => {
+			fileEnvs.push(parseEnvFile(envFile));
+		});
+	}
+	return Object.assign({}, ...fileEnvs);
+}