Skip to content

Commit

Permalink
Merge cd9d249 into 2e0ed83
Browse files Browse the repository at this point in the history
  • Loading branch information
benmosher committed May 17, 2018
2 parents 2e0ed83 + cd9d249 commit 3431027
Show file tree
Hide file tree
Showing 16 changed files with 215 additions and 51 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel

## [Unreleased]
### Added
- Ignore type imports for named rule ([#931], thanks [@mattijsbliek])
- Ignore type imports for [`named`] rule ([#931], thanks [@mattijsbliek])
- Add documentation for [`no-useless-path-segments`] rule ([#1068], thanks [@manovotny])


Expand Down Expand Up @@ -539,6 +539,7 @@ for info on changes for earlier releases.
[#912]: https://github.com/benmosher/eslint-plugin-import/pull/912

[#1058]: https://github.com/benmosher/eslint-plugin-import/issues/1058
[#931]: https://github.com/benmosher/eslint-plugin-import/issues/931
[#886]: https://github.com/benmosher/eslint-plugin-import/issues/886
[#863]: https://github.com/benmosher/eslint-plugin-import/issues/863
[#842]: https://github.com/benmosher/eslint-plugin-import/issues/842
Expand Down Expand Up @@ -714,3 +715,4 @@ for info on changes for earlier releases.
[@klimashkin]: https://github.com/klimashkin
[@lukeapage]: https://github.com/lukeapage
[@manovotny]: https://github.com/manovotny
[@mattijsbliek]: https://github.com/mattijsbliek
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ This plugin intends to support linting of ES2015+ (ES6+) import/export syntax, a
* Forbid webpack loader syntax in imports ([`no-webpack-loader-syntax`])
* Forbid a module from importing itself ([`no-self-import`])
* Forbid a module from importing a module with a dependency path back to itself ([`no-cycle`])
* Prevent unnecessary path segemnts in import and require statements ([`no-useless-path-segments`])
* Prevent unnecessary path segments in import and require statements ([`no-useless-path-segments`])

[`no-unresolved`]: ./docs/rules/no-unresolved.md
[`named`]: ./docs/rules/named.md
Expand Down Expand Up @@ -361,6 +361,7 @@ settings:
[`eslint_d`]: https://www.npmjs.com/package/eslint_d
[`eslint-loader`]: https://www.npmjs.com/package/eslint-loader


## SublimeLinter-eslint

SublimeLinter-eslint introduced a change to support `.eslintignore` files
Expand Down
7 changes: 7 additions & 0 deletions docs/rules/no-extraneous-dependencies.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ Also there is one more option called `packageDir`, this option is to specify the
"import/no-extraneous-dependencies": ["error", {"packageDir": './some-dir/'}]
```

It may also be an array of multiple paths, to support monorepos or other novel project
folder layouts:

```js
"import/no-extraneous-dependencies": ["error", {"packageDir": ['./some-dir/', './root-pkg']}]
```

## Rule Details

Given the following `package.json`:
Expand Down
26 changes: 12 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,11 @@
],
"scripts": {
"watch": "cross-env NODE_PATH=./src mocha --watch --compilers js:babel-register --recursive tests/src",
"cover": "gulp pretest && cross-env NODE_PATH=./lib istanbul cover --dir reports/coverage _mocha tests/lib/ -- --recursive -R progress",
"pretest": "linklocal",
"posttest": "eslint ./src",
"test": "cross-env BABEL_ENV=test NODE_PATH=./src nyc -s mocha -R dot --recursive tests/src -t 5s",
"test-compiled": "npm run prepublish && NODE_PATH=./lib mocha --compilers js:babel-register --recursive tests/src",
"coverage-report": "npm t && nyc report --reporter html",
"test-all": "npm test && for resolver in ./resolvers/*; do cd $resolver && npm test && cd ../..; done",
"ci-test": "eslint ./src && gulp pretest && cross-env NODE_PATH=./lib istanbul cover --report lcovonly --dir reports/coverage _mocha tests/lib/ -- --recursive --reporter dot",
"debug": "cross-env NODE_PATH=./lib mocha debug --recursive --reporter dot tests/lib/",
"prepublish": "gulp prepublish",
"coveralls": "nyc report --reporter lcovonly && cat ./coverage/lcov.info | coveralls"
},
Expand All @@ -48,12 +44,12 @@
},
"homepage": "https://github.com/benmosher/eslint-plugin-import",
"devDependencies": {
"babel-eslint": "next",
"babel-plugin-istanbul": "^2.0.1",
"babel-eslint": "8.0.x",
"babel-plugin-istanbul": "^4.1.6",
"babel-preset-es2015-argon": "latest",
"babel-register": "6.24.1",
"babel-register": "^6.26.0",
"babylon": "6.15.0",
"chai": "^3.4.0",
"chai": "^3.5.0",
"coveralls": "^3.0.0",
"cross-env": "^4.0.0",
"eslint": "2.x - 4.x",
Expand All @@ -62,18 +58,16 @@
"eslint-import-resolver-webpack": "file:./resolvers/webpack",
"eslint-module-utils": "file:./utils",
"eslint-plugin-import": "2.x",
"eslint-plugin-typescript": "^0.8.1",
"gulp": "^3.9.0",
"gulp-babel": "6.1.2",
"istanbul": "^0.4.0",
"linklocal": "^2.6.0",
"mocha": "^3.1.2",
"nyc": "^8.3.0",
"mocha": "^3.5.3",
"nyc": "^11.7.1",
"redux": "^3.0.4",
"rimraf": "^2.6.2",
"sinon": "^2.3.2",
"typescript": "^2.6.2",
"typescript-eslint-parser": "^12.0.0"
"typescript-eslint-parser": "^15.0.0"
},
"peerDependencies": {
"eslint": "2.x - 4.x"
Expand All @@ -95,6 +89,10 @@
"babel-register"
],
"sourceMap": false,
"instrument": false
"instrument": false,
"include": [
"src/",
"resolvers/"
]
}
}
11 changes: 9 additions & 2 deletions resolvers/node/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"index.js"
],
"scripts": {
"test": "nyc mocha"
"test": "nyc mocha",
"coveralls": "nyc report --reporter lcovonly && cd ../.. && coveralls < ./resolvers/node/coverage/lcov.info"
},
"repository": {
"type": "git",
Expand All @@ -32,7 +33,13 @@
},
"devDependencies": {
"chai": "^3.5.0",
"coveralls": "^3.0.0",
"mocha": "^3.5.3",
"nyc": "^10.3.2"
"nyc": "^11.7.1"
},
"nyc": {
"exclude": [
"test/"
]
}
}
30 changes: 24 additions & 6 deletions resolvers/webpack/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
var findRoot = require('find-root')
, path = require('path')
, get = require('lodash.get')
, get = require('lodash/get')
, isEqual = require('lodash/isEqual')
, find = require('array-find')
, interpret = require('interpret')
// not available on 0.10.x
, isAbsolute = path.isAbsolute || require('is-absolute')
, fs = require('fs')
, coreLibs = require('node-libs-browser')
, resolve = require('resolve')
Expand Down Expand Up @@ -56,7 +55,7 @@ exports.resolve = function (source, file, settings) {
if (!configPath || typeof configPath === 'string') {

// see if we've got an absolute path
if (!configPath || !isAbsolute(configPath)) {
if (!configPath || !path.isAbsolute(configPath)) {
// if not, find ancestral package.json and use its directory as base for the path
packageDir = findRoot(path.resolve(file))
if (!packageDir) throw new Error('package not found above ' + file)
Expand Down Expand Up @@ -105,7 +104,8 @@ exports.resolve = function (source, file, settings) {
}

// otherwise, resolve "normally"
var resolveSync = createResolveSync(configPath, webpackConfig)
var resolveSync = getResolveSync(configPath, webpackConfig)

try {
return { found: true, path: resolveSync(path.dirname(file), source) }
} catch (err) {
Expand All @@ -114,6 +114,24 @@ exports.resolve = function (source, file, settings) {
}
}

var MAX_CACHE = 10
var _cache = []
function getResolveSync(configPath, webpackConfig) {
var cacheKey = { configPath: configPath, webpackConfig: webpackConfig }
var cached = find(_cache, function (entry) { return isEqual(entry.key, cacheKey) })
if (!cached) {
cached = {
key: cacheKey,
value: createResolveSync(configPath, webpackConfig)
}
// put in front and pop last item
if (_cache.unshift(cached) > MAX_CACHE) {
_cache.pop()
}
}
return cached.value
}

function createResolveSync(configPath, webpackConfig) {
var webpackRequire
, basedir = null
Expand Down Expand Up @@ -316,7 +334,7 @@ function findConfigPath(configPath, packageDir) {
})

// see if we've got an absolute path
if (!isAbsolute(configPath)) {
if (!path.isAbsolute(configPath)) {
configPath = path.join(packageDir, configPath)
}
} else {
Expand Down
22 changes: 14 additions & 8 deletions resolvers/webpack/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"main": "index.js",
"scripts": {
"test": "nyc mocha -t 5s",
"report": "nyc report --reporter=html"
"report": "nyc report --reporter=html",
"coveralls": "nyc report --reporter lcovonly && cd ../.. && coveralls < ./resolvers/webpack/coverage/lcov.info"
},
"files": [
"index.js",
Expand Down Expand Up @@ -35,8 +36,7 @@
"find-root": "^1.1.0",
"has": "^1.0.1",
"interpret": "^1.0.0",
"is-absolute": "^0.2.3",
"lodash.get": "^4.4.2",
"lodash": "^4.17.4",
"node-libs-browser": "^1.0.0 || ^2.0.0",
"resolve": "^1.4.0",
"semver": "^5.3.0"
Expand All @@ -46,11 +46,17 @@
"webpack": ">=1.11.0"
},
"devDependencies": {
"babel-plugin-istanbul": "^4.1.5",
"babel-preset-es2015-argon": "^0.1.0",
"babel-plugin-istanbul": "^4.1.6",
"babel-preset-es2015-argon": "latest",
"babel-register": "^6.26.0",
"chai": "^3.4.1",
"mocha": "^2.3.3",
"nyc": "^7.0.0"
"chai": "^3.5.0",
"coveralls": "^3.0.0",
"mocha": "^3.5.3",
"nyc": "^11.7.1"
},
"nyc": {
"exclude": [
"test/"
]
}
}
3 changes: 2 additions & 1 deletion src/rules/no-anonymous-default-export.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/

import docsUrl from '../docsUrl'
import has from 'has'

const defs = {
ArrayExpression: {
Expand Down Expand Up @@ -65,7 +66,7 @@ const schemaProperties = Object.keys(defs)
const defaults = Object.keys(defs)
.map((key) => defs[key])
.reduce((acc, def) => {
acc[def.option] = def.hasOwnProperty('default') ? def.default : false
acc[def.option] = has(def, 'default') ? def.default : false
return acc
}, {})

Expand Down
72 changes: 57 additions & 15 deletions src/rules/no-extraneous-dependencies.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,73 @@
import path from 'path'
import fs from 'fs'
import { isArray, isEmpty } from 'lodash'
import readPkgUp from 'read-pkg-up'
import minimatch from 'minimatch'
import resolve from 'eslint-module-utils/resolve'
import importType from '../core/importType'
import isStaticRequire from '../core/staticRequire'
import docsUrl from '../docsUrl'

function hasKeys(obj = {}) {
return Object.keys(obj).length > 0
}

function extractDepFields(pkg) {
return {
dependencies: pkg.dependencies || {},
devDependencies: pkg.devDependencies || {},
optionalDependencies: pkg.optionalDependencies || {},
peerDependencies: pkg.peerDependencies || {},
}
}

function getDependencies(context, packageDir) {
let paths = []
try {
const packageContent = packageDir
? JSON.parse(fs.readFileSync(path.join(packageDir, 'package.json'), 'utf8'))
: readPkgUp.sync({cwd: context.getFilename(), normalize: false}).pkg
const packageContent = {
dependencies: {},
devDependencies: {},
optionalDependencies: {},
peerDependencies: {},
}

if (!packageContent) {
return null
if (!isEmpty(packageDir)) {
if (!isArray(packageDir)) {
paths = [path.resolve(packageDir)]
} else {
paths = packageDir.map(dir => path.resolve(dir))
}
}

return {
dependencies: packageContent.dependencies || {},
devDependencies: packageContent.devDependencies || {},
optionalDependencies: packageContent.optionalDependencies || {},
peerDependencies: packageContent.peerDependencies || {},
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
)
)
}

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

return packageContent
} catch (e) {
if (packageDir && e.code === 'ENOENT') {
if (!isEmpty(paths) && e.code === 'ENOENT') {
context.report({
message: 'The package.json file could not be found.',
loc: { line: 0, column: 0 },
Expand Down Expand Up @@ -66,9 +109,8 @@ function reportIfMissing(context, deps, depsOptions, node, name) {
}

const resolved = resolve(name, context)
if (!resolved) {
return
}
if (!resolved) { return }

const splitName = name.split('/')
const packageName = splitName[0][0] === '@'
? splitName.slice(0, 2).join('/')
Expand Down Expand Up @@ -124,7 +166,7 @@ module.exports = {
'devDependencies': { 'type': ['boolean', 'array'] },
'optionalDependencies': { 'type': ['boolean', 'array'] },
'peerDependencies': { 'type': ['boolean', 'array'] },
'packageDir': { 'type': 'string' },
'packageDir': { 'type': ['string', 'array'] },
},
'additionalProperties': false,
},
Expand Down
6 changes: 6 additions & 0 deletions tests/files/monorepo/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"private": true,
"devDependencies": {
"left-pad": "^1.2.0"
}
}
6 changes: 6 additions & 0 deletions tests/files/monorepo/packages/nested-package/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "nested-monorepo-pkg",
"dependencies": {
"react": "^16.0.0"
}
}
1 change: 1 addition & 0 deletions tests/files/node_modules/left-pad

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

1 change: 1 addition & 0 deletions tests/files/node_modules/react

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

Loading

0 comments on commit 3431027

Please sign in to comment.