Skip to content

Commit

Permalink
chore(generators): made enhancements to generator files (#719)
Browse files Browse the repository at this point in the history
* chore(generators): made enhancements to generator files

* Updated generator for default imports
  • Loading branch information
thatblindgeye authored Aug 6, 2024
1 parent 578475a commit 4c7d9da
Show file tree
Hide file tree
Showing 9 changed files with 126 additions and 114 deletions.
5 changes: 0 additions & 5 deletions generators/src/helpers.js

This file was deleted.

5 changes: 5 additions & 0 deletions generators/src/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
function betterStringSort(a: string, b: string) {
return a.toLowerCase().localeCompare(b.toLowerCase());
}

module.exports = { betterStringSort };
1 change: 1 addition & 0 deletions generators/src/plop-interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export interface Answers {
componentName: string;
propName: string;
ruleName: string;
referenceRepo: string;
referencePR: string;
message?: string;
}
16 changes: 14 additions & 2 deletions generators/src/write-readme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,17 @@ import { outputFile } from "fs-extra";
import { camelCase } from "case-anything";
import { Answers } from "./plop-interfaces";

async function baseReadme({ referencePR, ruleName, message }: Answers) {
export enum RepoNames {
react = "patternfly-react",
componentGroups = "react-component-groups",
}

async function baseReadme({
referenceRepo,
referencePR,
ruleName,
message,
}: Answers) {
const camelCaseRuleName = camelCase(ruleName);
const readMePath = join(
require
Expand All @@ -15,7 +25,9 @@ async function baseReadme({ referencePR, ruleName, message }: Answers) {
`${ruleName}.md`
);

const readMeContent = `### ${ruleName} [(#${referencePR})](https://github.com/patternfly/patternfly-react/pull/${referencePR})
const prLinkTextPrefix =
referenceRepo === RepoNames.react ? "" : `${referenceRepo}/`;
const readMeContent = `### ${ruleName} [(${prLinkTextPrefix}#${referencePR})](https://github.com/patternfly/${referenceRepo}/pull/${referencePR})
${message}
Expand Down
34 changes: 13 additions & 21 deletions generators/src/write-rule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,44 +22,34 @@ export async function genericRule({
componentName,
propName,
ruleName,
referenceRepo,
referencePR,
message,
}: Answers) {
// the formatting for content here looks weird, but that's to preserve indentation in the written file
const content = `import { Rule } from "eslint";
import { JSXOpeningElement } from "estree-jsx";
import { getFromPackage } from "../../helpers";
import { getAllImportsFromPackage, checkMatchingJSXOpeningElement, getAttribute } from "../../helpers";
// https://github.com/patternfly/patternfly-react/pull/${referencePR}
// https://github.com/patternfly/${referenceRepo}/pull/${referencePR}
module.exports = {
meta: { fixable: "code" },
create: function (context: Rule.RuleContext) {
const { imports } = getFromPackage(context, "@patternfly/react-core");
const componentImports = imports.filter(
(specifier) => specifier.imported.name === "${componentName}"
);
const basePackage = "@patternfly/react-core";
const componentImports = getAllImportsFromPackage(context, basePackage, ["${componentName}"]);
return !componentImports.length
? {}
: {
JSXOpeningElement(node: JSXOpeningElement) {
if (
node.name.type === "JSXIdentifier" &&
componentImports
.map((imp) => imp.local.name)
.includes(node.name.name)
) {
const attribute = node.attributes.find(
(attr) =>
attr.type === "JSXAttribute" && attr.name.name === "${propName}"
);
if (attribute) {
if (checkMatchingJSXOpeningElement(node, componentImports)) {
const ${propName}Prop = getAttribute(node, "${propName}");
if (${propName}Prop) {
context.report({
node,
message: "${message}",
fix(fixer) {
return fixer.replaceText(attribute, "");
return fixer.replaceText(${propName}Prop, "");
},
});
}
Expand All @@ -76,11 +66,12 @@ export async function addEventCBRule({
componentName,
propName,
ruleName,
referenceRepo,
referencePR,
}: Answers) {
const content = `const { addCallbackParam } = require("../../helpers");
// https://github.com/patternfly/patternfly-react/pull/${referencePR}
// https://github.com/patternfly/${referenceRepo}/pull/${referencePR}
module.exports = {
meta: { fixable: "code" },
create: addCallbackParam(["${componentName}"], { ${propName}: "_event" }),
Expand All @@ -93,11 +84,12 @@ export async function swapCBRule({
componentName,
propName,
ruleName,
referenceRepo,
referencePR,
}: Answers) {
const content = `const { addCallbackParam } = require("../../helpers");
// https://github.com/patternfly/patternfly-react/pull/${referencePR}
// https://github.com/patternfly/${referenceRepo}/pull/${referencePR}
module.exports = {
meta: { fixable: "code" },
create: addCallbackParam(["${componentName}"], { ${propName}: { defaultParamName: "_event", previousParamIndex: 1, otherMatchers: /^_?(ev\\w*|e$)/ } }),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export * from "./includesImport";
export * from "./interfaces";
export * from "./JSXAttributes";
export * from "./JSXElements";
export * from "./nodeMatches";
export * from "./pfPackageMatches";
export * from "./removeElement";
export * from "./removeEmptyLineAfter";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import {
JSXOpeningElement,
ImportSpecifier,
ImportDefaultSpecifier,
} from "estree-jsx";

export function checkMatchingJSXOpeningElement(
node: JSXOpeningElement,
imports:
| ImportSpecifier
| ImportDefaultSpecifier
| (ImportSpecifier | ImportDefaultSpecifier)[]
) {
if (Array.isArray(imports)) {
return (
node.name.type === "JSXIdentifier" &&
imports.map((imp) => imp.local.name).includes(node.name.name)
);
}

return (
node.name.type === "JSXIdentifier" && imports.local.name === node.name.name
);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getFromPackage } from "../../helpers";
import { getFromPackage, checkMatchingJSXOpeningElement } from "../../helpers";
import { Rule } from "eslint";
import { JSXOpeningElement } from "estree-jsx";

Expand All @@ -17,10 +17,7 @@ module.exports = {
? {}
: {
JSXOpeningElement(node: JSXOpeningElement) {
if (
node.name.type === "JSXIdentifier" &&
accordionItemImport.local.name === node.name.name
) {
if (checkMatchingJSXOpeningElement(node, accordionItemImport)) {
context.report({
node,
message:
Expand Down
147 changes: 66 additions & 81 deletions plopFile.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,49 @@ const {
swapCBTest,
} = require("./generators/dist/js/write-test");
const {
RepoNames,
genericReadme,
addEventCBReadme,
swapCBReadme
swapCBReadme,
} = require("./generators/dist/js/write-readme");
const {
genericTestSingle,
addEventCBTestSingle,
swapCBTestSingle,
} = require("./generators/dist/js/write-test-single");

const componentNamePrompt = {
type: "input",
name: "componentName",
message: "What is the name of the component being changed? (PascalCase)",
};
const propNamePrompt = {
type: "input",
name: "propName",
message: "What is the name of the prop being changed? (camelCase)",
};
const ruleNamePrompt = {
type: "input",
name: "ruleName",
message: "What should the name of this rule be? (kebab-case)",
};
const referenceRepoPrompt = {
type: "list",
name: "referenceRepo",
message: "What is the repo the PR was made in",
choices: Object.values(RepoNames),
};
const referencePrPrompt = {
type: "input",
name: "referencePR",
message: "What is the PR reference number",
};
const messagePrompt = {
type: "input",
name: "message",
message: "What message should the codemod send? (Sentence case)",
};

module.exports = function (plop) {
plop.setActionType("generateRule", async function (answers, config, plop) {
console.log("Generating rule file", answers.ruleName);
Expand Down Expand Up @@ -62,49 +95,32 @@ module.exports = function (plop) {
}
});

plop.setActionType("generateTestSingle", async function (answers, config, plop) {
console.log("Generating tsx files for", answers.ruleName);
switch (config.generatorSelection) {
case "addEventCB":
await addEventCBTestSingle(answers);
break;
case "swapCB":
await swapCBTestSingle(answers);
break;
default:
await genericTestSingle(answers);
plop.setActionType(
"generateTestSingle",
async function (answers, config, plop) {
console.log("Generating tsx files for", answers.ruleName);
switch (config.generatorSelection) {
case "addEventCB":
await addEventCBTestSingle(answers);
break;
case "swapCB":
await swapCBTestSingle(answers);
break;
default:
await genericTestSingle(answers);
}
}
});
);

plop.setGenerator("generic", {
description: "create a generic new rule",
prompts: [
{
type: "input",
name: "componentName",
message:
"What is the name of the component being changed? (PascalCase)",
},
{
type: "input",
name: "propName",
message: "What is the name of the prop being changed? (camelCase)",
},
{
type: "input",
name: "ruleName",
message: "What should the name of this rule be? (kebab-case)",
},
{
type: "input",
name: "referencePR",
message: "What is the PR reference number",
},
{
type: "input",
name: "message",
message: "What message should the codemod send? (Sentence case)",
},
componentNamePrompt,
propNamePrompt,
ruleNamePrompt,
referenceRepoPrompt,
referencePrPrompt,
messagePrompt,
],
actions: [
{
Expand All @@ -125,27 +141,12 @@ module.exports = function (plop) {
plop.setGenerator("add event parameter", {
description: "add an event parameter to the front of a callback",
prompts: [
{
type: "input",
name: "componentName",
message:
"What is the name of the component being changed? (PascalCase)",
},
{
type: "input",
name: "propName",
message: "What is the name of the prop being changed? (camelCase)",
},
{
type: "input",
name: "ruleName",
message: "What should the name of this rule be? (kebab-case)",
},
{
type: "input",
name: "referencePR",
message: "What is the PR reference number",
},
componentNamePrompt,
propNamePrompt,
ruleNamePrompt,
referenceRepoPrompt,
referencePrPrompt,
,
],
actions: [
{
Expand All @@ -170,27 +171,11 @@ module.exports = function (plop) {
plop.setGenerator("swap parameter", {
description: "move the position of a parameter in a callback to the front",
prompts: [
{
type: "input",
name: "componentName",
message:
"What is the name of the component being changed? (PascalCase)",
},
{
type: "input",
name: "propName",
message: "What is the name of the prop being changed? (camelCase)",
},
{
type: "input",
name: "ruleName",
message: "What should the name of this rule be? (kebab-case)",
},
{
type: "input",
name: "referencePR",
message: "What is the PR reference number",
},
componentNamePrompt,
propNamePrompt,
ruleNamePrompt,
referenceRepoPrompt,
referencePrPrompt,
],
actions: [
{
Expand Down

0 comments on commit 4c7d9da

Please sign in to comment.