Use require.resolve as a fallback of path.resolve (#342)

This commit is contained in:
Alexander Kachkaev 2020-10-22 04:40:54 +01:00 committed by David Anson
parent bc0b7373ff
commit 4bff44e33f
9 changed files with 5672 additions and 8 deletions

View file

@ -27,8 +27,8 @@ jobs:
- name: Install Dependencies - name: Install Dependencies
run: npm install --no-package-lock run: npm install --no-package-lock
- name: Run All Validations - name: Run All Validations
if: ${{ matrix.node-version != '10.x' }} if: ${{ matrix.node-version == '14.x' }}
run: npm run ci run: npm run ci
- name: Run Tests Only - name: Run Tests Only
if: ${{ matrix.node-version == '10.x' }} if: ${{ matrix.node-version != '14.x' }}
run: npm run test run: npm run test

1
.gitignore vendored
View file

@ -4,6 +4,7 @@ demo/markdownlint-browser.min.js
demo/markdownlint-rule-helpers-browser.js demo/markdownlint-rule-helpers-browser.js
lib-es3 lib-es3
node_modules node_modules
!test/node_modules
npm-debug.log npm-debug.log
test-repos test-repos
.vscode .vscode

View file

@ -894,6 +894,34 @@ function parseConfiguration(name, content, parsers) {
}; };
} }
/**
* Resolve referenced "extends" path in a configuration file
* using path.resolve() and require.resolve() as a fallback.
*
* @param {string} configFile Configuration file name.
* @param {string} referenceId Referenced identifier to resolve.
* @returns {string} Resolved path to file.
*/
function resolveConfigExtends(configFile, referenceId) {
const configFileDirname = path.dirname(configFile);
const resolvedExtendsFile = path.resolve(configFileDirname, referenceId);
try {
if (fs.statSync(resolvedExtendsFile).isFile()) {
return resolvedExtendsFile;
}
// eslint-disable-next-line unicorn/prefer-optional-catch-binding
} catch (error) {
// If fs.statSync has thrown, trying require.resolve
}
try {
return require.resolve(referenceId, { "paths": [ configFileDirname ] });
// eslint-disable-next-line unicorn/prefer-optional-catch-binding
} catch (error) {
// If require.resolve throws, returning resolvedExtendsFile for BC
}
return resolvedExtendsFile;
}
/** /**
* Read specified configuration file. * Read specified configuration file.
* *
@ -924,8 +952,8 @@ function readConfig(file, parsers, callback) {
const configExtends = config.extends; const configExtends = config.extends;
if (configExtends) { if (configExtends) {
delete config.extends; delete config.extends;
const extendsFile = path.resolve(path.dirname(file), configExtends); const resolvedExtends = resolveConfigExtends(file, configExtends);
return readConfig(extendsFile, parsers, (errr, extendsConfig) => { return readConfig(resolvedExtends, parsers, (errr, extendsConfig) => {
if (errr) { if (errr) {
return callback(errr); return callback(errr);
} }
@ -973,11 +1001,9 @@ function readConfigSync(file, parsers) {
const configExtends = config.extends; const configExtends = config.extends;
if (configExtends) { if (configExtends) {
delete config.extends; delete config.extends;
const resolvedExtends = resolveConfigExtends(file, configExtends);
return { return {
...readConfigSync( ...readConfigSync(resolvedExtends, parsers),
path.resolve(path.dirname(file), configExtends),
parsers
),
...config ...config
}; };
} }

5590
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,4 @@
{
"extends": "@oops/markdownlint-config",
"default": true
}

View file

@ -0,0 +1,7 @@
{
"extends": "pseudo-package",
"MD003": false,
"MD007": { "indent": 4 },
"no-hard-tabs": true,
"line-length": { "line_length": 200 }
}

View file

@ -1037,6 +1037,21 @@ tape("configMultiple", (test) => {
}); });
}); });
tape("configMultipleWithRequireResolve", (test) => {
test.plan(2);
markdownlint.readConfig("./test/config/config-packageparent.json",
function callback(err, actual) {
test.ifError(err);
const expected = {
...require("./node_modules/pseudo-package/config-frompackage.json"),
...require("./config/config-packageparent.json")
};
delete expected.extends;
test.deepEqual(actual, expected, "Config object not correct.");
test.end();
});
});
tape("configBadFile", (test) => { tape("configBadFile", (test) => {
test.plan(4); test.plan(4);
markdownlint.readConfig("./test/config/config-badfile.json", markdownlint.readConfig("./test/config/config-badfile.json",
@ -1064,6 +1079,20 @@ tape("configBadChildFile", (test) => {
}); });
}); });
tape("configBadChildPackage", (test) => {
test.plan(4);
markdownlint.readConfig("./test/config/config-badchildpackage.json",
function callback(err, result) {
test.ok(err, "Did not get an error for bad child file.");
test.ok(err instanceof Error, "Error not instance of Error.");
// @ts-ignore
test.equal(err.code, "ENOENT",
"Error code for bad child file not ENOENT.");
test.ok(!result, "Got result for bad child file.");
test.end();
});
});
tape("configBadJson", (test) => { tape("configBadJson", (test) => {
test.plan(3); test.plan(3);
markdownlint.readConfig("./test/config/config-badjson.json", markdownlint.readConfig("./test/config/config-badjson.json",

View file

@ -0,0 +1,4 @@
{
"no-hard-tabs": false,
"whitespace": false
}

3
test/node_modules/pseudo-package/package.json generated vendored Normal file
View file

@ -0,0 +1,3 @@
{
"main": "config-frompackage.json"
}