mirror of
https://github.com/pnpm/pnpm.git
synced 2026-02-02 19:22:52 -05:00
feat: check the engine when excute the create command (#9775)
* feat: check the engine when excute the create command * chore: test case * test: update * fix: update * fix: update * refactor: use readProjectManifestOnly to do engine checks on dependencies executed by dlx --------- Co-authored-by: Zoltan Kochan <z@kochan.io>
This commit is contained in:
5
.changeset/huge-apples-hang.md
Normal file
5
.changeset/huge-apples-hang.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@pnpm/plugin-commands-script-runners": patch
|
||||
---
|
||||
|
||||
When executing the `pnpm create` command, must verify whether the node version is supported even if a cache already exists.
|
||||
@@ -73,6 +73,7 @@
|
||||
"@pnpm/logger": "catalog:"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@pnpm/env.system-node-version": "workspace:*",
|
||||
"@pnpm/filter-workspace-packages": "workspace:*",
|
||||
"@pnpm/logger": "workspace:*",
|
||||
"@pnpm/plugin-commands-script-runners": "workspace:*",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import fs, { type Stats } from 'fs'
|
||||
import path from 'path'
|
||||
import util from 'util'
|
||||
import { docsUrl } from '@pnpm/cli-utils'
|
||||
import { docsUrl, readProjectManifestOnly } from '@pnpm/cli-utils'
|
||||
import { createResolver } from '@pnpm/client'
|
||||
import { parseWantedDependency } from '@pnpm/parse-wanted-dependency'
|
||||
import { OUTPUT_OPTIONS } from '@pnpm/common-cli-options-help'
|
||||
@@ -11,7 +11,7 @@ import { PnpmError } from '@pnpm/error'
|
||||
import { add } from '@pnpm/plugin-commands-installation'
|
||||
import { readPackageJsonFromDir } from '@pnpm/read-package-json'
|
||||
import { getBinsFromPackageManifest } from '@pnpm/package-bins'
|
||||
import { type PnpmSettings, type SupportedArchitectures } from '@pnpm/types'
|
||||
import { type PackageManifest, type PnpmSettings, type SupportedArchitectures } from '@pnpm/types'
|
||||
import { lexCompare } from '@pnpm/util.lex-comparator'
|
||||
import execa from 'execa'
|
||||
import pick from 'ramda/src/pick'
|
||||
@@ -138,15 +138,14 @@ export async function handler (
|
||||
}
|
||||
}
|
||||
}
|
||||
const modulesDir = path.join(cachedDir, 'node_modules')
|
||||
const binsDir = path.join(modulesDir, '.bin')
|
||||
const binsDir = path.join(cachedDir, 'node_modules/.bin')
|
||||
const env = makeEnv({
|
||||
userAgent: opts.userAgent,
|
||||
prependPaths: [binsDir, ...opts.extraBinPaths],
|
||||
})
|
||||
const binName = opts.package
|
||||
? command
|
||||
: await getBinName(modulesDir, await getPkgName(cachedDir))
|
||||
: await getBinName(cachedDir, opts)
|
||||
try {
|
||||
await execa(binName, args, {
|
||||
cwd: process.cwd(),
|
||||
@@ -174,9 +173,10 @@ async function getPkgName (pkgDir: string): Promise<string> {
|
||||
return dependencyNames[0]
|
||||
}
|
||||
|
||||
async function getBinName (modulesDir: string, pkgName: string): Promise<string> {
|
||||
const pkgDir = path.join(modulesDir, pkgName)
|
||||
const manifest = await readPackageJsonFromDir(pkgDir)
|
||||
async function getBinName (cachedDir: string, opts: Pick<DlxCommandOptions, 'engineStrict'>): Promise<string> {
|
||||
const pkgName = await getPkgName(cachedDir)
|
||||
const pkgDir = path.join(cachedDir, 'node_modules', pkgName)
|
||||
const manifest = await readProjectManifestOnly(pkgDir, opts) as PackageManifest
|
||||
const bins = await getBinsFromPackageManifest(manifest, pkgDir)
|
||||
if (bins.length === 0) {
|
||||
throw new PnpmError('DLX_NO_BIN', `No binaries found in ${pkgName}`)
|
||||
|
||||
@@ -2,6 +2,7 @@ import fs from 'fs'
|
||||
import path from 'path'
|
||||
import { add } from '@pnpm/plugin-commands-installation'
|
||||
import { dlx } from '@pnpm/plugin-commands-script-runners'
|
||||
import * as systemNodeVersion from '@pnpm/env.system-node-version'
|
||||
import { prepareEmpty } from '@pnpm/prepare'
|
||||
import { DLX_DEFAULT_OPTS as DEFAULT_OPTS } from './utils'
|
||||
|
||||
@@ -235,6 +236,20 @@ test('dlx with cache', async () => {
|
||||
expect(spy).not.toHaveBeenCalled()
|
||||
|
||||
spy.mockRestore()
|
||||
|
||||
// Specify a node version that shx@0.3.4 does not support. Currently supported versions are >= 6.
|
||||
const spySystemNodeVersion = jest.spyOn(systemNodeVersion, 'getSystemNodeVersion').mockReturnValue('v4.0.0')
|
||||
|
||||
await expect(dlx.handler({
|
||||
...DEFAULT_OPTS,
|
||||
engineStrict: true,
|
||||
dir: path.resolve('project'),
|
||||
storeDir: path.resolve('store'),
|
||||
cacheDir: path.resolve('cache'),
|
||||
dlxCacheMaxAge: Infinity,
|
||||
}, ['shx@0.3.4', 'touch', 'foo'])).rejects.toThrow('Unsupported engine for')
|
||||
|
||||
spySystemNodeVersion.mockRestore()
|
||||
})
|
||||
|
||||
test('dlx does not reuse expired cache', async () => {
|
||||
|
||||
@@ -39,6 +39,9 @@
|
||||
{
|
||||
"path": "../../env/plugin-commands-env"
|
||||
},
|
||||
{
|
||||
"path": "../../env/system-node-version"
|
||||
},
|
||||
{
|
||||
"path": "../../packages/core-loggers"
|
||||
},
|
||||
|
||||
3
pnpm-lock.yaml
generated
3
pnpm-lock.yaml
generated
@@ -2747,6 +2747,9 @@ importers:
|
||||
specifier: 'catalog:'
|
||||
version: 4.3.0
|
||||
devDependencies:
|
||||
'@pnpm/env.system-node-version':
|
||||
specifier: workspace:*
|
||||
version: link:../../env/system-node-version
|
||||
'@pnpm/filter-workspace-packages':
|
||||
specifier: workspace:*
|
||||
version: link:../../workspace/filter-workspace-packages
|
||||
|
||||
Reference in New Issue
Block a user