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

feat: data-codemods cleanup rule #745

Merged
merged 6 commits into from
Aug 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions packages/eslint-plugin-pf-codemods/src/ruleCuration.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { version } from "typescript";
import { betaRuleNames, warningRules } from "./ruleCustomization";
import { join } from "path";

Expand Down Expand Up @@ -27,13 +26,14 @@ const createListOfRules = (version: string, includeBeta = false) => {
}
}
});

return rules;
};

export const v6rules = createListOfRules("6");
export const v5rules = createListOfRules("5");
export const v4rules = createListOfRules("4");
export const betaV6Rules = createListOfRules("6", true);
export const betaV5Rules = createListOfRules("5", true);

const createRules = (rules: Rules) => {
Expand All @@ -52,7 +52,13 @@ export const mappedRules = {
...createRules(v4rules),
};

export const rules = { ...v6rules, ...v5rules, ...v4rules, ...betaV5Rules };
export const rules = {
...v6rules,
...v5rules,
...v4rules,
...betaV6Rules,
...betaV5Rules,
};

export const ruleVersionMapping = {
v4: Object.keys(v4rules),
Expand Down
5 changes: 4 additions & 1 deletion packages/eslint-plugin-pf-codemods/src/ruleCustomization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
* add the rule name to the below array. Do not add rules here if the React PR is
* not yet merged; instead add a "do not merge" label to the codemod PR.
*/
export const betaRuleNames: string[] = ["kebabToggle-replace-with-menuToggle"];
export const betaRuleNames: string[] = [
"data-codemods-cleanup",
"kebabToggle-replace-with-menuToggle",
];

// if you want a rule to have a severity that defaults to warning rather than error, add the rule name to the below array
export const warningRules = [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
### data-codemods-cleanup

This rule will remove `data-codemods` attributes and comments, which were introduced by our codemods in order to work correctly.
You should run this rule only once, after you finish running the codemods.

This rule can only run using the `--only data-codemods-cleanup` option.

#### Examples

In:

```jsx
%inputExample%
```

Out:

```jsx
%outputExample%
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
const ruleTester = require("../../ruletester");
import * as rule from "./data-codemods-cleanup";

const message = `This rule will remove data-codemods attributes and comments, which were introduced by our codemods in order to work correctly.`;

ruleTester.run("data-codemods-cleanup", rule, {
valid: [
{
code: `import { DualListSelector /* data-codemods */ } from 'somewhereElse';`,
},
{
code: `import { LoginMainFooterLinksItem } from 'somewhereElse'; <LoginMainFooterLinksItem data-codemods="true" />`,
},
],
invalid: [
{
code: `import { DualListSelector /* data-codemods */ } from '@patternfly/react-core';`,
output: `import { DualListSelector } from '@patternfly/react-core';`,
adamviktora marked this conversation as resolved.
Show resolved Hide resolved
errors: [
{
message,
type: "ImportSpecifier",
},
],
},
// aliased import
{
code: `import { DualListSelector as DLS /* data-codemods */ } from '@patternfly/react-core';`,
output: `import { DualListSelector as DLS } from '@patternfly/react-core';`,
errors: [
{
message,
type: "ImportSpecifier",
},
],
},
{
code: `import { LoginMainFooterLinksItem } from '@patternfly/react-core'; <LoginMainFooterLinksItem data-codemods="true" />`,
output: `import { LoginMainFooterLinksItem } from '@patternfly/react-core'; <LoginMainFooterLinksItem />`,
errors: [
{
message,
type: "JSXOpeningElement",
},
],
},
{
code: `import { MastheadLogo } from '@patternfly/react-core'; <MastheadLogo data-codemods />`,
output: `import { MastheadLogo } from '@patternfly/react-core'; <MastheadLogo />`,
errors: [
{
message,
type: "JSXOpeningElement",
},
],
},
// dist imports
{
code: `import { MastheadLogo } from '@patternfly/react-core/dist/esm/components/MastheadLogo'; <MastheadLogo data-codemods />`,
output: `import { MastheadLogo } from '@patternfly/react-core/dist/esm/components/MastheadLogo'; <MastheadLogo />`,
errors: [
{
message,
type: "JSXOpeningElement",
},
],
},
{
code: `import { MastheadLogo } from '@patternfly/react-core/dist/js/components/MastheadLogo'; <MastheadLogo data-codemods />`,
output: `import { MastheadLogo } from '@patternfly/react-core/dist/js/components/MastheadLogo'; <MastheadLogo />`,
errors: [
{
message,
type: "JSXOpeningElement",
},
],
},
// with alias
{
code: `import { MastheadLogo as ML } from '@patternfly/react-core'; <ML data-codemods />`,
output: `import { MastheadLogo as ML } from '@patternfly/react-core'; <ML />`,
errors: [
{
message,
type: "JSXOpeningElement",
},
],
},
// comment including other text and data-codemods
{
code: `import { DualListSelector /* This has been passed by data-codemods */ } from '@patternfly/react-core';`,
output: `import { DualListSelector } from '@patternfly/react-core';`,
errors: [
{
message,
type: "ImportSpecifier",
},
],
},
// data-codemods attribute including other value than true
{
code: `import { LoginMainFooterLinksItem } from '@patternfly/react-core'; <LoginMainFooterLinksItem data-codemods="no-remove" />`,
output: `import { LoginMainFooterLinksItem } from '@patternfly/react-core'; <LoginMainFooterLinksItem />`,
errors: [
{
message,
type: "JSXOpeningElement",
},
],
},
],
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { Rule } from "eslint";
import { ImportSpecifier, JSXOpeningElement } from "estree-jsx";
import {
checkMatchingJSXOpeningElement,
getAttribute,
getFromPackage,
} from "../../helpers";

module.exports = {
meta: { fixable: "code" },
create: function (context: Rule.RuleContext) {
const { imports: coreImports } = getFromPackage(
context,
"@patternfly/react-core"
);
const { imports: tableImports } = getFromPackage(
context,
"@patternfly/react-table"
);

const imports = [...coreImports, ...tableImports];

const message =
"This rule will remove data-codemods attributes and comments, which were introduced by our codemods in order to work correctly.";

return {
JSXOpeningElement(node: JSXOpeningElement) {
if (checkMatchingJSXOpeningElement(node, imports)) {
const dataCodemodsAttribute = getAttribute(node, "data-codemods");
if (dataCodemodsAttribute) {
context.report({
node,
message,
fix(fixer) {
return fixer.remove(dataCodemodsAttribute);
},
});
}
}
},
ImportSpecifier(node: ImportSpecifier) {
if (imports.some((specifier) => specifier === node)) {
const comments = context.getSourceCode().getCommentsAfter(node);
const dataCodemodsComment = comments.find((comment) =>
comment.value.includes("data-codemods")
);
if (dataCodemodsComment) {
context.report({
node,
message,
fix(fixer) {
return fixer.removeRange(dataCodemodsComment.range!);
},
});
}
}
},
};
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import {
DualListSelector /* data-codemods */,
LoginMainFooterLinksItem,
MastheadLogo,
} from "@patternfly/react-core";

export const DataCodemodsCleanupInput = () => (
<>
<DualListSelector />
<LoginMainFooterLinksItem data-codemods="true" />
<MastheadLogo data-codemods />
</>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import {
DualListSelector ,
LoginMainFooterLinksItem,
MastheadLogo,
} from "@patternfly/react-core";

export const DataCodemodsCleanupInput = () => (
<>
<DualListSelector />
<LoginMainFooterLinksItem />
<MastheadLogo />
</>
);
2 changes: 1 addition & 1 deletion packages/pf-codemods/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ Options:
These rules are based off the breaking change notes for React. Each rule links the breaking change patternfly-react PR in case you want to better understand the change. Also, each rule makes sure you're using a PatternFly component before running.

Some rules will add either a comment (`/* data-codemods */`) or data attribute (`data-codemods="true"`) in order to prevent certain other rules from applying an unnecessary fix.

These `data-codemods` attributes and comments can be removed by our `data-codemods-cleanup` rule. You should run this rule only once, after you finish running the general codemods, by adding the `--only data-codemods-cleanup` option.

### accordionContent-remove-isHidden-prop [(#9876)](https://github.com/patternfly/patternfly-react/pull/9876)

Expand Down
9 changes: 7 additions & 2 deletions packages/pf-codemods/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const {
configs,
ruleVersionMapping,
setupRules,
cleanupRules
cleanupRules,
} = require("@patternfly/eslint-plugin-pf-codemods/dist/js");
const { Command } = require("commander");
const program = new Command();
Expand Down Expand Up @@ -97,7 +97,12 @@ async function runCodemods(path, otherPaths, options) {

const rulesToRemove = getRulesToRemove(options);

rulesToRemove.forEach((rule) => delete configs.recommended.rules[prefix + rule]);
rulesToRemove.forEach((rule) => {
// data-codemods-cleanup rule should exist for any version of codemods
if (rule !== "data-codemods-cleanup") {
delete configs.recommended.rules[prefix + rule];
}
});
const eslintBaseConfig = {
extensions: [".js", ".jsx", ".ts", ".tsx"],
baseConfig: configs.recommended,
Expand Down
10 changes: 10 additions & 0 deletions packages/pf-codemods/scripts/baseReadMe.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ Requires Node.js >= 10.
npx @patternfly/pf-codemods ./path-to-src
```

Note: when updating from PatternFly 5 to 6, add the `--v6` flag.

```sh
npx @patternfly/pf-codemods --v6 ./path-to-src
```

Giving node more RAM can help for large codebases.

```sh
Expand All @@ -37,6 +43,9 @@ Options:
--exclude <rules> Run recommended rules EXCLUDING this comma-seperated list
--fix Whether to run fixer
--format <format> What eslint report format to use (default: "stylish")
--no-cache Disables eslint caching
--v4 Run v3 to v4 codemods
--v6 Run v5 to v6 codemods
-h, --help display help for command
```

Expand All @@ -45,4 +54,5 @@ Options:
These rules are based off the breaking change notes for React. Each rule links the breaking change patternfly-react PR in case you want to better understand the change. Also, each rule makes sure you're using a PatternFly component before running.

Some rules will add either a comment (`/* data-codemods */`) or data attribute (`data-codemods="true"`) in order to prevent certain other rules from applying an unnecessary fix.
These `data-codemods` attributes and comments can be removed by our `data-codemods-cleanup` rule. You should run this rule only once, after you finish running the general codemods, by adding the `--only data-codemods-cleanup` option.

Loading