Skip to content

Commit

Permalink
feat: vibrant-migrator
Browse files Browse the repository at this point in the history
  • Loading branch information
kang-heewon committed Jun 13, 2024
1 parent 0a0d978 commit a8c48ab
Show file tree
Hide file tree
Showing 27 changed files with 1,243 additions and 268 deletions.
3 changes: 3 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Add files here to ignore them from prettier formatting
/dist
/coverage
3 changes: 3 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"singleQuote": true
}
3 changes: 2 additions & 1 deletion .vscode/extensions.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"nrwl.angular-console",
"firsttris.vscode-jest-runner",
"dbaeumer.vscode-eslint",
"unifiedjs.vscode-mdx"
"unifiedjs.vscode-mdx",
"esbenp.prettier-vscode"
]
}
11 changes: 1 addition & 10 deletions jest.config.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,5 @@
import { getJestProjects } from '@nx/jest';

const projects = getJestProjects()
.filter(project => !(project.includes('vibrant-core') || project.includes('vibrant-icons')))
.concat(
'packages/vibrant-core/jest.config.web.ts',
'packages/vibrant-core/jest.config.native.ts',
'packages/vibrant-icons/jest.config.web.ts',
'packages/vibrant-icons/jest.config.native.ts'
);

export default {
projects,
projects: getJestProjects(),
};
15 changes: 2 additions & 13 deletions nx.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,8 @@
},
"tasksRunnerOptions": {
"default": {
"runner": "nx-cloud",
"options": {
"cacheableOperations": [
"build",
"lint",
"test",
"e2e",
"build-native",
"typecheck"
],
"accessToken": "ZDlmMzIwMjgtZThjZS00MWExLThlZTgtMGEyMGQyMzUyMmFifHJlYWQ=",
"parallel": 3
}
"runner": "nx/tasks-runners/default",
"options": {}
}
},
"workspaceLayout": {
Expand Down
11 changes: 7 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,15 @@
"@svgr/webpack": "6.5.1",
"@swc-node/register": "1.4.2",
"@swc/cli": "0.1.62",
"@swc/core": "1.2.173",
"@swc/core": "~1.3.51",
"@swc/jest": "0.2.20",
"@testing-library/jest-dom": "5.16.5",
"@testing-library/jest-native": "4.0.13",
"@testing-library/react": "13.4.0",
"@testing-library/react-native": "11.2.0",
"@testing-library/user-event": "14.2.1",
"@types/jest": "28.1.8",
"@types/jest": "^29.4.0",
"@types/jscodeshift": "0.11.11",
"@types/node": "18.7.18",
"@types/react": "18.0.20",
"@types/react-dom": "18.0.6",
Expand Down Expand Up @@ -110,8 +112,9 @@
"expo-modules-autolinking": "0.10.3",
"husky": "8.0.0",
"jest": "29.4.3",
"jest-environment-jsdom": "~28.1.1",
"jest-environment-jsdom": "^29.4.1",
"jest-expo": "48.0.2",
"jscodeshift": "0.15.2",
"jsonc-eslint-parser": "^2.1.0",
"metro": "0.74.1",
"metro-babel-register": "0.74.1",
Expand All @@ -133,7 +136,7 @@
"stylus-loader": "^7.1.0",
"ts-jest": "29.1.0",
"ts-node": "10.9.1",
"typescript": "4.7.2",
"typescript": "~5.0.2",
"url-loader": "^4.1.1",
"vite": "3.2.6",
"vite-tsconfig-paths": "3.5.0",
Expand Down
18 changes: 18 additions & 0 deletions packages/vibrant-migrator/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"extends": ["plugin:@nx/react", "../../.eslintrc.json"],
"ignorePatterns": ["!**/*", "**/__testfixtures__/**"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {}
},
{
"files": ["*.ts", "*.tsx"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"rules": {}
}
]
}
31 changes: 31 additions & 0 deletions packages/vibrant-migrator/.swcrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"jsc": {
"target": "es2016",
"parser": {
"syntax": "typescript",
"decorators": true,
"dynamicImport": true
},
"transform": {
"decoratorMetadata": true,
"legacyDecorator": true
},
"keepClassNames": true,
"externalHelpers": true,
"loose": true
},
"module": {
"type": "commonjs",
"strict": true,
"noInterop": true
},
"sourceMaps": true,
"exclude": [
"jest.config.ts",
".*\\.spec.tsx?$",
".*\\.test.tsx?$",
"./src/jest-setup.ts$",
"./**/jest-setup.ts$",
".*.js$"
]
}
11 changes: 11 additions & 0 deletions packages/vibrant-migrator/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# vibrant-migrator

