Skip to content

Commit

Permalink
feat(Masthead): Update structure (#730)
Browse files Browse the repository at this point in the history
* feat(Masthead): Update structure

* feat(Masthead): Add support for aliases

* feat(masthead): Add dist import tests

* chore(Masthead): cleanup

* chore(helpers): Finish TSDoc message for stringifyJSXElement

* chore(helpers): Remove stringifyJSXElement helper that isn't needed

* chore(masthead): Remove duplicated code after merge

* chore(masthead): Improve codemod error messages
  • Loading branch information
wise-king-sullyman authored Aug 14, 2024
1 parent b92b9d7 commit 827500c
Show file tree
Hide file tree
Showing 9 changed files with 465 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { ImportSpecifier, JSXOpeningElement } from "estree-jsx";

/** Resolves the imported name of a node, even if that node has an aliased local name */
export function getImportedName(
namedImports: ImportSpecifier[],
node: JSXOpeningElement
) {
if (node.name.type !== "JSXIdentifier") {
return;
}

const nodeName = node.name.name;

const nodeImport = namedImports.find((imp) => imp.local.name === nodeName);

return nodeImport?.imported.name;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { ImportSpecifier } from "estree-jsx";

/** Resolves the local name of an import */
export function getLocalComponentName(
namedImports: ImportSpecifier[],
importedName: string
) {
const componentImport = namedImports.find(
(name) => name.imported.name === importedName
);

const isAlias =
componentImport?.imported.name !== componentImport?.local.name;

if (componentImport && isAlias) {
return componentImport.local.name;
}

return importedName;
}
2 changes: 2 additions & 0 deletions packages/eslint-plugin-pf-codemods/src/rules/helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ export * from "./getComponentImportName";
export * from "./getDefaultDeclarationString";
export * from "./getEndRange";
export * from "./getFromPackage";
export * from "./getImportedName";
export * from "./getLocalComponentName";
export * from "./getNodeName";
export * from "./getText";
export * from "./hasCodemodDataTag";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ export interface ImportDefaultSpecifierWithParent
parent?: ImportDeclaration;
}

export interface JSXOpeningElementWithParent extends JSXOpeningElement {
export interface JSXElementWithParent extends JSXElement {
parent?: JSXElement;
}

export interface JSXOpeningElementWithParent extends JSXOpeningElement {
parent?: JSXElementWithParent;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
### masthead-structure-changes [(#10809)](https://github.com/patternfly/patternfly-react/pull/10809)

The structure of Masthead has been updated, MastheadToggle and MastheadBrand should now be wrapped in MastheadMain.

#### Examples

In:

```jsx
%inputExample%
```

Out:

```jsx
%outputExample%
```

Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
const ruleTester = require("../../ruletester");
import * as rule from "./masthead-structure-changes";

ruleTester.run("masthead-structure-changes", rule, {
valid: [
// no pf import and has NOT had MastheadBrand renamed to MastheadLogo by the masthead-name-changes codemod
{
code: `<Masthead><MastheadToggle>Foo</MastheadToggle><MastheadMain><MastheadBrand>Bar</MastheadBrand></MastheadMain></Masthead>`,
},
// no pf import and has had MastheadBrand renamed to MastheadLogo by the masthead-name-changes codemod
{
code: `<Masthead><MastheadToggle>Foo</MastheadToggle><MastheadMain><MastheadLogo>Bar</MastheadLogo></MastheadMain></Masthead>`,
},
//toggle already wrapped in MastheadMain and brand double wrapped with data-codemods on the top level, has NOT had MastheadBrand renamed to MastheadLogo by the masthead-name-changes codemod
{
code: `import { Masthead, MastheadBrand, MastheadMain, MastheadToggle } from '@patternfly/react-core'; <Masthead><MastheadMain><MastheadToggle>Foo</MastheadToggle><MastheadBrand data-codemods><MastheadBrand>Bar</MastheadBrand></MastheadBrand></MastheadMain></Masthead>`,
},
// toggle already wrapped in MastheadMain and logo wrapped in a brand with data-codemods, has had MastheadBrand renamed to MastheadLogo by the masthead-name-changes codemod
{
code: `import { Masthead, MastheadLogo, MastheadMain, MastheadToggle, MastheadBrand } from '@patternfly/react-core'; <Masthead><MastheadMain><MastheadToggle>Foo</MastheadToggle><MastheadBrand data-codemods><MastheadLogo>Bar</MastheadLogo></MastheadBrand></MastheadMain></Masthead>`,
},
],
invalid: [
// stage one of a file that has NOT had MastheadBrand renamed to MastheadLogo by the masthead-name-changes codemod
{
code: `import { Masthead, MastheadBrand, MastheadMain, MastheadToggle } from '@patternfly/react-core'; <Masthead><MastheadToggle>Foo</MastheadToggle><MastheadMain><MastheadBrand>Bar</MastheadBrand></MastheadMain></Masthead>`,
output: `import { Masthead, MastheadBrand, MastheadMain, MastheadToggle } from '@patternfly/react-core'; <Masthead><MastheadMain><MastheadToggle>Foo</MastheadToggle><MastheadBrand>Bar</MastheadBrand></MastheadMain></Masthead>`,
errors: [
{
message: `The structure of Masthead has been updated, MastheadToggle should now be wrapped in MastheadMain.`,
type: "JSXOpeningElement",
},
{
message: `The structure of Masthead has been updated, the PF5 MastheadBrand has been renamed to MastheadLogo (this renaming is handled by our masthead-name-changes codemod) and should now be wrapped in a new MastheadBrand.`,
type: "JSXOpeningElement",
},
],
},
// stage two of a file that has NOT had MastheadBrand renamed to MastheadLogo by the masthead-name-changes codemod
{
code: `import { Masthead, MastheadBrand, MastheadMain, MastheadToggle } from '@patternfly/react-core'; <Masthead><MastheadMain><MastheadToggle>Foo</MastheadToggle><MastheadBrand>Bar</MastheadBrand></MastheadMain></Masthead>`,
output: `import { Masthead, MastheadBrand, MastheadMain, MastheadToggle } from '@patternfly/react-core'; <Masthead><MastheadMain><MastheadToggle>Foo</MastheadToggle><MastheadBrand data-codemods><MastheadBrand>Bar</MastheadBrand></MastheadBrand></MastheadMain></Masthead>`,
errors: [
{
message: `The structure of Masthead has been updated, the PF5 MastheadBrand has been renamed to MastheadLogo (this renaming is handled by our masthead-name-changes codemod) and should now be wrapped in a new MastheadBrand.`,
type: "JSXOpeningElement",
},
],
},
// stage one of a file that has had MastheadBrand renamed to MastheadLogo by the masthead-name-changes codemod
{
code: `import { Masthead, MastheadLogo, MastheadMain, MastheadToggle } from '@patternfly/react-core'; <Masthead><MastheadToggle>Foo</MastheadToggle><MastheadMain><MastheadLogo>Bar</MastheadLogo></MastheadMain></Masthead>`,
output: `import { Masthead, MastheadLogo, MastheadMain, MastheadToggle, MastheadBrand } from '@patternfly/react-core'; <Masthead><MastheadToggle>Foo</MastheadToggle><MastheadMain><MastheadBrand data-codemods><MastheadLogo>Bar</MastheadLogo></MastheadBrand></MastheadMain></Masthead>`,
errors: [
{
message: `The structure of Masthead has been updated, MastheadToggle should now be wrapped in MastheadMain.`,
type: "JSXOpeningElement",
},
{
message: `The structure of Masthead has been updated, MastheadLogo should now be wrapped in MastheadBrand.`,
type: "JSXOpeningElement",
},
],
},
// stage two of a file that has had MastheadBrand renamed to MastheadLogo by the masthead-name-changes codemod
{
code: `import { Masthead, MastheadLogo, MastheadMain, MastheadToggle, MastheadBrand } from '@patternfly/react-core'; <Masthead><MastheadToggle>Foo</MastheadToggle><MastheadMain><MastheadBrand data-codemods><MastheadLogo>Bar</MastheadLogo></MastheadBrand></MastheadMain></Masthead>`,
output: `import { Masthead, MastheadLogo, MastheadMain, MastheadToggle, MastheadBrand } from '@patternfly/react-core'; <Masthead><MastheadMain><MastheadToggle>Foo</MastheadToggle><MastheadBrand data-codemods><MastheadLogo>Bar</MastheadLogo></MastheadBrand></MastheadMain></Masthead>`,
errors: [
{
message: `The structure of Masthead has been updated, MastheadToggle should now be wrapped in MastheadMain.`,
type: "JSXOpeningElement",
},
],
},
// with aliases
{
code: `import { Masthead as MH, MastheadBrand as MB, MastheadMain as MM, MastheadToggle as MT } from '@patternfly/react-core'; <MH><MT>Foo</MT><MM><MB>Bar</MB></MM></MH>`,
output: `import { Masthead as MH, MastheadBrand as MB, MastheadMain as MM, MastheadToggle as MT } from '@patternfly/react-core'; <MH><MM><MT>Foo</MT><MB>Bar</MB></MM></MH>`,
errors: [
{
message: `The structure of Masthead has been updated, MastheadToggle should now be wrapped in MastheadMain.`,
type: "JSXOpeningElement",
},
{
message: `The structure of Masthead has been updated, the PF5 MastheadBrand has been renamed to MastheadLogo (this renaming is handled by our masthead-name-changes codemod) and should now be wrapped in a new MastheadBrand.`,
type: "JSXOpeningElement",
},
],
},
{
code: `import { Masthead as MH, MastheadBrand as MB, MastheadMain as MM, MastheadToggle as MT } from '@patternfly/react-core'; <MH><MM><MT>Foo</MT><MB>Bar</MB></MM></MH>`,
output: `import { Masthead as MH, MastheadBrand as MB, MastheadMain as MM, MastheadToggle as MT } from '@patternfly/react-core'; <MH><MM><MT>Foo</MT><MB data-codemods><MB>Bar</MB></MB></MM></MH>`,
errors: [
{
message: `The structure of Masthead has been updated, the PF5 MastheadBrand has been renamed to MastheadLogo (this renaming is handled by our masthead-name-changes codemod) and should now be wrapped in a new MastheadBrand.`,
type: "JSXOpeningElement",
},
],
},
// with dist imports
{
code: `import { Masthead, MastheadLogo, MastheadMain, MastheadToggle } from '@patternfly/react-core/dist/esm/components/Masthead'; <Masthead><MastheadToggle>Foo</MastheadToggle><MastheadMain><MastheadLogo>Bar</MastheadLogo></MastheadMain></Masthead>`,
output: `import { Masthead, MastheadLogo, MastheadMain, MastheadToggle, MastheadBrand } from '@patternfly/react-core/dist/esm/components/Masthead'; <Masthead><MastheadToggle>Foo</MastheadToggle><MastheadMain><MastheadBrand data-codemods><MastheadLogo>Bar</MastheadLogo></MastheadBrand></MastheadMain></Masthead>`,
errors: [
{
message: `The structure of Masthead has been updated, MastheadToggle should now be wrapped in MastheadMain.`,
type: "JSXOpeningElement",
},
{
message: `The structure of Masthead has been updated, MastheadLogo should now be wrapped in MastheadBrand.`,
type: "JSXOpeningElement",
},
],
},
{
code: `import { Masthead, MastheadLogo, MastheadMain, MastheadToggle, MastheadBrand } from '@patternfly/react-core/dist/esm/components/Masthead'; <Masthead><MastheadToggle>Foo</MastheadToggle><MastheadMain><MastheadBrand data-codemods><MastheadLogo>Bar</MastheadLogo></MastheadBrand></MastheadMain></Masthead>`,
output: `import { Masthead, MastheadLogo, MastheadMain, MastheadToggle, MastheadBrand } from '@patternfly/react-core/dist/esm/components/Masthead'; <Masthead><MastheadMain><MastheadToggle>Foo</MastheadToggle><MastheadBrand data-codemods><MastheadLogo>Bar</MastheadLogo></MastheadBrand></MastheadMain></Masthead>`,
errors: [
{
message: `The structure of Masthead has been updated, MastheadToggle should now be wrapped in MastheadMain.`,
type: "JSXOpeningElement",
},
],
},
{
code: `import { Masthead, MastheadLogo, MastheadMain, MastheadToggle } from '@patternfly/react-core/dist/js/components/Masthead'; <Masthead><MastheadToggle>Foo</MastheadToggle><MastheadMain><MastheadLogo>Bar</MastheadLogo></MastheadMain></Masthead>`,
output: `import { Masthead, MastheadLogo, MastheadMain, MastheadToggle, MastheadBrand } from '@patternfly/react-core/dist/js/components/Masthead'; <Masthead><MastheadToggle>Foo</MastheadToggle><MastheadMain><MastheadBrand data-codemods><MastheadLogo>Bar</MastheadLogo></MastheadBrand></MastheadMain></Masthead>`,
errors: [
{
message: `The structure of Masthead has been updated, MastheadToggle should now be wrapped in MastheadMain.`,
type: "JSXOpeningElement",
},
{
message: `The structure of Masthead has been updated, MastheadLogo should now be wrapped in MastheadBrand.`,
type: "JSXOpeningElement",
},
],
},
{
code: `import { Masthead, MastheadLogo, MastheadMain, MastheadToggle, MastheadBrand } from '@patternfly/react-core/dist/js/components/Masthead'; <Masthead><MastheadToggle>Foo</MastheadToggle><MastheadMain><MastheadBrand data-codemods><MastheadLogo>Bar</MastheadLogo></MastheadBrand></MastheadMain></Masthead>`,
output: `import { Masthead, MastheadLogo, MastheadMain, MastheadToggle, MastheadBrand } from '@patternfly/react-core/dist/js/components/Masthead'; <Masthead><MastheadMain><MastheadToggle>Foo</MastheadToggle><MastheadBrand data-codemods><MastheadLogo>Bar</MastheadLogo></MastheadBrand></MastheadMain></Masthead>`,
errors: [
{
message: `The structure of Masthead has been updated, MastheadToggle should now be wrapped in MastheadMain.`,
type: "JSXOpeningElement",
},
],
},
{
code: `import { Masthead, MastheadLogo, MastheadMain, MastheadToggle } from '@patternfly/react-core/dist/dynamic/components/Masthead'; <Masthead><MastheadToggle>Foo</MastheadToggle><MastheadMain><MastheadLogo>Bar</MastheadLogo></MastheadMain></Masthead>`,
output: `import { Masthead, MastheadLogo, MastheadMain, MastheadToggle, MastheadBrand } from '@patternfly/react-core/dist/dynamic/components/Masthead'; <Masthead><MastheadToggle>Foo</MastheadToggle><MastheadMain><MastheadBrand data-codemods><MastheadLogo>Bar</MastheadLogo></MastheadBrand></MastheadMain></Masthead>`,
errors: [
{
message: `The structure of Masthead has been updated, MastheadToggle should now be wrapped in MastheadMain.`,
type: "JSXOpeningElement",
},
{
message: `The structure of Masthead has been updated, MastheadLogo should now be wrapped in MastheadBrand.`,
type: "JSXOpeningElement",
},
],
},
{
code: `import { Masthead, MastheadLogo, MastheadMain, MastheadToggle, MastheadBrand } from '@patternfly/react-core/dist/dynamic/components/Masthead'; <Masthead><MastheadToggle>Foo</MastheadToggle><MastheadMain><MastheadBrand data-codemods><MastheadLogo>Bar</MastheadLogo></MastheadBrand></MastheadMain></Masthead>`,
output: `import { Masthead, MastheadLogo, MastheadMain, MastheadToggle, MastheadBrand } from '@patternfly/react-core/dist/dynamic/components/Masthead'; <Masthead><MastheadMain><MastheadToggle>Foo</MastheadToggle><MastheadBrand data-codemods><MastheadLogo>Bar</MastheadLogo></MastheadBrand></MastheadMain></Masthead>`,
errors: [
{
message: `The structure of Masthead has been updated, MastheadToggle should now be wrapped in MastheadMain.`,
type: "JSXOpeningElement",
},
],
},
],
});
Loading

0 comments on commit 827500c

Please sign in to comment.