-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(EmptyState): components no longer exported (#642)
* fix(EmptyState): components no longer exported * PR feedback
- Loading branch information
1 parent
f9bbb92
commit f6f3028
Showing
5 changed files
with
288 additions
and
0 deletions.
There are no files selected for viewing
17 changes: 17 additions & 0 deletions
17
...c/rules/v6/emptyStateNonExportedComponents/emptyState-nonExported-components.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
### emptyState-nonExported-components [(#10364)](https://github.com/patternfly/patternfly-react/pull/10364) | ||
|
||
EmptyStateHeader and EmptyStateIcon are no longer exported by PatternFly. This rule will only apply fixes for exports of these components, as our rule for unused imports will handle applying fixes for imports. | ||
|
||
#### Examples | ||
|
||
In: | ||
|
||
```jsx | ||
%inputExample% | ||
``` | ||
|
||
Out: | ||
|
||
```jsx | ||
%outputExample% | ||
``` |
149 changes: 149 additions & 0 deletions
149
...ds/src/rules/v6/emptyStateNonExportedComponents/emptyState-nonExported-components.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
const ruleTester = require("../../ruletester"); | ||
import * as rule from "./emptyState-nonExported-components"; | ||
|
||
ruleTester.run("emptyState-nonExported-components", rule, { | ||
valid: [ | ||
{ | ||
code: `import { EmptyStateHeader } from '@some/other/package';`, | ||
}, | ||
{ | ||
code: `import { EmptyStateIcon } from '@some/other/package';`, | ||
}, | ||
], | ||
invalid: [ | ||
{ | ||
code: `import { EmptyStateHeader } from '@patternfly/react-core';`, | ||
output: `import { EmptyStateHeader } from '@patternfly/react-core';`, | ||
errors: [ | ||
{ | ||
message: `EmptyStateHeader is no longer exported by PatternFly. This rule will not fix any imports, as our cleanup rule handles removal of unused imports.`, | ||
type: "ImportSpecifier", | ||
}, | ||
], | ||
}, | ||
{ | ||
code: `import { EmptyStateHeader as CustomHeader } from '@patternfly/react-core';`, | ||
output: `import { EmptyStateHeader as CustomHeader } from '@patternfly/react-core';`, | ||
errors: [ | ||
{ | ||
message: `EmptyStateHeader is no longer exported by PatternFly. This rule will not fix any imports, as our cleanup rule handles removal of unused imports.`, | ||
type: "ImportSpecifier", | ||
}, | ||
], | ||
}, | ||
{ | ||
code: `export { EmptyStateHeader } from '@patternfly/react-core';`, | ||
output: ``, | ||
errors: [ | ||
{ | ||
message: `EmptyStateHeader is no longer exported by PatternFly.`, | ||
type: "ExportNamedDeclaration", | ||
}, | ||
], | ||
}, | ||
{ | ||
code: `export { EmptyStateHeader as CustomHeader } from '@patternfly/react-core';`, | ||
output: ``, | ||
errors: [ | ||
{ | ||
message: `EmptyStateHeader is no longer exported by PatternFly.`, | ||
type: "ExportNamedDeclaration", | ||
}, | ||
], | ||
}, | ||
{ | ||
code: `export { EmptyStateHeader, EmptyStateIcon } from '@patternfly/react-core';`, | ||
output: ``, | ||
errors: [ | ||
{ | ||
message: `EmptyStateHeader and EmptyStateIcon are no longer exported by PatternFly.`, | ||
type: "ExportNamedDeclaration", | ||
}, | ||
], | ||
}, | ||
{ | ||
code: `export { EmptyStateHeader, Button, EmptyStateIcon } from '@patternfly/react-core';`, | ||
output: `export { Button } from '@patternfly/react-core';`, | ||
errors: [ | ||
{ | ||
message: `EmptyStateHeader is no longer exported by PatternFly.`, | ||
type: "ExportNamedDeclaration", | ||
}, | ||
{ | ||
message: `EmptyStateIcon is no longer exported by PatternFly.`, | ||
type: "ExportNamedDeclaration", | ||
}, | ||
], | ||
}, | ||
{ | ||
code: `import { EmptyStateHeader } from '@patternfly/react-core';export { EmptyStateHeader };`, | ||
output: `import { EmptyStateHeader } from '@patternfly/react-core';`, | ||
errors: [ | ||
{ | ||
message: `EmptyStateHeader is no longer exported by PatternFly. This rule will not fix any imports, as our cleanup rule handles removal of unused imports.`, | ||
type: "ImportSpecifier", | ||
}, | ||
{ | ||
message: `EmptyStateHeader is no longer exported by PatternFly.`, | ||
type: "ExportNamedDeclaration", | ||
}, | ||
], | ||
}, | ||
{ | ||
code: `import { EmptyStateHeader as CustomHeader } from '@patternfly/react-core';export { CustomHeader };`, | ||
output: `import { EmptyStateHeader as CustomHeader } from '@patternfly/react-core';`, | ||
errors: [ | ||
{ | ||
message: `EmptyStateHeader is no longer exported by PatternFly. This rule will not fix any imports, as our cleanup rule handles removal of unused imports.`, | ||
type: "ImportSpecifier", | ||
}, | ||
{ | ||
message: `CustomHeader is no longer exported by PatternFly.`, | ||
type: "ExportNamedDeclaration", | ||
}, | ||
], | ||
}, | ||
{ | ||
code: `import { EmptyStateHeader } from '@patternfly/react-core';export { EmptyStateHeader as CustomHeader };`, | ||
output: `import { EmptyStateHeader } from '@patternfly/react-core';`, | ||
errors: [ | ||
{ | ||
message: `EmptyStateHeader is no longer exported by PatternFly. This rule will not fix any imports, as our cleanup rule handles removal of unused imports.`, | ||
type: "ImportSpecifier", | ||
}, | ||
{ | ||
message: `EmptyStateHeader is no longer exported by PatternFly.`, | ||
type: "ExportNamedDeclaration", | ||
}, | ||
], | ||
}, | ||
{ | ||
code: `import { EmptyStateHeader } from '@patternfly/react-core';export default EmptyStateHeader;`, | ||
output: `import { EmptyStateHeader } from '@patternfly/react-core';`, | ||
errors: [ | ||
{ | ||
message: `EmptyStateHeader is no longer exported by PatternFly. This rule will not fix any imports, as our cleanup rule handles removal of unused imports.`, | ||
type: "ImportSpecifier", | ||
}, | ||
{ | ||
message: `EmptyStateHeader is no longer exported by PatternFly.`, | ||
type: "ExportDefaultDeclaration", | ||
}, | ||
], | ||
}, | ||
{ | ||
code: `import { EmptyStateHeader as CustomHeader } from '@patternfly/react-core';export default CustomHeader;`, | ||
output: `import { EmptyStateHeader as CustomHeader } from '@patternfly/react-core';`, | ||
errors: [ | ||
{ | ||
message: `EmptyStateHeader is no longer exported by PatternFly. This rule will not fix any imports, as our cleanup rule handles removal of unused imports.`, | ||
type: "ImportSpecifier", | ||
}, | ||
{ | ||
message: `CustomHeader is no longer exported by PatternFly.`, | ||
type: "ExportDefaultDeclaration", | ||
}, | ||
], | ||
}, | ||
], | ||
}); |
114 changes: 114 additions & 0 deletions
114
...odemods/src/rules/v6/emptyStateNonExportedComponents/emptyState-nonExported-components.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
import { Rule } from "eslint"; | ||
import { | ||
ImportSpecifier, | ||
ExportNamedDeclaration, | ||
ExportDefaultDeclaration, | ||
} from "estree-jsx"; | ||
import { getFromPackage } from "../../helpers"; | ||
|
||
// https://github.com/patternfly/patternfly-react/pull/10364 | ||
module.exports = { | ||
meta: { fixable: "code" }, | ||
create: function (context: Rule.RuleContext) { | ||
const { imports, exports } = getFromPackage( | ||
context, | ||
"@patternfly/react-core" | ||
); | ||
const emptyStateComponents = ["EmptyStateHeader", "EmptyStateIcon"]; | ||
const emptyStateImports = imports.filter((specifier) => | ||
emptyStateComponents.includes(specifier.imported.name) | ||
); | ||
const emptyStateExports = exports.filter((specifier) => | ||
emptyStateComponents.includes(specifier.local.name) | ||
); | ||
|
||
if (!emptyStateImports.length && !emptyStateExports.length) { | ||
return {}; | ||
} | ||
|
||
return { | ||
ImportSpecifier(node: ImportSpecifier) { | ||
if (!emptyStateImports.length) { | ||
return; | ||
} | ||
|
||
emptyStateImports.forEach((esImport) => { | ||
context.report({ | ||
node, | ||
message: `${esImport.imported.name} is no longer exported by PatternFly. This rule will not fix any imports, as our cleanup rule handles removal of unused imports.`, | ||
}); | ||
}); | ||
}, | ||
ExportNamedDeclaration(node: ExportNamedDeclaration) { | ||
const exportsToRemove = node.specifiers.filter( | ||
(spec) => | ||
(emptyStateComponents.includes(spec.local.name) && | ||
node.source?.value === "@patternfly/react-core") || | ||
emptyStateImports.some((imp) => imp.local.name === spec.local.name) | ||
); | ||
if (!exportsToRemove.length) { | ||
return; | ||
} | ||
|
||
if (exportsToRemove.length === node.specifiers.length) { | ||
const validExportNames = exportsToRemove | ||
.map((exportToRemove) => exportToRemove.local.name) | ||
.join(" and "); | ||
context.report({ | ||
node, | ||
message: `${validExportNames} ${ | ||
exportsToRemove.length > 1 ? "are" : "is" | ||
} no longer exported by PatternFly.`, | ||
fix(fixer) { | ||
return fixer.remove(node); | ||
}, | ||
}); | ||
|
||
return; | ||
} | ||
|
||
exportsToRemove.forEach((exportToRemove) => { | ||
const { range } = exportToRemove; | ||
const tokenBefore = context | ||
.getSourceCode() | ||
.getTokenBefore(exportToRemove); | ||
const isCommaBefore = tokenBefore?.value === ","; | ||
const tokenAfter = context | ||
.getSourceCode() | ||
.getTokenAfter(exportToRemove); | ||
const isCommaAfter = tokenAfter?.value === ","; | ||
const rangeStartValue = isCommaBefore | ||
? tokenBefore.range[0] | ||
: range?.[0]; | ||
const rangeEndValue = isCommaAfter ? tokenAfter.range[1] : range?.[1]; | ||
context.report({ | ||
node, | ||
message: `${exportToRemove.local.name} is no longer exported by PatternFly.`, | ||
fix(fixer) { | ||
return rangeStartValue && rangeEndValue | ||
? fixer.removeRange([rangeStartValue, rangeEndValue]) | ||
: []; | ||
}, | ||
}); | ||
}); | ||
}, | ||
ExportDefaultDeclaration(node: ExportDefaultDeclaration) { | ||
const exportName = | ||
node.declaration.type === "Identifier" && node.declaration.name; | ||
const isEmptyStateDefaultExport = emptyStateImports.some( | ||
(imp) => imp.local.name === exportName | ||
); | ||
|
||
if (isEmptyStateDefaultExport) { | ||
context.report({ | ||
node, | ||
message: `${exportName} is no longer exported by PatternFly.`, | ||
fix(fixer) { | ||
return fixer.remove(node); | ||
}, | ||
}); | ||
} | ||
}, | ||
}; | ||
}, | ||
}; |
7 changes: 7 additions & 0 deletions
7
...ods/src/rules/v6/emptyStateNonExportedComponents/emptyStateNonExportedComponentsInput.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { EmptyStateHeader, EmptyStateIcon } from "@patternfly/react-core"; | ||
|
||
export { EmptyStateHeader, EmptyStateIcon }; | ||
export { | ||
EmptyStateHeader as CustomESHeader, | ||
EmptyStateIcon as CustomESIcon, | ||
} from "@patternfly/react-core"; |
1 change: 1 addition & 0 deletions
1
...ds/src/rules/v6/emptyStateNonExportedComponents/emptyStateNonExportedComponentsOutput.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
import { EmptyStateHeader, EmptyStateIcon } from "@patternfly/react-core"; |