From e53d1dc7d33bb66313e3da6f743d7575769658d6 Mon Sep 17 00:00:00 2001 From: "A. Vaden" Date: Tue, 26 Nov 2019 19:33:35 -0500 Subject: [PATCH 1/2] allow a .envFile to be read from settings and evaluated when commands are run --- package-lock.json | 5 +++++ package.json | 6 ++++++ src/executor.ts | 12 ++++++++++- src/utility.ts | 51 ++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 72 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 542270d..137a152 100644 --- a/package-lock.json +++ b/package-lock.json @@ -762,6 +762,11 @@ "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" }, + "dotenv": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", + "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==" + }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", diff --git a/package.json b/package.json index 7778fc9..116dbef 100644 --- a/package.json +++ b/package.json @@ -242,6 +242,11 @@ "type": "boolean", "default": false, "description": "If true, will discover/build and run test in parallel if you have multiple test projects" + }, + "dotnet-test-explorer.envFilePath": { + "type": "string", + "default": "", + "description": "Relative path to a .env from the workspace root directory, to be loaded for each test run" } } }, @@ -285,6 +290,7 @@ "dependencies": { "applicationinsights": "^1.0.5", "chokidar": "^2.1.0", + "dotenv": "^8.2.0", "fkill": "^5.3.0", "glob": "^7.1.2", "ts-node": "^7.0.1", diff --git a/src/executor.ts b/src/executor.ts index f6542d6..d9fb348 100644 --- a/src/executor.ts +++ b/src/executor.ts @@ -6,6 +6,8 @@ import * as vscode from "vscode"; import { Debug, IDebugRunnerInfo } from "./debug"; import { Logger } from "./logger"; +import { Utility } from "./utility"; + export class Executor { public static runInTerminal(command: string, cwd?: string, addNewLine: boolean = true, terminal: string = "Test Explorer"): void { @@ -25,7 +27,15 @@ export class Executor { process.env.DOTNET_CLI_UI_LANGUAGE = "en"; process.env.VSTEST_HOST_DEBUG = "0"; - const childProcess = exec(this.handleWindowsEncoding(command), { encoding: "utf8", maxBuffer: 5120000, cwd }, callback); + let childProcess: ChildProcess; + if (Utility.envFileSet) { + const envFile = Utility.envFileContents; + const env = {}; + Object.assign(env, process.env, envFile); + childProcess = exec(this.handleWindowsEncoding(command), { encoding: "utf8", maxBuffer: 5120000, cwd, env }, callback); + } else { + childProcess = exec(this.handleWindowsEncoding(command), { encoding: "utf8", maxBuffer: 5120000, cwd }, callback); + } if (addToProcessList) { diff --git a/src/utility.ts b/src/utility.ts index 36e9163..c86d1bf 100644 --- a/src/utility.ts +++ b/src/utility.ts @@ -1,7 +1,10 @@ "use strict"; +import { parse } from "dotenv"; +import * as fs from "fs"; import { platform, tmpdir } from "os"; import * as path from "path"; import * as vscode from "vscode"; +import { Logger } from "./logger"; export class Utility { @@ -38,6 +41,14 @@ export class Utility { return (testArguments && testArguments.length > 0) ? ` ${testArguments}` : ""; } + public static envFileSet(): boolean { + return Utility.envFilePath !== ""; + } + + public static get envFileContents() { + return Utility.envFileContentsCache; + } + public static getConfiguration(): vscode.WorkspaceConfiguration { return vscode.workspace.getConfiguration("dotnet-test-explorer"); } @@ -49,7 +60,7 @@ export class Utility { return testName .split(/\.(?![^\(]*\))/g) // Split on all . that are not in paranthesis - .map( (n) => { + .map((n) => { let name = n; const firstParanthesis = name.indexOf("("); @@ -74,6 +85,37 @@ export class Utility { Utility.autoExpandTree = configuration.get("autoExpandTree", false); Utility.skipBuild = Utility.additionalArgumentsOption.indexOf("--no-build") > -1; Utility.runInParallel = configuration.get("runInParallel", false); + + if (this.watchedEnvFilePath !== "") { + fs.unwatchFile(this.watchedEnvFilePath); + this.watchedEnvFilePath = ""; + } + Utility.envFilePath = configuration.get("envFilePath", ""); + + if (Utility.envFileSet) { + const absoluteFilePath = this.getEnvFilePath(this.envFilePath); + Logger.Log(`Loading env file contents from ${absoluteFilePath}`); + + const parseFile = () => { + fs.readFile(absoluteFilePath, (err, data) => { + if (err) { + Logger.LogError("Error while loading env file", err); + return; + } + this.envFileContentsCache = parse(data, { debug: true }); + }); + }; + + fs.watchFile(absoluteFilePath, () => { + Logger.Log("EnvFile updated, reloading"); + parseFile(); + }); + this.watchedEnvFilePath = absoluteFilePath; + + parseFile(); + } else { + this.envFileContentsCache = null; + } } /** @@ -95,6 +137,9 @@ export class Utility { private static failed: string; private static passed: string; private static skipped: string; + private static envFilePath: string; + private static watchedEnvFilePath: string = ""; + private static envFileContentsCache: { [name: string]: string } | null; private static getLensText(configuration: vscode.WorkspaceConfiguration, name: string, fallback: string): string { // This is an invisible character that indicates the previous character @@ -104,4 +149,8 @@ export class Utility { const setting = configuration.get(name); return setting ? setting : (fallback + emojiVariation); } + + private static getEnvFilePath(relativePath: string): string { + return path.resolve(vscode.workspace.workspaceFolders[0].uri.fsPath, this.envFilePath); + } } From fc1dbe8e32ac3d6d65445976e3c2aacca32e6234 Mon Sep 17 00:00:00 2001 From: "A. Vaden" Date: Tue, 26 Nov 2019 19:36:41 -0500 Subject: [PATCH 2/2] Add the new setting to the readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 7f28467..87de93c 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,7 @@ Text from the dotnet test output as well as debug info is written to the Output/ * `dotnet-test-explorer.testArguments`: Additional arguments that are added to the dotnet test command * `dotnet-test-explorer.leftClickAction`: What happens when a test in the list is left clicked. (Default is **gotoTest**) * `dotnet-test-explorer.runInParallel`: If true, will discover/build and run test in parallel if you have multiple test projects (Default is **false**) +* `dotnet-test-explorer.envFilePath` : Relative path to a .env from the workspace root directory, to be loaded for each test run ## Known issues ##### Go to test does not work with multiple workspaces