Skip to content

Commit

Permalink
next-upgrade: Default to release channel that's used (#70638)
Browse files Browse the repository at this point in the history
  • Loading branch information
eps1lon authored Oct 1, 2024
1 parent 0249bdf commit 33f8f62
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 113 deletions.
7 changes: 6 additions & 1 deletion packages/next-codemod/bin/next-codemod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,12 @@ program

.argument(
'[revision]',
'NPM dist tag or exact version to upgrade to (e.g. "latest" or "15.0.0-canary.167"). Prompts to choose a dist tag if omitted.'
'NPM dist tag or exact version to upgrade to (e.g. "latest" or "15.0.0-canary.167"). Valid dist-tags are "latest", "canary" or "rc".',
packageJson.version.includes('-canary.')
? 'canary'
: packageJson.version.includes('-rc.')
? 'rc'
: 'latest'
)
.option('--verbose', 'Verbose output', false)
.action(runUpgrade)
Expand Down
121 changes: 9 additions & 112 deletions packages/next-codemod/bin/upgrade.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,8 @@ import { availableCodemods } from '../lib/codemods'
import { getPkgManager, installPackages } from '../lib/handle-package'
import { runTransform } from './transform'

type StandardVersionSpecifier = 'canary' | 'rc' | 'latest'
type CustomVersionSpecifier = string
type VersionSpecifier = StandardVersionSpecifier | CustomVersionSpecifier
type PackageManager = 'pnpm' | 'npm' | 'yarn' | 'bun'

interface Response {
version: StandardVersionSpecifier
}

/**
* @param query
* @example loadHighestNPMVersionMatching("react@^18.3.0 || ^19.0.0") === Promise<"19.0.0">
Expand Down Expand Up @@ -50,93 +43,18 @@ export async function runUpgrade(
version: string
peerDependencies: Record<string, string>
}
let targetVersionSpecifier: VersionSpecifier = ''

if (revision !== undefined) {
const res = await fetch(`https://registry.npmjs.org/next/${revision}`)
if (res.status === 200) {
targetNextPackageJson = await res.json()
targetVersionSpecifier = targetNextPackageJson.version
} else {
console.error(
`${chalk.yellow(`next@${revision}`)} does not exist. Check available versions at ${chalk.underline('https://www.npmjs.com/package/next?activeTab=versions')}, or choose one from below\n`
)
}
}

const installedNextVersion = await getInstalledNextVersion()

if (!targetNextPackageJson) {
let nextPackageJson: { [key: string]: any } = {}
try {
const resCanary = await fetch(`https://registry.npmjs.org/next/canary`)
nextPackageJson['canary'] = await resCanary.json()

const resRc = await fetch(`https://registry.npmjs.org/next/rc`)
nextPackageJson['rc'] = await resRc.json()

const resLatest = await fetch(`https://registry.npmjs.org/next/latest`)
nextPackageJson['latest'] = await resLatest.json()
} catch (error) {
console.error('Failed to fetch versions from npm registry.')
return
}

let showRc = true
if (nextPackageJson['latest'].version && nextPackageJson['rc'].version) {
showRc =
compareVersions(
nextPackageJson['rc'].version,
nextPackageJson['latest'].version
) === 1
}

const choices = [
{
title: 'Canary',
value: 'canary',
description: `Experimental version with latest features (${nextPackageJson['canary'].version})`,
},
]
if (showRc) {
choices.push({
title: 'Release Candidate',
value: 'rc',
description: `Pre-release version for final testing (${nextPackageJson['rc'].version})`,
})
}
choices.push({
title: 'Stable',
value: 'latest',
description: `Production-ready release (${nextPackageJson['latest'].version})`,
})

if (installedNextVersion) {
console.log(
`You are currently using ${chalk.blue('Next.js ' + installedNextVersion)}`
)
}

const initialVersionSpecifierIdx = await getVersionSpecifierIdx(
installedNextVersion,
showRc
)

const response: Response = await prompts(
{
type: 'select',
name: 'version',
message: 'What Next.js version do you want to upgrade to?',
choices: choices,
initial: initialVersionSpecifierIdx,
},
{ onCancel: () => process.exit(0) }
const res = await fetch(`https://registry.npmjs.org/next/${revision}`)
if (res.status === 200) {
targetNextPackageJson = await res.json()
} else {
throw new Error(
`${chalk.yellow(`next@${revision}`)} does not exist. Check available versions at ${chalk.underline('https://www.npmjs.com/package/next?activeTab=versions')}.`
)

targetNextPackageJson = nextPackageJson[response.version]
targetVersionSpecifier = response.version
}

const installedNextVersion = await getInstalledNextVersion()

const targetNextVersion = targetNextPackageJson.version

// We're resolving a specific version here to avoid including "ugly" version queries
Expand Down Expand Up @@ -190,7 +108,7 @@ export async function runUpgrade(
}

console.log(
`Upgrading your project to ${chalk.blue('Next.js ' + targetVersionSpecifier)}...\n`
`Upgrading your project to ${chalk.blue('Next.js ' + targetNextVersion)}...\n`
)

installPackages([nextDependency, ...reactDependencies], {
Expand Down Expand Up @@ -244,27 +162,6 @@ async function getInstalledNextVersion(): Promise<string> {
return installedNextPackageJson.version
}

/*
* Returns the index of the current version's specifier in the
* array ['canary', 'rc', 'latest'] or ['canary', 'latest']
*/
async function getVersionSpecifierIdx(
installedNextVersion: string,
showRc: boolean
): Promise<number> {
if (installedNextVersion == null) {
return 0
}

if (installedNextVersion.includes('canary')) {
return 0
}
if (installedNextVersion.includes('rc')) {
return 1
}
return showRc ? 2 : 1
}

/*
* Heuristics are used to determine whether to Turbopack is enabled or not and
* to determine how to update the dev script.
Expand Down

0 comments on commit 33f8f62

Please sign in to comment.