Merge pull request #19752 from strapi/v5/upgrade-tool/react-files-support

This commit is contained in:
Jean-Sébastien Herbaux 2024-03-18 12:02:49 +01:00 committed by GitHub
commit 25d852de3a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 92 additions and 9 deletions

View File

@ -0,0 +1,42 @@
import type { Transform } from 'jscodeshift';
import { relative } from 'node:path';
const transform: Transform = (file, api) => {
const j = api.jscodeshift;
const root = j.withParser('JSX')(file.source);
const isReactFile = file.path.endsWith('.jsx') || file.path.endsWith('.tsx');
if (!isReactFile) {
return root.toSource();
}
const fileName = relative(process.cwd(), file.path);
console.log(`Found React file: ${fileName}`);
const buttons = root.findJSXElements('Button');
console.log(`Found ${buttons.length} buttons in ${fileName}`);
buttons.forEach((button) => {
const { openingElement } = button.node;
const isDisabled = openingElement.attributes.some(
(attribute) => j.JSXAttribute.check(attribute) && attribute.name.name === 'disabled'
);
console.log(`Is disabled? ${isDisabled}`);
if (!isDisabled) {
openingElement.attributes.push(
j.jsxAttribute(j.jsxIdentifier('disabled'), j.jsxExpressionContainer(j.literal(true)))
);
console.log('Added the disabled attribute');
}
});
return root.toSource();
};
export default transform;

View File

@ -23,6 +23,8 @@ const srcFiles = {
'b.ts': 'console.log("b.ts")',
'c.js': 'console.log("c.js")',
'd.json': `{ "foo": "bar", "bar": 123 }`,
'e.jsx': `console.log('e.jsx')`,
'f.tsx': `console.log('f.tsx')`,
};
const defaultVolume = { 'package.json': packageJSONFile, src: srcFiles };
@ -92,7 +94,7 @@ describe('Project', () => {
const project = projectFactory(defaultCWD);
expect(project.files.length).toBe(5);
expect(project.files.length).toBe(7);
expect(project.files).toStrictEqual(
expect.arrayContaining([path.join(defaultCWD, 'package.json'), ...srcFilenames(defaultCWD)])
);
@ -111,7 +113,7 @@ describe('Project', () => {
project.refresh();
expect(project.files.length).toBe(5);
expect(project.files.length).toBe(7);
expect(project.files).toStrictEqual(
expect.arrayContaining([path.join(defaultCWD, 'package.json'), ...srcFilenames(defaultCWD)])
);
@ -149,6 +151,22 @@ describe('Project', () => {
);
});
test('Get .jsx files only', () => {
const project = projectFactory(defaultCWD);
const tsFiles = project.getFilesByExtensions(['.jsx']);
expect(tsFiles).toStrictEqual(expect.arrayContaining([srcFilename(defaultCWD, 'e.jsx')]));
});
test('Get .tsx files only', () => {
const project = projectFactory(defaultCWD);
const tsFiles = project.getFilesByExtensions(['.tsx']);
expect(tsFiles).toStrictEqual(expect.arrayContaining([srcFilename(defaultCWD, 'f.tsx')]));
});
test('Get both .js and .ts files', () => {
const project = projectFactory(defaultCWD);

View File

@ -2,7 +2,22 @@ export const PROJECT_PACKAGE_JSON = 'package.json';
export const PROJECT_DEFAULT_ALLOWED_ROOT_PATHS = ['src', 'config', 'public'];
export const PROJECT_DEFAULT_ALLOWED_EXTENSIONS = ['js', 'ts', 'json'];
export const PROJECT_DEFAULT_CODE_EXTENSIONS = [
// Source files
'js',
'mjs',
'ts',
// React files
'jsx',
'tsx',
];
export const PROJECT_DEFAULT_JSON_EXTENSIONS = ['json'];
export const PROJECT_DEFAULT_ALLOWED_EXTENSIONS = [
...PROJECT_DEFAULT_CODE_EXTENSIONS,
...PROJECT_DEFAULT_JSON_EXTENSIONS,
];
export const PROJECT_DEFAULT_PATTERNS = ['package.json'];

View File

@ -75,18 +75,26 @@ export class Project implements ProjectInterface {
}
private createProjectCodemodsRunners(dry: boolean = false) {
const jsonFiles = this.getFilesByExtensions(['.json']);
const codeFiles = this.getFilesByExtensions(['.js', '.ts', '.mjs']);
const jsonExtensions = constants.PROJECT_DEFAULT_JSON_EXTENSIONS.map<FileExtension>(
(ext) => `.${ext}`
);
const codeExtensions = constants.PROJECT_DEFAULT_CODE_EXTENSIONS.map<FileExtension>(
(ext) => `.${ext}`
);
const jsonFiles = this.getFilesByExtensions(jsonExtensions);
const codeFiles = this.getFilesByExtensions(codeExtensions);
const codeRunner = codeRunnerFactory(codeFiles, {
dry,
parser: 'ts',
runInBand: true,
babel: true,
extensions: constants.PROJECT_DEFAULT_CODE_EXTENSIONS.join(','),
// Don't output any log coming from the runner
print: false,
silent: true,
extensions: 'js,ts',
runInBand: true,
verbose: 0,
babel: true,
parser: 'ts',
});
const jsonRunner = jsonRunnerFactory(jsonFiles, { dry, cwd: this.cwd });