-
Notifications
You must be signed in to change notification settings - Fork 37
[package-json-lint] Add rule for hard coded dependencies in module and devModule. #704
Conversation
@@ -2,5 +2,6 @@ module.exports = { | |||
rules: { | |||
'require-no-terra-base-peer-dependency-versions': 'warn', | |||
'require-theme-context-versions': 'warn', | |||
'require-no-hard-coded-dependency-versions': 'warn', |
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 actually think we should start this as an error out of the gate.
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.
Updated here cc6d1e0.
But now the build will fail due to hardcoded dependencies in these packages:
eslint-config-terra
jest-config-terra
terra-function-testing
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 updating these packages with no hard-coded dependencies.
At least in terra-toolkit only eslint-config-terra
is causing a fail (Note: Currently we are using 7.22.0). As the latest released version of [email protected]
, throws an error no prop-validation of children prop
. But that will be fixed in either 7.25.2 or 7.26.0
, as per their changelog eslint-plugin-react
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.
Ahh I see. I think in the long run, we'll want consumers to be able to allow for these types of situations. Do you think it would be possible to allow for something like this in the config?
"package-json-lint": {
"extends": "package-json-lint.config",
"projectType": "devModule",
"rules": {
"require-no-hard-coded-dependency-versions": ["error", { "allowList": "eslint-plugin-react" }]
}
},
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.
What I am thinking is, we can change the structure of severity for all the rules to something like this:
"require-no-hard-coded-dependency-versions": {"severityType": "error", "allowList": ["eslint-plugin-react"] }
This will allow us to have more consistent structure for all the rules. What do you think?
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.
Let's go with your suggestion. What I had suggested was something that eslint does, but I think we can go our own way with this.
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.
Updated here dfc30a5
const currentProblems = Object.keys(dependencies).map(dependencyName => { | ||
const dependencyVersion = dependencies[dependencyName]; | ||
if (!dependencyVersion.startsWith('^') && !(ruleConfig.severity.allowList && ruleConfig.severity.allowList.includes(dependencyName))) { | ||
return `${dependencyName}@${dependencyVersion} does not satisfy requirement for ${messageString}`; |
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.
Should we update messageString
to call out which rule it does not satisfy instead of no hard coded dependency
?
${dependencyName}@${dependencyVersion} does not satisfy requirement for the require-no-hard-coded-dependency-versions rule;
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 add documentation for each rule explaining why we set it up and what problems it helps teams avoid.
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.
Should we update messageString to call out which rule it does not satisfy instead of no hard coded dependency?
Updated here b3446c5.
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.
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.
Added documentation here 0095a1f
packages/package-json-lint/src/rules/require-no-hard-coded-dependency-versions.js
Outdated
Show resolved
Hide resolved
const messageString = 'no hard coded dependency'; | ||
const currentProblems = Object.keys(dependencies).map(dependencyName => { | ||
const dependencyVersion = dependencies[dependencyName]; | ||
if (!dependencyVersion.startsWith('^') && !(ruleConfig.severity.allowList && ruleConfig.severity.allowList.includes(dependencyName))) { |
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.
Some project dependencies may look like this that could reference a range, the latest snapshot, or renaming the dependency where ^
is not always the first character. Is the recommendation for teams to just add such dependencies in the allowList or should the rule handle some of these less common cases?
"blood-loss-calculator-js": ">= 2.3.0-dev.0 <2.3.0-dev.x"
"ion-provider-relationship-js": "master"
"procedures-js": "dev"
"real-wicg-inert": "npm:wicg-inert@^3.0.2"
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 have added a compatibility regex array, through which we can check whether the dependency is hardcoded or not. Added here b3446c5.
Do let me know if I missed any scenarios. Thanks
@@ -40,7 +40,7 @@ | |||
"@jest/reporters": "^25.3.0", | |||
"babel-jest": "^26.6.3", | |||
"identity-obj-proxy": "^3.0.0", | |||
"jest-environment-jsdom": "26.6.2", | |||
"jest-environment-jsdom": "^26.6.2", |
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 could not tell you why i locked this down, or if it was a mistake. 🤷♂️
const messageString = 'require-no-hard-coded-dependency-versions'; | ||
const currentProblems = Object.keys(dependencies).map(dependencyName => { | ||
const dependencyVersion = dependencies[dependencyName]; | ||
const isCompatibleVersion = compatibleVersionRegexList.map(versionRegex => (!!dependencyVersion.match(versionRegex))).includes(true); |
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 did a little digging with semver. I wonder if we can say:
const isCompatibleVersion = semver.clean(version) === null;
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.
It doesn't look like semver.clean can handle ranges so syntax like ">= 2.3.0-dev.0 <2.3.0-dev.x"
or even just 2.3.0-dev.x
would not work so we may still need to handle those separately.
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 think it’ll handle them fine. We want them to return undefined or null. Basically anything but a solitary version should return null or undefined by the clean function. Thus they will be accepted
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.
@benbcai,
semver.clean
works for >= 2.3.0-dev.0 <2.3.0-dev.x
. And it will work if it has < >
symbols.
It only doesn't work for 2.3.0-dev.x
as this seems to be a fixed version.
If we are sure about it's going to be dev.x or branch.x
, we can add it as an exception and have a check for it using regex.
What do you think? @ryanthemanuel @benbcai
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.
2.3.0-dev.x will only resolve to a version that is released as 2.3.0-dev.x so this is effectively hard coded. I think it's fine to not allow this.
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.
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 confused myself at first but after thinking thru this again, it all makes sense now.
Removed extension from the import.
….com/cerner/terra-toolkit into add-rule-for-hard-coded-dependencies
Co-authored-by: Akarsh Shetty <[email protected]>
Summary
This PR adds the rule
require-no-hard-coded-dependency-versions
, to not allow any hardcoded dependencies inmodule
ordevModule
.Closes: #697
Additional Details
@cerner/terra