diff --git a/packages/eslint-plugin-pf-codemods/src/ruleCuration.ts b/packages/eslint-plugin-pf-codemods/src/ruleCuration.ts
index f7694e5d1..4f9a3a62c 100644
--- a/packages/eslint-plugin-pf-codemods/src/ruleCuration.ts
+++ b/packages/eslint-plugin-pf-codemods/src/ruleCuration.ts
@@ -1,4 +1,3 @@
-import { version } from "typescript";
import { betaRuleNames, warningRules } from "./ruleCustomization";
import { join } from "path";
@@ -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) => {
@@ -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),
diff --git a/packages/eslint-plugin-pf-codemods/src/ruleCustomization.ts b/packages/eslint-plugin-pf-codemods/src/ruleCustomization.ts
index 03873479f..fcc12a5da 100644
--- a/packages/eslint-plugin-pf-codemods/src/ruleCustomization.ts
+++ b/packages/eslint-plugin-pf-codemods/src/ruleCustomization.ts
@@ -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 = [
diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/dataCodemodsCleanup/data-codemods-cleanup.md b/packages/eslint-plugin-pf-codemods/src/rules/v6/dataCodemodsCleanup/data-codemods-cleanup.md
new file mode 100644
index 000000000..169909031
--- /dev/null
+++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/dataCodemodsCleanup/data-codemods-cleanup.md
@@ -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%
+```
diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/dataCodemodsCleanup/data-codemods-cleanup.test.ts b/packages/eslint-plugin-pf-codemods/src/rules/v6/dataCodemodsCleanup/data-codemods-cleanup.test.ts
new file mode 100644
index 000000000..703a163c7
--- /dev/null
+++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/dataCodemodsCleanup/data-codemods-cleanup.test.ts
@@ -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'; `,
+ },
+ ],
+ invalid: [
+ {
+ code: `import { DualListSelector /* data-codemods */ } from '@patternfly/react-core';`,
+ output: `import { DualListSelector } from '@patternfly/react-core';`,
+ 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'; `,
+ output: `import { LoginMainFooterLinksItem } from '@patternfly/react-core'; `,
+ errors: [
+ {
+ message,
+ type: "JSXOpeningElement",
+ },
+ ],
+ },
+ {
+ code: `import { MastheadLogo } from '@patternfly/react-core'; `,
+ output: `import { MastheadLogo } from '@patternfly/react-core'; `,
+ errors: [
+ {
+ message,
+ type: "JSXOpeningElement",
+ },
+ ],
+ },
+ // dist imports
+ {
+ code: `import { MastheadLogo } from '@patternfly/react-core/dist/esm/components/MastheadLogo'; `,
+ output: `import { MastheadLogo } from '@patternfly/react-core/dist/esm/components/MastheadLogo'; `,
+ errors: [
+ {
+ message,
+ type: "JSXOpeningElement",
+ },
+ ],
+ },
+ {
+ code: `import { MastheadLogo } from '@patternfly/react-core/dist/js/components/MastheadLogo'; `,
+ output: `import { MastheadLogo } from '@patternfly/react-core/dist/js/components/MastheadLogo'; `,
+ errors: [
+ {
+ message,
+ type: "JSXOpeningElement",
+ },
+ ],
+ },
+ // with alias
+ {
+ code: `import { MastheadLogo as ML } from '@patternfly/react-core'; `,
+ output: `import { MastheadLogo as ML } from '@patternfly/react-core'; `,
+ 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'; `,
+ output: `import { LoginMainFooterLinksItem } from '@patternfly/react-core'; `,
+ errors: [
+ {
+ message,
+ type: "JSXOpeningElement",
+ },
+ ],
+ },
+ ],
+});
diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/dataCodemodsCleanup/data-codemods-cleanup.ts b/packages/eslint-plugin-pf-codemods/src/rules/v6/dataCodemodsCleanup/data-codemods-cleanup.ts
new file mode 100644
index 000000000..21979176b
--- /dev/null
+++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/dataCodemodsCleanup/data-codemods-cleanup.ts
@@ -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!);
+ },
+ });
+ }
+ }
+ },
+ };
+ },
+};
diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/dataCodemodsCleanup/dataCodemodsCleanupInput.tsx b/packages/eslint-plugin-pf-codemods/src/rules/v6/dataCodemodsCleanup/dataCodemodsCleanupInput.tsx
new file mode 100644
index 000000000..54e6d6c17
--- /dev/null
+++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/dataCodemodsCleanup/dataCodemodsCleanupInput.tsx
@@ -0,0 +1,13 @@
+import {
+ DualListSelector /* data-codemods */,
+ LoginMainFooterLinksItem,
+ MastheadLogo,
+} from "@patternfly/react-core";
+
+export const DataCodemodsCleanupInput = () => (
+ <>
+
+
+
+ >
+);
diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/dataCodemodsCleanup/dataCodemodsCleanupOutput.tsx b/packages/eslint-plugin-pf-codemods/src/rules/v6/dataCodemodsCleanup/dataCodemodsCleanupOutput.tsx
new file mode 100644
index 000000000..9bed8c708
--- /dev/null
+++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/dataCodemodsCleanup/dataCodemodsCleanupOutput.tsx
@@ -0,0 +1,13 @@
+import {
+ DualListSelector ,
+ LoginMainFooterLinksItem,
+ MastheadLogo,
+} from "@patternfly/react-core";
+
+export const DataCodemodsCleanupInput = () => (
+ <>
+
+
+
+ >
+);
diff --git a/packages/pf-codemods/README.md b/packages/pf-codemods/README.md
index 39cd1ddb8..f1c52fb19 100644
--- a/packages/pf-codemods/README.md
+++ b/packages/pf-codemods/README.md
@@ -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)
diff --git a/packages/pf-codemods/index.js b/packages/pf-codemods/index.js
index bf6b745bb..63e4bdb9c 100755
--- a/packages/pf-codemods/index.js
+++ b/packages/pf-codemods/index.js
@@ -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();
@@ -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,
diff --git a/packages/pf-codemods/scripts/baseReadMe.md b/packages/pf-codemods/scripts/baseReadMe.md
index 93568a5f8..5cab0762d 100644
--- a/packages/pf-codemods/scripts/baseReadMe.md
+++ b/packages/pf-codemods/scripts/baseReadMe.md
@@ -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
@@ -37,6 +43,9 @@ Options:
--exclude Run recommended rules EXCLUDING this comma-seperated list
--fix Whether to run fixer
--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
```
@@ -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.