-
Notifications
You must be signed in to change notification settings - Fork 1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(cli): avoid
npx
during upgrade command (#10479)
**Problem** Fixes #10466. During `yarn rw upgrade` we check the version of `npx` installed. It's entirely possible that `npx` is not available or installed. We only do this check because we have to handle dedupe differently between yarn v1 and yarn >v1. We specify that redwood projects should be using yarn v4 using `"packageManager": "[email protected]"` in the `package.json`. Therefore when following the recommended setup users should not be using yarn v1 in their redwood projects. **Changes** 1. Avoid `npx` version check. 2. Skip dedupe step if for some reason have yarn v1. When this happens we log a warning message to tell the user to run a command manually to dedupe.
- Loading branch information
1 parent
942f296
commit 793c537
Showing
2 changed files
with
39 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
- fix(cli): avoid `npx` during upgrade command (#10479) by @Josh-Walker-GM | ||
|
||
This change fixes a problem with the `yarn rw upgrade` command when you don't have `npx` installed. If you don't have `npx` installed you will now have to manually run a command to dedupe dependencies rather than this being done for you automatically during the upgrade command. If this is the case, the `npx` command will be logged to the console when you run `yarn rw upgrade`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,7 +20,7 @@ export const builder = (yargs) => { | |
yargs | ||
.example( | ||
'rw upgrade -t 0.20.1-canary.5', | ||
'Specify a version. URL for Version History:\nhttps://www.npmjs.com/package/@redwoodjs/core' | ||
'Specify a version. URL for Version History:\nhttps://www.npmjs.com/package/@redwoodjs/core', | ||
) | ||
.option('dry-run', { | ||
alias: 'd', | ||
|
@@ -49,11 +49,11 @@ export const builder = (yargs) => { | |
.epilogue( | ||
`Also see the ${terminalLink( | ||
'Redwood CLI Reference for the upgrade command', | ||
'https://redwoodjs.com/docs/cli-commands#upgrade' | ||
'https://redwoodjs.com/docs/cli-commands#upgrade', | ||
)}.\nAnd the ${terminalLink( | ||
'GitHub releases page', | ||
'https://github.com/redwoodjs/redwood/releases' | ||
)} for more information on the current release.` | ||
'https://github.com/redwoodjs/redwood/releases', | ||
)} for more information on the current release.`, | ||
) | ||
} | ||
|
||
|
@@ -76,8 +76,8 @@ export const validateTag = (tag) => { | |
// Stop execution | ||
throw new Error( | ||
c.error( | ||
"Invalid tag supplied. Supported values: 'rc', 'canary', 'latest', 'next', 'experimental', or a valid semver version\n" | ||
) | ||
"Invalid tag supplied. Supported values: 'rc', 'canary', 'latest', 'next', 'experimental', or a valid semver version\n", | ||
), | ||
) | ||
} | ||
|
||
|
@@ -132,19 +132,19 @@ export const handler = async ({ dryRun, tag, verbose, dedupe }) => { | |
const version = ctx.versionToUpgradeTo | ||
const messageSections = [ | ||
`One more thing...\n\n ${c.warning( | ||
`🎉 Your project has been upgraded to RedwoodJS ${version}!` | ||
`🎉 Your project has been upgraded to RedwoodJS ${version}!`, | ||
)} \n\n`, | ||
] | ||
// Show links when switching to 'latest' or 'rc', undefined is essentially an alias of 'latest' | ||
if ([undefined, 'latest', 'rc'].includes(tag)) { | ||
messageSections.push( | ||
` Please review the release notes for any manual steps: \n ❖ ${terminalLink( | ||
`Redwood community discussion`, | ||
`https://community.redwoodjs.com/search?q=${version}%23announcements` | ||
`https://community.redwoodjs.com/search?q=${version}%23announcements`, | ||
)}\n ❖ ${terminalLink( | ||
`GitHub Release notes`, | ||
`https://github.com/redwoodjs/redwood/releases` // intentionally not linking to specific version | ||
)} \n\n` | ||
`https://github.com/redwoodjs/redwood/releases`, // intentionally not linking to specific version | ||
)} \n\n`, | ||
) | ||
} | ||
// @MARK | ||
|
@@ -157,14 +157,14 @@ export const handler = async ({ dryRun, tag, verbose, dedupe }) => { | |
isValidRedwoodJSTag(tag) | ||
) { | ||
additionalMessages.push( | ||
` ❖ You may want to update your redwood.toml config so that \`notifications.versionUpdates\` includes "${tag}"\n` | ||
` ❖ You may want to update your redwood.toml config so that \`notifications.versionUpdates\` includes "${tag}"\n`, | ||
) | ||
} | ||
// Append additional messages with a header | ||
if (additionalMessages.length > 0) { | ||
messageSections.push( | ||
` 📢 ${c.warning(`We'd also like to remind you that:`)} \n`, | ||
...additionalMessages | ||
...additionalMessages, | ||
) | ||
} | ||
} | ||
|
@@ -175,7 +175,7 @@ export const handler = async ({ dryRun, tag, verbose, dedupe }) => { | |
{ | ||
renderer: verbose && 'verbose', | ||
rendererOptions: { collapseSubtasks: false }, | ||
} | ||
}, | ||
) | ||
|
||
await tasks.run() | ||
|
@@ -192,11 +192,11 @@ async function yarnInstall({ verbose }) { | |
stdio: verbose ? 'inherit' : 'pipe', | ||
|
||
cwd: getPaths().base, | ||
} | ||
}, | ||
) | ||
} catch (e) { | ||
throw new Error( | ||
'Could not finish installation. Please run `yarn install` and then `yarn dedupe`, before continuing' | ||
'Could not finish installation. Please run `yarn install` and then `yarn dedupe`, before continuing', | ||
) | ||
} | ||
} | ||
|
@@ -205,7 +205,7 @@ async function setLatestVersionToContext(ctx, tag) { | |
try { | ||
const foundVersion = await latestVersion( | ||
'@redwoodjs/core', | ||
tag ? { version: tag } : {} | ||
tag ? { version: tag } : {}, | ||
) | ||
|
||
ctx.versionToUpgradeTo = foundVersion | ||
|
@@ -220,12 +220,12 @@ async function setLatestVersionToContext(ctx, tag) { | |
*/ | ||
function updatePackageJsonVersion(pkgPath, version, { dryRun, verbose }) { | ||
const pkg = JSON.parse( | ||
fs.readFileSync(path.join(pkgPath, 'package.json'), 'utf-8') | ||
fs.readFileSync(path.join(pkgPath, 'package.json'), 'utf-8'), | ||
) | ||
|
||
if (pkg.dependencies) { | ||
for (const depName of Object.keys(pkg.dependencies).filter( | ||
(x) => x.startsWith('@redwoodjs/') && x !== '@redwoodjs/studio' | ||
(x) => x.startsWith('@redwoodjs/') && x !== '@redwoodjs/studio', | ||
)) { | ||
if (verbose || dryRun) { | ||
console.log(` - ${depName}: ${pkg.dependencies[depName]} => ${version}`) | ||
|
@@ -235,11 +235,11 @@ function updatePackageJsonVersion(pkgPath, version, { dryRun, verbose }) { | |
} | ||
if (pkg.devDependencies) { | ||
for (const depName of Object.keys(pkg.devDependencies).filter( | ||
(x) => x.startsWith('@redwoodjs/') && x !== '@redwoodjs/studio' | ||
(x) => x.startsWith('@redwoodjs/') && x !== '@redwoodjs/studio', | ||
)) { | ||
if (verbose || dryRun) { | ||
console.log( | ||
` - ${depName}: ${pkg.devDependencies[depName]} => ${version}` | ||
` - ${depName}: ${pkg.devDependencies[depName]} => ${version}`, | ||
) | ||
} | ||
pkg.devDependencies[depName] = `${version}` | ||
|
@@ -249,7 +249,7 @@ function updatePackageJsonVersion(pkgPath, version, { dryRun, verbose }) { | |
if (!dryRun) { | ||
fs.writeFileSync( | ||
path.join(pkgPath, 'package.json'), | ||
JSON.stringify(pkg, undefined, 2) | ||
JSON.stringify(pkg, undefined, 2), | ||
) | ||
} | ||
} | ||
|
@@ -274,7 +274,7 @@ function updateRedwoodDepsForAllSides(ctx, options) { | |
updatePackageJsonVersion(basePath, ctx.versionToUpgradeTo, options), | ||
skip: () => !fs.existsSync(pkgJsonPath), | ||
} | ||
}) | ||
}), | ||
) | ||
} | ||
|
||
|
@@ -318,13 +318,13 @@ async function updatePackageVersionsFromTemplate(ctx, { dryRun, verbose }) { | |
if (!depName.startsWith('@redwoodjs/')) { | ||
if (verbose || dryRun) { | ||
console.log( | ||
` - ${depName}: ${localPackageJson.dependencies[depName]} => ${depVersion}` | ||
` - ${depName}: ${localPackageJson.dependencies[depName]} => ${depVersion}`, | ||
) | ||
} | ||
|
||
localPackageJson.dependencies[depName] = depVersion | ||
} | ||
} | ||
}, | ||
) | ||
|
||
Object.entries(templatePackageJson.devDependencies || {}).forEach( | ||
|
@@ -333,25 +333,25 @@ async function updatePackageVersionsFromTemplate(ctx, { dryRun, verbose }) { | |
if (!depName.startsWith('@redwoodjs/')) { | ||
if (verbose || dryRun) { | ||
console.log( | ||
` - ${depName}: ${localPackageJson.devDependencies[depName]} => ${depVersion}` | ||
` - ${depName}: ${localPackageJson.devDependencies[depName]} => ${depVersion}`, | ||
) | ||
} | ||
|
||
localPackageJson.devDependencies[depName] = depVersion | ||
} | ||
} | ||
}, | ||
) | ||
|
||
if (!dryRun) { | ||
fs.writeFileSync( | ||
pkgJsonPath, | ||
JSON.stringify(localPackageJson, null, 2) | ||
JSON.stringify(localPackageJson, null, 2), | ||
) | ||
} | ||
}, | ||
skip: () => !fs.existsSync(pkgJsonPath), | ||
} | ||
}) | ||
}), | ||
) | ||
} | ||
|
||
|
@@ -366,7 +366,7 @@ async function refreshPrismaClient(task, { verbose }) { | |
} catch (e) { | ||
task.skip('Refreshing the Prisma client caused an Error.') | ||
console.log( | ||
'You may need to update your prisma client manually: $ yarn rw prisma generate' | ||
'You may need to update your prisma client manually: $ yarn rw prisma generate', | ||
) | ||
console.log(c.error(e.message)) | ||
} | ||
|
@@ -390,11 +390,6 @@ export const getCmdMajorVersion = async (command) => { | |
const dedupeDeps = async (task, { verbose }) => { | ||
try { | ||
const yarnVersion = await getCmdMajorVersion('yarn') | ||
const npxVersion = await getCmdMajorVersion('npx') | ||
let npxArgs = [] | ||
if (npxVersion > 6) { | ||
npxArgs = ['--yes'] | ||
} | ||
|
||
const baseExecaArgsForDedupe = { | ||
shell: true, | ||
|
@@ -404,16 +399,18 @@ const dedupeDeps = async (task, { verbose }) => { | |
if (yarnVersion > 1) { | ||
await execa('yarn', ['dedupe'], baseExecaArgsForDedupe) | ||
} else { | ||
await execa( | ||
'npx', | ||
[...npxArgs, 'yarn-deduplicate'], | ||
baseExecaArgsForDedupe | ||
// Redwood projects should not be using yarn 1.x as we specify a version of yarn in the package.json | ||
// with "packageManager": "[email protected]" or similar. | ||
// Although we could (and previous did) automatically run `npx yarn-deduplicate` here, that would require | ||
// the user to have `npx` installed, which is not guaranteed and we do not wish to enforce that. | ||
task.skip( | ||
"Yarn 1.x doesn't support dedupe directly. Please upgrade yarn or use npx with `npx yarn-deduplicate` manually.", | ||
) | ||
} | ||
} catch (e) { | ||
console.log(c.error(e.message)) | ||
throw new Error( | ||
'Could not finish de-duplication. For yarn 1.x, please run `npx yarn-deduplicate`, or for yarn 3 run `yarn dedupe` before continuing' | ||
'Could not finish de-duplication. For yarn 1.x, please run `npx yarn-deduplicate`, or for yarn 3 run `yarn dedupe` before continuing', | ||
) | ||
} | ||
await yarnInstall({ verbose }) | ||
|