Skip to content

Commit 827500c

Browse files
feat(Masthead): Update structure (#730)
* 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
1 parent b92b9d7 commit 827500c

File tree

9 files changed

+465
-1
lines changed

9 files changed

+465
-1
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { ImportSpecifier, JSXOpeningElement } from "estree-jsx";
2+
3+
/** Resolves the imported name of a node, even if that node has an aliased local name */
4+
export function getImportedName(
5+
namedImports: ImportSpecifier[],
6+
node: JSXOpeningElement
7+
) {
8+
if (node.name.type !== "JSXIdentifier") {
9+
return;
10+
}
11+
12+
const nodeName = node.name.name;
13+
14+
const nodeImport = namedImports.find((imp) => imp.local.name === nodeName);
15+
16+
return nodeImport?.imported.name;
17+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { ImportSpecifier } from "estree-jsx";
2+
3+
/** Resolves the local name of an import */
4+
export function getLocalComponentName(
5+
namedImports: ImportSpecifier[],
6+
importedName: string
7+
) {
8+
const componentImport = namedImports.find(
9+
(name) => name.imported.name === importedName
10+
);
11+
12+
const isAlias =
13+
componentImport?.imported.name !== componentImport?.local.name;
14+
15+
if (componentImport && isAlias) {
16+
return componentImport.local.name;
17+
}
18+
19+
return importedName;
20+
}

packages/eslint-plugin-pf-codemods/src/rules/helpers/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ export * from "./getComponentImportName";
77
export * from "./getDefaultDeclarationString";
88
export * from "./getEndRange";
99
export * from "./getFromPackage";
10+
export * from "./getImportedName";
11+
export * from "./getLocalComponentName";
1012
export * from "./getNodeName";
1113
export * from "./getText";
1214
export * from "./hasCodemodDataTag";

packages/eslint-plugin-pf-codemods/src/rules/helpers/interfaces.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ export interface ImportDefaultSpecifierWithParent
2020
parent?: ImportDeclaration;
2121
}
2222

23-
export interface JSXOpeningElementWithParent extends JSXOpeningElement {
23+
export interface JSXElementWithParent extends JSXElement {
2424
parent?: JSXElement;
2525
}
26+
27+
export interface JSXOpeningElementWithParent extends JSXOpeningElement {
28+
parent?: JSXElementWithParent;
29+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
### masthead-structure-changes [(#10809)](https://github.com/patternfly/patternfly-react/pull/10809)
2+
3+
The structure of Masthead has been updated, MastheadToggle and MastheadBrand should now be wrapped in MastheadMain.
4+
5+
#### Examples
6+
7+
In:
8+
9+
```jsx
10+
%inputExample%
11+
```
12+
13+
Out:
14+
15+
```jsx
16+
%outputExample%
17+
```
18+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
const ruleTester = require("../../ruletester");
2+
import * as rule from "./masthead-structure-changes";
3+
4+
ruleTester.run("masthead-structure-changes", rule, {
5+
valid: [
6+
// no pf import and has NOT had MastheadBrand renamed to MastheadLogo by the masthead-name-changes codemod
7+
{
8+
code: `<Masthead><MastheadToggle>Foo</MastheadToggle><MastheadMain><MastheadBrand>Bar</MastheadBrand></MastheadMain></Masthead>`,
9+
},
10+
// no pf import and has had MastheadBrand renamed to MastheadLogo by the masthead-name-changes codemod
11+
{
12+
code: `<Masthead><MastheadToggle>Foo</MastheadToggle><MastheadMain><MastheadLogo>Bar</MastheadLogo></MastheadMain></Masthead>`,
13+
},
14+
//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
15+
{
16+
code: `import { Masthead, MastheadBrand, MastheadMain, MastheadToggle } from '@patternfly/react-core'; <Masthead><MastheadMain><MastheadToggle>Foo</MastheadToggle><MastheadBrand data-codemods><MastheadBrand>Bar</MastheadBrand></MastheadBrand></MastheadMain></Masthead>`,
17+
},
18+
// 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
19+
{
20+
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>`,
21+
},
22+
],
23+
invalid: [
24+
// stage one of a file that has NOT had MastheadBrand renamed to MastheadLogo by the masthead-name-changes codemod
25+
{
26+
code: `import { Masthead, MastheadBrand, MastheadMain, MastheadToggle } from '@patternfly/react-core'; <Masthead><MastheadToggle>Foo</MastheadToggle><MastheadMain><MastheadBrand>Bar</MastheadBrand></MastheadMain></Masthead>`,
27+
output: `import { Masthead, MastheadBrand, MastheadMain, MastheadToggle } from '@patternfly/react-core'; <Masthead><MastheadMain><MastheadToggle>Foo</MastheadToggle><MastheadBrand>Bar</MastheadBrand></MastheadMain></Masthead>`,
28+
errors: [
29+
{
30+
message: `The structure of Masthead has been updated, MastheadToggle should now be wrapped in MastheadMain.`,
31+
type: "JSXOpeningElement",
32+
},
33+
{
34+
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.`,
35+
type: "JSXOpeningElement",
36+
},
37+
],
38+
},
39+
// stage two of a file that has NOT had MastheadBrand renamed to MastheadLogo by the masthead-name-changes codemod
40+
{
41+
code: `import { Masthead, MastheadBrand, MastheadMain, MastheadToggle } from '@patternfly/react-core'; <Masthead><MastheadMain><MastheadToggle>Foo</MastheadToggle><MastheadBrand>Bar</MastheadBrand></MastheadMain></Masthead>`,
42+
output: `import { Masthead, MastheadBrand, MastheadMain, MastheadToggle } from '@patternfly/react-core'; <Masthead><MastheadMain><MastheadToggle>Foo</MastheadToggle><MastheadBrand data-codemods><MastheadBrand>Bar</MastheadBrand></MastheadBrand></MastheadMain></Masthead>`,
43+
errors: [
44+
{
45+
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.`,
46+
type: "JSXOpeningElement",
47+
},
48+
],
49+
},
50+
// stage one of a file that has had MastheadBrand renamed to MastheadLogo by the masthead-name-changes codemod
51+
{
52+
code: `import { Masthead, MastheadLogo, MastheadMain, MastheadToggle } from '@patternfly/react-core'; <Masthead><MastheadToggle>Foo</MastheadToggle><MastheadMain><MastheadLogo>Bar</MastheadLogo></MastheadMain></Masthead>`,
53+
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>`,
54+
errors: [
55+
{
56+
message: `The structure of Masthead has been updated, MastheadToggle should now be wrapped in MastheadMain.`,
57+
type: "JSXOpeningElement",
58+
},
59+
{
60+
message: `The structure of Masthead has been updated, MastheadLogo should now be wrapped in MastheadBrand.`,
61+
type: "JSXOpeningElement",
62+
},
63+
],
64+
},
65+
// stage two of a file that has had MastheadBrand renamed to MastheadLogo by the masthead-name-changes codemod
66+
{
67+
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>`,
68+
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>`,
69+
errors: [
70+
{
71+
message: `The structure of Masthead has been updated, MastheadToggle should now be wrapped in MastheadMain.`,
72+
type: "JSXOpeningElement",
73+
},
74+
],
75+
},
76+
// with aliases
77+
{
78+
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>`,
79+
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>`,
80+
errors: [
81+
{
82+
message: `The structure of Masthead has been updated, MastheadToggle should now be wrapped in MastheadMain.`,
83+
type: "JSXOpeningElement",
84+
},
85+
{
86+
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.`,
87+
type: "JSXOpeningElement",
88+
},
89+
],
90+
},
91+
{
92+
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>`,
93+
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>`,
94+
errors: [
95+
{
96+
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.`,
97+
type: "JSXOpeningElement",
98+
},
99+
],
100+
},
101+
// with dist imports
102+
{
103+
code: `import { Masthead, MastheadLogo, MastheadMain, MastheadToggle } from '@patternfly/react-core/dist/esm/components/Masthead'; <Masthead><MastheadToggle>Foo</MastheadToggle><MastheadMain><MastheadLogo>Bar</MastheadLogo></MastheadMain></Masthead>`,
104+
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>`,
105+
errors: [
106+
{
107+
message: `The structure of Masthead has been updated, MastheadToggle should now be wrapped in MastheadMain.`,
108+
type: "JSXOpeningElement",
109+
},
110+
{
111+
message: `The structure of Masthead has been updated, MastheadLogo should now be wrapped in MastheadBrand.`,
112+
type: "JSXOpeningElement",
113+
},
114+
],
115+
},
116+
{
117+
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>`,
118+
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>`,
119+
errors: [
120+
{
121+
message: `The structure of Masthead has been updated, MastheadToggle should now be wrapped in MastheadMain.`,
122+
type: "JSXOpeningElement",
123+
},
124+
],
125+
},
126+
{
127+
code: `import { Masthead, MastheadLogo, MastheadMain, MastheadToggle } from '@patternfly/react-core/dist/js/components/Masthead'; <Masthead><MastheadToggle>Foo</MastheadToggle><MastheadMain><MastheadLogo>Bar</MastheadLogo></MastheadMain></Masthead>`,
128+
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>`,
129+
errors: [
130+
{
131+
message: `The structure of Masthead has been updated, MastheadToggle should now be wrapped in MastheadMain.`,
132+
type: "JSXOpeningElement",
133+
},
134+
{
135+
message: `The structure of Masthead has been updated, MastheadLogo should now be wrapped in MastheadBrand.`,
136+
type: "JSXOpeningElement",
137+
},
138+
],
139+
},
140+
{
141+
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>`,
142+
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>`,
143+
errors: [
144+
{
145+
message: `The structure of Masthead has been updated, MastheadToggle should now be wrapped in MastheadMain.`,
146+
type: "JSXOpeningElement",
147+
},
148+
],
149+
},
150+
{
151+
code: `import { Masthead, MastheadLogo, MastheadMain, MastheadToggle } from '@patternfly/react-core/dist/dynamic/components/Masthead'; <Masthead><MastheadToggle>Foo</MastheadToggle><MastheadMain><MastheadLogo>Bar</MastheadLogo></MastheadMain></Masthead>`,
152+
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>`,
153+
errors: [
154+
{
155+
message: `The structure of Masthead has been updated, MastheadToggle should now be wrapped in MastheadMain.`,
156+
type: "JSXOpeningElement",
157+
},
158+
{
159+
message: `The structure of Masthead has been updated, MastheadLogo should now be wrapped in MastheadBrand.`,
160+
type: "JSXOpeningElement",
161+
},
162+
],
163+
},
164+
{
165+
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>`,
166+
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>`,
167+
errors: [
168+
{
169+
message: `The structure of Masthead has been updated, MastheadToggle should now be wrapped in MastheadMain.`,
170+
type: "JSXOpeningElement",
171+
},
172+
],
173+
},
174+
],
175+
});

0 commit comments

Comments
 (0)