-
Notifications
You must be signed in to change notification settings - Fork 3k
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
[HOLD for payment 2023-04-03] [$4000] New Lint Rule: onyx-props-must-have default #14309
Comments
@roryabraham the |
Job added to Upwork: https://www.upwork.com/jobs/~0188c3bb2e4ac48bf8 |
Triggered auto assignment to @tjferriss ( |
Triggered auto assignment to Contributor-plus team member for initial proposal review - @mollfpr ( |
Triggered auto assignment to @grgia ( |
Proposal:We should create a custom linter to check the following:
To accomplish this, we will:
Linter code :const PropTypes = require('prop-types');
module.exports = {
create: context => ({
CallExpression(node) {
if (node.callee.name !== 'withOnyx') {
return;
}
const wrappedComponent = node.arguments[0];
let propTypes, defaultProps, componentName;
if (wrappedComponent.type === "ClassExpression") {
propTypes = wrappedComponent.body.body.find(
(m) => m.key.name === "propTypes"
);
defaultProps = wrappedComponent.body.body.find(
(m) => m.key.name === "defaultProps"
);
componentName = wrappedComponent.id.name;
} else {
propTypes = wrappedComponent.propTypes;
defaultProps = wrappedComponent.defaultProps;
componentName = wrappedComponent.displayName || wrappedComponent.name;
}
if (node.arguments.length === 0) {
context.report({
node,
message: `withOnyx must be passed a component`
});
}
node.arguments[1].properties.forEach(({ key, value }) => {
if (!propTypes[key.name]) {
context.report({
node,
message: `Prop '${key.name}' is not defined in propTypes for component ${componentName}`
});
return;
}
if (!defaultProps[key.name]) {
context.report({
node,
message: `Prop '${key.name}' has no default value for component ${componentName}`
});
}
if (propTypes[key.name].isRequired ) {
context.report({
node,
message: `Prop '${key.name}' is required in propTypes for component ${componentName} `
});
});
},
}),
}; |
ProposalBackgroundIt is not safe to assume that props provided by withOnyx can be required. Thus, we need to create a eslint rule that will report if any of the props passed to
SolutionWe need to create a rule in
My solution covers for all the occurrences of this issue in the repository, including the ones mentioned in the Slack thread WorkflowThe steps with ensures in bold signify that the check is reported as well.
Rule Impact on current codebaseTo implement this standard in the current codebase, once the PR for the fix has been merged, the following needs to be done-
CodeFor better visibility and readability, have commited the code to my fork. TestsTo test for the various cases covered by this rule, I've added the test rules to |
I don't think we can cover cases where the value is imported from another file.
|
@ahmdshrif @Prince-Mendiratta How do you guys test the local eslint config? My npm is doesn't install the package that required from |
@mollfpr Hey! To test out the rule,
If you personally want to make any changes and see their effect, you can do so by directly modifying the source code in |
Thanks a lot @Prince-Mendiratta! |
After checking out all the reported rules, a couple of edge cases I'd like to mention - Imports prop types and default props from an external file.Something like this -
withOnyx() call has a key as an arrayApp/src/components/createOnyxContext.js Lines 23 to 27 in 7ca2979
This is the only occurrence of this issue. Prop types and Default props have been declared but have a different variable nameApp/src/components/withCurrentUserPersonalDetails.js Lines 8 to 14 in 7ca2979
The rule specifically triggers on the variable name propTypes and defaultProps .Other occurrences - https://github.com/Expensify/App/blob/main/src/pages/workspace/withPolicy.js Prop types declared inside a functionhttps://github.com/Expensify/App/blob/main/src/pages/home/report/withReportOrNavigateHome.js#L10-L26 SolutionThese are the few false negatives I was able to find by initially combing through the reported errors by the config. To fix these, we can take either of the following approaches: Ignore the rule for specific componentsThis can be used for Problem 2 and Problem 4. Standardize coding style according to expectations set by rule.This can be done for Problem 1 and Problem 3 Read prop types from external fileThe rule can be modified to get the prop variables from Imported files, if they are not declared inside the component itself. This can be a nested condition such that the rule first checks for prop variables declared inside the component and if not found, check for externally imported declaration of prop variables. However, we should decide on a fix pattern for this. |
Thanks for the proposal @ahmdshrif @Prince-Mendiratta! @ahmdshrif I can't run your code, I got the above error after creating the rule suggested. Can you update your solution? |
@Prince-Mendiratta I think the rule should be applied too for HOC that use
Could you update your solution to work with this? We have a lot of components that use imported propTypes/defaultProps for DRY's sake.
I do not understand what we should do here. |
These are the only HOCs that make use of
Sure! I'll create update and ping you here once I'm done.
Had something else in mind, doesn't look relevant anymore. please ignore this haha |
Just checking in, do you have an update on your proposal? @Prince-Mendiratta |
Hi, @mollfpr. I've been working on it, trying to work with externally declared propTypes turned out to be more complex than I expected, I'm exploring all the possible ways to go ahead with this to get the maximum coverage of components in an efficient manner. I'm trying to create a single rule that'll work for all components instead of a different rule for HOCs. Rest assured, I've made much progress and will share an updated proposal soon! |
Thanks for the update @Prince-Mendiratta! |
Not overdue, I believe PR is in the works |
Heyy @Prince-Mendiratta any update on the work in progress PR? |
PR is ready for review! Sorry for the delay and thank you for your patience. |
Well done @Prince-Mendiratta! I'll review it tonight! |
@tjferriss, @mollfpr, @grgia, @Prince-Mendiratta Whoops! This issue is 2 days overdue. Let's get this updated quick! |
@mollfpr have you had a chance to review the PR? |
@tjferriss Yup, just need to do the final review! |
@tjferriss, @mollfpr, @grgia, @Prince-Mendiratta Whoops! This issue is 2 days overdue. Let's get this updated quick! |
PR is in under testing phase. |
With the rule merged, sent in a disclaimer about the update on slack! |
|
The solution for this issue has been 🚀 deployed to production 🚀 in version 1.2.89-0 and is now subject to a 7-day regression period 📆. Here is the list of pull requests that resolve this issue: If no regressions arise, payment will be issued on 2023-04-03. 🎊 After the hold period is over and BZ checklist items are completed, please complete any of the applicable payments for this issue, and check them off once done.
As a reminder, here are the bonuses/penalties that should be applied for any External issue:
|
Hello, while this is under the regression phase, I'd like to request a bounty reconsidering, considering the scope and complexity of the issue. Can you please discuss this internally and let me know if it'd be possible? Thanks. |
@Prince-Mendiratta thanks for sharing the feedback. I shared your request internally and ultimately we feel the current $4k bounty is fair for the work completed. |
Noted, thank you @tjferriss! |
Payments have been made! |
If you haven’t already, check out our contributing guidelines for onboarding and email contributors@expensify.com to request to join our Slack channel!
Action Performed:
withOnyx
HOCExpected Result:
The lint rule should catch this and insist than any props originating from
withOnyx
be optional and provide a default.Actual Result:
n/a – nothing happens right now
Workaround:
n/a
Issue reported by: @roryabraham
Slack conversation: https://expensify.slack.com/archives/C01GTK53T8Q/p1673645106127709?thread_ts=1673641691.365339&cid=C01GTK53T8Q
View all open jobs on GitHub
Upwork Automation - Do Not Edit
The text was updated successfully, but these errors were encountered: