Skip to content

Commit

Permalink
Add data-codemods attribute on rename (#91)
Browse files Browse the repository at this point in the history
* updated renameCompont function, adjusted all tests it touches - import statement for rename-toolbar-components not finalized

* fix ensureimports

Co-authored-by: redallen <[email protected]>
  • Loading branch information
evwilkin and redallen authored Jun 5, 2020
1 parent 7d55ee6 commit 91994c6
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 65 deletions.
2 changes: 0 additions & 2 deletions packages/eslint-plugin-pf-codemods/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ const rules = {
"alert-new-action": require('./lib/rules/alert-new-action'),
"card-rename-components": require('./lib/rules/card-rename-components'),
"chipgroup-remove-props": require('./lib/rules/chipgroup-remove-props'),
"chipgroup-remove-props": require('./lib/rules/chipgroup-remove-props'),
"chipgroup-remove-chipbutton": require('./lib/rules/chipgroup-remove-chipbutton'),
"chipgroup-remove-chipbutton": require('./lib/rules/chipgroup-remove-chipbutton'),
"chipgroup-remove-chipgrouptoolbaritem": require('./lib/rules/chipgroup-remove-chipgrouptoolbaritem'),
"dropdown-rename-icon": require('./lib/rules/dropdown-rename-icon'),
Expand Down
50 changes: 23 additions & 27 deletions packages/eslint-plugin-pf-codemods/lib/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,52 +82,48 @@ function renameProp(components, propMap, message, replaceAttribute) {

function renameComponent(
componentMap,
message = (prevName, newName) => `${prevName} has been replaced with ${newName}`
message = (prevName, newName) => `${prevName} has been replaced with ${newName}`,
package = '@patternfly/react-core'
) {
return function(context) {
const imports = getPackageImports(context, '@patternfly/react-core')
const imports = getPackageImports(context, package)
.filter(specifier => Object.keys(componentMap).includes(specifier.imported.name));
const importedNamesArr = imports.map(imp => imp.imported.name);

return imports.length === 0 ? {} : {
// update component's import statement
ImportSpecifier(node) {
const importedName = node.imported.name;
if (importedNamesArr.includes(importedName)) {
const localName = node.local.name;
const isAliased = importedName !== localName;
const aliasText = isAliased ? ` as ${localName}` : '';
const newName = `${componentMap[importedName]}${aliasText}`;
context.report({
node,
message: message(importedName, newName),
fix(fixer) {
return fixer.replaceText(node, newName);
}
});
}
ImportDeclaration(node) {
ensureImports(context, node, package, Object.values(componentMap));
},
// update component's JSX usage
JSXIdentifier(node) {
const nodeName = node.name;
const importedNode = imports.find(imp => imp.local.name === nodeName);
if (
importedNamesArr.includes(nodeName) &&
importedNode.imported.name === importedNode.local.name // don't rename an aliased component
) {
// if data-codemods attribute, do nothing
const parentNode = node.parent;
const isOpeningTag = parentNode.type === 'JSXOpeningElement';
const openingTagAttributes = isOpeningTag ? parentNode.attributes : parentNode.parent.openingElement.attributes;
const hasDataAttr = openingTagAttributes && openingTagAttributes.filter(attr => attr.name.name === 'data-codemods').length;
if (hasDataAttr) {
return;
}
// if no data-codemods && opening tag, add attribute & rename
// if no data-codemods && closing tag, rename
const newName = componentMap[nodeName];
const updateTagName = node => context
.getSourceCode()
.getText(node)
.replace(nodeName, newName);
const updateTagName = node => context.getSourceCode().getText(node).replace(nodeName, newName);
const addDataAttr = jsxStr => `${jsxStr.slice(0, -1)} data-codemods="true">`;
const newOpeningParentTag = newName.includes('Toolbar')
? addDataAttr(updateTagName(parentNode))
: updateTagName(parentNode);
context.report({
node,
message: message(nodeName, newName),
fix(fixer) {
const fixes = [
fixer.replaceText(node, updateTagName(node))
];
return fixes;
return isOpeningTag
? fixer.replaceText(parentNode, newOpeningParentTag)
: fixer.replaceText(node, updateTagName(node));
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ ruleTester.run("chipgroup-remove-chipbutton", rule, {
invalid: [
{
code: `import { ChipButton } from '@patternfly/react-core'; <ChipButton>button</ChipButton>`,
output: `import { Button } from '@patternfly/react-core'; <Button>button</Button>`,
output: `import { ChipButton, Button } from '@patternfly/react-core'; <Button>button</Button>`,
errors: [
{
message: `ChipButton has been replaced with Button`,
type: "ImportSpecifier",
message: `add missing imports Button from @patternfly/react-core`,
type: "ImportDeclaration",
},
{
message: `ChipButton has been replaced with Button`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,15 @@ ruleTester.run("expandable-rename-expandablesection", rule, {
}
],
invalid: [
{
code: `import { Expandable } from '@patternfly/react-core';`,
output: `import { ExpandableSection } from '@patternfly/react-core';`,
errors: [{
message: `Expandable has been replaced with ExpandableSection`,
type: "ImportSpecifier",
}]
},
{
code: `import { Expandable } from '@patternfly/react-core';
<Expandable toggleText="Show More"></Expandable>`,
output: `import { ExpandableSection } from '@patternfly/react-core';
output: `import { Expandable, ExpandableSection } from '@patternfly/react-core';
<ExpandableSection toggleText="Show More"></ExpandableSection>`,
errors: [
{
message: `Expandable has been replaced with ExpandableSection`,
type: "ImportSpecifier",
message: `add missing imports ExpandableSection from @patternfly/react-core`,
type: "ImportDeclaration",
},
{
message: 'Expandable has been replaced with ExpandableSection',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ ruleTester.run("rename-toolbar-components", rule, {
</Page>
`,
output: `
import { Page, PageHeader, PageHeaderTools, PageHeaderToolsGroup, PageHeaderToolsItem } from '@patternfly/react-core';
import { Page, PageHeader, Toolbar, ToolbarGroup, ToolbarItem, PageHeaderTools, PageHeaderToolsGroup, PageHeaderToolsItem } from '@patternfly/react-core';
<Page>
<PageHeader toolbar={
<PageHeaderTools>
Expand All @@ -53,16 +53,8 @@ ruleTester.run("rename-toolbar-components", rule, {
`,
errors: [
{
message: `Toolbar has been replaced with PageHeaderTools`,
type: "ImportSpecifier",
},
{
message: `ToolbarGroup has been replaced with PageHeaderToolsGroup`,
type: "ImportSpecifier",
},
{
message: `ToolbarItem has been replaced with PageHeaderToolsItem`,
type: "ImportSpecifier",
message: `add missing imports PageHeaderTools, PageHeaderToolsGroup, PageHeaderToolsItem from @patternfly/react-core`,
type: "ImportDeclaration",
},
{
message: `Toolbar has been replaced with PageHeaderTools`,
Expand Down
25 changes: 14 additions & 11 deletions test/test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,20 @@ export const TestExpandable = <Expandable toggleText="Show More" ></Expandable>;
import { ChipButton } from '@patternfly/react-core';
export const TestChipButton = <ChipButton></ChipButton>;

import { Avatar, Page, PageHeader, Toolbar, ToolbarGroup, ToolbarItem } from '@patternfly/react-core';
<Page>
<PageHeader avatar={<Avatar />} toolbar={
<Toolbar>
<ToolbarGroup>
<ToolbarItem></ToolbarItem>
</ToolbarGroup>
</Toolbar>
}
/>
</Page>;
// import { Avatar, Page, PageHeader, Toolbar, ToolbarGroup, ToolbarItem } from '@patternfly/react-core';
// <Page>
// <PageHeader avatar={<Avatar />} toolbar={
// <Toolbar>
// <ToolbarGroup>
// <ToolbarItem></ToolbarItem>
// </ToolbarGroup>
// </Toolbar>
// }
// />
// </Page>;

import { Flex } from '@patternfly/react-core';
<Flex breakpointMods={[{ modifier: 'justify-content-space-between' }] as any}></Flex>

import { DataToolbar } from '@patternfly/react-core';
<DataToolbar></DataToolbar>

0 comments on commit 91994c6

Please sign in to comment.