Skip to content
This repository has been archived by the owner on Jul 15, 2023. It is now read-only.

add support for testEnvFile #971

Merged
merged 5 commits into from
Jun 5, 2017
Merged
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
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,11 @@
"default": {},
"description": "Environment variables that will passed to the process that runs the Go tests"
},
"go.testEnvFile": {
"type": "string",
"default": null,
"description": "Absolute path to a file containing environment variables definitions"
},
"go.testFlags": {
"type": [
"array",
Expand Down
24 changes: 6 additions & 18 deletions src/debugAdapter/goDebug.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -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);
Expand Down
24 changes: 24 additions & 0 deletions src/goPath.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,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}`);
}
}
21 changes: 12 additions & 9 deletions src/goRunTestCodelens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,28 @@ 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 {
private readonly debugConfig: any = {
'name': 'Launch',
'type': 'go',
'request': 'launch',
'mode': 'test',
'env': {
'GOPATH': process.env['GOPATH']
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

am guessing you are removing this because you expect this to be passed in the testEnvFile?

For someone who has set the GOPATH in the settings, but doesn't use the testEnvVars or the new testEnvFile setting, the debug test codelens will not work if this is removed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed because of this line. GoDebug is always loading everything process.env. Am I missing something?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point

}
'mode': 'test'
};

public provideCodeLenses(document: TextDocument, token: CancellationToken): CodeLens[] | Thenable<CodeLens[]> {
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;
}

return Promise.all([
this.getCodeLensForPackage(document),
this.getCodeLensForFunctions(document)
this.getCodeLensForFunctions(config, document)
]).then(res => {
return res[0].concat(res[1]);
});
Expand All @@ -58,7 +57,7 @@ export class GoRunTestCodeLensProvider implements CodeLensProvider {
});
}

private getCodeLensForFunctions(document: TextDocument): Thenable<CodeLens[]> {
private getCodeLensForFunctions(vsConfig: vscode.WorkspaceConfiguration, document: TextDocument): Thenable<CodeLens[]> {
return getTestFunctions(document).then(testFunctions => {
let codelens = [];

Expand All @@ -69,8 +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) });
Object.assign(config.env, vscode.workspace.getConfiguration('go').get('testEnvVars'));
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',
Expand Down
4 changes: 2 additions & 2 deletions src/goTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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');

Expand Down Expand Up @@ -204,7 +204,7 @@ export function goTest(testconfig: TestConfig): Thenable<boolean> {

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) {
Expand Down
18 changes: 17 additions & 1 deletion src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@

import vscode = require('vscode');
import path = require('path');
import { getGoRuntimePath, getBinPathWithPreferredGopath, resolvePath } from './goPath';
import { parseEnvFile, getGoRuntimePath, getBinPathWithPreferredGopath, resolvePath, stripBOM } from './goPath';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stripBOM not needed here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch, I'll remove it.

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;
Expand Down Expand Up @@ -298,6 +299,21 @@ export function getToolsEnvVars(): any {
return Object.assign({}, process.env, toolsEnvVars);
}

export function getTestEnvVars(): any {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

goTest.ts would be a better place for this function as that file has all things test related.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll move it :)

const config = vscode.workspace.getConfiguration('go');
const toolsEnv = getToolsEnvVars();
const testEnv = config['testEnvVars'] || {};

let fileEnv = {};
let testEnvFile = config['testEnvFile'];
if (testEnvFile) {
testEnvFile = testEnvFile.replace(/\${workspaceRoot}/g, vscode.workspace.rootPath);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can use the resolvePath method here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, didn't see this function. Will change it.

fileEnv = parseEnvFile(testEnvFile);
}

return Object.assign({}, toolsEnv, fileEnv, testEnv);
}

export function getExtensionCommands(): any[] {
let pkgJSON = vscode.extensions.getExtension(extensionId).packageJSON;
if (!pkgJSON.contributes || !pkgJSON.contributes.commands) {
Expand Down