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

Commit

Permalink
Merge pull request #509 from ramya-rao-a/optional-goimports
Browse files Browse the repository at this point in the history
Update installTools logic to support optional tools
  • Loading branch information
ramya-rao-a authored Oct 6, 2016
2 parents a0fa2d2 + 9ac767f commit 91637fb
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 37 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ install:
- npm run vscode:prepublish
- go get -u -v github.com/nsf/gocode
- go get -u -v github.com/rogpeppe/godef
- go get -u -v github.com/golang/lint/golint
- if [[ "$(go version)" =~ "go version go1.5" ]]; then echo cannot get golint; else go get -u -v github.com/golang/lint/golint; fi
- go get -u -v github.com/lukehoban/go-outline
- go get -u -v sourcegraph.com/sqs/goreturns
- go get -u -v golang.org/x/tools/cmd/gorename
Expand Down
116 changes: 87 additions & 29 deletions src/goInstallTools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,38 +11,76 @@ import path = require('path');
import os = require('os');
import cp = require('child_process');
import { showGoStatus, hideGoStatus } from './goStatus';
import { getBinPath } from './goPath';
import { getBinPath, getGoRuntimePath } from './goPath';
import { outputChannel } from './goStatus';

let tools: { [key: string]: string } = {
'gocode': 'github.com/nsf/gocode',
'goreturns': 'sourcegraph.com/sqs/goreturns',
'gopkgs': 'github.com/tpng/gopkgs',
'godef': 'github.com/rogpeppe/godef',
'golint': 'github.com/golang/lint/golint',
'go-outline': 'github.com/lukehoban/go-outline',
'go-symbols': 'github.com/newhook/go-symbols',
'guru': 'golang.org/x/tools/cmd/guru',
'gorename': 'golang.org/x/tools/cmd/gorename',
'goimports': 'golang.org/x/tools/cmd/goimports'
};
interface SemVersion {
major: number;
minor: number;
}

let goVersion: SemVersion = null;

function getTools(): { [key: string]: string } {
let goConfig = vscode.workspace.getConfiguration('go');
let tools: { [key: string]: string } = {
'gocode': 'github.com/nsf/gocode',
'gopkgs': 'github.com/tpng/gopkgs',
'godef': 'github.com/rogpeppe/godef',
'go-outline': 'github.com/lukehoban/go-outline',
'go-symbols': 'github.com/newhook/go-symbols',
'guru': 'golang.org/x/tools/cmd/guru',
'gorename': 'golang.org/x/tools/cmd/gorename'
};

// Install the formattool that was chosen by the user
if (goConfig['formatTool'] === 'goimports') {
tools['goimports'] = 'golang.org/x/tools/cmd/goimports';
} else if (goConfig['formatTool'] === 'goreturns') {
tools['goreturns'] = 'sourcegraph.com/sqs/goreturns';
}

// golint is no longer supported in go1.5
if (goVersion && (goVersion.major > 1 || (goVersion.major === 1 && goVersion.minor > 5))) {
tools['golint'] = 'github.com/golang/lint/golint';
}
return tools;
}

export function installAllTools() {
installTools(Object.keys(tools));
getGoVersion().then(() => installTools());
}

