Skip to content

Commit

Permalink
chore(next-codemod): suggest pre-release codemods by their "stable" v…
Browse files Browse the repository at this point in the history
…ersion (#71158)

### What?

Suggest pre-released codemods by their "stable" version.

### Why?

It is because if we suggest by the version range `(installed ~ target)`, pre-released codemods for the target version are not suggested when upgrading.
Let's say we have a codemod for `v15.0.0-canary.x`, and we're upgrading from `v15.x` -> `v15.x`.
Our initial version is higher than the codemod's version, so the codemod **will not be** suggested.

This is not ideal as the codemods for pre-releases are also targeting the major version.
Also, when the user attempts to run the upgrade command twice, and have installed the target version, the behavior must be **idempotent** and suggest the codemods including the pre-releases of the target version.

https://github.com/user-attachments/assets/db1ab0c0-fc4e-4170-bc91-b0a096b04cef
  • Loading branch information
devjiwonchoi authored Oct 11, 2024
1 parent d8c0539 commit 1bc31e7
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 63 deletions.
27 changes: 24 additions & 3 deletions packages/next-codemod/bin/upgrade.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import prompts from 'prompts'
import fs from 'fs'
import semver from 'semver'
import compareVersions from 'semver/functions/compare'
import { execSync } from 'child_process'
import path from 'path'
import { compareVersions } from 'compare-versions'
import pc from 'picocolors'
import { getPkgManager, installPackages } from '../lib/handle-package'
import { runTransform } from './transform'
Expand Down Expand Up @@ -306,9 +307,29 @@ async function suggestCodemods(
initialNextVersion: string,
targetNextVersion: string
): Promise<string[]> {
// Here we suggest pre-released codemods by their "stable" version.
// It is because if we suggest by the version range (installed ~ target),
// pre-released codemods for the target version are not suggested when upgrading.

// Let's say we have a codemod for v15.0.0-canary.x, and we're upgrading from
// v15.x -> v15.x. Our initial version is higher than the codemod's version,
// so the codemod will not be suggested.

// This is not ideal as the codemods for pre-releases are also targeting the major version.
// Also, when the user attempts to run the upgrade command twice, and have installed the
// target version, the behavior must be idempotent and suggest the codemods including the
// pre-releases of the target version.
const initial = semver.parse(initialNextVersion)
const initialVersionIndex = TRANSFORMER_INQUIRER_CHOICES.findIndex(
(versionCodemods) =>
compareVersions(versionCodemods.version, initialNextVersion) > 0
(versionCodemods) => {
const codemod = semver.parse(versionCodemods.version)
return (
compareVersions(
`${codemod.major}.${codemod.minor}.${codemod.patch}`,
`${initial.major}.${initial.minor}.${initial.patch}`
) >= 0
)
}
)
if (initialVersionIndex === -1) {
return []
Expand Down
22 changes: 11 additions & 11 deletions packages/next-codemod/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,64 +40,64 @@ export const TRANSFORMER_INQUIRER_CHOICES = [
title:
'Transform the deprecated automatically injected url property on top level pages to using withRouter',
value: 'url-to-withrouter',
version: '6.0',
version: '6.0.0',
},
{
title: 'Transforms the withAmp HOC into Next.js 9 page configuration',
value: 'withamp-to-config',
version: '8.0',
version: '8.0.0',
},
{
title:
'Transforms anonymous components into named components to make sure they work with Fast Refresh',
value: 'name-default-component',
version: '9.0',
version: '9.0.0',
},
{
title:
'Transforms files that do not import `React` to include the import in order for the new React JSX transform',
value: 'add-missing-react-import',
version: '10.0',
version: '10.0.0',
},
{
title:
'Automatically migrates a Create React App project to Next.js (experimental)',
value: 'cra-to-next',
version: '11.0',
version: '11.0.0',
},
{
title: 'Ensures your <Link> usage is backwards compatible',
value: 'new-link',
version: '13.0',
version: '13.0.0',
},
{
title:
'Dangerously migrates from `next/legacy/image` to the new `next/image` by adding inline styles and removing unused props (experimental)',
value: 'next-image-experimental',
version: '13.0',
version: '13.0.0',
},
{
title:
'Safely migrate Next.js 10, 11, 12 applications importing `next/image` to the renamed `next/legacy/image` import in Next.js 13',
value: 'next-image-to-legacy-image',
version: '13.0',
version: '13.0.0',
},
{
title: 'Uninstall `@next/font` and transform imports to `next/font`',
value: 'built-in-next-font',
version: '13.2',
version: '13.2.0',
},
{
title:
'Migrates certain viewport related metadata from the `metadata` export to a new `viewport` export',
value: 'metadata-to-viewport-export',
version: '14.0',
version: '14.0.0',
},
{
title:
'Transforms imports from `next/server` to `next/og` for usage of Dynamic OG Image Generation',
value: 'next-og-import',
version: '14.0',
version: '14.0.0',
},
{
title:
Expand Down
7 changes: 4 additions & 3 deletions packages/next-codemod/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@
"dependencies": {
"cheerio": "1.0.0-rc.9",
"commander": "12.1.0",
"compare-versions": "6.1.1",
"execa": "4.0.3",
"find-up": "4.1.0",
"globby": "11.0.1",
"is-git-clean": "1.1.0",
"jscodeshift": "17.0.0",
"picocolors": "1.0.0",
"prompts": "2.4.2"
"prompts": "2.4.2",
"semver": "7.6.3"
},
"files": [
"transforms/*.js",
Expand All @@ -36,6 +36,7 @@
"devDependencies": {
"@types/find-up": "4.0.0",
"@types/jscodeshift": "0.11.0",
"@types/prompts": "2.4.2"
"@types/prompts": "2.4.2",
"@types/semver": "7.3.1"
}
}
61 changes: 15 additions & 46 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 1bc31e7

Please sign in to comment.