Skip to content
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(codemod): change package version to latest #131

Merged
merged 1 commit into from
Jan 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 0 additions & 13 deletions packages/codemod/src/actions/migrate-action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ export async function migrateAction(projectPaths?: string[], options = {} as Mig
let step = 1;

p.intro(chalk.inverse(' Starting to migrate nextui to heroui '));
const spinner = p.spinner();

/** ======================== 1. Migrate package.json ======================== */
const runMigratePackageJson = getCanRunCodemod(codemod, 'package-json-package-name');
Expand All @@ -56,9 +55,7 @@ export async function migrateAction(projectPaths?: string[], options = {} as Mig
});

if (selectMigrate) {
spinner.start('Migrating package.json...');
await migrateJson(packagesJson);
spinner.stop('Migrated package.json');
}
step++;
}
Expand All @@ -76,9 +73,7 @@ export async function migrateAction(projectPaths?: string[], options = {} as Mig
// Store all the parsed content of the nextuiFiles
storeParsedContent(nextuiFiles);

spinner.start('Migrating import nextui to heroui...');
migrateImportPackageWithPaths(nextuiFiles);
spinner.stop('Migrated import nextui to heroui');
}
step++;
}
Expand All @@ -93,9 +88,7 @@ export async function migrateAction(projectPaths?: string[], options = {} as Mig
});

if (selectMigrateNextuiProvider) {
spinner.start('Migrating NextUIProvider to HeroUIProvider...');
migrateNextuiProvider(nextuiFiles);
spinner.stop('Migrated NextUIProvider to HeroUIProvider');
}
step++;
}
Expand All @@ -112,9 +105,7 @@ export async function migrateAction(projectPaths?: string[], options = {} as Mig
if (selectMigrateTailwindcss) {
const tailwindcssFiles = files.filter((file) => /tailwind\.config\.[jt]s/.test(file));

spinner.start('Migrating tailwindcss...');
migrateTailwindcss(tailwindcssFiles);
spinner.stop('Migrated tailwindcss');
}
step++;
}
Expand All @@ -129,9 +120,7 @@ export async function migrateAction(projectPaths?: string[], options = {} as Mig
});

if (selectMigrateCssVariables) {
spinner.start('Migrating css variables...');
migrateCssVariables(files);
spinner.stop('Migrated css variables');
}
step++;
}
Expand All @@ -150,9 +139,7 @@ export async function migrateAction(projectPaths?: string[], options = {} as Mig
});

if (selectMigrateNpmrc) {
spinner.start('Migrating npmrc...');
migrateNpmrc(npmrcFiles);
spinner.stop('Migrated npmrc');
}
step++;
}
Expand Down
31 changes: 29 additions & 2 deletions packages/codemod/src/helpers/actions/migrate/migrate-json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import type {SAFE_ANY} from '@helpers/type';
import {Logger} from '@helpers/logger';

import {HEROUI_PREFIX, NEXTUI_PREFIX} from '../../../constants/prefix';
import {fetchPackageLatestVersion} from '../../https';
import {safeParseJson} from '../../parse';
import {getStore, writeFileAndUpdateStore} from '../../store';

const DEFAULT_INDENT = 2;
Expand All @@ -13,17 +15,42 @@ export function detectIndent(content: string): number {
return match ? match[1]?.length || DEFAULT_INDENT : DEFAULT_INDENT;
}

function filterHeroUiPkgs(pkgs: string[]) {
return pkgs.filter((pkg) => pkg.includes(HEROUI_PREFIX) || pkg.includes(NEXTUI_PREFIX));
}

export async function migrateJson(files: string[]) {
try {
await Promise.all(
files.map((file) => {
files.map(async (file) => {
const content = getStore(file, 'rawContent');
const dirtyFlag = content.includes(NEXTUI_PREFIX);

if (dirtyFlag) {
const replacedContent = content.replaceAll(NEXTUI_PREFIX, HEROUI_PREFIX);
const json = safeParseJson(replacedContent);

try {
await Promise.all([
...filterHeroUiPkgs(Object.keys(json.dependencies)).map(async (key) => {
const version = await fetchPackageLatestVersion(key);

json.dependencies[key] = version;
}),
...filterHeroUiPkgs(Object.keys(json.devDependencies)).map(async (key) => {
const version = await fetchPackageLatestVersion(key);

json.devDependencies[key] = version;
})
]);
} catch (error) {
Logger.warn(
`Migrate ${file} failed\n${error}\nYou need to manually migrate the rest of the packages.`
);
}
const indent = detectIndent(content);

writeFileAndUpdateStore(file, 'rawContent', replacedContent);
writeFileAndUpdateStore(file, 'rawContent', JSON.stringify(json, null, indent));
}
})
);
Expand Down
61 changes: 61 additions & 0 deletions packages/codemod/src/helpers/https.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import chalk from 'chalk';
import ora from 'ora';

export async function fetchPackageLatestVersion(packageName: string): Promise<string> {
const text = `Fetching ${packageName} version`;
const spinner = ora({
discardStdin: false,
spinner: {
frames: [
`⠋ ${chalk.gray(`${text}.`)}`,
`⠙ ${chalk.gray(`${text}..`)}`,
`⠹ ${chalk.gray(`${text}...`)}`,
`⠸ ${chalk.gray(`${text}.`)}`,
`⠼ ${chalk.gray(`${text}..`)}`,
`⠴ ${chalk.gray(`${text}...`)}`,
`⠦ ${chalk.gray(`${text}.`)}`,
`⠧ ${chalk.gray(`${text}..`)}`,
`⠇ ${chalk.gray(`${text}...`)}`,
`⠏ ${chalk.gray(`${text}.`)}`
],
interval: 150
}
});

spinner.start();

try {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 15000); // 15 seconds timeout

const response = await fetch(`https://registry.npmjs.org/${packageName}/latest`, {
headers: {
Accept: 'application/json'
},
signal: controller.signal
});

clearTimeout(timeoutId);

if (!response.ok) {
throw new Error(`Request failed with status ${response.status}`);
}

const data = await response.json();

return (data as {version: string}).version;
} catch (error) {
if (error instanceof Error) {
if (error.name === 'AbortError') {
throw new Error('Request timeout');
}
if (error.message.includes('fetch failed')) {
throw new Error('Connection failed. Please check your network connection.');
}
throw error;
}
throw new Error('Parse version info failed');
} finally {
spinner.stop();
}
}
8 changes: 8 additions & 0 deletions packages/codemod/src/helpers/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,11 @@ export function parseContent(path: string): Collection<SAFE_ANY> | undefined {
return;
}
}

export function safeParseJson(content: string) {
try {
return JSON.parse(content);
} catch {
return {};
}
}
Loading