Skip to content
This repository has been archived by the owner on Dec 18, 2021. It is now read-only.

Commit

Permalink
feat(husky): upgraded the husky lifter to enable updating v4 config t…
Browse files Browse the repository at this point in the history
…o v5
  • Loading branch information
travi committed Apr 17, 2021
1 parent 7402696 commit 549c0a6
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 24 deletions.
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
},
"dependencies": {
"@form8ion/core": "^1.3.1",
"@form8ion/husky": "1.1.0",
"@form8ion/husky": "1.2.0-alpha.2",
"@form8ion/javascript-core": "^2.9.0",
"@travi/cli-messages": "^1.0.4",
"deepmerge": "^4.2.2",
Expand Down
14 changes: 9 additions & 5 deletions src/lift-test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as huskyLifter from '@form8ion/husky';
import deepmerge from 'deepmerge';
import sinon from 'sinon';
import any from '@travi/any';
import {assert} from 'chai';
Expand Down Expand Up @@ -44,27 +45,30 @@ suite('lift', () => {

const liftResults = await lift({projectRoot, results, configs: {eslint: {scope}}});

assert.deepEqual(liftResults, {nextSteps: [...eslintNextSteps, ...huskyNextSteps]});
assert.deepEqual(liftResults, {nextSteps: eslintNextSteps});
assert.calledWith(
packageLifter.default,
{projectRoot, scripts, tags, dependencies, devDependencies, eslintDevDependencies, packageManager}
deepmerge(
{projectRoot, scripts, tags, dependencies, devDependencies, eslintDevDependencies, packageManager},
huskyLiftResults
)
);
});

test('that eslint-configs are not processed if configs are not provided', async () => {
const liftResults = await lift({projectRoot, results});

assert.deepEqual(liftResults, {nextSteps: huskyNextSteps});
assert.deepEqual(liftResults, {});

assert.calledWith(
packageLifter.default,
{projectRoot, scripts, tags, dependencies, devDependencies, packageManager}
deepmerge({projectRoot, scripts, tags, dependencies, devDependencies, packageManager}, huskyLiftResults)
);
});

test('that eslint-configs are not processed if config for eslint is not provided', async () => {
const liftResults = await lift({projectRoot, results, configs: any.simpleObject()});

assert.deepEqual(liftResults, {nextSteps: huskyNextSteps});
assert.deepEqual(liftResults, {});
});
});
36 changes: 23 additions & 13 deletions src/lift.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,32 @@ export default async function ({
devDependencies: eslintDevDependencies
} = await liftEslint({configs: eslintConfigs, scope: configs.eslint.scope, projectRoot});

await liftPackage({
projectRoot,
scripts,
tags,
dependencies,
devDependencies,
packageManager,
eslintDevDependencies
});

return deepmerge({nextSteps}, huskyResults);
await liftPackage(
deepmerge(
{
projectRoot,
scripts,
tags,
dependencies,
devDependencies,
packageManager,
eslintDevDependencies
},
huskyResults
)
);

return {nextSteps};
}

if (eslintConfigs) warn('Config for ESLint not provided. Skipping ESLint configuration');

await liftPackage({projectRoot, scripts, tags, dependencies, devDependencies, packageManager});
await liftPackage(
deepmerge(
{projectRoot, scripts, tags, dependencies, devDependencies, packageManager},
huskyResults
)
);

return huskyResults;
return {};
}
4 changes: 3 additions & 1 deletion test/integration/features/husky.feature
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ Feature: Husky

Scenario: Husky v5 installed, v4 config
Given husky v5 is installed
And "npm" is the package manager
And husky config is in v4 format
When the scaffolder results are processed
Then the next-steps include a warning about the husky config
Then husky is configured for "npm"
And the v4 config is removed

Scenario: Husky v5 installed, v5 config
Given husky v5 is installed
Expand Down
3 changes: 2 additions & 1 deletion test/integration/features/step_definitions/common-steps.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ After(function () {
stubbedFs.restore();
td.reset();
clearModule('@form8ion/husky');
clearModule('@form8ion/javascript-core');
});

When('the scaffolder results are processed', async function () {
Expand All @@ -39,7 +40,7 @@ When('the scaffolder results are processed', async function () {

this.results = await lift({
projectRoot: process.cwd(),
results: {scripts: this.scriptsResults, tags: this.tagsResults},
results: {scripts: this.scriptsResults, tags: this.tagsResults, packageManager: this.packageManager},
...this.eslintConfigScope && {configs: {eslint: {scope: this.eslintConfigScope}}}
});
});
30 changes: 30 additions & 0 deletions test/integration/features/step_definitions/husky-steps.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
import {promises as fs} from 'fs';
import {fileExists} from '@form8ion/core';
import makeDir from 'make-dir';
import {Given, Then} from 'cucumber';
import any from '@travi/any';
import td from 'testdouble';
import {assert} from 'chai';

export async function assertHookContainsScript(hook, script) {
const hookContents = await fs.readFile(`${process.cwd()}/.husky/${hook}`, 'utf-8');

assert.include(
hookContents,
`#!/bin/sh
. "$(dirname "$0")/_/husky.sh"`
);
assert.include(hookContents, script);
}

Given('husky v5 is installed', async function () {
td
.when(this.execa('npm', ['ls', 'husky', '--json']))
Expand Down Expand Up @@ -34,6 +46,10 @@ Given('husky config is in v5 format', async function () {
await makeDir(`${process.cwd()}/.husky`);
});

Given('{string} is the package manager', async function (packageManager) {
this.packageManager = packageManager;
});

Then('the next-steps include a warning about the husky config', async function () {
assert.deepInclude(
this.results.nextSteps,
Expand All @@ -48,3 +64,17 @@ Then('the next-steps do not include a warning about the husky config', async fun
assert.notDeepInclude(nextSteps, {summary: 'Husky configuration is outdated for the installed Husky version'});
}
});

Then('husky is configured for {string}', async function (packageManager) {
td.verify(this.execa(td.matchers.contains('. ~/.nvm/nvm.sh && nvm use && npm install')), {ignoreExtraArgs: true});
td.verify(this.execa(td.matchers.contains('husky')), {ignoreExtraArgs: true});
assert.equal(
JSON.parse(await fs.readFile(`${process.cwd()}/package.json`, 'utf-8')).scripts.prepare,
'husky install'
);
await assertHookContainsScript('pre-commit', `${packageManager} test`);
});

Then('the v4 config is removed', async function () {
assert.isFalse(await fileExists(`${process.cwd()}/.huskyrc.json`));
});

0 comments on commit 549c0a6

Please sign in to comment.