This library was generated with [Nx](https://nx.dev).

## Building

Run `nx build vibrant-migrator` to build the library.

## Running unit tests

Run `nx test vibrant-migrator` to execute the unit tests via [Jest](https://jestjs.io).
18 changes: 18 additions & 0 deletions packages/vibrant-migrator/bin/codemod.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/* eslint-disable no-console */

const path = require('node:path');
const { run: jscodeshift } = require('jscodeshift/src/Runner');
const [, , transformer, target] = process.argv;
const transformPath = path.resolve(__dirname, `../src/lib/${transformer}.js`);
const paths = [target];
const options = {
print: true,
verbose: 1,
parser: 'tsx',
};

(async () => {
const res = await jscodeshift(transformPath, paths, options);

console.log(res);
})();
5 changes: 5 additions & 0 deletions packages/vibrant-migrator/bin/codemod.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env node

'use strict';

require('./codemod.js');
30 changes: 30 additions & 0 deletions packages/vibrant-migrator/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/* eslint-disable */
import { readFileSync } from 'fs';

// Reading the SWC compilation config and remove the "exclude"
// for the test files to be compiled by SWC
const { exclude: _, ...swcJestConfig } = JSON.parse(
readFileSync(`${__dirname}/.swcrc`, 'utf-8')
);

// disable .swcrc look-up by SWC core because we're passing in swcJestConfig ourselves.
// If we do not disable this, SWC Core will read .swcrc and won't transform our test files due to "exclude"
if (swcJestConfig.swcrc === undefined) {
swcJestConfig.swcrc = false;
}

// Uncomment if using global setup/teardown files being transformed via swc
// https://nx.dev/packages/jest/documents/overview#global-setup/teardown-with-nx-libraries
// jest needs EsModule Interop to find the default exported setup/teardown functions
// swcJestConfig.module.noInterop = false;

export default {
displayName: 'vibrant-migrator',
preset: '../../jest.preset.js',
transform: {
'^.+\\.[tj]s$': ['@swc/jest', swcJestConfig],
},
moduleFileExtensions: ['ts', 'js', 'html'],
runner: 'jest-runner',
testEnvironment: 'node',
};
8 changes: 8 additions & 0 deletions packages/vibrant-migrator/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "@vibrant-ui/migrator",
"version": "0.0.1",
"type": "commonjs",
"bin": {
"vibrant-migrator": "./bin/codemod.js"
}
}
69 changes: 69 additions & 0 deletions packages/vibrant-migrator/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
{
"name": "vibrant-migrator",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "packages/vibrant-migrator/src",
"projectType": "library",
"targets": {
"build": {
"executor": "@nx/js:swc",
"outputs": ["{options.outputPath}"],
"options": {
"outputPath": "dist/packages/vibrant-migrator",
"main": "packages/vibrant-migrator/src/index.ts",
"tsConfig": "packages/vibrant-migrator/tsconfig.lib.json",
"assets": ["packages/vibrant-migrator/*.md", "packages/vibrant-migrator/bin/*"]
}
},
"typecheck": {
"executor": "nx:run-commands",
"options": {
"commands": ["yarn tsc --project ./packages/vibrant-migrator/tsconfig.lib.json"]
}
},
"lint": {
"executor": "@nx/linter:eslint",
"outputs": ["{options.outputFile}"],
"options": {
"lintFilePatterns": ["packages/vibrant-migrator/**/*.ts"]
}
},
"test": {
"executor": "@nx/jest:jest",
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
"options": {
"jestConfig": "packages/vibrant-migrator/jest.config.ts",
"passWithNoTests": true
},
"configurations": {
"ci": {
"ci": true,
"codeCoverage": true
}
}
},
"version": {
"executor": "@jscutlery/semver:version",
"dependsOn": ["build-native"],
"options": {
"preset": "conventional",
"skipCommit": true,
"trackDeps": true,
"postTargets": ["vibrant-migrator:github", "vibrant-migrator:deploy"]
}
},
"github": {
"executor": "@jscutlery/semver:github",
"options": {
"tag": "${tag}",
"notes": "${notes}"
}
},
"deploy": {
"executor": "ngx-deploy-npm:deploy",
"options": {
"access": "public"
}
}
},
"tags": []
}
1 change: 1 addition & 0 deletions packages/vibrant-migrator/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import './lib/ui-system/title-replace';
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { Title, Body } from "@class101/ui-system";

export const Hello = () => <Title>hello</Title>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { Body } from "@class101/ui-system";
import { Title } from "@vibrant-ui/components";

export const Hello = () => <Title>hello</Title>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { defineTest } from 'jscodeshift/src/testUtils';

describe('Migrate Title Component', () => {
defineTest(__dirname, './title-replace', null, 'title-replace/basic', { parser: 'babel' });
});
23 changes: 23 additions & 0 deletions packages/vibrant-migrator/src/lib/ui-system/title-replace.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import type { API, FileInfo } from 'jscodeshift';
import { addImportVariable } from '../utils/addImportVariable';
import { findImportDeclarations } from '../utils/findImportDeclarations';
import { removeImportVariable } from '../utils/removeImportVariable';

export default function transformer(file: FileInfo, { jscodeshift }: API) {
const root = jscodeshift(file.source);

const uiSystemImports = findImportDeclarations({ root, importPackage: '@class101/ui-system', jscodeshift });

uiSystemImports.forEach(path => {
removeImportVariable({ importPath: path, variableName: 'Title', jscodeshift });

addImportVariable({
importPath: path,
variableName: 'Title',
packageName: '@vibrant-ui/components',
jscodeshift,
});
});

return root.toSource();
}
20 changes: 20 additions & 0 deletions packages/vibrant-migrator/src/lib/utils/addImportVariable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { API, ASTPath, ImportDeclaration } from 'jscodeshift';

type AddImportVariableParams = {
importPath: ASTPath<ImportDeclaration>;
variableName: string;
packageName: string;
jscodeshift: API['jscodeshift'];
};

export function addImportVariable({ importPath, variableName, packageName, jscodeshift }: AddImportVariableParams) {
try {
jscodeshift(importPath).insertAfter(
jscodeshift.importDeclaration(
[jscodeshift.importSpecifier(jscodeshift.identifier(variableName))],
jscodeshift.literal(packageName)
)
);
// eslint-disable-next-line no-empty
} catch {}
}
12 changes: 12 additions & 0 deletions packages/vibrant-migrator/src/lib/utils/findImportDeclarations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { API, Collection } from 'jscodeshift';
import { ImportDeclaration } from 'jscodeshift';

type FindImportDeclarationsParams = {
root: Collection;
importPackage: string;
jscodeshift: API['jscodeshift'];
};

export function findImportDeclarations({ root, importPackage }: FindImportDeclarationsParams) {
return root.find(ImportDeclaration, node => node.type === 'ImportDeclaration' && node.source.value === importPackage);
}
22 changes: 22 additions & 0 deletions packages/vibrant-migrator/src/lib/utils/removeImportVariable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import type { API, ASTPath, ImportDeclaration } from 'jscodeshift';

type RemoveImportVariableParams = {
importPath: ASTPath<ImportDeclaration>;
variableName: string;
jscodeshift: API['jscodeshift'];
};

export function removeImportVariable({ importPath, variableName, jscodeshift }: RemoveImportVariableParams) {
const importDeclaration = importPath.node;
const importVariables = (importDeclaration.specifiers ?? []).filter(
specifier => specifier.type !== 'ImportSpecifier' || specifier.imported.name !== variableName
);

if (importVariables.length === 0) {
jscodeshift(importDeclaration.source).remove();

return;
}

jscodeshift(importPath).replaceWith(jscodeshift.importDeclaration(importVariables, importDeclaration.source));
}
Loading

0 comments on commit a8c48ab

Please sign in to comment.