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

Commit

Permalink
Print absolute paths in test output when using modules #1973
Browse files Browse the repository at this point in the history
  • Loading branch information
ramya-rao-a committed Oct 8, 2018
1 parent ab59cb6 commit ddd2635
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 74 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "Go",
"version": "0.6.90",
"version": "0.6.91-beta.2",
"publisher": "ms-vscode",
"description": "Rich Go language support for Visual Studio Code",
"author": {
Expand Down
2 changes: 1 addition & 1 deletion src/goBuild.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export function goBuild(fileUri: vscode.Uri, isMod: boolean, goConfig: vscode.Wo
let count = 1;
return getNonVendorPackages(currentWorkspace).then(pkgs => {
let buildPromises = [];
buildPromises = pkgs.map(pkgPath => {
buildPromises = Array.from(pkgs.keys()).map(pkgPath => {
running = true;
return runTool(
buildArgs.concat('-o', `${tmpPath}-${count++}`, pkgPath),
Expand Down
2 changes: 1 addition & 1 deletion src/goCover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ export function applyCodeCoverageToAllEditors(coverProfilePath: string, packageD
// The first line will be "mode: set" which will be ignored
let fileRange = data.match(/([^:]+)\:([\d]+)\.([\d]+)\,([\d]+)\.([\d]+)\s([\d]+)\s([\d]+)/);
if (!fileRange) return;

let filePath = path.join(packageDirPath, path.basename(fileRange[1]));
let coverage = getCoverageData(filePath);
let range = new vscode.Range(
Expand Down
2 changes: 1 addition & 1 deletion src/goModules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export function updateWorkspaceModCache() {
}
let inferGopathUpdated = false;
const promises = vscode.workspace.workspaceFolders.map(folder => {
return containsModFile(folder.uri.fragment).then(result => {
return containsModFile(folder.uri.fsPath).then(result => {
workspaceModCache.set(folder.uri.fsPath, result);
if (result) {
logModuleUsage(true);
Expand Down
34 changes: 21 additions & 13 deletions src/goPackages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,34 +244,42 @@ function getRelativePackagePath(currentFileDirPath: string, currentWorkspace: st
return pkgPath;
}

const pkgToFolderMappingRegex = /ImportPath: (.*) FolderPath: (.*)/;
/**
* Returns import paths for all packages under given folder (vendor will be excluded)
* Returns mapping between import paths and folder paths for all packages under given folder (vendor will be excluded)
*/
export function getNonVendorPackages(folderPath: string): Promise<string[]> {
export function getNonVendorPackages(folderPath: string): Promise<Map<string, string>> {
let goRuntimePath = getBinPath('go');

if (!goRuntimePath) {
vscode.window.showInformationMessage('Cannot find "go" binary. Update PATH or GOROOT appropriately');
return Promise.resolve(null);
}
return new Promise<string[]>((resolve, reject) => {
let childProcess = cp.spawn(goRuntimePath, ['list', './...'], { cwd: folderPath, env: getToolsEnvVars() });
return new Promise<Map<string, string>>((resolve, reject) => {
let childProcess = cp.spawn(goRuntimePath, ['list', '-f', 'ImportPath: {{.ImportPath}} FolderPath: {{.Dir}}', './...'], { cwd: folderPath, env: getToolsEnvVars() });
let chunks = [];
childProcess.stdout.on('data', (stdout) => {
chunks.push(stdout);
});

childProcess.on('close', (status) => {
let pkgs = chunks.join('').toString().split('\n');
if (!pkgs[pkgs.length - 1]) {
pkgs.splice(pkgs.length - 1);
}
let lines = chunks.join('').toString().split('\n');

getGoVersion().then((ver: SemVersion) => {
if (ver && (ver.major > 1 || (ver.major === 1 && ver.minor >= 9))) {
resolve(pkgs);
} else {
resolve(pkgs.filter(pkgPath => pkgPath && !pkgPath.includes('/vendor/')));
}
const result = new Map<string, string>();
const vendorAlreadyExcluded = !ver || ver.major > 1 || (ver.major === 1 && ver.minor >= 9);
lines.forEach(line => {
const matches = line.match(pkgToFolderMappingRegex);
if (!matches || matches.length !== 3) {
return;
}
let [_, pkgPath, folderPath] = matches;
if (!pkgPath || (!vendorAlreadyExcluded && pkgPath.includes('/vendor/'))) {
return;
}
result.set(pkgPath, folderPath);
});
resolve(result);
});
});
});
Expand Down
22 changes: 13 additions & 9 deletions src/goTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,25 +137,29 @@ export function testCurrentPackage(goConfig: vscode.WorkspaceConfiguration, isBe
* @param goConfig Configuration for the Go extension.
*/
export function testWorkspace(goConfig: vscode.WorkspaceConfiguration, args: any) {
let dir = vscode.workspace.rootPath;
if (vscode.window.activeTextEditor && vscode.workspace.getWorkspaceFolder(vscode.window.activeTextEditor.document.uri)) {
dir = vscode.workspace.getWorkspaceFolder(vscode.window.activeTextEditor.document.uri).uri.fsPath;
}
if (!dir) {
if (!vscode.workspace.workspaceFolders.length) {
vscode.window.showInformationMessage('No workspace is open to run tests.');
return;
}
const testConfig = {
let workspaceUri = vscode.workspace.workspaceFolders[0].uri;
if (vscode.window.activeTextEditor && vscode.workspace.getWorkspaceFolder(vscode.window.activeTextEditor.document.uri)) {
workspaceUri = vscode.workspace.getWorkspaceFolder(vscode.window.activeTextEditor.document.uri).uri;
}

const testConfig: TestConfig = {
goConfig: goConfig,
dir: dir,
dir: workspaceUri.fsPath,
flags: getTestFlags(goConfig, args),
includeSubDirectories: true
};
// Remember this config as the last executed test.
lastTestConfig = testConfig;

goTest(testConfig).then(null, err => {
console.error(err);
isModSupported(workspaceUri).then(isMod => {
testConfig.isMod = isMod;
goTest(testConfig).then(null, err => {
console.error(err);
});
});
}

Expand Down
112 changes: 64 additions & 48 deletions src/testUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,13 +199,40 @@ export function goTest(testconfig: TestConfig): Thenable<boolean> {
return Promise.resolve();
}

// Fetch the package name to be used in the args to enable running tests in symlinked directories
let currentGoWorkspace = getCurrentGoWorkspaceFromGOPATH(getCurrentGoPath(), testconfig.dir);
if (currentGoWorkspace && !testconfig.includeSubDirectories) {
testconfig.currentPackage = testconfig.dir.substr(currentGoWorkspace.length + 1);
let currentGoWorkspace = testconfig.isMod ? '' : getCurrentGoWorkspaceFromGOPATH(getCurrentGoPath(), testconfig.dir);
let targets = targetArgs(testconfig);
let getCurrentPackagePromise = testconfig.isMod ? getCurrentPackage(testconfig.dir) : Promise.resolve(currentGoWorkspace ? testconfig.dir.substr(currentGoWorkspace.length + 1) : '');
let pkgMapPromise: Promise<Map<string, string> | null> = Promise.resolve(null);
if (testconfig.includeSubDirectories) {
if (testconfig.isMod) {
targets = ['./...'];
pkgMapPromise = getNonVendorPackages(testconfig.dir); // We need the mapping to get absolute paths for the files in the test output
} else {
pkgMapPromise = getGoVersion().then(ver => {
if (!ver || ver.major > 1 || (ver.major === 1 && ver.minor >= 9)) {
targets = ['./...'];
return null; // We dont need mapping, as we can derive the absolute paths from package path
}
return getNonVendorPackages(testconfig.dir).then(pkgMap => {
targets = Array.from(pkgMap.keys());
return pkgMap; // We need the individual package paths to pass to `go test`
});
});
}
}

targetArgs(testconfig).then(targets => {
Promise.all([pkgMapPromise, getCurrentPackagePromise]).then(([pkgMap, currentPackage]) => {
if (!pkgMap) {
pkgMap = new Map<string, string>();
}
if (!testconfig.includeSubDirectories) {
if (currentPackage) {
testconfig.currentPackage = currentPackage;

// Use the package name to be in the args to enable running tests in symlinked directories
targets.splice(0, 0, testconfig.currentPackage);
}
}
let outTargets = args.slice(0);
if (targets.length > 4) {
outTargets.push('<long arguments omitted>');
Expand All @@ -225,11 +252,15 @@ export function goTest(testconfig: TestConfig): Thenable<boolean> {
const testResultLines: string[] = [];

const processTestResultLine = (line: string) => {
if (!testconfig.includeSubDirectories) {
outputChannel.appendLine(expandFilePathInOutput(line, testconfig.dir));
return;
}
testResultLines.push(line);
const result = line.match(packageResultLineRE);
if (result && currentGoWorkspace) {
if (result && (pkgMap.has(result[2]) || currentGoWorkspace)) {
const packageNameArr = result[2].split('/');
const baseDir = path.join(currentGoWorkspace, ...packageNameArr);
const baseDir = pkgMap.get(result[2]) || path.join(currentGoWorkspace, ...packageNameArr);
testResultLines.forEach(line => outputChannel.appendLine(expandFilePathInOutput(line, baseDir)));
testResultLines.splice(0);
}
Expand Down Expand Up @@ -326,51 +357,36 @@ function expandFilePathInOutput(output: string, cwd: string): string {
*
* @param testconfig Configuration for the Go extension.
*/
function targetArgs(testconfig: TestConfig): Thenable<Array<string>> {
function targetArgs(testconfig: TestConfig): Array<string> {
let params: string[] = [];
let getCurrentPackagePromise = testconfig.isMod ? getCurrentPackage(testconfig.dir) : Promise.resolve(testconfig.currentPackage);

return getCurrentPackagePromise.then(pkg => {
if (pkg && !testconfig.includeSubDirectories) {
params.push(pkg);
testconfig.currentPackage = pkg;
}

if (testconfig.functions) {
if (testconfig.isBenchmark) {
params = ['-bench', util.format('^%s$', testconfig.functions.join('|'))];
} else {
let testFunctions = testconfig.functions;
let testifyMethods = testFunctions.filter(fn => testMethodRegex.test(fn));
if (testifyMethods.length > 0) {
// filter out testify methods
testFunctions = testFunctions.filter(fn => !testMethodRegex.test(fn));
testifyMethods = testifyMethods.map(extractInstanceTestName);
}

// we might skip the '-run' param when running only testify methods, which will result
// in running all the test methods, but one of them should call testify's `suite.Run(...)`
// which will result in the correct thing to happen
if (testFunctions.length > 0) {
params = params.concat(['-run', util.format('^%s$', testFunctions.join('|'))]);
}
if (testifyMethods.length > 0) {
params = params.concat(['-testify.m', util.format('^%s$', testifyMethods.join('|'))]);
}
if (testconfig.functions) {
if (testconfig.isBenchmark) {
params = ['-bench', util.format('^%s$', testconfig.functions.join('|'))];
} else {
let testFunctions = testconfig.functions;
let testifyMethods = testFunctions.filter(fn => testMethodRegex.test(fn));
if (testifyMethods.length > 0) {
// filter out testify methods
testFunctions = testFunctions.filter(fn => !testMethodRegex.test(fn));
testifyMethods = testifyMethods.map(extractInstanceTestName);
}
return params;
}

if (testconfig.isBenchmark) {
params = ['-bench', '.'];
} else if (testconfig.includeSubDirectories) {
return getGoVersion().then((ver: SemVersion) => {
if (ver && (ver.major > 1 || (ver.major === 1 && ver.minor >= 9))) {
return ['./...'];
}
return getNonVendorPackages(testconfig.dir);
});
// we might skip the '-run' param when running only testify methods, which will result
// in running all the test methods, but one of them should call testify's `suite.Run(...)`
// which will result in the correct thing to happen
if (testFunctions.length > 0) {
params = params.concat(['-run', util.format('^%s$', testFunctions.join('|'))]);
}
if (testifyMethods.length > 0) {
params = params.concat(['-testify.m', util.format('^%s$', testifyMethods.join('|'))]);
}
}
return params;
});
}

if (testconfig.isBenchmark) {
params = ['-bench', '.'];
}
return params;
}

0 comments on commit ddd2635

Please sign in to comment.