export function promptForMissingTool(tool: string) {
vscode.window.showInformationMessage(`The "${tool}" command is not available. Use "go get -v ${tools[tool]}" to install.`, 'Install All', 'Install').then(selected => {
if (selected === 'Install') {
installTools([tool]);
} else if (selected === 'Install All') {
getMissingTools().then(installTools);
hideGoStatus();

getGoVersion().then(() => {
if (tool === 'golint' && goVersion.major === 1 && goVersion.minor < 6) {
vscode.window.showInformationMessage('golint no longer supports go1.5, update your settings to use gometalinter as go.lintTool and install gometalinter');
return;
}

vscode.window.showInformationMessage(`The "${tool}" command is not available. Use "go get -v ${getTools()[tool]}" to install.`, 'Install All', 'Install').then(selected => {
if (selected === 'Install') {
installTools([tool]);
} else if (selected === 'Install All') {
getMissingTools().then(installTools);
hideGoStatus();
}
});
});

}

export function installTools(missing: string[]) {
/**
* Installs given array of missing tools. If no input is given, the all tools are installed
*
* @param string[] array of tool names to be installed
*/
function installTools(missing?: string[]) {
let tools = getTools();
if (!missing) {
missing = Object.keys(tools);
}
outputChannel.show();
outputChannel.clear();
outputChannel.appendLine('Installing ' + missing.length + ' tools');
Expand Down Expand Up @@ -134,14 +172,34 @@ export function setupGoPathAndOfferToInstallTools() {
}

function getMissingTools(): Promise<string[]> {
let keys = Object.keys(tools);
return Promise.all<string>(keys.map(tool => new Promise<string>((resolve, reject) => {
let toolPath = getBinPath(tool);
fs.exists(toolPath, exists => {
resolve(exists ? null : tool);
return getGoVersion().then(() => {
let keys = Object.keys(getTools());
return Promise.all<string>(keys.map(tool => new Promise<string>((resolve, reject) => {
let toolPath = getBinPath(tool);
fs.exists(toolPath, exists => {
resolve(exists ? null : tool);
});
}))).then(res => {
let missing = res.filter(x => x != null);
return missing;
});
}))).then(res => {
let missing = res.filter(x => x != null);
return missing;
});
}

export function getGoVersion(): Promise<SemVersion> {
if (goVersion) {
return Promise.resolve(goVersion);
}
return new Promise<SemVersion>((resolve, reject) => {
cp.execFile(getGoRuntimePath(), ['version'], {}, (err, stdout, stderr) => {
let matches = /go version go(\d).(\d).*/.exec(stdout);
if (matches) {
goVersion = {
major: parseInt(matches[1]),
minor: parseInt(matches[2])
};
}
return resolve(goVersion);
});
});
}
23 changes: 16 additions & 7 deletions test/go.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import cp = require('child_process');
import { getEditsFromUnifiedDiffStr, getEdits } from '../src/diffUtils';
import jsDiff = require('diff');
import { testCurrentFile } from '../src/goTest';
import { getGoVersion } from '../src/goInstallTools';

suite('Go Extension Tests', () => {
let gopath = process.env['GOPATH'];
Expand Down Expand Up @@ -122,15 +123,23 @@ encountered.
// { line: 7, severity: 'warning', msg: 'no formatting directive in Printf call' },
{ line: 11, severity: 'error', msg: 'undefined: prin' },
];
check(path.join(fixturePath, 'errorsTest', 'errors.go'), config).then(diagnostics => {
let sortedDiagnostics = diagnostics.sort((a, b) => a.line - b.line);
for (let i in expected) {
assert.equal(sortedDiagnostics[i].line, expected[i].line);
assert.equal(sortedDiagnostics[i].severity, expected[i].severity);
assert.equal(sortedDiagnostics[i].msg, expected[i].msg);
getGoVersion().then(version => {
if (version.major === 1 && version.minor === 5) {
// golint is not supported in Go 1.5, so skip the test
return Promise.resolve();
}
assert.equal(sortedDiagnostics.length, expected.length, `too many errors ${JSON.stringify(sortedDiagnostics)}`);
return check(path.join(fixturePath, 'errorsTest', 'errors.go'), config).then(diagnostics => {
let sortedDiagnostics = diagnostics.sort((a, b) => a.line - b.line);
for (let i in expected) {
assert.equal(sortedDiagnostics[i].line, expected[i].line);
assert.equal(sortedDiagnostics[i].severity, expected[i].severity);
assert.equal(sortedDiagnostics[i].msg, expected[i].msg);
}
assert.equal(sortedDiagnostics.length, expected.length, `too many errors ${JSON.stringify(sortedDiagnostics)}`);
});

}).then(() => done(), done);

});

test('Gometalinter error checking', (done) => {
Expand Down

0 comments on commit 91637fb

Please sign in to comment.