diff --git a/package.json b/package.json index 5d46de20c..05780e4bf 100644 --- a/package.json +++ b/package.json @@ -822,6 +822,11 @@ "description": "Environment variables passed to the program.", "default": {} }, + "envFile": { + "type": "string", + "description": "Environment variables passed to the program by a file.", + "default": "${workspaceFolder}/.env" + }, "console": { "type": "string", "enum": [ @@ -1884,6 +1889,11 @@ "description": "Environment variables passed to the program.", "default": {} }, + "envFile": { + "type": "string", + "description": "Environment variables passed to the program by a file.", + "default": "${workspaceFolder}/.env" + }, "console": { "type": "string", "enum": [ diff --git a/src/configurationProvider.ts b/src/configurationProvider.ts index bf48d0400..d6f456ce1 100644 --- a/src/configurationProvider.ts +++ b/src/configurationProvider.ts @@ -100,11 +100,79 @@ export class CSharpConfigurationProvider implements vscode.DebugConfigurationPro }); } + /** + * Parse envFile and add to config.env + */ + private parseEnvFile(envFile: string, config: vscode.DebugConfiguration): vscode.DebugConfiguration { + if(envFile) { + try { + let content: string = fs.readFileSync(envFile, "utf8"); + let parseErrors: string[] = []; + + // Remove UTF-8 BOM if present + if(content.charAt(0) === '\uFEFF') { + content = content.substr(1); + } + + content.split("\n").forEach(line => { + const r: RegExpMatchArray = line.match(/^\s*([\w\.\-]+)\s*=\s*(.*)?\s*$/); + + if (r !== null) { + const key: string = r[1]; + let value: string = r[2] || ""; + if ((value.length > 0) && (value.charAt(0) === '"') && (value.charAt(value.length - 1) === '"')) { + value = value.replace(/\\n/gm, "\n"); + } + + value = value.replace(/(^['"]|['"]$)/g, ""); + + if(!config.env) { + config.env = {}; + } + config.env[key] = value; + } + else { + // Blank lines and lines starting with # are no parse errors + const comments: RegExp = new RegExp(/^\s*(#|$)/); + if (!comments.test(line)) { + parseErrors.push(line); + } + } + }); + + // show error message if single lines cannot get parsed + if(parseErrors.length !== 0) { + let parseError: string = "Ignoring non-parseable lines in envFile " + envFile + ": "; + parseErrors.forEach(function (value, idx, array) { + parseError += "\"" + value + "\"" + ((idx !== array.length - 1) ? ", " : "."); + }); + showErrorMessage(vscode, parseError); + } + } + catch (e) { + throw new Error("Can't parse envFile " + envFile); + } + } + + // remove envFile from config after parsing + if(config.envFile) { + delete config.envFile; + } + + return config; + } + /** * Try to add all missing attributes to the debug configuration being launched. */ resolveDebugConfiguration(folder: vscode.WorkspaceFolder | undefined, config: vscode.DebugConfiguration, token?: vscode.CancellationToken): vscode.ProviderResult { // vsdbg does the error checking + + // read from envFile and set config.env + if(config.envFile) { + config = this.parseEnvFile(config.envFile.replace(/\${workspaceFolder}/g, folder.uri.path), config); + } + return config; } } \ No newline at end of file diff --git a/src/tools/OptionsSchema.json b/src/tools/OptionsSchema.json index 53367ba42..5d6b35910 100644 --- a/src/tools/OptionsSchema.json +++ b/src/tools/OptionsSchema.json @@ -317,6 +317,11 @@ "description": "Environment variables passed to the program.", "default": {} }, + "envFile": { + "type": "string", + "description": "Environment variables passed to the program by a file.", + "default": "${workspaceFolder}/.env" + }, "console": { "type": "string", "enum": [ "internalConsole", "integratedTerminal", "externalTerminal" ],