Skip to content
Permalink
Browse files

Fix: Load shared webhint when prompting to install locally ()

Previously a prompt to install to a project would delay
loading any copy of webhint until the user responded,
causing the experience to feel broken once the
notification was automatically hidden.

- - - - - - - - - - - - - - - - - - - - - - - - - - - -

Close #3031
  • Loading branch information...
antross authored and molant committed Sep 26, 2019
1 parent 61b3d66 commit 0ed84ba7c8022f3cd20b9127a451c563e11c5f66
@@ -45,6 +45,7 @@ export class Analyzer {
return promptAddWebhint(this.connection.window, async () => {
this.connection.sendNotification(notifications.showOutput);
await install();
this.onConfigurationChanged();
});
});

@@ -23,7 +23,7 @@ export const promptRetry = async <T>(window: RemoteWindow, retry: () => Promise<
// Prompt the user to retry after checking their configuration.
const retryTitle = 'Retry';
const answer = await window.showErrorMessage(
'Unable to start webhint. Ensure you are using the latest version of the `hint` and `@hint/configuration-development` packages.',
'Unable to start webhint. Ensure you are using the latest version of the `hint` package.',
{ title: retryTitle }
);

@@ -1,8 +1,9 @@
import { hasFile, mkdir } from './fs';
import { installPackages, loadPackage, InstallOptions } from './packages';

/* istanbul ignore next */
const installWebhint = (options: InstallOptions) => {
return installPackages(['hint', '@hint/configuration-development'], options);
return installPackages(['hint'], options);
};

/**
@@ -47,16 +48,19 @@ const loadSharedWebhint = async (globalStoragePath: string): Promise<typeof impo
* Load webhint, installing it if needed.
* Will prompt to install a local copy if `.hintrc` is present.
*/
export const loadWebhint = async (directory: string, globalStoragePath: string, promptToInstall?: (install: () => Promise<void>) => Promise<void>): Promise<typeof import('hint') | null> => {
export const loadWebhint = async (directory: string, globalStoragePath: string, promptToInstall: (install: () => Promise<void>) => Promise<void>): Promise<typeof import('hint') | null> => {
try {
return loadPackage('hint', { paths: [directory] });
} catch (e) {
if (promptToInstall && await hasFile('.hintrc', directory)) {
await promptToInstall(async () => {
if (await hasFile('.hintrc', directory)) {
/**
* Prompt to install, but don't wait in case the user ignores.
* Load the shared copy for now until the install is done.
* Caller is expected to reload once install is complete.
*/
promptToInstall(async () => {
await installWebhint({ cwd: directory });
});

return loadWebhint(directory, globalStoragePath);
}

return loadSharedWebhint(globalStoragePath);
@@ -0,0 +1,56 @@
import test from 'ava';
import * as proxyquire from 'proxyquire';
import * as sinon from 'sinon';

const stubContext = () => {
const stubs = {
'./fs': {
'@noCallThru': true,
hasFile() {
return Promise.resolve(true);
}
},
'./packages': {
'@noCallThru': true,
loadPackage(name: string, opts: any) {
if (name !== 'hint' || !opts.paths || opts.paths[0] !== 'global') {
throw new Error('Not found');
}

return Promise.resolve('webhint');
}
} as Partial<typeof import('../../src/utils/packages')>
};

const module = proxyquire('../../src/utils/webhint-packages', stubs) as typeof import('../../src/utils/webhint-packages');

return { module, stubs };
};

test('It loads shared webhint when prompting to install a local copy', async (t) => {
const sandbox = sinon.createSandbox();
const { module, stubs } = stubContext();
const loadPackageSpy = sandbox.spy(stubs['./packages'], 'loadPackage');

let promptCalled = false;
let promptComplete = false;

const hint = await module.loadWebhint('local', 'global', async () => {
promptCalled = true;

await new Promise((resolve) => {
setTimeout(resolve, 0);
});

promptComplete = true;
});

t.is(hint as any, 'webhint');
t.true(promptCalled);
t.false(promptComplete);
t.true(loadPackageSpy.calledTwice);
t.deepEqual(loadPackageSpy.firstCall.args[0], 'hint');
t.deepEqual(loadPackageSpy.firstCall.args[1], { paths: ['local'] });
t.deepEqual(loadPackageSpy.secondCall.args[0], 'hint');
t.deepEqual(loadPackageSpy.secondCall.args[1], { paths: ['global'] });
});

0 comments on commit 0ed84ba

Please sign in to comment.
You can’t perform that action at this time.