From 97be2bb83f432bbf5524965e2f1d7f8c7d0cc7f1 Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Sun, 2 Oct 2016 14:22:13 -0700 Subject: [PATCH 1/5] prompt to install goimports only if it is chosen --- src/goInstallTools.ts | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/src/goInstallTools.ts b/src/goInstallTools.ts index 99aa4b9e6..090ba3795 100644 --- a/src/goInstallTools.ts +++ b/src/goInstallTools.ts @@ -14,25 +14,33 @@ import { showGoStatus, hideGoStatus } from './goStatus'; import { getBinPath } 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' -}; +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', + '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' + }; + + if (goConfig['formatTool'] === 'goimports') { + tools['goimports'] = 'golang.org/x/tools/cmd/goimports'; + } else if (goConfig['formatTool'] === 'goreturns') { + tools['goreturns'] = 'sourcegraph.com/sqs/goreturns'; + } + return tools; +} export function installAllTools() { - installTools(Object.keys(tools)); + installTools(Object.keys(getTools())); } 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 => { + 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') { @@ -54,7 +62,7 @@ export function installTools(missing: string[]) { missing.reduce((res: Promise, tool: string) => { return res.then(sofar => new Promise((resolve, reject) => { - cp.exec('go get -u -v ' + tools[tool], { env: process.env }, (err, stdout, stderr) => { + cp.exec('go get -u -v ' + getTools()[tool], { env: process.env }, (err, stdout, stderr) => { if (err) { outputChannel.appendLine('Installing ' + tool + ' FAILED'); let failureReason = tool + ';;' + err + stdout.toString() + stderr.toString(); @@ -134,7 +142,7 @@ export function setupGoPathAndOfferToInstallTools() { } function getMissingTools(): Promise { - let keys = Object.keys(tools); + let keys = Object.keys(getTools()); return Promise.all(keys.map(tool => new Promise((resolve, reject) => { let toolPath = getBinPath(tool); fs.exists(toolPath, exists => { From 1a26d3653a6e8ba87ea8ca64b1f20daea3806924 Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Wed, 5 Oct 2016 12:56:54 -0700 Subject: [PATCH 2/5] reaction to golint dropping support for Go 1.5 --- .travis.yml | 1 - src/goInstallTools.ts | 75 +++++++++++++++++++++++++++++++++---------- 2 files changed, 58 insertions(+), 18 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8c635458d..2d16537ab 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,6 @@ language: go go: - - 1.5 - 1.6 - 1.7 diff --git a/src/goInstallTools.ts b/src/goInstallTools.ts index 090ba3795..b48fb98bb 100644 --- a/src/goInstallTools.ts +++ b/src/goInstallTools.ts @@ -14,43 +14,64 @@ import { showGoStatus, hideGoStatus } from './goStatus'; import { getBinPath } from './goPath'; import { outputChannel } from './goStatus'; +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', - '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' }; + // 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(getTools())); + getGoVersion().then(() => installTools(Object.keys(getTools()))); } export function promptForMissingTool(tool: string) { - 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(); + + 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[]) { +function installTools(missing: string[]) { outputChannel.show(); outputChannel.clear(); outputChannel.appendLine('Installing ' + missing.length + ' tools'); @@ -142,14 +163,34 @@ export function setupGoPathAndOfferToInstallTools() { } function getMissingTools(): Promise { - let keys = Object.keys(getTools()); - return Promise.all(keys.map(tool => new Promise((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(keys.map(tool => new Promise((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 { + if (goVersion) { + return Promise.resolve(goVersion); + } + return new Promise((resolve, reject) => { + cp.exec('go 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); + }); + }); +} \ No newline at end of file From 9f099055bf2780ecf2596bdfdaefa1934391300b Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Wed, 5 Oct 2016 13:51:12 -0700 Subject: [PATCH 3/5] Use runtimepath for go while getting version --- src/goInstallTools.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/goInstallTools.ts b/src/goInstallTools.ts index b48fb98bb..f85a078c9 100644 --- a/src/goInstallTools.ts +++ b/src/goInstallTools.ts @@ -11,7 +11,7 @@ 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'; interface SemVersion { @@ -182,7 +182,7 @@ export function getGoVersion(): Promise { return Promise.resolve(goVersion); } return new Promise((resolve, reject) => { - cp.exec('go version', (err, stdout, stderr) => { + cp.execFile(getGoRuntimePath(), ['version'], {}, (err, stdout, stderr) => { let matches = /go version go(\d).(\d).*/.exec(stdout); if (matches) { goVersion = { From 93d8f90c340797e6305cdf739413fcbff746d6f6 Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Wed, 5 Oct 2016 14:55:16 -0700 Subject: [PATCH 4/5] simplifying installAllTools command --- src/goInstallTools.ts | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/goInstallTools.ts b/src/goInstallTools.ts index f85a078c9..21e5b0772 100644 --- a/src/goInstallTools.ts +++ b/src/goInstallTools.ts @@ -48,7 +48,7 @@ function getTools(): { [key: string]: string } { } export function installAllTools() { - getGoVersion().then(() => installTools(Object.keys(getTools()))); + getGoVersion().then(() => installTools()); } export function promptForMissingTool(tool: string) { @@ -71,7 +71,16 @@ export function promptForMissingTool(tool: string) { } -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'); @@ -83,7 +92,7 @@ function installTools(missing: string[]) { missing.reduce((res: Promise, tool: string) => { return res.then(sofar => new Promise((resolve, reject) => { - cp.exec('go get -u -v ' + getTools()[tool], { env: process.env }, (err, stdout, stderr) => { + cp.exec('go get -u -v ' + tools[tool], { env: process.env }, (err, stdout, stderr) => { if (err) { outputChannel.appendLine('Installing ' + tool + ' FAILED'); let failureReason = tool + ';;' + err + stdout.toString() + stderr.toString(); From 9ac767f64119d1e2aa43542efd3fea9cb4df8e3a Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Wed, 5 Oct 2016 15:38:31 -0700 Subject: [PATCH 5/5] skip golint install in travis if Go 1.5 --- .travis.yml | 3 ++- test/go.test.ts | 23 ++++++++++++++++------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2d16537ab..abfd1e12d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,7 @@ language: go go: + - 1.5 - 1.6 - 1.7 @@ -22,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 diff --git a/test/go.test.ts b/test/go.test.ts index e887314f0..72a814b2c 100644 --- a/test/go.test.ts +++ b/test/go.test.ts @@ -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']; @@ -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) => {