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

Enable linter #67

Merged
merged 13 commits into from
Jul 7, 2021
Merged

Enable linter #67

merged 13 commits into from
Jul 7, 2021

Conversation

tuckerzp
Copy link
Contributor

This makes our code conform to the linter as much as possible. I have removed /*disable-linter*/ comments where they were not needed. This led to a lot of issues with the code to arise, so some of the logic had to be changed and cleaned up. .eslintignore and .eslintrc.json were both disabling parts of the linter that did not need to be disabled. Finally, package.json had to be changed to lint .test files.

Where and why linter is still disabled

  1. eslint no-param-reassign: "error"
    • This is done in: ComponentResolver, ProfileResolver, & SSPResolver.
    • Due to how we are using state and passing props, it would require a very large change to the code base to fix these linting issues. Instead of disabling large portions of the code, the linter is disabled for only a small segment.
  2. .eslintrc.json rules
    • Rules enabled:
      • react/jsx-filename-extension
      • react/prop-types
      • react/destructuring-assignment
      • react/jsx-props-no-spreading
      • prettier/prettier
    • Much like above, it would take a significant change of the code base to conform to these linter rules. prettier/prettier makes eslint play nice with prettier.

uuid's and keys

I also imported react-uuid to deal with places where generating keys is an issue. Specifically OSCALControl generating a list of OSCALControlParts is a situation where having a meaningful and unique key is difficult. A uuid acts as a next best solution for providing a key. This may be something to deal with better in a future issue or this PR. I was hoping to discuss this more with the PR.

@tuckerzp
Copy link
Contributor Author

tuckerzp commented Jun 29, 2021

I also thought it would be worthwhile to discuss linting practices now that our code should be in line with linter requirements.

Linting in the future

Writing code and fixing linting issues later on is not a very efficient way to use the linter. Like testing, I think it should be done as part of an issue not it's own issue. After working on this issue I think that some linter issues might just have to be ignored/disabled. When doing so, we should:

  1. Prefer eslint no-param-reassign: "error". Disabling multiple lines of code is not necessary and instead should be disabled by individual line.
  2. Document why it is needed to disable the linter either in comment or in PR.

<OSCALControlPart
part={part}
parameters={props.control.params}
implReqStatements={props.implReqStatements}
componentId={props.componentId}
control={props.control}
modifications={props.modifications}
// eslint-disable-next-line
key={`part-${index}`}
key={uuid(part)}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This map is what I am referring to with not having a great key to use for each OSCALControlPart created.

@kylelaker
Copy link
Contributor

What happened to package-lock.json?

@tuckerzp tuckerzp force-pushed the EGRC-412 branch 2 times, most recently from 45b1588 to ef93d7c Compare June 29, 2021 19:53
Copy link
Contributor

@hreineck hreineck left a comment

Choose a reason for hiding this comment

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

Looks good.

