Skip to content

Commit

Permalink
fix: allow packageDir and readPkgUp logic to play nice
Browse files Browse the repository at this point in the history
  • Loading branch information
Steven Hargrove committed May 18, 2018
1 parent ebafcbf commit bbb672a
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 51 deletions.
85 changes: 39 additions & 46 deletions src/rules/no-extraneous-dependencies.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import path from 'path'
import fs from 'fs'
import { isArray, isEmpty } from 'lodash'
import { get, set } from 'lodash'
import readPkgUp from 'read-pkg-up'
import minimatch from 'minimatch'
import resolve from 'eslint-module-utils/resolve'
Expand All @@ -21,67 +21,54 @@ function extractDepFields(pkg) {
}
}

function assignDeps(fromDeps, toDeps) {
Object.keys(toDeps).forEach((depType) => {
set(fromDeps, [depType], Object.assign(
get(fromDeps, [depType], {}),
get(toDeps, [depType], {})
))
})
}

function getDependencies(context, packageDir) {
let paths = []
try {
const packageContent = {
dependencies: {},
devDependencies: {},
optionalDependencies: {},
peerDependencies: {},
}

if (!isEmpty(packageDir)) {
if (!isArray(packageDir)) {
paths = [path.resolve(packageDir)]
} else {
paths = packageDir.map(dir => path.resolve(dir))
}
}
const closest = readPkgUp.sync({cwd: context.getFilename(), normalize: false})
const packageContent = [].concat(packageDir)
.reduce((allDeps, dir) => {
if (dir && dir !== closest.path) {
assignDeps(allDeps, extractDepFields(
JSON.parse(
fs.readFileSync(path.join(dir, 'package.json'), 'utf8')
)
))
}

if (!isEmpty(paths)) {
// use rule config to find package.json
paths.forEach(dir => {
Object.assign(packageContent, extractDepFields(
JSON.parse(fs.readFileSync(path.join(dir, 'package.json'), 'utf8'))
))
})
} else {
// use closest package.json
Object.assign(
packageContent,
extractDepFields(
readPkgUp.sync({cwd: context.getFilename(), normalize: false}).pkg
)
)
}
return allDeps
}, extractDepFields(closest.pkg))

if (![
if ([
packageContent.dependencies,
packageContent.devDependencies,
packageContent.optionalDependencies,
packageContent.peerDependencies,
].some(hasKeys)) {
return null
return packageContent
}

return packageContent
} catch (e) {
if (!isEmpty(paths) && e.code === 'ENOENT') {
if (e.name === 'JSONError' || e instanceof SyntaxError) {
context.report({
message: 'The package.json file could not be found.',
message: 'The package.json file could not be parsed: ' + e.message,
loc: { line: 0, column: 0 },
})
}
if (e.name === 'JSONError' || e instanceof SyntaxError) {
} else if (e.code === 'ENOENT') {
context.report({
message: 'The package.json file could not be parsed: ' + e.message,
message: 'The package.json file could not be found.',
loc: { line: 0, column: 0 },
})
}

return null
}

return null
}

function missingErrorMessage(packageName) {
Expand All @@ -99,6 +86,7 @@ function optDepErrorMessage(packageName) {
}

function reportIfMissing(context, deps, depsOptions, node, name) {
debugger;
// Do not report when importing types
if (node.importKind === 'type') {
return
Expand Down Expand Up @@ -142,10 +130,15 @@ function reportIfMissing(context, deps, depsOptions, node, name) {
}

function testConfig(config, filename) {

// Simplest configuration first, either a boolean or nothing.
if (typeof config === 'boolean' || typeof config === 'undefined') {
return config
if (!Array.isArray(config)) {
if (typeof config === 'undefined') {
return true
}
return !!config
}

// Array of globs.
return config.some(c => (
minimatch(filename, c) ||
Expand Down Expand Up @@ -175,13 +168,13 @@ module.exports = {

create: function (context) {
const options = context.options[0] || {}
const filename = context.getFilename()
const deps = getDependencies(context, options.packageDir)

if (!deps) {
return {}
}

const filename = context.getFilename()
const depsOptions = {
allowDevDeps: testConfig(options.devDependencies, filename) !== false,
allowOptDeps: testConfig(options.optionalDependencies, filename) !== false,
Expand Down
14 changes: 9 additions & 5 deletions tests/src/rules/no-extraneous-dependencies.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@ ruleTester.run('no-extraneous-dependencies', rule, {
code: 'import leftpad from "left-pad";',
options: [{packageDir: packageDirMonoRepoRoot}],
}),
test({
code: 'import leftPad from "left-pad";',
filename: path.join(packageDirMonoRepoWithNested, 'foo.js'),
options: [{packageDir: packageDirMonoRepoRoot}],
}),
],
invalid: [
test({
Expand Down Expand Up @@ -243,24 +248,23 @@ ruleTester.run('no-extraneous-dependencies', rule, {
options: [{packageDir: packageDirMonoRepoWithNested}],
errors: [{
ruleId: 'no-extraneous-dependencies',
message: "'left-pad' should be listed in the project's dependencies. Run 'npm i -S left-pad' to add it",
message: '\'left-pad\' should be listed in the project\'s dependencies. Run \'npm i -S left-pad\' to add it',
}],
}),
test({
code: 'import react from "react";',
filename: path.join(packageDirMonoRepoRoot, 'foo.js'),
errors: [{
ruleId: 'no-extraneous-dependencies',
message: "'react' should be listed in the project's dependencies. Run 'npm i -S react' to add it",
message: '\'react\' should be listed in the project\'s dependencies. Run \'npm i -S react\' to add it',
}],
}),
test({
code: 'import react from "react";',
code: 'import leftPad from "left-pad";',
filename: path.join(packageDirMonoRepoWithNested, 'foo.js'),
options: [{packageDir: packageDirMonoRepoRoot}],
errors: [{
ruleId: 'no-extraneous-dependencies',
message: "'react' should be listed in the project's dependencies. Run 'npm i -S react' to add it",
message: '\'left-pad\' should be listed in the project\'s dependencies. Run \'npm i -S left-pad\' to add it',
}],
}),
]
Expand Down

0 comments on commit bbb672a

Please sign in to comment.