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

Commit

Permalink
Add build package and workspace cmds
Browse files Browse the repository at this point in the history
  • Loading branch information
ramya-rao-a committed Nov 10, 2017
1 parent 951a72b commit 97ffefc
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 66 deletions.
10 changes: 10 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,16 @@
"command": "go.vet.workspace",
"title": "Go: Vet Workspace",
"description": "Run go vet in the current workspace."
},
{
"command": "go.build.package",
"title": "Go: Build Package",
"description": "Build the package of the current file."
},
{
"command": "go.build.workspace",
"title": "Go: Build Workspace",
"description": "Build the current workspace."
}
],
"debuggers": [
Expand Down
101 changes: 101 additions & 0 deletions src/goBuild.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import path = require('path');
import vscode = require('vscode');
import { getToolsEnvVars, runTool, ICheckResult, handleDiagnosticErrors, getWorkspaceFolderPath, getCurrentGoPath } from './util';
import { outputChannel } from './goStatus';
import os = require('os');
import { getNonVendorPackages } from './goPackages';
import { getTestFlags } from './testUtils';
import { getCurrentGoWorkspaceFromGOPATH } from './goPath';

/**
* Builds current package or workspace.
*/
export function buildCode(buildWorkspace?: boolean) {
let editor = vscode.window.activeTextEditor;
if (!editor && !buildWorkspace) {
vscode.window.showInformationMessage('No editor is active, cant find current package to build');
return;
}

let documentUri = editor ? editor.document.uri : null;
let goConfig = vscode.workspace.getConfiguration('go', documentUri);
outputChannel.clear();
goBuild(documentUri, goConfig, buildWorkspace)
.then(errors => handleDiagnosticErrors(editor ? editor.document : null, errors, vscode.DiagnosticSeverity.Error))
.catch(err => {
vscode.window.showInformationMessage('Error: ' + err);
});
}

/**
* Runs go build -i or go test -i and presents the output in the 'Go' channel and in the diagnostic collections.
*
* @param fileUri Document uri.
* @param goConfig Configuration for the Go extension.
* @param buildWorkspace If true builds code in all workspace.
*/
export function goBuild(fileUri: vscode.Uri, goConfig: vscode.WorkspaceConfiguration, buildWorkspace?: boolean): Promise<ICheckResult[]> {
const buildEnv = Object.assign({}, getToolsEnvVars());
const currentWorkspace = getWorkspaceFolderPath(fileUri);
const cwd = path.dirname(fileUri.fsPath);
const tmpPath = path.normalize(path.join(os.tmpdir(), 'go-code-check'));
const isTestFile = fileUri.fsPath.endsWith('_test.go');

let buildFlags = isTestFile ? getTestFlags(goConfig, null) : (goConfig['buildFlags'] || []);
// Remove the -i flag as it will be added later anyway
if (buildFlags.indexOf('-i') > -1) {
buildFlags.splice(buildFlags.indexOf('-i'), 1);
}

// If current file is a test file, then use `go test -c` instead of `go build` to find build errors
let buildArgs: string[] = isTestFile ? ['test', '-c'] : ['build'];
buildArgs.push('-i', '-o', tmpPath, ...buildFlags);
if (goConfig['buildTags'] && buildFlags.indexOf('-tags') === -1) {
buildArgs.push('-tags');
buildArgs.push('"' + goConfig['buildTags'] + '"');
}

if (buildWorkspace && currentWorkspace && !isTestFile) {
return getNonVendorPackages(currentWorkspace).then(pkgs => {
let buildPromises = [];
buildPromises = pkgs.map(pkgPath => {
return runTool(
buildArgs.concat(pkgPath),
currentWorkspace,
'error',
true,
null,
buildEnv,
true
);
});
return Promise.all(buildPromises).then((resultSets) => {
let results: ICheckResult[] = [].concat.apply([], resultSets);
// Filter duplicates
return results.filter((results, index, self) =>
self.findIndex((t) => {
return t.file === results.file && t.line === results.line && t.msg === results.msg && t.severity === results.severity;

This comment has been minimized.

Copy link
@mgood

mgood Aug 29, 2018

This could be rather inefficient if there are a large number of results since it's going to be O(N^2).

It seems like the duplicates here are likely a result of it calling go build individually for each package, so compilation errors in shared dependencies will be repeated.

As I noted in #1890 it seems like you could pass the list of packages to a single call of go build instead. Then you should only get one set of results back for the whole list of packages that shouldn't contain the duplication.

}) === index);
});
});
}

// Find the right importPath instead of directly using `.`. Fixes https://github.com/Microsoft/vscode-go/issues/846
let currentGoWorkspace = getCurrentGoWorkspaceFromGOPATH(getCurrentGoPath(), cwd);
let importPath = currentGoWorkspace ? cwd.substr(currentGoWorkspace.length + 1) : '.';

return runTool(
buildArgs.concat(importPath),
cwd,
'error',
true,
null,
buildEnv,
true
);





}
73 changes: 7 additions & 66 deletions src/goCheck.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,14 @@
import vscode = require('vscode');
import path = require('path');
import os = require('os');
import { getGoRuntimePath, getCurrentGoWorkspaceFromGOPATH } from './goPath';
import { getGoRuntimePath } from './goPath';
import { getCoverage } from './goCover';
import { outputChannel } from './goStatus';
import { goTest } from './testUtils';
import { getCurrentGoPath, getToolsEnvVars, ICheckResult, runTool } from './util';
import { getNonVendorPackages } from './goPackages';
import { getTestFlags } from './testUtils';
import { ICheckResult } from './util';
import { goLint } from './goLint';
import { goVet } from './goVet';
import { goBuild } from './goBuild';

let statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left);
statusBarItem.command = 'go.test.showOutput';
Expand All @@ -33,8 +32,6 @@ export function check(fileUri: vscode.Uri, goConfig: vscode.WorkspaceConfigurati
outputChannel.clear();
let runningToolsPromises = [];
let cwd = path.dirname(fileUri.fsPath);
let currentWorkspace = vscode.workspace.getWorkspaceFolder(fileUri) ? vscode.workspace.getWorkspaceFolder(fileUri).uri.fsPath : '';
let env = getToolsEnvVars();
let goRuntimePath = getGoRuntimePath();

if (!goRuntimePath) {
Expand Down Expand Up @@ -67,56 +64,7 @@ export function check(fileUri: vscode.Uri, goConfig: vscode.WorkspaceConfigurati
};

if (!!goConfig['buildOnSave'] && goConfig['buildOnSave'] !== 'off') {
const tmpPath = path.normalize(path.join(os.tmpdir(), 'go-code-check'));
const isTestFile = fileUri.fsPath.endsWith('_test.go');
let buildFlags = isTestFile ? getTestFlags(goConfig, null) : (goConfig['buildFlags'] || []);
// Remove the -i flag as it will be added later anyway
if (buildFlags.indexOf('-i') > -1) {
buildFlags.splice(buildFlags.indexOf('-i'), 1);
}

// If current file is a test file, then use `go test -c` instead of `go build` to find build errors
let buildArgs: string[] = isTestFile ? ['test', '-c'] : ['build'];
buildArgs.push('-i', '-o', tmpPath, ...buildFlags);
if (goConfig['buildTags'] && buildFlags.indexOf('-tags') === -1) {
buildArgs.push('-tags');
buildArgs.push('"' + goConfig['buildTags'] + '"');
}

if (goConfig['buildOnSave'] === 'workspace' && currentWorkspace && !isTestFile) {
let buildPromises = [];
let outerBuildPromise = getNonVendorPackages(currentWorkspace).then(pkgs => {
buildPromises = pkgs.map(pkgPath => {
return runTool(
buildArgs.concat(pkgPath),
cwd,
'error',
true,
null,
env,
true
);
});
return Promise.all(buildPromises).then((resultSets) => {
return Promise.resolve([].concat.apply([], resultSets));
});
});
runningToolsPromises.push(outerBuildPromise);
} else {
// Find the right importPath instead of directly using `.`. Fixes https://github.com/Microsoft/vscode-go/issues/846
let currentGoWorkspace = getCurrentGoWorkspaceFromGOPATH(getCurrentGoPath(), cwd);
let importPath = currentGoWorkspace ? cwd.substr(currentGoWorkspace.length + 1) : '.';

runningToolsPromises.push(runTool(
buildArgs.concat(importPath),
cwd,
'error',
true,
null,
env,
true
));
}
runningToolsPromises.push(goBuild(fileUri, goConfig, goConfig['buildOnSave'] === 'workspace'));
}

if (!!goConfig['testOnSave']) {
Expand All @@ -135,13 +83,11 @@ export function check(fileUri: vscode.Uri, goConfig: vscode.WorkspaceConfigurati
}

if (!!goConfig['lintOnSave'] && goConfig['lintOnSave'] !== 'off') {
let lintWorkspace = goConfig['lintOnSave'] === 'workspace';
runningToolsPromises.push(goLint(fileUri, goConfig, lintWorkspace));
runningToolsPromises.push(goLint(fileUri, goConfig, goConfig['lintOnSave'] === 'workspace'));
}

if (!!goConfig['vetOnSave'] && goConfig['vetOnSave'] !== 'off') {
let vetWorkspace = goConfig['vetOnSave'] === 'workspace';
runningToolsPromises.push(goVet(fileUri, goConfig, vetWorkspace));
runningToolsPromises.push(goVet(fileUri, goConfig, goConfig['vetOnSave'] === 'workspace'));
}

if (!!goConfig['coverOnSave']) {
Expand All @@ -155,11 +101,6 @@ export function check(fileUri: vscode.Uri, goConfig: vscode.WorkspaceConfigurati
}

return Promise.all(runningToolsPromises).then(function (resultSets) {
let results: ICheckResult[] = [].concat.apply([], resultSets);
// Filter duplicates
return results.filter((results, index, self) =>
self.findIndex((t) => {
return t.file === results.file && t.line === results.line && t.msg === results.msg && t.severity === results.severity;
}) === index);
return [].concat.apply([], resultSets);
});
}
5 changes: 5 additions & 0 deletions src/goMain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import { GoDebugConfigurationProvider } from './goDebugConfiguration';
import { playgroundCommand } from './goPlayground';
import { lintCode } from './goLint';
import { vetCode } from './goVet';
import { buildCode } from './goBuild';

export let errorDiagnosticCollection: vscode.DiagnosticCollection;
export let warningDiagnosticCollection: vscode.DiagnosticCollection;
Expand Down Expand Up @@ -299,6 +300,10 @@ export function activate(ctx: vscode.ExtensionContext): void {

ctx.subscriptions.push(vscode.commands.registerCommand('go.vet.workspace', () => vetCode(true)));

ctx.subscriptions.push(vscode.commands.registerCommand('go.build.package', buildCode));

ctx.subscriptions.push(vscode.commands.registerCommand('go.build.workspace', () => buildCode(true)));

vscode.languages.setLanguageConfiguration(GO_MODE.language, {
indentationRules: {
decreaseIndentPattern: /^\s*(\bcase\b.*:|\bdefault\b:|}[),]?|\)[,]?)$/,
Expand Down

0 comments on commit 97ffefc

Please sign in to comment.