@@ -19,12 +19,15 @@ export default function OSCALSspResolveProfile(
if (!profileUrl.startsWith("http")) {
profileUrl = `${parentUrl}/../${profileUrl}`;
}

// Fixing linting error here would take significant change to codebase given how we use props.
/* eslint no-param-reassign: "error" */
Copy link
Contributor

Choose a reason for hiding this comment

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

If I understand correctly, this is necessary because we are overwriting the props that are passed into this component? If so, that could be something to fix in the future; React specifies that components should have read-only props.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@hreineck yes that is why it is necessary. @rgauss or @zclarkEDC can correct me here, but I think this is due to an intentional decision on how we interact with state. So potentially something we will just have without so very big changes.

Copy link
Contributor

Choose a reason for hiding this comment

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

@hreineck and @tuckerzp, we could look at havingOSCALSspResolveProfile return the resolved controls rather than adding them to the ssp object.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is that worth doing in this issue or another one? This is done in: ComponentResolver, ProfileResolver, & SSPResolver.

Copy link
Contributor

Choose a reason for hiding this comment

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

A separate issue please, thanks.

Copy link
Contributor

@kylelaker kylelaker left a comment

Choose a reason for hiding this comment

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

Lots of improvements here that I am very glad to see! Thank you for your work. I do have a few requests.

src/OSCALControl.js Outdated Show resolved Hide resolved
src/OSCALControlPart.js Outdated Show resolved Hide resolved
src/OSCALControlProse.js Outdated Show resolved Hide resolved
src/OSCALMetadata.js Outdated Show resolved Hide resolved
src/oscal-utils/OSCALControlResolver.js Outdated Show resolved Hide resolved
Comment on lines 11 to 22
// If the control isn't at the root level, it may be a subcontrol of it's parent;
// so for example, "ac-2.3" may be a child of "ac-2"
const isSubControl = (testControlId) => testControlId.includes(".");
if (isSubControl(controlId)) {
const parentControlId = controlId.split(".")[0];
const parentControl = findControlById(resolvedControls, parentControlId);
const subControl = findControlById(parentControl?.controls, controlId);

if (subControl) {
return subControl;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Is the complexity of this check worth the potential improvement in the case where it works? I'd be curious to see how often we end up having to fall through to the flatMap().find() step below. Always? Sometimes? Never? We may not know that. But we should somehow track this as a potentially overly complex and unnecessary performance improvement.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

From just testing default profile, I have found it did not have use the flatMap().find() at all. I also have not seen many examples, if any, where the control is not in the root level or a sub control of it's parent. I am leaning towards it being worth it but also am curious if there are examples that disprove what I am seeing.

Copy link
Contributor

Choose a reason for hiding this comment

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

The convention of 'subcontrols' having a '.' notation is 800-53-specific, but that is certainly the most used control framework in OSCAL at the moment.

As is, I don't believe this comprehensively address the specification since controls can have an unbounded depth, and we'd need to traverse that.

There probably aren't enough controls for performance to really be an issue with 800-53.

Please create a Jira issue to address an unbounded control depth and further investigate the solution in the future.

package.json Outdated Show resolved Hide resolved
@tuckerzp tuckerzp force-pushed the EGRC-412 branch 2 times, most recently from cfe1499 to 877b546 Compare June 30, 2021 17:57
src/OSCALControl.js Outdated Show resolved Hide resolved
@tuckerzp tuckerzp mentioned this pull request Jul 1, 2021
@tuckerzp tuckerzp requested a review from rgauss July 1, 2021 19:29
@kylelaker
Copy link
Contributor

While this looks good; I wonder whether it'd be easier to hold this until after #63 is merged. Feels easier to fix/move any lint errors than to ask to have the owner(s) of #63 resolve conflicts again

Copy link
Contributor

@rgauss rgauss left a comment

Choose a reason for hiding this comment

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

Follow up tasks, but the changes look good. Thanks!

@@ -11,7 +11,7 @@ import FolderIcon from "@material-ui/icons/Folder";
import { makeStyles } from "@material-ui/core/styles";
import OSCALControl from "./OSCALControl";

const useStyles = makeStyles((theme) => ({
const useStyles = makeStyles(() => ({
Copy link
Contributor

Choose a reason for hiding this comment

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

Did the linter complain about the theme not being used?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah it does not like unused vars.

color: "#d4d4d4",
};
}
if (props.control?.props?.find((property) => property.name === "status")) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like this needs a property.value === "withdrawn" check as well. Please raise a separate bug.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is being done in #127

src/OSCALMetadata.js Outdated Show resolved Hide resolved
Comment on lines 11 to 22
// If the control isn't at the root level, it may be a subcontrol of it's parent;
// so for example, "ac-2.3" may be a child of "ac-2"
const isSubControl = (testControlId) => testControlId.includes(".");
if (isSubControl(controlId)) {
const parentControlId = controlId.split(".")[0];
const parentControl = findControlById(resolvedControls, parentControlId);
const subControl = findControlById(parentControl?.controls, controlId);

if (subControl) {
return subControl;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

The convention of 'subcontrols' having a '.' notation is 800-53-specific, but that is certainly the most used control framework in OSCAL at the moment.

As is, I don't believe this comprehensively address the specification since controls can have an unbounded depth, and we'd need to traverse that.

There probably aren't enough controls for performance to really be an issue with 800-53.

Please create a Jira issue to address an unbounded control depth and further investigate the solution in the future.

@@ -19,12 +19,15 @@ export default function OSCALSspResolveProfile(
if (!profileUrl.startsWith("http")) {
profileUrl = `${parentUrl}/../${profileUrl}`;
}

// Fixing linting error here would take significant change to codebase given how we use props.
/* eslint no-param-reassign: "error" */
Copy link
Contributor

Choose a reason for hiding this comment

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

A separate issue please, thanks.

@rgauss
Copy link
Contributor

rgauss commented Jul 1, 2021

While this looks good; I wonder whether it'd be easier to hold this until after #63 is merged. Feels easier to fix/move any lint errors than to ask to have the owner(s) of #63 resolve conflicts again

Complete agree, please get #63 in first.

.eslintignore Outdated
Comment on lines 1 to 5
## uncomment this to disable linting
##src/**/*.js
src/serviceWorker.ts
src/oscal-utils/OSCALSspResolver.js
public/*
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd almost like to just remove this file and find another way to disable the linter when necessary

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That is a good point, but I believe #63 adds things to ignore again. I do not think we have completely resolved what is needed and what isn't, but it is safe to assume there will be something in the file after that is merged.

@tuckerzp
Copy link
Contributor Author

tuckerzp commented Jul 7, 2021

Changes from EGRC-168 are now merged into EGRC-412. It was a little wonky so I had to make changes to OSCALLoader & package*. I think it should be ready for one last review and to be merged.

Copy link
Member

@zclarkEDC zclarkEDC left a comment

Choose a reason for hiding this comment

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

Excellent work resolving the merge conflicts.

There were a few places where the linter was disabled unnecessarily.
Removing the /*disable*/ comment and doing minor formatting resolved
any issues the linter had originally.
There were multiple linter violations due to illegal function useage and
logic. Cleaning up these functions to be in accordance with style guide
makes code cleaner and keeps original functionality.
Linter checking for these issues was disabled. We renabled checking for
this issue and fixed problems that arose.
OSCALProfile was attempting to preform a React state update on an
unmounted component. This indicates a memory leak and caused the tests
to have warnings. We added a check to see if a component is mounted
before updating state.
OSCALControl was using an index as a key for each OSCALControlPart
created. This is advised against by react. The parts being mapped do not
have a clear id or field to use as a unique key. Using uuid is the next
best way of giving each child element of a list a unique key that
persists until the child is recreated.
A few changes were needed to make the code more elegant and readable. Using part.id
in OSCALControlPart when possible will also speed up the code.
Due to concern for preformace, index makes more sense to use than
generating a uuid for each part.
OSCALMetadata's getPartyRolesText function sometimes would try to use
filter() on null values.
EGRC-168 made some very major changes. In order to merge EGRC-412 into
develop, they had to be merged. Changes to OSCALLoader & the
package-lock files were also needed.
@tuckerzp
Copy link
Contributor Author

tuckerzp commented Jul 7, 2021

After another fun round of merge conflicts, I now am fairly certain we can review and merge.

Copy link
Contributor

@kylelaker kylelaker left a comment

Choose a reason for hiding this comment

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

Looks good! Thank you so much for your patience with all these rebases and conflicts. You've done a great job with this.

@kylelaker kylelaker merged commit 1ab856e into develop Jul 7, 2021
@kylelaker kylelaker deleted the EGRC-412 branch July 7, 2021 18:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants