-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: [FX-4053] create codemods for RTE #3657
Merged
dmaklygin
merged 6 commits into
fx-4053-create-separate-package-for-rte
from
feat/rte-codemod
Jun 28, 2023
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
8a53efa
chore: create codemods for rte
dmaklygin 5507cb7
chore: adjust codemod
dmaklygin 2b53dd5
chore: update eslint rules for codemod
dmaklygin a86e56c
chore: update eslintignore
dmaklygin b217233
chore: update prettier ignore
dmaklygin 4975888
chore: update version
dmaklygin File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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 @@ | ||
--- | ||
'@toptal/picasso-codemod': minor | ||
--- | ||
|
||
--- | ||
|
||
- add codemod for replacing RichTextEditor imports |
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
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
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 |
---|---|---|
|
@@ -14,7 +14,7 @@ const require = createRequire(import.meta.url) | |
const codemodsDirectory = path.join(__dirname, '../', 'src') | ||
const jscodeshift = require.resolve('.bin/jscodeshift') | ||
const paths = { | ||
spa: 'src/**/*.tsx', | ||
spa: 'src/**/*.ts*', | ||
monorepo: { | ||
libs: '*libs/*/src/*', | ||
hosts: '*hosts/*/src/*', | ||
|
@@ -28,7 +28,7 @@ const findFilesInMonorepo = () => | |
execaSync('find', [ | ||
'.', | ||
'-name', | ||
'*.tsx', | ||
'*.ts*', | ||
'(', | ||
...['-path', paths.monorepo.libs], | ||
...['-or', '-path', paths.monorepo.apps], | ||
|
@@ -51,7 +51,7 @@ const findCodemodPath = codemod => | |
.map(ext => path.join(codemodsDirectory, `${codemod}/index.${ext}`)) | ||
.find(fs.existsSync) | ||
|
||
const runTransform = async ({ codemod, inputFiles, parserConfig }) => { | ||
const runTransform = async ({ codemod, inputFiles, parserConfig, runInBand }) => { | ||
const codemodPath = findCodemodPath(codemod) | ||
const isMonorepo = await checkIsMonorepo() | ||
|
||
|
@@ -60,6 +60,7 @@ const runTransform = async ({ codemod, inputFiles, parserConfig }) => { | |
|
||
args = args.concat(['--parser', 'tsx']) | ||
args = args.concat(['--transform', codemodPath]) | ||
args = args.concat(['--run-in-band', runInBand]) | ||
|
||
if (parserConfig) { | ||
args.push(`--parser-config=${parserConfig}`) | ||
|
@@ -105,6 +106,7 @@ export const run = () => { | |
|
||
Options | ||
--parser-config Add parser config | ||
--run-in-band Run serially in the current process (default: false) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we have to execute this |
||
|
||
Examples | ||
$ npx @toptal/picasso-codemod v17.0.0/typography-sizes | ||
|
@@ -124,10 +126,12 @@ export const run = () => { | |
const codemod = cli.input[0] | ||
const inputFiles = cli.input.slice(1) | ||
const parserConfig = cli.flags.parserConfig | ||
const runInBand = cli.flags.runInBand | ||
|
||
return runTransform({ | ||
codemod, | ||
inputFiles, | ||
parserConfig, | ||
runInBand, | ||
}) | ||
} |
13 changes: 13 additions & 0 deletions
13
packages/picasso-codemod/src/v36.0.0/__testfixtures__/imports.input.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,13 @@ | ||
import { RichTextEditor } from '@toptal/picasso-forms' | ||
import type { CustomEmojiGroup } from '@toptal/picasso/RichTextEditor' | ||
import type { CustomEmoji } from '@toptal/picasso/RichTextEditor/types' | ||
import type { RichTextEditorProps as LocalRichTextEditorProps } from '@toptal/picasso' | ||
import { | ||
Container, | ||
RichText as LocalRichText, | ||
Typography, | ||
} from '@toptal/picasso' | ||
import { RichText } from '@toptal/picasso' | ||
dmaklygin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
import { Icon } from '@toptal/picasso' | ||
import { Something, transformString } from 'some-module' | ||
import { htmlToHast } from '@toptal/picasso/utils' |
10 changes: 10 additions & 0 deletions
10
packages/picasso-codemod/src/v36.0.0/__testfixtures__/imports.output.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,10 @@ | ||
import { RichTextEditor } from '@toptal/picasso-forms' | ||
import type { CustomEmojiGroup } from '@toptal/picasso-rich-text-editor/RichTextEditor'; | ||
import type { CustomEmoji } from '@toptal/picasso-rich-text-editor/RichTextEditor/types'; | ||
import type { RichTextEditorProps as LocalRichTextEditorProps } from '@toptal/picasso-rich-text-editor'; | ||
import { Container, Typography } from '@toptal/picasso'; | ||
import { RichText as LocalRichText } from '@toptal/picasso-rich-text-editor'; | ||
import { RichText } from '@toptal/picasso-rich-text-editor'; | ||
OleksandrNechai marked this conversation as resolved.
Show resolved
Hide resolved
|
||
import { Icon } from '@toptal/picasso' | ||
import { Something, transformString } from 'some-module' | ||
import { htmlToHast } from '@toptal/picasso-rich-text-editor/utils'; | ||
OleksandrNechai marked this conversation as resolved.
Show resolved
Hide resolved
|
15 changes: 15 additions & 0 deletions
15
packages/picasso-codemod/src/v36.0.0/__testfixtures__/package.json
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,15 @@ | ||
{ | ||
"name": "somemodule", | ||
"description": "test", | ||
"version": "0.0.3", | ||
"author": "Toptal", | ||
"license": "ISC", | ||
"main": "./src/index.ts", | ||
"dependencies": { | ||
"@toptal/picasso": "36.0.0", | ||
"@toptal/picasso-forms": "58.0.0", | ||
"@toptal/picasso-rich-text-editor": "1.0.2" | ||
}, | ||
"private": true, | ||
"sideEffects": false | ||
} |
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,5 @@ | ||
import { defineTest } from 'jscodeshift/src/testUtils' | ||
|
||
defineTest(__dirname, 'rich-text-editor-replacement', {}, 'imports', { | ||
parser: '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 @@ | ||
export { default } from './rich-text-editor-replacement' |
194 changes: 194 additions & 0 deletions
194
packages/picasso-codemod/src/v36.0.0/rich-text-editor-replacement.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,194 @@ | ||
import type { Transform } from 'jscodeshift' | ||
import path from 'path' | ||
import fs from 'fs' | ||
|
||
const specificModules = [ | ||
'RichText', | ||
'htmlToHast', | ||
'RichTextEditor', | ||
'RichTextEditorProps', | ||
'ASTType', | ||
'CustomEmojiGroup', | ||
'CustomEmoji', | ||
] | ||
const picassoVersion = '36.0.0' | ||
const picassoFormsVersion = '58.0.0' | ||
const picassoRichTextEditorVersion = '1.0.1' | ||
|
||
// Get current execution directory | ||
const execDir = process.cwd() | ||
|
||
const findPackageJson = (dirPath: string) => { | ||
// Start with the directory provided | ||
let currentPath = dirPath | ||
|
||
while (currentPath !== '/' && currentPath !== execDir) { | ||
// Attempt to read package.json at current path | ||
try { | ||
const packageJsonPath = path.join(currentPath, 'package.json') | ||
|
||
if (fs.existsSync(packageJsonPath)) { | ||
return packageJsonPath | ||
} | ||
} catch (err) { | ||
console.error(err) | ||
} | ||
|
||
// If package.json doesn't exist, move up one directory | ||
currentPath = path.dirname(currentPath) | ||
} | ||
|
||
throw new Error('Could not find package.json') | ||
} | ||
|
||
const updatePackageJsonVersions = ( | ||
path: string, | ||
{ addRichTextEditorDependency }: { addRichTextEditorDependency: boolean } | ||
) => { | ||
try { | ||
const packageJsonPath = findPackageJson(path) | ||
|
||
// If it exists, read and parse it | ||
try { | ||
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8')) | ||
|
||
if (!packageJson.dependencies) { | ||
return | ||
} | ||
|
||
let inDevDependencies = false | ||
|
||
// Update Picasso and Picasso forms dependencies | ||
if (packageJson.dependencies['@toptal/picasso']) { | ||
packageJson.dependencies['@toptal/picasso'] = picassoVersion | ||
} else if ( | ||
packageJson.devDependencies && | ||
packageJson.devDependencies['@toptal/picasso'] | ||
) { | ||
packageJson.devDependencies['@toptal/picasso'] = picassoVersion | ||
inDevDependencies = true | ||
} | ||
|
||
if (packageJson.dependencies['@toptal/picasso-forms']) { | ||
packageJson.dependencies['@toptal/picasso-forms'] = picassoFormsVersion | ||
// if picasso form is defined, it depends on RichTextEditor, we should also add a dependency | ||
packageJson.dependencies['@toptal/picasso-rich-text-editor'] = | ||
picassoRichTextEditorVersion | ||
} else if ( | ||
packageJson.devDependencies && | ||
packageJson.devDependencies['@toptal/picasso-forms'] | ||
) { | ||
packageJson.devDependencies['@toptal/picasso-forms'] = | ||
picassoFormsVersion | ||
// if picasso form is defined, it depends on RichTextEditor, we should also add a dependency | ||
packageJson.devDependencies['@toptal/picasso-rich-text-editor'] = | ||
picassoRichTextEditorVersion | ||
inDevDependencies = true | ||
} | ||
|
||
// if RTE is used inside package, we should add a dependency | ||
if (addRichTextEditorDependency) { | ||
if (inDevDependencies) { | ||
packageJson.devDependencies['@toptal/picasso-rich-text-editor'] = | ||
picassoRichTextEditorVersion | ||
} else { | ||
packageJson.dependencies['@toptal/picasso-rich-text-editor'] = | ||
picassoRichTextEditorVersion | ||
} | ||
} | ||
|
||
fs.writeFileSync( | ||
packageJsonPath, | ||
JSON.stringify(packageJson, null, 2) + '\n' | ||
) | ||
} catch (err) { | ||
console.log(`Could not parse package.json at ${packageJsonPath}: ${err}`) | ||
} | ||
} catch (err) { | ||
console.log('err: ', err) | ||
console.error(`Package json not found for ${path}: ${err}`) | ||
} | ||
} | ||
|
||
const transform: Transform = (file, { jscodeshift: j }) => { | ||
const source = j(file.source) | ||
let fileContainsRichTextEditorImport = false | ||
let hasPicassoForms = false | ||
|
||
const picassoImports = source.find(j.ImportDeclaration).filter(path => { | ||
const pattern = /@toptal\/picasso($|\/[a-z\d]*)/gi | ||
|
||
hasPicassoForms = | ||
hasPicassoForms || path.node.source.value === '@toptal/picasso-forms' | ||
|
||
return ( | ||
pattern.test(path.node.source.value as string) && | ||
path.node.source.value !== '@toptal/picasso-forms' | ||
) | ||
}) | ||
|
||
// Iterate over react imports | ||
picassoImports.forEach(picassoImport => { | ||
const richTextSpecifiers = j(picassoImport) | ||
.find(j.ImportSpecifier) | ||
.filter(path => { | ||
return specificModules.includes(path.node.imported.name) | ||
}) | ||
|
||
// there is only single specifier, replace the whole import | ||
if (picassoImport.node.specifiers?.length === richTextSpecifiers.length) { | ||
j(picassoImport).replaceWith( | ||
// Build a new import declaration node based on the existing one | ||
j.importDeclaration( | ||
picassoImport.node.specifiers, // copy over the existing import specificers | ||
j.stringLiteral( | ||
(picassoImport.node.source.value as string).replace( | ||
'@toptal/picasso', | ||
'@toptal/picasso-rich-text-editor' | ||
) | ||
), | ||
picassoImport.node.importKind | ||
) | ||
) | ||
|
||
fileContainsRichTextEditorImport = true | ||
} else if (richTextSpecifiers.length > 0) { | ||
// insert specifiers for rich text editor | ||
// const importSpecifier = j.importSpecifier(richTextSpecifiers); | ||
// Generate new specifiers for the new import | ||
const newSpecifiers = richTextSpecifiers.nodes().map(node => { | ||
return j.importSpecifier( | ||
j.identifier(node.imported.name), | ||
node.local ? j.identifier(node.local.name) : undefined | ||
) | ||
}) | ||
// Create a new import declaration | ||
const newImport = j.importDeclaration( | ||
newSpecifiers, | ||
j.literal('@toptal/picasso-rich-text-editor'), | ||
picassoImport.node.importKind | ||
) | ||
|
||
j(picassoImport).insertAfter(newImport) | ||
|
||
// there are some specifiers left, remove the ones that are replaced | ||
j(picassoImport) | ||
.find(j.ImportSpecifier) | ||
.filter(path => specificModules.includes(path.node.imported.name)) | ||
.remove() | ||
|
||
fileContainsRichTextEditorImport = true | ||
} | ||
}) | ||
|
||
// we must update package.json as well. We have to upgrade @toptal/picasso, @toptal/picasso-forms and add new dependency @toptal/picasso-rich-text-editor | ||
// first of all, we need to search for a package json, it must be in the root of the package | ||
updatePackageJsonVersions(file.path, { | ||
addRichTextEditorDependency: | ||
fileContainsRichTextEditorImport || hasPicassoForms, | ||
}) | ||
|
||
return source.toSource({ trailingComma: false, quote: 'single' }) | ||
} | ||
|
||
export default transform | ||
OleksandrNechai marked this conversation as resolved.
Show resolved
Hide resolved
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it used to take only TSX files