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

Commit

Permalink
Better user experience when tools are missing Fixes #998
Browse files Browse the repository at this point in the history
  • Loading branch information
ramya-rao-a committed Jul 17, 2017
1 parent 96026f5 commit 45be8da
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 20 deletions.
8 changes: 3 additions & 5 deletions src/goCheck.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,9 @@ function runTool(args: string[], cwd: string, severity: string, useStdErr: boole
cp.execFile(cmd, args, { env: env, cwd: cwd }, (err, stdout, stderr) => {
try {
if (err && (<any>err).code === 'ENOENT') {
if (toolName) {
promptForMissingTool(toolName);
} else {
vscode.window.showInformationMessage(`Cannot find ${goRuntimePath}`);
}
// 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 : goRuntimePath}`);
return resolve([]);
}
if (err && stderr && !useStdErr) {
Expand Down
19 changes: 12 additions & 7 deletions src/goDeclaration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { byteOffsetAt, getBinPath } from './util';
import { promptForMissingTool } from './goInstallTools';
import { getGoVersion, SemVersion, goKeywords, isPositionInString, getToolsEnvVars, getFileArchive } from './util';

const missingToolMsg = 'Missing tool: ';

export interface GoDefinitionInformation {
file: string;
line: number;
Expand Down Expand Up @@ -55,8 +57,7 @@ function definitionLocation_godef(document: vscode.TextDocument, position: vscod
let p = cp.execFile(godef, ['-t', '-i', '-f', document.fileName, '-o', offset.toString()], {env}, (err, stdout, stderr) => {
try {
if (err && (<any>err).code === 'ENOENT') {
promptForMissingTool('godef');
return reject();
return reject(missingToolMsg + 'godef');
}
if (err) {
return reject(err);
Expand Down Expand Up @@ -124,8 +125,7 @@ function definitionLocation_gogetdoc(document: vscode.TextDocument, position: vs
let p = cp.execFile(gogetdoc, gogetdocFlags, {env}, (err, stdout, stderr) => {
try {
if (err && (<any>err).code === 'ENOENT') {
promptForMissingTool('gogetdoc');
return reject();
return reject(missingToolMsg + 'gogetdoc');
}
if (stderr && stderr.startsWith('flag provided but not defined: -tags')) {
return definitionLocation_gogetdoc(document, position, offset, env, false);
Expand Down Expand Up @@ -167,8 +167,7 @@ function definitionLocation_guru(document: vscode.TextDocument, position: vscode
let p = cp.execFile(guru, ['-json', '-modified', 'definition', document.fileName + ':#' + offset.toString()], {env}, (err, stdout, stderr) => {
try {
if (err && (<any>err).code === 'ENOENT') {
promptForMissingTool('guru');
return reject();
return reject(missingToolMsg + 'guru');
}
if (err) {
return reject(err);
Expand Down Expand Up @@ -216,7 +215,13 @@ export class GoDefinitionProvider implements vscode.DefinitionProvider {
return new vscode.Location(definitionResource, pos);
}, err => {
if (err) {
console.log(err);
// Prompt for missing tool is located here so that the
// prompts dont show up on hover or signature help
if (typeof err === 'string' && err.startsWith(missingToolMsg)) {
promptForMissingTool(err.substr(missingToolMsg.length));
} else {
console.log(err);
}
}
return Promise.resolve(null);
});
Expand Down
20 changes: 15 additions & 5 deletions src/goFormat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { isDiffToolAvailable, getEdits, getEditsFromUnifiedDiffStr } from './dif
import { promptForMissingTool } from './goInstallTools';
import { sendTelemetryEvent, getBinPath, getToolsEnvVars } from './util';

const missingToolMsg = 'Missing tool: ';

export class Formatter {
public formatDocument(document: vscode.TextDocument): Thenable<vscode.TextEdit[]> {
return new Promise((resolve, reject) => {
Expand All @@ -29,11 +31,10 @@ export class Formatter {
}
let t0 = Date.now();
let env = getToolsEnvVars();
cp.execFile(formatCommandBinPath, [...formatFlags, filename], {env}, (err, stdout, stderr) => {
cp.execFile(formatCommandBinPath, [...formatFlags, filename], { env }, (err, stdout, stderr) => {
try {
if (err && (<any>err).code === 'ENOENT') {
promptForMissingTool(formatTool);
return resolve(null);
return reject(missingToolMsg + formatTool);
}
if (err) {
console.log(err);
Expand All @@ -48,7 +49,7 @@ export class Formatter {
});

let timeTaken = Date.now() - t0;
sendTelemetryEvent('format', { tool: formatTool}, {timeTaken});
sendTelemetryEvent('format', { tool: formatTool }, { timeTaken });
return resolve(textEdits);
} catch (e) {
reject('Internal issues while getting diff from formatted content');
Expand All @@ -67,7 +68,16 @@ export class GoDocumentFormattingEditProvider implements vscode.DocumentFormatti

public provideDocumentFormattingEdits(document: vscode.TextDocument, options: vscode.FormattingOptions, token: vscode.CancellationToken): Thenable<vscode.TextEdit[]> {
return document.save().then(() => {
return this.formatter.formatDocument(document);
return this.formatter.formatDocument(document).then(null, err => {
// Prompt for missing tool is located here so that the
// prompts dont show up when formatting is run on save
if (typeof err === 'string' && err.startsWith(missingToolMsg)) {
promptForMissingTool(err.substr(missingToolMsg.length));
} else {
console.log(err);
}
return [];
});
});
}
}
Expand Down
9 changes: 7 additions & 2 deletions src/goImport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@ import { promptForMissingTool } from './goInstallTools';
import path = require('path');
import { getRelativePackagePath } from './goPackages';

const missingToolMsg = 'Missing tool: ';

export function listPackages(excludeImportedPkgs: boolean = false): Thenable<string[]> {
let importsPromise = excludeImportedPkgs && vscode.window.activeTextEditor ? getImports(vscode.window.activeTextEditor.document) : Promise.resolve([]);
let vendorSupportPromise = isVendorSupported();
let goPkgsPromise = new Promise<string[]>((resolve, reject) => {
cp.execFile(getBinPath('gopkgs'), [], (err, stdout, stderr) => {
if (err && (<any>err).code === 'ENOENT') {
promptForMissingTool('gopkgs');
return reject();
return reject(missingToolMsg + 'gopkgs');
}
let lines = stdout.toString().split('\n');
if (lines[lines.length - 1] === '') {
Expand Down Expand Up @@ -84,6 +85,10 @@ function getImports(document: vscode.TextDocument): Promise<string[]> {
function askUserForImport(): Thenable<string> {
return listPackages(true).then(packages => {
return vscode.window.showQuickPick(packages);
}, err => {
if (typeof err === 'string' && err.startsWith(missingToolMsg)) {
promptForMissingTool(err.substr(missingToolMsg.length));
}
});
}

Expand Down
8 changes: 7 additions & 1 deletion src/goInstallTools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { getBinPath, getToolsGopath, getGoVersion, SemVersion, isVendorSupported
import { goLiveErrorsEnabled } from './goLiveErrors';

let updatesDeclinedTools: string[] = [];
let installsDeclinedTools: string[] = [];

function getTools(goVersion: SemVersion): { [key: string]: string } {
let goConfig = vscode.workspace.getConfiguration('go');
Expand Down Expand Up @@ -78,7 +79,10 @@ export function installAllTools() {
}

export function promptForMissingTool(tool: string) {

// If user has declined to install, then don't prompt
if (installsDeclinedTools.indexOf(tool) > -1) {
return;
}
getGoVersion().then((goVersion) => {
if (goVersion && goVersion.major === 1 && goVersion.minor < 6) {
if (tool === 'golint') {
Expand All @@ -97,6 +101,8 @@ export function promptForMissingTool(tool: string) {
} else if (selected === 'Install All') {
getMissingTools(goVersion).then((missing) => installTools(goVersion, missing));
hideGoStatus();
} else {
installsDeclinedTools.push(tool);
}
});
});
Expand Down

0 comments on commit 45be8da

Please sign in to comment.