diff --git a/src/goCheck.ts b/src/goCheck.ts index 49a60ec57..933fb13c1 100644 --- a/src/goCheck.ts +++ b/src/goCheck.ts @@ -14,6 +14,7 @@ import { getBinPath, getGoRuntimePath } from './goPath'; import { getCoverage } from './goCover'; import { outputChannel } from './goStatus'; import { promptForMissingTool } from './goInstallTools'; +import { parseFilePrelude } from './util'; export interface ICheckResult { file: string; @@ -72,22 +73,42 @@ export function check(filename: string, goConfig: vscode.WorkspaceConfiguration) } if (!!goConfig['buildOnSave']) { - let buildFlags = goConfig['buildFlags'] || []; - let buildTags = '"' + goConfig['buildTags'] + '"'; - let tmppath = path.normalize(path.join(os.tmpdir(), 'go-code-check')); - let args = ['build', '-o', tmppath, '-tags', buildTags, ...buildFlags, '.']; - if (filename.match(/_test.go$/i)) { - args = ['test', '-copybinary', '-o', tmppath, '-c', '-tags', buildTags, ...buildFlags, '.']; - } - runningToolsPromises.push(runTool( - goRuntimePath, - args, - cwd, - 'error', - true, - null, - `Cannot find ${goRuntimePath}` - )); + // we need to parse the file to check the package name + // if the package is a main pkg, we won't be doing a go build -i + let buildPromise = new Promise<{}>((resolve, reject) => { + let isMainPkg = false; + fs.readFile(filename, 'utf8', (err, data) => { + if (err) { + return; + } + let prelude = parseFilePrelude(data); + if (prelude.pkg) { + isMainPkg = prelude.pkg.name === 'main'; + } + + let buildFlags = goConfig['buildFlags'] || []; + let buildTags = '"' + goConfig['buildTags'] + '"'; + let tmppath = path.normalize(path.join(os.tmpdir(), 'go-code-check')); + let args = ['build']; + if (!isMainPkg) { + args.push('- i'); + }; + args = args.concat(['-o', tmppath, '-tags', buildTags, ...buildFlags, '.']); + if (filename.match(/_test.go$/i)) { + args = ['test', '-copybinary', '-o', tmppath, '-c', '-tags', buildTags, ...buildFlags, '.']; + } + runTool( + goRuntimePath, + args, + cwd, + 'error', + true, + null, + `Cannot find ${goRuntimePath}` + ).then(result => resolve(result), err => reject(err)); + }); + }); + runningToolsPromises.push(buildPromise); } if (!!goConfig['lintOnSave']) { let lintTool = getBinPath(goConfig['lintTool'] || 'golint'); diff --git a/src/util.ts b/src/util.ts index bc5ee5e68..fac9608df 100644 --- a/src/util.ts +++ b/src/util.ts @@ -63,7 +63,7 @@ export function byteOffsetAt(document: vscode.TextDocument, position: vscode.Pos export interface Prelude { imports: Array<{ kind: string; start: number; end: number; }>; - pkg: { start: number; end: number; }; + pkg: { start: number; end: number; name: string }; } export function parseFilePrelude(text: string): Prelude { @@ -71,8 +71,9 @@ export function parseFilePrelude(text: string): Prelude { let ret: Prelude = { imports: [], pkg: null }; for (let i = 0; i < lines.length; i++) { let line = lines[i]; - if (line.match(/^(\s)*package(\s)+/)) { - ret.pkg = { start: i, end: i }; + let pkgMatch = line.match(/^(\s)*package(\s)+(\w+)/); + if (pkgMatch) { + ret.pkg = { start: i, end: i, name: pkgMatch[3] }; } if (line.match(/^(\s)*import(\s)+\(/)) { ret.imports.push({ kind: 'multi', start: i, end: -1 }); diff --git a/test/go.test.ts b/test/go.test.ts index 1e0664874..3e64b880f 100644 --- a/test/go.test.ts +++ b/test/go.test.ts @@ -288,12 +288,15 @@ It returns the number of bytes written and any write error encountered. } return check(path.join(fixturePath, 'errorsTest', 'errors.go'), config).then(diagnostics => { let sortedDiagnostics = diagnostics.sort((a, b) => a.line - b.line); + assert.equal(sortedDiagnostics.length, expected.length, `too many errors ${JSON.stringify(sortedDiagnostics)}`); for (let i in expected) { - assert.equal(sortedDiagnostics[i].line, expected[i].line); + if (expected[i].line) { + assert(sortedDiagnostics[i]); + 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); });