Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: Ensure config extends reads from the right spot (fixes #5450) #6468

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
35 changes: 30 additions & 5 deletions lib/config/config-file.js
Expand Up @@ -377,18 +377,35 @@ function applyExtends(config, filePath, relativeTo) {
parentPath = path.resolve(__dirname, "../../conf/eslint-all.js");
} else if (isFilePath(parentPath)) {

debug("parentPath before:" + parentPath);

/*
* If the `extends` path is relative, use the directory of the current configuration
* file as the reference point. Otherwise, use as-is.
*/
parentPath = (!isAbsolutePath(parentPath) ?
path.join(relativeTo || path.dirname(filePath), parentPath) :
parentPath
);
if (!isAbsolutePath(parentPath)) {
var dirname = path.dirname(filePath);

/*
* Special case: if filePath is a package name (such as "foo" for eslint-config-foo)
* then dirname will end up as just ".". When you pass "." into path.join(), it is
* treated differently so if parentPath is "./foo.js" it becomes "foo.js". When that
* happens, the rest of the logic breaks because "foo.js" looks like a package name.
* So, we have to just not do the join in that situation. See:
* https://github.com/eslint/eslint/issues/6450
* https://github.com/eslint/eslint/issues/6358
*/
if (dirname !== ".") {
parentPath = path.join(dirname, parentPath);
}

}

debug("parentPath after:" + parentPath);
}

try {
debug("Loading " + parentPath);
debug("Loading " + parentPath + " relative to " + relativeTo);
return ConfigOps.merge(load(parentPath, false, relativeTo), previousValue);
} catch (e) {

Expand Down Expand Up @@ -460,11 +477,16 @@ function normalizePackageName(name, prefix) {
* @private
*/
function resolve(filePath, relativeTo) {
debug("resolve(): " + filePath + "," + relativeTo);

if (isFilePath(filePath)) {
debug("Path to resolve is a file path:" + filePath);
return { filePath: path.resolve(relativeTo || "", filePath) };
} else {
var normalizedPackageName;

debug("filePath " + filePath + " is not a filepath, must be a package name");

if (filePath.indexOf("plugin:") === 0) {
var packagePath = filePath.substr(7, filePath.lastIndexOf("/") - 7);
var configName = filePath.substr(filePath.lastIndexOf("/") + 1, filePath.length - filePath.lastIndexOf("/") - 1);
Expand Down Expand Up @@ -493,6 +515,9 @@ function resolve(filePath, relativeTo) {
* @private
*/
function load(filePath, applyEnvironments, relativeTo) {

debug("load(): " + filePath + ", " + relativeTo);

var resolvedPath = resolve(filePath, relativeTo),
dirname = path.dirname(resolvedPath.filePath),
basedir = getBaseDir(dirname),
Expand Down
@@ -0,0 +1,3 @@
{
"extends": "./node_modules/eslint-config-a/index.js"
}
17 changes: 16 additions & 1 deletion tests/lib/config/config-file.js
Expand Up @@ -642,7 +642,7 @@ describe("ConfigFile", function() {
});
});

it("should load information from `extends` chain with relative path.", function() {
it("should load information from `extends` chain in .eslintrc with relative path.", function() {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was a duplicate test name, which caused trouble while I was trying to debug.

var config = ConfigFile.load(getFixturePath("extends-chain-2/.eslintrc.json"));

assert.deepEqual(config, {
Expand All @@ -657,6 +657,21 @@ describe("ConfigFile", function() {
});
});

it("should load information from `extends` chain in non-.eslintrc file with relative path.", function() {
var config = ConfigFile.load(getFixturePath("extends-chain-2/relative.eslintrc.json"));

assert.deepEqual(config, {
env: {},
extends: "./node_modules/eslint-config-a/index.js",
globals: {},
parserOptions: {},
rules: {
a: 2, // from node_modules/eslint-config-a/index.js
relative: 2 // from node_modules/eslint-config-a/relative.js
}
});
});

describe("Plugins", function() {

it("should load information from a YML file and load plugins", function() {
Expand Down