From 8d69ca4cd0594012844bfe85497eef01aa9849a5 Mon Sep 17 00:00:00 2001 From: goenning Date: Fri, 5 May 2017 08:05:07 +0100 Subject: [PATCH 1/4] load testEnvFile during run/debug test --- src/goRunTestCodelens.ts | 5 ++--- src/goTest.ts | 4 ++-- src/util.ts | 28 +++++++++++++++++++++++++++- 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/goRunTestCodelens.ts b/src/goRunTestCodelens.ts index 284f60fb7..c0de0df7c 100644 --- a/src/goRunTestCodelens.ts +++ b/src/goRunTestCodelens.ts @@ -9,6 +9,7 @@ import vscode = require('vscode'); import path = require('path'); import { CodeLensProvider, TextDocument, CancellationToken, CodeLens, Command } from 'vscode'; import { getTestFunctions } from './goTest'; +import { getTestEnvVars } from './util'; import { GoDocumentSymbolProvider } from './goOutline'; export class GoRunTestCodeLensProvider implements CodeLensProvider { @@ -17,9 +18,7 @@ export class GoRunTestCodeLensProvider implements CodeLensProvider { 'type': 'go', 'request': 'launch', 'mode': 'test', - 'env': { - 'GOPATH': process.env['GOPATH'] - } + 'env': getTestEnvVars() }; public provideCodeLenses(document: TextDocument, token: CancellationToken): CodeLens[] | Thenable { diff --git a/src/goTest.ts b/src/goTest.ts index 915f626a1..2bb22275d 100644 --- a/src/goTest.ts +++ b/src/goTest.ts @@ -12,7 +12,7 @@ import util = require('util'); import os = require('os'); import { getGoRuntimePath } from './goPath'; import { GoDocumentSymbolProvider } from './goOutline'; -import { getToolsEnvVars } from './util'; +import { getTestEnvVars } from './util'; let outputChannel = vscode.window.createOutputChannel('Go Tests'); @@ -204,7 +204,7 @@ export function goTest(testconfig: TestConfig): Thenable { let buildTags: string = testconfig.goConfig['buildTags']; let args = ['test', ...testconfig.flags, '-timeout', testconfig.goConfig['testTimeout'], '-tags', buildTags]; - let testEnvVars = Object.assign({}, getToolsEnvVars(), testconfig.goConfig['testEnvVars']); + let testEnvVars = getTestEnvVars(); let goRuntimePath = getGoRuntimePath(); if (!goRuntimePath) { diff --git a/src/util.ts b/src/util.ts index 2205be773..a1d847558 100644 --- a/src/util.ts +++ b/src/util.ts @@ -5,9 +5,10 @@ import vscode = require('vscode'); import path = require('path'); -import { getGoRuntimePath, getBinPathWithPreferredGopath, resolvePath } from './goPath'; +import { getGoRuntimePath, getBinPathWithPreferredGopath, resolvePath, stripBOM } from './goPath'; import cp = require('child_process'); import TelemetryReporter from 'vscode-extension-telemetry'; +import fs = require('fs'); const extensionId: string = 'lukehoban.Go'; const extensionVersion: string = vscode.extensions.getExtension(extensionId).packageJSON.version; @@ -296,6 +297,31 @@ export function getToolsEnvVars(): any { return Object.assign({}, process.env, toolsEnvVars); } +export function getTestEnvVars(): any { + let config = vscode.workspace.getConfiguration('go'); + let testEnvFile = config['testEnvFile']; + let fileEnv = {}; + if (testEnvFile) { + try { + testEnvFile = testEnvFile.replace(/\${workspaceRoot}/g, vscode.workspace.rootPath); + const buffer = stripBOM(fs.readFileSync(testEnvFile, 'utf8')); + buffer.split('\n').forEach( line => { + const r = line.match(/^\s*([\w\.\-]+)\s*=\s*(.*)?\s*$/); + if (r !== null) { + let value = r[2] || ''; + if (value.length > 0 && value.charAt(0) === '"' && value.charAt(value.length - 1) === '"') { + value = value.replace(/\\n/gm, '\n'); + } + fileEnv[r[1]] = value.replace(/(^['"]|['"]$)/g, ''); + } + }); + } catch (e) { + throw('Cannot load environment variables from file'); + } + } + return Object.assign({}, fileEnv, getToolsEnvVars(), config['testEnvVars'] || {}); +} + export function getExtensionCommands(): any[] { let pkgJSON = vscode.extensions.getExtension(extensionId).packageJSON; if (!pkgJSON.contributes || !pkgJSON.contributes.commands) { From 5e0533085a387a6a963b5868249708b35fceedf9 Mon Sep 17 00:00:00 2001 From: goenning Date: Sat, 6 May 2017 18:04:52 +0100 Subject: [PATCH 2/4] working as expected --- package.json | 5 +++++ src/debugAdapter/goDebug.ts | 24 ++++++------------------ src/goPath.ts | 24 ++++++++++++++++++++++++ src/goRunTestCodelens.ts | 17 +++++++++++------ src/util.ts | 30 ++++++++++-------------------- 5 files changed, 56 insertions(+), 44 deletions(-) diff --git a/package.json b/package.json index 2393086c2..1a957dfb0 100644 --- a/package.json +++ b/package.json @@ -484,6 +484,11 @@ "default": {}, "description": "Environment variables that will passed to the process that runs the Go tests" }, + "go.testEnvFile": { + "type": "string", + "default": {}, + "description": "Absolute path to a file containing environment variables definitions" + }, "go.testFlags": { "type": [ "array", diff --git a/src/debugAdapter/goDebug.ts b/src/debugAdapter/goDebug.ts index 042d47d52..1077107eb 100644 --- a/src/debugAdapter/goDebug.ts +++ b/src/debugAdapter/goDebug.ts @@ -11,7 +11,7 @@ import { readFileSync, existsSync, lstatSync } from 'fs'; import { basename, dirname, extname } from 'path'; import { spawn, ChildProcess, execSync, spawnSync } from 'child_process'; import { Client, RPCConnection } from 'json-rpc2'; -import { getBinPathWithPreferredGopath, resolvePath, stripBOM, getGoRuntimePath } from '../goPath'; +import { parseEnvFile, getBinPathWithPreferredGopath, resolvePath, stripBOM, getGoRuntimePath } from '../goPath'; import * as logger from 'vscode-debug-logger'; import * as FS from 'fs'; @@ -207,24 +207,12 @@ class Delve { return reject('The program attribute must point to valid directory, .go file or executable.'); } - // read env from disk and merge into envVars + // read env from disk and merge into env variables let fileEnv = {}; - if (launchArgs.envFile) { - try { - const buffer = stripBOM(FS.readFileSync(launchArgs.envFile, 'utf8')); - buffer.split('\n').forEach( line => { - const r = line.match(/^\s*([\w\.\-]+)\s*=\s*(.*)?\s*$/); - if (r !== null) { - let value = r[2] || ''; - if (value.length > 0 && value.charAt(0) === '"' && value.charAt(value.length - 1) === '"') { - value = value.replace(/\\n/gm, '\n'); - } - fileEnv[r[1]] = value.replace(/(^['"]|['"]$)/g, ''); - } - }); - } catch (e) { - return reject('Cannot load environment variables from file'); - } + try { + fileEnv = parseEnvFile(launchArgs.envFile); + } catch (e) { + return reject(e); } let env = Object.assign({}, process.env, fileEnv, launchArgs.env); diff --git a/src/goPath.ts b/src/goPath.ts index 1546ef54b..4c9201cb9 100644 --- a/src/goPath.ts +++ b/src/goPath.ts @@ -119,4 +119,28 @@ export function stripBOM(s: string): string { s = s.substr(1); } return s; +} + +export function parseEnvFile(path: string): { [key: string]: string } { + const env = { }; + if (!path) { + return env; + } + + try { + const buffer = stripBOM(fs.readFileSync(path, 'utf8')); + buffer.split('\n').forEach( line => { + const r = line.match(/^\s*([\w\.\-]+)\s*=\s*(.*)?\s*$/); + if (r !== null) { + let value = r[2] || ''; + if (value.length > 0 && value.charAt(0) === '"' && value.charAt(value.length - 1) === '"') { + value = value.replace(/\\n/gm, '\n'); + } + env[r[1]] = value.replace(/(^['"]|['"]$)/g, ''); + } + }); + return env; + } catch (e) { + throw(`Cannot load environment variables from file ${path}`); + } } \ No newline at end of file diff --git a/src/goRunTestCodelens.ts b/src/goRunTestCodelens.ts index c0de0df7c..f2f2dcc1d 100644 --- a/src/goRunTestCodelens.ts +++ b/src/goRunTestCodelens.ts @@ -17,12 +17,12 @@ export class GoRunTestCodeLensProvider implements CodeLensProvider { 'name': 'Launch', 'type': 'go', 'request': 'launch', - 'mode': 'test', - 'env': getTestEnvVars() + 'mode': 'test' }; public provideCodeLenses(document: TextDocument, token: CancellationToken): CodeLens[] | Thenable { - let codeLensConfig = vscode.workspace.getConfiguration('go').get('enableCodeLens'); + let config = vscode.workspace.getConfiguration('go'); + let codeLensConfig = config.get('enableCodeLens'); let codelensEnabled = codeLensConfig ? codeLensConfig['runtest'] : false; if (!codelensEnabled || !document.fileName.endsWith('_test.go')) { return; @@ -30,7 +30,7 @@ export class GoRunTestCodeLensProvider implements CodeLensProvider { return Promise.all([ this.getCodeLensForPackage(document), - this.getCodeLensForFunctions(document) + this.getCodeLensForFunctions(config, document) ]).then(res => { return res[0].concat(res[1]); }); @@ -57,7 +57,7 @@ export class GoRunTestCodeLensProvider implements CodeLensProvider { }); } - private getCodeLensForFunctions(document: TextDocument): Thenable { + private getCodeLensForFunctions(vsConfig: vscode.WorkspaceConfiguration, document: TextDocument): Thenable { return getTestFunctions(document).then(testFunctions => { let codelens = []; @@ -68,7 +68,12 @@ export class GoRunTestCodeLensProvider implements CodeLensProvider { arguments: [ { functionName: func.name} ] }; - let config = Object.assign({}, this.debugConfig, { args: ['-test.run', func.name], program: path.dirname(document.fileName) }); + const args = ['-test.run', func.name]; + const program = path.dirname(document.fileName); + const env = vsConfig['testEnvVars'] || {}; + const envFile = vsConfig['testEnvFile']; + + let config = Object.assign({}, this.debugConfig, { args, program, env, envFile }); let debugTestCmd: Command = { title: 'debug test', command: 'vscode.startDebug', diff --git a/src/util.ts b/src/util.ts index a1d847558..12edf840c 100644 --- a/src/util.ts +++ b/src/util.ts @@ -5,7 +5,7 @@ import vscode = require('vscode'); import path = require('path'); -import { getGoRuntimePath, getBinPathWithPreferredGopath, resolvePath, stripBOM } from './goPath'; +import { parseEnvFile, getGoRuntimePath, getBinPathWithPreferredGopath, resolvePath, stripBOM } from './goPath'; import cp = require('child_process'); import TelemetryReporter from 'vscode-extension-telemetry'; import fs = require('fs'); @@ -298,28 +298,18 @@ export function getToolsEnvVars(): any { } export function getTestEnvVars(): any { - let config = vscode.workspace.getConfiguration('go'); - let testEnvFile = config['testEnvFile']; + const config = vscode.workspace.getConfiguration('go'); + const toolsEnv = getToolsEnvVars(); + const testEnv = config['testEnvVars'] || {}; + let fileEnv = {}; + let testEnvFile = config['testEnvFile']; if (testEnvFile) { - try { - testEnvFile = testEnvFile.replace(/\${workspaceRoot}/g, vscode.workspace.rootPath); - const buffer = stripBOM(fs.readFileSync(testEnvFile, 'utf8')); - buffer.split('\n').forEach( line => { - const r = line.match(/^\s*([\w\.\-]+)\s*=\s*(.*)?\s*$/); - if (r !== null) { - let value = r[2] || ''; - if (value.length > 0 && value.charAt(0) === '"' && value.charAt(value.length - 1) === '"') { - value = value.replace(/\\n/gm, '\n'); - } - fileEnv[r[1]] = value.replace(/(^['"]|['"]$)/g, ''); - } - }); - } catch (e) { - throw('Cannot load environment variables from file'); - } + testEnvFile = testEnvFile.replace(/\${workspaceRoot}/g, vscode.workspace.rootPath); + fileEnv = parseEnvFile(testEnvFile); } - return Object.assign({}, fileEnv, getToolsEnvVars(), config['testEnvVars'] || {}); + + return Object.assign({}, fileEnv, toolsEnv, testEnv); } export function getExtensionCommands(): any[] { From 7be35b5b0abba262a9c7410d16fa46b080c0cbf8 Mon Sep 17 00:00:00 2001 From: goenning Date: Sat, 6 May 2017 18:11:55 +0100 Subject: [PATCH 3/4] change to null as default --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1a957dfb0..fcaf9b395 100644 --- a/package.json +++ b/package.json @@ -486,7 +486,7 @@ }, "go.testEnvFile": { "type": "string", - "default": {}, + "default": null, "description": "Absolute path to a file containing environment variables definitions" }, "go.testFlags": { From 3ac188357a53c44822129925a91ddfa64f65284b Mon Sep 17 00:00:00 2001 From: goenning Date: Sat, 6 May 2017 18:17:55 +0100 Subject: [PATCH 4/4] fileEnv task precedence over tools env --- src/util.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util.ts b/src/util.ts index 12edf840c..544c2fec6 100644 --- a/src/util.ts +++ b/src/util.ts @@ -309,7 +309,7 @@ export function getTestEnvVars(): any { fileEnv = parseEnvFile(testEnvFile); } - return Object.assign({}, fileEnv, toolsEnv, testEnv); + return Object.assign({}, toolsEnv, fileEnv, testEnv); } export function getExtensionCommands(): any[] {