diff --git a/index.js b/index.js index 1565b2f..c433713 100644 --- a/index.js +++ b/index.js @@ -1,9 +1,30 @@ 'use strict'; const fs = require('fs'); +const path = require('path'); +const loadJsonFile = require('load-json-file'); const requireDirectory = require('require-directory'); const detectors = requireDirectory(module, './lib', { recurse: false }); +function createLoadPackageJson(dir) { + let packageJsonPromise; + + return () => { + if (!packageJsonPromise) { + packageJsonPromise = loadJsonFile(path.join(dir, 'package.json')) + .catch((err) => { + if (err.code === 'ENOENT') { + return null; + } + + throw err; + }); + } + + return packageJsonPromise; + }; +} + function detectRepoLinters(dir) { // Check if dir exists return new Promise((resolve, reject) => { @@ -17,9 +38,13 @@ function detectRepoLinters(dir) { }) // Run the linter detectors and build the results .then(() => { - return Promise.all(Object.keys(detectors) - .map((name) => detectors[name](dir) - .then((detected) => detected && name))); + const loadPackageJson = createLoadPackageJson(dir); + + return Promise.all( + Object.keys(detectors) + .map((name) => detectors[name](dir, loadPackageJson) + .then((detected) => detected && name)) + ); }) .then((linters) => linters.filter((linter) => linter)); } diff --git a/lib/coffeelint.js b/lib/coffeelint.js index 2392c55..0137592 100644 --- a/lib/coffeelint.js +++ b/lib/coffeelint.js @@ -4,13 +4,13 @@ const path = require('path'); const tryFiles = require('./util/tryFiles'); const tryPackageJson = require('./util/tryPackageJson'); -function detectCoffeeLint(dir) { +function detectCoffeeLint(dir, loadPackageJson) { const paths = ['coffeelint.json'] .map((entry) => path.join(dir, entry)); return Promise.all([ tryFiles(paths), - tryPackageJson(dir, ['coffeelintConfig', 'devDependencies.coffeelint']), + tryPackageJson(loadPackageJson, ['coffeelintConfig', 'devDependencies.coffeelint']), ]) .then((booleans) => booleans.some((bool) => bool)); } diff --git a/lib/csslint.js b/lib/csslint.js index 61bf326..308379a 100644 --- a/lib/csslint.js +++ b/lib/csslint.js @@ -4,13 +4,13 @@ const path = require('path'); const tryFiles = require('./util/tryFiles'); const tryPackageJson = require('./util/tryPackageJson'); -function detectCssLint(dir) { +function detectCssLint(dir, loadPackageJson) { const paths = ['.csslintrc'] .map((entry) => path.join(dir, entry)); return Promise.all([ tryFiles(paths), - tryPackageJson(dir, ['devDependencies.csslint']), + tryPackageJson(loadPackageJson, ['devDependencies.csslint']), ]) .then((booleans) => booleans.some((bool) => bool)); } diff --git a/lib/eslint.js b/lib/eslint.js index b6dd0af..9b339be 100644 --- a/lib/eslint.js +++ b/lib/eslint.js @@ -4,13 +4,13 @@ const path = require('path'); const tryFiles = require('./util/tryFiles'); const tryPackageJson = require('./util/tryPackageJson'); -function detectEslint(dir) { +function detectEslint(dir, loadPackageJson) { const paths = ['.eslintrc.js', '.eslintrc.yaml', '.eslintrc.yml', '.eslintrc.json', '.eslintrc'] .map((entry) => path.join(dir, entry)); return Promise.all([ tryFiles(paths), - tryPackageJson(dir, ['devDependencies.eslint', 'eslintConfig', 'eslintIgnore']), + tryPackageJson(loadPackageJson, ['devDependencies.eslint', 'eslintConfig', 'eslintIgnore']), ]) .then((booleans) => booleans.some((bool) => bool)); } diff --git a/lib/htmlhint.js b/lib/htmlhint.js index f9dcc03..bd8392b 100644 --- a/lib/htmlhint.js +++ b/lib/htmlhint.js @@ -4,13 +4,13 @@ const path = require('path'); const tryFiles = require('./util/tryFiles'); const tryPackageJson = require('./util/tryPackageJson'); -function detectHtmlHint(dir) { +function detectHtmlHint(dir, loadPackageJson) { const paths = ['.htmlhintrc'] .map((entry) => path.join(dir, entry)); return Promise.all([ tryFiles(paths), - tryPackageJson(dir, ['devDependencies.htmlhint']), + tryPackageJson(loadPackageJson, ['devDependencies.htmlhint']), ]) .then((booleans) => booleans.some((bool) => bool)); } diff --git a/lib/jscs.js b/lib/jscs.js index 017d709..02dd5ad 100644 --- a/lib/jscs.js +++ b/lib/jscs.js @@ -4,13 +4,13 @@ const path = require('path'); const tryFiles = require('./util/tryFiles'); const tryPackageJson = require('./util/tryPackageJson'); -function detectJscs(dir) { +function detectJscs(dir, loadPackageJson) { const paths = ['.jscsrc', '.jscs.json'] .map((entry) => path.join(dir, entry)); return Promise.all([ tryFiles(paths), - tryPackageJson(dir, ['jscsConfig']), + tryPackageJson(loadPackageJson, ['jscsConfig']), ]) .then((booleans) => booleans.some((bool) => bool)); } diff --git a/lib/jshint.js b/lib/jshint.js index d9b6d59..ce30104 100644 --- a/lib/jshint.js +++ b/lib/jshint.js @@ -4,13 +4,13 @@ const path = require('path'); const tryFiles = require('./util/tryFiles'); const tryPackageJson = require('./util/tryPackageJson'); -function detectJsHint(dir) { +function detectJsHint(dir, loadPackageJson) { const paths = ['.jshintrc'] .map((entry) => path.join(dir, entry)); return Promise.all([ tryFiles(paths), - tryPackageJson(dir, ['devDependencies.jshint', 'jshintConfig']), + tryPackageJson(loadPackageJson, ['devDependencies.jshint', 'jshintConfig']), ]) .then((booleans) => booleans.some((bool) => bool)); } diff --git a/lib/prettier.js b/lib/prettier.js index 9607da4..a061cfb 100644 --- a/lib/prettier.js +++ b/lib/prettier.js @@ -4,13 +4,13 @@ const path = require('path'); const tryFiles = require('./util/tryFiles'); const tryPackageJson = require('./util/tryPackageJson'); -function detectPrettierLint(dir) { +function detectPrettierLint(dir, loadPackageJson) { const paths = ['.prettierrc', '.prettierrc.yaml', '.prettierrc.yml', '.prettierrc.json', '.prettierrc.js', 'prettier.config.js'] .map((entry) => path.join(dir, entry)); return Promise.all([ tryFiles(paths), - tryPackageJson(dir, ['devDependencies.prettier', 'prettier']), + tryPackageJson(loadPackageJson, ['devDependencies.prettier', 'prettier']), ]) .then((booleans) => booleans.some((bool) => bool)); } diff --git a/lib/standard.js b/lib/standard.js index d1dc2c2..b9b7782 100644 --- a/lib/standard.js +++ b/lib/standard.js @@ -2,8 +2,8 @@ const tryPackageJson = require('./util/tryPackageJson'); -function detectStandardLint(dir) { - return tryPackageJson(dir, ['devDependencies.standard', 'standard']); +function detectStandardLint(dir, loadPackageJson) { + return tryPackageJson(loadPackageJson, ['devDependencies.standard', 'standard']); } module.exports = detectStandardLint; diff --git a/lib/stylelint.js b/lib/stylelint.js index 0d5321c..22a7b27 100644 --- a/lib/stylelint.js +++ b/lib/stylelint.js @@ -4,13 +4,13 @@ const path = require('path'); const tryFiles = require('./util/tryFiles'); const tryPackageJson = require('./util/tryPackageJson'); -function detectStyleLint(dir) { +function detectStyleLint(dir, loadPackageJson) { const paths = ['.stylelintrc.js', '.stylelintrc.yaml', '.stylelintrc.json', '.stylelintrc'] .map((entry) => path.join(dir, entry)); return Promise.all([ tryFiles(paths), - tryPackageJson(dir, ['devDependencies.stylelint', 'stylelint']), + tryPackageJson(loadPackageJson, ['devDependencies.stylelint', 'stylelint']), ]) .then((booleans) => booleans.some((bool) => bool)); } diff --git a/lib/tslint.js b/lib/tslint.js index fa3190e..4a2f39b 100644 --- a/lib/tslint.js +++ b/lib/tslint.js @@ -4,13 +4,13 @@ const path = require('path'); const tryFiles = require('./util/tryFiles'); const tryPackageJson = require('./util/tryPackageJson'); -function detectTsLint(dir) { +function detectTsLint(dir, loadPackageJson) { const paths = ['tslint.json'] .map((entry) => path.join(dir, entry)); return Promise.all([ tryFiles(paths), - tryPackageJson(dir, ['devDependencies.tslint']), + tryPackageJson(loadPackageJson, ['devDependencies.tslint']), ]) .then((booleans) => booleans.some((bool) => bool)); } diff --git a/lib/util/tryPackageJson.js b/lib/util/tryPackageJson.js index d589479..86ff06c 100644 --- a/lib/util/tryPackageJson.js +++ b/lib/util/tryPackageJson.js @@ -1,19 +1,15 @@ 'use strict'; -const path = require('path'); -const loadJsonFile = require('load-json-file'); const get = require('lodash.get'); -function tryPackageJson(dir, props) { - return loadJsonFile(path.join(dir, 'package.json')) - .then((json) => { - return props.some((prop) => get(json, prop)); - }, (err) => { - if (err.code === 'ENOENT') { +function tryPackageJson(loadPackageJson, props) { + return loadPackageJson() + .then((packageJson) => { + if (!packageJson) { return false; } - throw err; + return props.some((prop) => get(packageJson, prop)); }); } diff --git a/lib/xo.js b/lib/xo.js index 398d4ee..382b535 100644 --- a/lib/xo.js +++ b/lib/xo.js @@ -2,8 +2,8 @@ const tryPackageJson = require('./util/tryPackageJson'); -function detectXOLint(dir) { - return tryPackageJson(dir, ['devDependencies.xo', 'xo']); +function detectXOLint(dir, loadPackageJson) { + return tryPackageJson(loadPackageJson, ['devDependencies.xo', 'xo']); } module.exports = detectXOLint;