-
Notifications
You must be signed in to change notification settings - Fork 887
resolve rulesDirectory - fixes #2163 #2358
resolve rulesDirectory - fixes #2163 #2358
Conversation
Would be great if this could work with the This may conflict with the module resolution that is done for finding configs, though. |
I'm not sure if this would be a good addition. AFAIK |
Sorry for the delayed response.
I get your point, but then there is this commit by @jkillian which suggests adding an (empty) That's how the configuration directory is resolved. As a bonus that wouldn't add another dependency, because we can simply use https://www.npmjs.com/package/resolve for both. |
Additions to my last comment:
that's not entirely true. you can still use @donaldpipowitch you should also check the path first before resolving as package. When the path starts with And there need to be tests for this new feature. The best place to start is |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with @ajafff on most of those points ^
also, yeah, needs tests :)
Cool. Thank you both for the good feedback. I'll try to make the changes in the next days :) |
f4c8d0e
to
c2e1ad7
Compare
I updated my PR. The logic for resolving the directory is now inside
I did all that. I tested this with the
Can you give me more guidance to test this? Do I need to mock a 3rd party node module to do that correctly? |
There is already. |
src/configuration.ts
Outdated
@@ -277,6 +277,12 @@ export function getRelativePath(directory?: string | null, relativeTo?: string) | |||
return undefined; | |||
} | |||
|
|||
// check if directory should be used as path or if it should be resolved like a module | |||
export function useAsPath(directory: string) { | |||
return directory.startsWith("/") || directory.startsWith("./") || directory.startsWith("../") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should probably include paths starting with node_modules/
to simplify the check, you can use this regex:
/^(?:\.?\.?(?:\/|$)|node_modules\/)/.test(directory)
src/configuration.ts
Outdated
try { | ||
absolutePath = resolve.sync(dir, { basedir: relativeTo }).replace("index.js", ""); | ||
} catch (err) { | ||
throw new Error(`Could not find custom rule directory: ${dir}`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of throwing here, it should fall back using path as directory
src/configuration.ts
Outdated
} | ||
} else { | ||
try { | ||
absolutePath = resolve.sync(dir, { basedir: relativeTo }).replace("index.js", ""); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just to be safe, because the path may include index.js earlier: .replace(/index.js$/, "")
src/configuration.ts
Outdated
return arrayify(directories) | ||
.map((dir) => { | ||
let absolutePath; | ||
if (useAsPath(dir)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to avoid code duplication, consider writing it as follows:
if (!useAsPath(dir)) {
try {
return resolve.sync(...).replace(...);
} catch (err) {
// swallow error and fallback to using directory as path
}
}
const absolutePath = getRelativePath(...);
if (absolutePath != null) {
...
}
return absolutePath;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
Is this fine now? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Almost done, I had only a few things to comment.
In addition this feature needs a bit of documentation.
https://github.com/palantir/tslint/blob/master/docs/usage/configuration/index.md should contain some information that rulesDirectory
tries to resolve to a package in node_modules.
It should also suggest prefixing relative paths with ./
to avoid module resolution.
@@ -0,0 +1,3 @@ | |||
{ | |||
"rulesDirectory": ["tslint-test-custom-rules/rules"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should also have tests to ensure that the fallback works. for that you can simply add an entry like "test/external/tslint-test-custom-rules/rules"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
btw. the package tslint-test-custom-rules
needs a index.js
in its rules
directory
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to add a test, but didn't use "test/external/tslint-test-custom-rules/rules"
, because it would throw. I'm not sure, this works now as you expected...?
src/configuration.ts
Outdated
.map((dir) => { | ||
if (!useAsPath(dir)) { | ||
try { | ||
return resolve.sync(dir, { basedir: relativeTo }).replace(/index.js$/, ""); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if main
in package.json does not point to a file called index.js
, this will not quite work. maybe we should use path.dirname(...)
instead of .replace(...)
988e987
to
dd60d03
Compare
dd60d03
to
c45072f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bear with me, I hope that's the last iteration
@@ -0,0 +1,3 @@ | |||
{ | |||
"rulesDirectory": ["../external/tslint-test-custom-rules/rules"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually I wanted a test where the path was relative but did not start with ./
or ../
Consider adding a folder test/config/relativeRulesDirectory
and change this line to "rulesDirectory": ["relativeRulesDirectory"]
test/configurationTests.ts
Outdated
@@ -252,6 +252,11 @@ describe("Configuration", () => { | |||
assert.equal("off", config.rules.get("no-eval")!.ruleSeverity); | |||
}); | |||
|
|||
it("resolve rule directory from package", () => { | |||
assert.doesNotThrow(() => loadConfigurationFromPath("./test/config/tslint-custom-rules-with-package.json")); | |||
assert.doesNotThrow(() => loadConfigurationFromPath("./test/config/tslint-custom-rules-with-package-fallback.json")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
consider checking if it resolved to the expected rulesDirectory
in both cases
@ajafff Thank you for reviewing this :) I updated the tests. I think it looks good now. |
PR checklist
Overview of change:
When someone uses a
rulesDirectory
we try to resolve it with Node resolve logic first, before falling back to the old algorithm.CHANGELOG.md entry:
~[enhancement]
rulesDirectory
can now be resolved withdir-resolve
(#2163)~~[enhancement]
rulesDirectory
can now be resolved with Nodes resolve logic, if the directory contains anindex.js
(#2163)