Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow a .env file to be loaded #237

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}
},
Expand Down Expand Up @@ -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",
Expand Down
12 changes: 11 additions & 1 deletion src/executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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) {

Expand Down
51 changes: 50 additions & 1 deletion src/utility.ts
Original file line number Diff line number Diff line change
@@ -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 {

Expand Down Expand Up @@ -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");
}
Expand All @@ -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("(");
Expand All @@ -74,6 +85,37 @@ export class Utility {
Utility.autoExpandTree = configuration.get<boolean>("autoExpandTree", false);
Utility.skipBuild = Utility.additionalArgumentsOption.indexOf("--no-build") > -1;
Utility.runInParallel = configuration.get<boolean>("runInParallel", false);

if (this.watchedEnvFilePath !== "") {
fs.unwatchFile(this.watchedEnvFilePath);
this.watchedEnvFilePath = "";
}
Utility.envFilePath = configuration.get<string>("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;
}
}

/**
Expand All @@ -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
Expand All @@ -104,4 +149,8 @@ export class Utility {
const setting = configuration.get<string>(name);
return setting ? setting : (fallback + emojiVariation);
}

private static getEnvFilePath(relativePath: string): string {
return path.resolve(vscode.workspace.workspaceFolders[0].uri.fsPath, this.envFilePath);
}
}