in src/util.ts [759:859]
export function runTool(
args: string[],
cwd: string,
severity: string,
useStdErr: boolean,
toolName: string,
env: any,
printUnexpectedOutput: boolean,
token?: vscode.CancellationToken
): Promise<ICheckResult[]> {
let cmd: string;
if (toolName) {
cmd = getBinPath(toolName);
} else {
const goRuntimePath = getBinPath('go');
if (!goRuntimePath) {
return Promise.reject(new Error('Cannot find "go" binary. Update PATH or GOROOT appropriately'));
}
cmd = goRuntimePath;
}
let p: cp.ChildProcess;
if (token) {
token.onCancellationRequested(() => {
if (p) {
killProcessTree(p);
}
});
}
cwd = fixDriveCasingInWindows(cwd);
return new Promise((resolve, reject) => {
p = cp.execFile(cmd, args, { env, cwd }, (err, stdout, stderr) => {
try {
if (err && (<any>err).code === 'ENOENT') {
// Since the tool is run on save which can be frequent
// we avoid sending explicit notification if tool is missing
console.log(`Cannot find ${toolName ? toolName : 'go'}`);
return resolve([]);
}
if (err && stderr && !useStdErr) {
outputChannel.appendLine(['Error while running tool:', cmd, ...args].join(' '));
outputChannel.appendLine(stderr);
return resolve([]);
}
const lines = (useStdErr ? stderr : stdout).toString().split('\n');
outputChannel.appendLine([cwd + '>Finished running tool:', cmd, ...args].join(' '));
const ret: ICheckResult[] = [];
let unexpectedOutput = false;
let atLeastSingleMatch = false;
for (const l of lines) {
if (l[0] === '\t' && ret.length > 0) {
ret[ret.length - 1].msg += '\n' + l;
continue;
}
const match = /^([^:]*: )?((.:)?[^:]*):(\d+)(:(\d+)?)?:(?:\w+:)? (.*)$/.exec(l);
if (!match) {
if (printUnexpectedOutput && useStdErr && stderr) {
unexpectedOutput = true;
}
continue;
}
atLeastSingleMatch = true;
const [, , file, , lineStr, , colStr, msg] = match;
const line = +lineStr;
const col = colStr ? +colStr : undefined;
// Building skips vendor folders,
// But vet and lint take in directories and not import paths, so no way to skip them
// So prune out the results from vendor folders here.
if (
!path.isAbsolute(file) &&
(file.startsWith(`vendor${path.sep}`) || file.indexOf(`${path.sep}vendor${path.sep}`) > -1)
) {
continue;
}
const filePath = path.resolve(cwd, file);
ret.push({ file: filePath, line, col, msg, severity });
outputChannel.appendLine(`${filePath}:${line}:${col ?? ''} ${msg}`);
}
if (!atLeastSingleMatch && unexpectedOutput && vscode.window.activeTextEditor) {
outputChannel.appendLine(stderr);
if (err) {
ret.push({
file: vscode.window.activeTextEditor.document.fileName,
line: 1,
col: 1,
msg: stderr,
severity: 'error'
});
}
}
outputChannel.appendLine('');
resolve(ret);
} catch (e) {
reject(e);
}
});
});
}