feat: add an option to fail on unapproved dependency builds (#9071)

This commit is contained in:
Zoltan Kochan
2025-02-11 00:26:25 +01:00
committed by GitHub
parent e209a3559f
commit f6006f2b4b
51 changed files with 341 additions and 269 deletions

View File

@@ -0,0 +1,5 @@
---
"@pnpm/core": major
---
Changed the API of all the functions. Now they always return an ignoredBuilds array.

View File

@@ -0,0 +1,9 @@
---
"@pnpm/plugin-commands-installation": minor
"@pnpm/headless": minor
"@pnpm/core": minor
"@pnpm/config": minor
"pnpm": minor
---
Added a new setting called `strict-dep-builds`. When enabled, the installation will exit with a non-zero exit code if any dependencies have unreviewed build scripts (aka postinstall scripts) [#9071](https://github.com/pnpm/pnpm/pull/9071).

View File

@@ -213,6 +213,7 @@ export interface Config {
peersSuffixMaxLength?: number
strictStorePkgContentCheck: boolean
managePackageManagerVersions: boolean
strictDepBuilds: boolean
}
export interface ConfigWithDeprecatedSettings extends Config {

View File

@@ -168,6 +168,7 @@ export async function getConfig (opts: {
'save-peer': false,
'save-workspace-protocol': 'rolling',
'scripts-prepend-node-path': false,
'strict-dep-builds': false,
'side-effects-cache': true,
symlink: true,
'shared-workspace-lockfile': true,

View File

@@ -97,6 +97,7 @@ export const types = Object.assign({
'state-dir': String,
'store-dir': String,
stream: Boolean,
'strict-dep-builds': Boolean,
'strict-store-pkg-content-check': Boolean,
'strict-peer-dependencies': Boolean,
'use-beta-cli': Boolean,

View File

@@ -265,6 +265,7 @@
"undollar",
"uninstallation",
"unnest",
"unreviewed",
"unskip",
"unstar",
"usecase",

View File

@@ -141,9 +141,9 @@ type Opts = Omit<InstallOptions, 'allProjects'> & {
export async function install (
manifest: ProjectManifest,
opts: Opts
): Promise<ProjectManifest> {
): Promise<{ updatedManifest: ProjectManifest, ignoredBuilds: string[] | undefined }> {
const rootDir = (opts.dir ?? process.cwd()) as ProjectRootDir
const { updatedProjects: projects } = await mutateModules(
const { updatedProjects: projects, ignoredBuilds } = await mutateModules(
[
{
mutation: 'install',
@@ -165,7 +165,7 @@ export async function install (
}],
}
)
return projects[0].manifest
return { updatedManifest: projects[0].manifest, ignoredBuilds }
}
interface ProjectToBeInstalled {
@@ -193,7 +193,7 @@ export async function mutateModulesInSingleProject (
modulesDir?: string
},
maybeOpts: Omit<MutateModulesOptions, 'allProjects'> & InstallMutationOptions
): Promise<UpdatedProject> {
): Promise<{ updatedProject: UpdatedProject, ignoredBuilds: string[] | undefined }> {
const result = await mutateModules(
[
{
@@ -212,13 +212,14 @@ export async function mutateModulesInSingleProject (
}],
}
)
return result.updatedProjects[0]
return { updatedProject: result.updatedProjects[0], ignoredBuilds: result.ignoredBuilds }
}
export interface MutateModulesResult {
updatedProjects: UpdatedProject[]
stats: InstallationResultStats
depsRequiringBuild?: DepPath[]
ignoredBuilds: string[] | undefined
}
export async function mutateModules (
@@ -314,9 +315,10 @@ export async function mutateModules (
updatedProjects: result.updatedProjects,
stats: result.stats ?? { added: 0, removed: 0, linkedToRoot: 0 },
depsRequiringBuild: result.depsRequiringBuild,
ignoredBuilds: result.ignoredBuilds,
}
async function _install (): Promise<{ updatedProjects: UpdatedProject[], stats?: InstallationResultStats, depsRequiringBuild?: DepPath[] }> {
async function _install (): Promise<{ updatedProjects: UpdatedProject[], stats?: InstallationResultStats, depsRequiringBuild?: DepPath[], ignoredBuilds: string[] | undefined }> {
const scriptsOpts: RunLifecycleHooksConcurrentlyOptions = {
extraBinPaths: opts.extraBinPaths,
extraNodePaths: ctx.extraNodePaths,
@@ -469,6 +471,7 @@ Note that in CI environments, this setting is enabled by default.`,
await writeWantedLockfile(ctx.lockfileDir, ctx.wantedLockfile)
return {
updatedProjects: projects.map((mutatedProject) => ctx.projects[mutatedProject.rootDir]),
ignoredBuilds: undefined,
}
}
if (!ctx.existsNonEmptyWantedLockfile) {
@@ -482,7 +485,7 @@ Note that in CI environments, this setting is enabled by default.`,
logger.info({ message: 'Lockfile is up to date, resolution step is skipped', prefix: opts.lockfileDir })
}
try {
const { stats } = await headlessInstall({
const { stats, ignoredBuilds } = await headlessInstall({
...ctx,
...opts,
currentEngine: {
@@ -520,6 +523,7 @@ Note that in CI environments, this setting is enabled by default.`,
}
}),
stats,
ignoredBuilds,
}
} catch (error: any) { // eslint-disable-line
if (
@@ -691,6 +695,7 @@ Note that in CI environments, this setting is enabled by default.`,
updatedProjects: result.projects,
stats: result.stats,
depsRequiringBuild: result.depsRequiringBuild,
ignoredBuilds: result.ignoredBuilds,
}
}
}
@@ -760,9 +765,9 @@ export async function addDependenciesToPackage (
pinnedVersion?: 'major' | 'minor' | 'patch'
targetDependenciesField?: DependenciesField
} & InstallMutationOptions
): Promise<ProjectManifest> {
): Promise<{ updatedManifest: ProjectManifest, ignoredBuilds: string[] | undefined }> {
const rootDir = (opts.dir ?? process.cwd()) as ProjectRootDir
const { updatedProjects: projects } = await mutateModules(
const { updatedProjects: projects, ignoredBuilds } = await mutateModules(
[
{
allowNew: opts.allowNew,
@@ -790,7 +795,7 @@ export async function addDependenciesToPackage (
},
],
})
return projects[0].manifest
return { updatedManifest: projects[0].manifest, ignoredBuilds }
}
export type ImporterToUpdate = {
@@ -819,6 +824,7 @@ interface InstallFunctionResult {
projects: UpdatedProject[]
stats?: InstallationResultStats
depsRequiringBuild: DepPath[]
ignoredBuilds?: string[]
}
type InstallFunction = (
@@ -1031,6 +1037,7 @@ const _installInContext: InstallFunction = async (projects, ctx, opts) => {
}
let stats: InstallationResultStats | undefined
const allowBuild = createAllowBuildFunction(opts)
let ignoredBuilds: string[] | undefined
if (!opts.lockfileOnly && !isInstallationOnlyForLockfileCheck && opts.enableModulesDir) {
const result = await linkPackages(
projects,
@@ -1086,7 +1093,6 @@ const _installInContext: InstallFunction = async (projects, ctx, opts) => {
ctx.pendingBuilds = ctx.pendingBuilds
.filter((relDepPath) => !result.removedDepPaths.has(relDepPath))
let ignoredBuilds: string[] | undefined
if (result.newDepPaths?.length) {
if (opts.ignoreScripts) {
// we can use concat here because we always only append new packages, which are guaranteed to not be there by definition
@@ -1324,6 +1330,7 @@ const _installInContext: InstallFunction = async (projects, ctx, opts) => {
})),
stats,
depsRequiringBuild,
ignoredBuilds,
}
}
@@ -1380,7 +1387,7 @@ const installInContext: InstallFunction = async (projects, ctx, opts) => {
...opts,
lockfileOnly: true,
})
const { stats } = await headlessInstall({
const { stats, ignoredBuilds } = await headlessInstall({
...ctx,
...opts,
currentEngine: {
@@ -1398,6 +1405,7 @@ const installInContext: InstallFunction = async (projects, ctx, opts) => {
return {
...result,
stats,
ignoredBuilds,
}
}
}
@@ -1407,7 +1415,7 @@ const installInContext: InstallFunction = async (projects, ctx, opts) => {
...opts,
lockfileOnly: true,
})
const { stats } = await headlessInstall({
const { stats, ignoredBuilds } = await headlessInstall({
...ctx,
...opts,
currentEngine: {
@@ -1425,6 +1433,7 @@ const installInContext: InstallFunction = async (projects, ctx, opts) => {
return {
...result,
stats,
ignoredBuilds,
}
}
if (opts.lockfileOnly && ctx.existsCurrentLockfile) {

View File

@@ -41,7 +41,7 @@ test("don't fail on non-compatible node_modules when forced in a workspace", asy
const opts = testDefaults({ force: true })
process.chdir('pkg')
const manifest = await addDependenciesToPackage({}, ['is-positive@1.0.0'], testDefaults({ lockfileDir: path.resolve('..') }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['is-positive@1.0.0'], testDefaults({ lockfileDir: path.resolve('..') }))
rimraf('node_modules')
process.chdir('..')

View File

@@ -16,7 +16,7 @@ test('installation breaks if the lockfile contains the wrong checksum', async ()
await addDistTag({ package: '@pnpm.e2e/dep-of-pkg-with-1-dep', version: '100.0.0', distTag: 'latest' })
const project = prepareEmpty()
const manifest = await addDependenciesToPackage({},
const { updatedManifest: manifest } = await addDependenciesToPackage({},
[
'@pnpm.e2e/pkg-with-1-dep@100.0.0',
],
@@ -62,7 +62,7 @@ test('installation breaks if the lockfile contains the wrong checksum and the st
await addDistTag({ package: '@pnpm.e2e/dep-of-pkg-with-1-dep', version: '100.0.0', distTag: 'latest' })
const project = prepareEmpty()
const manifest = await addDependenciesToPackage({},
const { updatedManifest: manifest } = await addDependenciesToPackage({},
[
'@pnpm.e2e/pkg-with-1-dep@100.0.0',
],

View File

@@ -10,7 +10,7 @@ test('should fail to update when requests are cached', async () => {
await addDistTag({ package: '@pnpm.e2e/dep-of-pkg-with-1-dep', version: '100.0.0', distTag: 'latest' })
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/pkg-with-1-dep'], opts)
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/pkg-with-1-dep'], opts)
project.storeHas('@pnpm.e2e/dep-of-pkg-with-1-dep', '100.0.0')
@@ -26,7 +26,7 @@ test('should not cache when cache is not used', async () => {
await addDistTag({ package: '@pnpm.e2e/dep-of-pkg-with-1-dep', version: '100.0.0', distTag: 'latest' })
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/pkg-with-1-dep'], testDefaults({ save: true }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/pkg-with-1-dep'], testDefaults({ save: true }))
project.storeHas('@pnpm.e2e/dep-of-pkg-with-1-dep', '100.0.0')

View File

@@ -520,7 +520,7 @@ describe('add', () => {
dependencies: {},
}])
const updatedManifest = await addDependenciesToPackage(
const { updatedManifest } = await addDependenciesToPackage(
projects['project1' as ProjectId],
['is-positive@catalog:'],
{
@@ -550,7 +550,7 @@ describe('add', () => {
dependencies: {},
}])
const updatedManifest = await addDependenciesToPackage(
const { updatedManifest } = await addDependenciesToPackage(
projects['project1' as ProjectId],
['is-positive'],
{
@@ -580,7 +580,7 @@ describe('add', () => {
dependencies: {},
}])
const updatedManifest = await addDependenciesToPackage(
const { updatedManifest } = await addDependenciesToPackage(
projects['project1' as ProjectId],
['is-positive@1.0.0'],
{
@@ -610,7 +610,7 @@ describe('add', () => {
dependencies: {},
}])
const updatedManifest = await addDependenciesToPackage(
const { updatedManifest } = await addDependenciesToPackage(
projects['project1' as ProjectId],
['is-positive@2.0.0'],
{
@@ -648,7 +648,7 @@ describe('update', () => {
},
}])
const updatedManifest = await addDependenciesToPackage(
const { updatedManifest } = await addDependenciesToPackage(
projects['project1' as ProjectId],
['is-positive'],
{
@@ -699,7 +699,7 @@ describe('update', () => {
})
// Expecting the manifest to remain unchanged after running an update.
const updatedManifest = await addDependenciesToPackage(
const { updatedManifest } = await addDependenciesToPackage(
projects['project1' as ProjectId],
['is-positive'],
{
@@ -747,7 +747,7 @@ describe('update', () => {
'is-positive': { specifier: '1.0.0', version: '1.0.0' },
})
const updatedManifest = await addDependenciesToPackage(
const { updatedManifest } = await addDependenciesToPackage(
projects['project1' as ProjectId],
['is-positive'],
{

View File

@@ -57,7 +57,7 @@ test('installing with hoisted node-linker and no lockfile', async () => {
test('overwriting (is-positive@3.0.0 with is-positive@latest)', async () => {
const project = prepareEmpty()
const manifest = await addDependenciesToPackage(
const { updatedManifest: manifest } = await addDependenciesToPackage(
{},
['is-positive@3.0.0'],
testDefaults({ nodeLinker: 'hoisted', save: true })
@@ -65,7 +65,7 @@ test('overwriting (is-positive@3.0.0 with is-positive@latest)', async () => {
project.storeHas('is-positive', '3.0.0')
const updatedManifest = await addDependenciesToPackage(
const { updatedManifest } = await addDependenciesToPackage(
manifest,
['is-positive@latest'],
testDefaults({ nodeLinker: 'hoisted', save: true })
@@ -80,7 +80,7 @@ test('overwriting existing files in node_modules', async () => {
prepareEmpty()
await symlinkDir(__dirname, path.resolve('node_modules/is-positive'))
const manifest = await addDependenciesToPackage(
const { updatedManifest: manifest } = await addDependenciesToPackage(
{},
['is-positive@3.0.0'],
testDefaults({ nodeLinker: 'hoisted', save: true })
@@ -95,7 +95,7 @@ test('preserve subdeps on update', async () => {
await addDistTag({ package: '@pnpm.e2e/foobarqar', version: '1.0.0', distTag: 'latest' })
const manifest = await addDependenciesToPackage(
const { updatedManifest: manifest } = await addDependenciesToPackage(
{},
['@pnpm.e2e/foobarqar@1.0.0', '@pnpm.e2e/bar@100.1.0'],
testDefaults({ nodeLinker: 'hoisted' })
@@ -153,11 +153,11 @@ test('adding a new dependency to one of the workspace projects', async () => {
],
nodeLinker: 'hoisted',
}))).updatedProjects
manifest = await addDependenciesToPackage(
manifest = (await addDependenciesToPackage(
manifest,
['is-negative@1.0.0'],
testDefaults({ nodeLinker: 'hoisted', prefix: path.resolve('project-1'), targetDependenciesField: 'devDependencies' })
)
)).updatedManifest
expect(manifest.dependencies).toStrictEqual({ '@pnpm.e2e/bar': '100.0.0' })
expect(manifest.devDependencies).toStrictEqual({ 'is-negative': '1.0.0' })

View File

@@ -14,7 +14,7 @@ import { testDefaults } from './../utils'
test('uninstall package with no dependencies', async () => {
const project = prepareEmpty()
let manifest = await addDependenciesToPackage(
let { updatedManifest: manifest } = await addDependenciesToPackage(
{},
['is-negative@2.1.0'],
testDefaults({ save: true, nodeLinker: 'hoisted' })
@@ -26,7 +26,7 @@ test('uninstall package with no dependencies', async () => {
manifest,
mutation: 'uninstallSome',
rootDir: process.cwd() as ProjectRootDir,
}, testDefaults({ nodeLinker: 'hoisted', save: true, reporter }))).manifest
}, testDefaults({ nodeLinker: 'hoisted', save: true, reporter }))).updatedProject.manifest
expect(reporter.calledWithMatch({
initial: {
@@ -74,7 +74,7 @@ test('uninstall package with no dependencies', async () => {
test('uninstall package with dependencies and do not touch other deps', async () => {
const project = prepareEmpty()
let manifest = await addDependenciesToPackage(
let { updatedManifest: manifest } = await addDependenciesToPackage(
{},
['is-negative@2.1.0', 'camelcase-keys@3.0.0'],
testDefaults({ nodeLinker: 'hoisted', save: true })
@@ -84,7 +84,7 @@ test('uninstall package with dependencies and do not touch other deps', async ()
manifest,
mutation: 'uninstallSome',
rootDir: process.cwd() as ProjectRootDir,
}, testDefaults({ nodeLinker: 'hoisted', pruneStore: true, save: true }))).manifest
}, testDefaults({ nodeLinker: 'hoisted', pruneStore: true, save: true }))).updatedProject.manifest
project.storeHasNot('camelcase-keys', '3.0.0')
project.hasNot('camelcase-keys')

View File

@@ -121,7 +121,7 @@ test('a dependency has an aliased subdependency', async () => {
test('installing the same package via an alias and directly', async () => {
const project = prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['negative@npm:is-negative@^1.0.1', 'is-negative@^1.0.1'], testDefaults({ fastUnpack: false }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['negative@npm:is-negative@^1.0.1', 'is-negative@^1.0.1'], testDefaults({ fastUnpack: false }))
expect(manifest.dependencies).toStrictEqual({ negative: 'npm:is-negative@^1.0.1', 'is-negative': '^1.0.1' })

View File

@@ -20,7 +20,7 @@ test('a package that need authentication', async () => {
[`//localhost:${REGISTRY_MOCK_PORT}/:_authToken`]: data.token,
registry: `http://localhost:${REGISTRY_MOCK_PORT}/`,
}
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/needs-auth'], testDefaults({}, {
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/needs-auth'], testDefaults({}, {
authConfig,
}, {
authConfig,
@@ -113,7 +113,7 @@ test('a scoped package that need authentication specific to scope', async () =>
}, {
authConfig,
})
const manifest = await addDependenciesToPackage({}, ['@private/foo'], opts)
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@private/foo'], opts)
project.has('@private/foo')
@@ -153,7 +153,7 @@ test('a scoped package that need legacy authentication specific to scope', async
}, {
authConfig,
})
const manifest = await addDependenciesToPackage({}, ['@private/foo'], opts)
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@private/foo'], opts)
project.has('@private/foo')
@@ -224,7 +224,7 @@ skipOnNode17('a package that need authentication reuses authorization tokens for
authConfig,
})
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/needs-auth'], opts)
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/needs-auth'], opts)
rimraf('node_modules')
rimraf(path.join('..', '.registry'))

View File

@@ -79,7 +79,7 @@ test('don\'t fail on linked package, when peers are auto installed', async () =>
},
])
process.chdir('pkg')
const updatedManifest = await addDependenciesToPackage(pkgManifest, ['@pnpm.e2e/peer-b'], testDefaults({ autoInstallPeers: true }))
const { updatedManifest } = await addDependenciesToPackage(pkgManifest, ['@pnpm.e2e/peer-b'], testDefaults({ autoInstallPeers: true }))
expect(Object.keys(updatedManifest.dependencies ?? {})).toStrictEqual(['linked', '@pnpm.e2e/peer-b'])
})
@@ -184,7 +184,7 @@ test('prefer the peer dependency version already used in the root', async () =>
test('automatically install root peer dependencies', async () => {
const project = prepareEmpty()
let manifest = await install({
let { updatedManifest: manifest } = await install({
dependencies: {
'is-negative': '^1.0.1',
},
@@ -219,7 +219,7 @@ test('automatically install root peer dependencies', async () => {
project.has('is-negative')
// The auto installed peer is not removed when a new dependency is added
manifest = await addDependenciesToPackage(manifest, ['is-odd@1.0.0'], testDefaults({ autoInstallPeers: true, resolutionMode: 'lowest-direct' }))
manifest = (await addDependenciesToPackage(manifest, ['is-odd@1.0.0'], testDefaults({ autoInstallPeers: true, resolutionMode: 'lowest-direct' }))).updatedManifest
project.has('is-odd')
project.has('is-positive')
project.has('is-negative')

View File

@@ -28,7 +28,7 @@ test('prefer version ranges specified for top dependencies, when doing named ins
await addDistTag({ package: '@pnpm.e2e/dep-of-pkg-with-1-dep', version: '100.1.0', distTag: 'latest' })
const manifest = await install(
const { updatedManifest: manifest } = await install(
{
dependencies: {
'@pnpm.e2e/dep-of-pkg-with-1-dep': '100.0.0',
@@ -181,7 +181,7 @@ test('dedupe subdependency when a newer version of the same package is installed
await addDistTag({ package: '@pnpm.e2e/dep-of-pkg-with-1-dep', version: '100.0.0', distTag: 'latest' })
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/dep-of-pkg-with-1-dep@100.0.0', '@pnpm.e2e/pkg-with-1-dep@100.0.0'], testDefaults())
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/dep-of-pkg-with-1-dep@100.0.0', '@pnpm.e2e/pkg-with-1-dep@100.0.0'], testDefaults())
await addDistTag({ package: '@pnpm.e2e/dep-of-pkg-with-1-dep', version: '100.1.0', distTag: 'latest' })
@@ -196,7 +196,7 @@ test('when resolving dependencies, prefer versions that are used by direct depen
await addDistTag({ package: '@pnpm.e2e/foo', version: '100.1.0', distTag: 'latest' })
const project = prepareEmpty()
const manifest = await install({
const { updatedManifest: manifest } = await install({
dependencies: {
'@pnpm.e2e/foo': '100.0.0',
'@pnpm.e2e/has-foo-100.1.0-dep-1': '1.0.0',
@@ -214,7 +214,7 @@ test('when resolving dependencies, prefer versions that are used by direct depen
await addDistTag({ package: '@pnpm.e2e/foo', version: '100.1.0', distTag: 'latest' })
const project = prepareEmpty()
const manifest = await install({
const { updatedManifest: manifest } = await install({
dependencies: {
'@pnpm.e2e/foo': '100.0.0',
'@pnpm.e2e/has-foo-100.1.0-dep-1': '1.0.0',

View File

@@ -126,7 +126,7 @@ test('local file using absolute path is correctly installed on repeat install',
f.copy('local-pkg', absolutePath)
// is-odd is only added because otherwise no lockfile is created
const manifest = await addDependenciesToPackage({},
const { updatedManifest: manifest } = await addDependenciesToPackage({},
[`link:${absolutePath}`, 'is-odd@1.0.0'],
testDefaults({ excludeLinksFromLockfile: true })
)
@@ -151,7 +151,7 @@ test('hoisted install should not fail with excludeLinksFromLockfile true', async
f.copy('local-pkg', absolutePath)
// is-odd is only added because otherwise no lockfile is created
const manifest = await addDependenciesToPackage({},
const { updatedManifest: manifest } = await addDependenciesToPackage({},
[`link:${absolutePath}`, 'is-odd@1.0.0'],
testDefaults({ excludeLinksFromLockfile: true, nodeLinker: 'hoisted' })
)

View File

@@ -20,7 +20,7 @@ const withGitProtocolDepFixture = f.find('with-git-protocol-dep')
test('from a github repo', async () => {
const project = prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['kevva/is-negative'], testDefaults())
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['kevva/is-negative'], testDefaults())
project.has('is-negative')
@@ -32,7 +32,7 @@ test('from a github repo', async () => {
test('from a github repo through URL', async () => {
const project = prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['https://github.com/kevva/is-negative'], testDefaults())
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['https://github.com/kevva/is-negative'], testDefaults())
project.has('is-negative')
@@ -44,7 +44,7 @@ test('from a github repo with different name via named installation', async () =
const reporter = sinon.spy()
const manifest = await addDependenciesToPackage(
const { updatedManifest: manifest } = await addDependenciesToPackage(
{},
['say-hi@github:zkochan/hi#4cdebec76b7b9d1f6e219e06c42d92a6b8ea60cd'],
testDefaults({ fastUnpack: false, reporter })
@@ -85,7 +85,7 @@ test('from a github repo with different name', async () => {
const reporter = sinon.spy()
const manifest = await install({
const { updatedManifest: manifest } = await install({
dependencies: {
'say-hi': 'github:zkochan/hi#4cdebec76b7b9d1f6e219e06c42d92a6b8ea60cd',
},
@@ -178,7 +178,7 @@ test.skip('from a non-github git repo', async () => {
test('from a github repo the has no package.json file', async () => {
const project = prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['pnpm/for-testing.no-package-json'], testDefaults())
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['pnpm/for-testing.no-package-json'], testDefaults())
project.has('for-testing.no-package-json')
@@ -198,7 +198,7 @@ test('from a github repo the has no package.json file', async () => {
test.skip('from a github repo that needs to be built. isolated node linker is used', async () => {
const project = prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['pnpm-e2e/prepare-script-works'], testDefaults({ ignoreScripts: true }, { ignoreScripts: true }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['pnpm-e2e/prepare-script-works'], testDefaults({ ignoreScripts: true }, { ignoreScripts: true }))
project.hasNot('@pnpm.e2e/prepare-script-works/prepare.txt')
@@ -218,7 +218,7 @@ test.skip('from a github repo that needs to be built. isolated node linker is us
test.skip('from a github repo that needs to be built. hoisted node linker is used', async () => {
const project = prepareEmpty()
const manifest = await addDependenciesToPackage(
const { updatedManifest: manifest } = await addDependenciesToPackage(
{},
['pnpm-e2e/prepare-script-works'],
testDefaults({ ignoreScripts: true, nodeLinker: 'hoisted' }, { ignoreScripts: true })
@@ -241,7 +241,7 @@ test.skip('from a github repo that needs to be built. hoisted node linker is us
test('re-adding a git repo with a different tag', async () => {
const project = prepareEmpty()
let manifest = await addDependenciesToPackage({}, ['kevva/is-negative#1.0.0'], testDefaults())
let { updatedManifest: manifest } = await addDependenciesToPackage({}, ['kevva/is-negative#1.0.0'], testDefaults())
project.has('is-negative')
expect(manifest.dependencies).toStrictEqual({
'is-negative': 'github:kevva/is-negative#1.0.0',
@@ -261,7 +261,7 @@ test('re-adding a git repo with a different tag', async () => {
},
}
)
manifest = await addDependenciesToPackage(manifest, ['kevva/is-negative#1.0.1'], testDefaults())
manifest = (await addDependenciesToPackage(manifest, ['kevva/is-negative#1.0.1'], testDefaults())).updatedManifest
project.has('is-negative')
expect(JSON.parse(fs.readFileSync('./node_modules/is-negative/package.json', 'utf8')).version).toBe('1.0.1')
lockfile = project.readLockfile()
@@ -291,7 +291,7 @@ test('should not update when adding unrelated dependency', async () => {
expect(fs.readdirSync('./node_modules/.pnpm')).toContain('is-negative@https+++codeload.github.com+kevva+is-negative+tar.gz+1d7e288222b53a0cab90a331f1865220ec29560c') // cspell:disable-line
manifest = await addDependenciesToPackage(manifest, ['is-number'], testDefaults({ preferFrozenLockfile: false, modulesCacheMaxAge: 0 }))
manifest = (await addDependenciesToPackage(manifest, ['is-number'], testDefaults({ preferFrozenLockfile: false, modulesCacheMaxAge: 0 }))).updatedManifest
expect(manifest.dependencies).toHaveProperty('is-number')
expect(manifest.dependencies['is-negative']).toBe('github:kevva/is-negative#master')
@@ -326,7 +326,7 @@ test('git-hosted repository is not added to the store if it fails to be built',
test('from subdirectories of a git repo', async () => {
const project = prepareEmpty()
const manifest = await addDependenciesToPackage({}, [
const { updatedManifest: manifest } = await addDependenciesToPackage({}, [
'github:RexSkz/test-git-subfolder-fetch#path:/packages/simple-react-app',
'github:RexSkz/test-git-subfolder-fetch#path:/packages/simple-express-server',
], testDefaults())

View File

@@ -6,7 +6,7 @@ import { testDefaults } from '../utils'
test('tarball from npm registry', async () => {
const project = prepareEmpty()
const manifest = await addDependenciesToPackage({}, [`http://localhost:${REGISTRY_MOCK_PORT}/is-array/-/is-array-1.0.1.tgz`], testDefaults())
const { updatedManifest: manifest } = await addDependenciesToPackage({}, [`http://localhost:${REGISTRY_MOCK_PORT}/is-array/-/is-array-1.0.1.tgz`], testDefaults())
project.has('is-array')
project.storeHas(`localhost+${REGISTRY_MOCK_PORT}/is-array/1.0.1`)

View File

@@ -103,7 +103,7 @@ test(`frozen-lockfile: fail on a shared ${WANTED_LOCKFILE} that does not satisfy
test(`frozen-lockfile: should successfully install when ${WANTED_LOCKFILE} is available`, async () => {
const project = prepareEmpty()
const manifest = await install({
const { updatedManifest: manifest } = await install({
dependencies: {
'is-positive': '^3.0.0',
},
@@ -131,7 +131,7 @@ test(`frozen-lockfile: should fail if no ${WANTED_LOCKFILE} is present`, async (
test(`prefer-frozen-lockfile: should prefer headless installation when ${WANTED_LOCKFILE} satisfies package.json`, async () => {
const project = prepareEmpty()
const manifest = await install({
const { updatedManifest: manifest } = await install({
dependencies: {
'is-positive': '^3.0.0',
},
@@ -193,7 +193,7 @@ test(`frozen-lockfile: should not fail if no ${WANTED_LOCKFILE} is present and p
test(`prefer-frozen-lockfile+hoistPattern: should prefer headless installation when ${WANTED_LOCKFILE} satisfies package.json`, async () => {
const project = prepareEmpty()
const manifest = await install({
const { updatedManifest: manifest } = await install({
dependencies: {
'@pnpm.e2e/pkg-with-1-dep': '100.0.0',
},

View File

@@ -21,7 +21,7 @@ import { testDefaults } from '../utils'
test('should hoist dependencies', async () => {
const project = prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['express', '@foo/has-dep-from-same-scope'], testDefaults({ fastUnpack: false, hoistPattern: '*' }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['express', '@foo/has-dep-from-same-scope'], testDefaults({ fastUnpack: false, hoistPattern: '*' }))
project.has('express')
project.has('.pnpm/node_modules/debug')
@@ -118,7 +118,7 @@ test('should hoist dependencies by pattern', async () => {
test('should remove hoisted dependencies', async () => {
const project = prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['express'], testDefaults({ fastUnpack: false, hoistPattern: '*' }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['express'], testDefaults({ fastUnpack: false, hoistPattern: '*' }))
await mutateModulesInSingleProject({
dependencyNames: ['express'],
manifest,
@@ -135,7 +135,7 @@ test('should not override root packages with hoisted dependencies', async () =>
const project = prepareEmpty()
// this installs debug@3.1.0
const manifest = await addDependenciesToPackage({}, ['debug@3.1.0'], testDefaults({ hoistPattern: '*' }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['debug@3.1.0'], testDefaults({ hoistPattern: '*' }))
// this installs express@4.16.2, that depends on debug 2.6.9, but we don't want to flatten debug@2.6.9
await addDependenciesToPackage(manifest, ['express@4.16.2'], testDefaults({ fastUnpack: false, hoistPattern: '*' }))
@@ -146,7 +146,7 @@ test('should rehoist when uninstalling a package', async () => {
const project = prepareEmpty()
// this installs debug@3.1.0 and express@4.16.0
const manifest = await addDependenciesToPackage({}, ['debug@3.1.0', 'express@4.16.0'], testDefaults({ fastUnpack: false, hoistPattern: '*' }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['debug@3.1.0', 'express@4.16.0'], testDefaults({ fastUnpack: false, hoistPattern: '*' }))
// uninstall debug@3.1.0 to check if debug@2.6.9 gets reflattened
await mutateModulesInSingleProject({
dependencyNames: ['debug'],
@@ -205,7 +205,7 @@ test('should not override aliased dependencies', async () => {
test('hoistPattern=* throws exception when executed on node_modules installed w/o the option', async () => {
prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['is-positive'], testDefaults({ hoistPattern: undefined }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['is-positive'], testDefaults({ hoistPattern: undefined }))
await expect(
addDependenciesToPackage(manifest, ['is-negative'], testDefaults({
@@ -218,7 +218,7 @@ test('hoistPattern=* throws exception when executed on node_modules installed w/
test('hoistPattern=undefined throws exception when executed on node_modules installed with hoist-pattern=*', async () => {
prepareEmpty()
const opts = testDefaults({ hoistPattern: '*' })
const manifest = await addDependenciesToPackage({}, ['is-positive'], opts)
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['is-positive'], opts)
await expect(
addDependenciesToPackage(manifest, ['is-negative'], {
@@ -255,7 +255,7 @@ test('hoist by alias', async () => {
test('should remove aliased hoisted dependencies', async () => {
const project = prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/pkg-with-1-aliased-dep'], testDefaults({ hoistPattern: '*' }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/pkg-with-1-aliased-dep'], testDefaults({ hoistPattern: '*' }))
await mutateModulesInSingleProject({
dependencyNames: ['@pnpm.e2e/pkg-with-1-aliased-dep'],
manifest,
@@ -332,7 +332,7 @@ test('should hoist correctly peer dependencies', async () => {
test('should uninstall correctly peer dependencies', async () => {
prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/using-ajv'], testDefaults({ hoistPattern: '*' }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/using-ajv'], testDefaults({ hoistPattern: '*' }))
await mutateModulesInSingleProject({
dependencyNames: ['@pnpm.e2e/using-ajv'],
manifest,
@@ -518,7 +518,7 @@ test('hoist when updating in one of the workspace projects', async () => {
test('should recreate node_modules with hoisting', async () => {
const project = prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/pkg-with-1-dep'], testDefaults({ hoistPattern: undefined }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/pkg-with-1-dep'], testDefaults({ hoistPattern: undefined }))
project.hasNot('.pnpm/node_modules/@pnpm.e2e/dep-of-pkg-with-1-dep')
{
@@ -572,7 +572,7 @@ test('hoisting should not create a broken symlink to a skipped optional dependen
test('the hoisted packages should not override the bin files of the direct dependencies', async () => {
prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/hello-world-js-bin-parent'], testDefaults({ fastUnpack: false, publicHoistPattern: '*' }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/hello-world-js-bin-parent'], testDefaults({ fastUnpack: false, publicHoistPattern: '*' }))
{
const cmd = await fs.promises.readFile('node_modules/.bin/hello-world-js-bin', 'utf-8')

View File

@@ -24,7 +24,7 @@ const testOnNonWindows = isWindows() ? test.skip : test
test('run pre/postinstall scripts', async () => {
const project = prepareEmpty()
const manifest = await addDependenciesToPackage({},
const { updatedManifest: manifest } = await addDependenciesToPackage({},
['@pnpm.e2e/pre-and-postinstall-scripts-example@1.0.0'],
testDefaults({ fastUnpack: false, targetDependenciesField: 'devDependencies' })
)
@@ -106,7 +106,7 @@ test('run pre/postinstall scripts, when PnP is used and no symlinks', async () =
test('testing that the bins are linked when the package with the bins was already in node_modules', async () => {
const project = prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/hello-world-js-bin'], testDefaults({ fastUnpack: false }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/hello-world-js-bin'], testDefaults({ fastUnpack: false }))
await addDependenciesToPackage(manifest, ['@pnpm.e2e/pre-and-postinstall-scripts-example@1.0.0'], testDefaults({ fastUnpack: false, targetDependenciesField: 'devDependencies' }))
const generatedByPreinstall = project.requireModule('@pnpm.e2e/pre-and-postinstall-scripts-example/generated-by-preinstall')
@@ -128,7 +128,7 @@ test('run install scripts in the current project', async () => {
await using server = await createTestIpcServer()
await using serverForDevPreinstall = await createTestIpcServer()
prepareEmpty()
const manifest = await addDependenciesToPackage({
const { updatedManifest: manifest } = await addDependenciesToPackage({
scripts: {
'pnpm:devPreinstall': `node -e "console.log('pnpm:devPreinstall-' + process.cwd())" | ${serverForDevPreinstall.generateSendStdinScript()}`,
install: `node -e "console.log('install-' + process.cwd())" | ${server.generateSendStdinScript()}`,
@@ -153,7 +153,7 @@ test('run install scripts in the current project', async () => {
test('run install scripts in the current project when its name is different than its directory', async () => {
await using server = await createTestIpcServer()
prepareEmpty()
const manifest = await addDependenciesToPackage({
const { updatedManifest: manifest } = await addDependenciesToPackage({
name: 'different-name',
scripts: {
install: `node -e "console.log('install-' + process.cwd())" | ${server.generateSendStdinScript()}`,
@@ -325,7 +325,7 @@ test('run prepare script for git-hosted dependencies', async () => {
test('lifecycle scripts run before linking bins', async () => {
const project = prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/generated-bins'], testDefaults({ fastUnpack: false }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/generated-bins'], testDefaults({ fastUnpack: false }))
project.isExecutable('.bin/cmd1')
project.isExecutable('.bin/cmd2')
@@ -345,7 +345,7 @@ test('lifecycle scripts run before linking bins', async () => {
test('hoisting does not fail on commands that will be created by lifecycle scripts on a later stage', async () => {
prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/has-generated-bins-as-dep'], testDefaults({ fastUnpack: false, hoistPattern: '*' }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/has-generated-bins-as-dep'], testDefaults({ fastUnpack: false, hoistPattern: '*' }))
// project.isExecutable('.pnpm/node_modules/.bin/cmd1')
// project.isExecutable('.pnpm/node_modules/.bin/cmd2')
@@ -366,7 +366,7 @@ test('hoisting does not fail on commands that will be created by lifecycle scrip
test('bins are linked even if lifecycle scripts are ignored', async () => {
const project = prepareEmpty()
const manifest = await addDependenciesToPackage(
const { updatedManifest: manifest } = await addDependenciesToPackage(
{},
[
'@pnpm.e2e/pkg-with-peer-having-bin',
@@ -402,7 +402,7 @@ test('bins are linked even if lifecycle scripts are ignored', async () => {
test('dependency should not be added to current lockfile if it was not built successfully during headless install', async () => {
const project = prepareEmpty()
const manifest = await addDependenciesToPackage(
const { updatedManifest: manifest } = await addDependenciesToPackage(
{},
[
'package-that-cannot-be-installed@0.0.0', // TODO: this package should be replaced
@@ -439,7 +439,7 @@ test('scripts have access to unlisted bins when hoisting is used', async () => {
test('selectively ignore scripts in some dependencies by neverBuiltDependencies', async () => {
prepareEmpty()
const neverBuiltDependencies = ['@pnpm.e2e/pre-and-postinstall-scripts-example']
const manifest = await addDependenciesToPackage({},
const { updatedManifest: manifest } = await addDependenciesToPackage({},
['@pnpm.e2e/pre-and-postinstall-scripts-example@1.0.0', '@pnpm.e2e/install-script-example'],
testDefaults({ fastUnpack: false, neverBuiltDependencies })
)
@@ -473,7 +473,7 @@ test('selectively allow scripts in some dependencies by onlyBuiltDependencies',
prepareEmpty()
const reporter = sinon.spy()
const onlyBuiltDependencies = ['@pnpm.e2e/install-script-example']
const manifest = await addDependenciesToPackage({},
const { updatedManifest: manifest } = await addDependenciesToPackage({},
['@pnpm.e2e/pre-and-postinstall-scripts-example@1.0.0', '@pnpm.e2e/install-script-example'],
testDefaults({ fastUnpack: false, onlyBuiltDependencies, reporter })
)
@@ -686,7 +686,7 @@ test('run pre/postinstall scripts in a workspace that uses node-linker=hoisted',
test('run pre/postinstall scripts in a project that uses node-linker=hoisted. Should not fail on repeat install', async () => {
const project = prepareEmpty()
const manifest = await addDependenciesToPackage({},
const { updatedManifest: manifest } = await addDependenciesToPackage({},
['@pnpm.e2e/pre-and-postinstall-scripts-example@1.0.0'],
testDefaults({ fastUnpack: false, targetDependenciesField: 'devDependencies', nodeLinker: 'hoisted', sideEffectsCacheRead: true, sideEffectsCacheWrite: true })
)

View File

@@ -34,7 +34,7 @@ test('local file', async () => {
const project = prepareEmpty()
f.copy('local-pkg', path.resolve('..', 'local-pkg'))
const manifest = await addDependenciesToPackage({}, ['link:../local-pkg'], testDefaults())
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['link:../local-pkg'], testDefaults())
const expectedSpecs = { 'local-pkg': `link:..${path.sep}local-pkg` }
expect(manifest.dependencies).toStrictEqual(expectedSpecs)
@@ -80,7 +80,7 @@ test('local directory with no package.json', async () => {
fs.mkdirSync('pkg')
fs.writeFileSync('pkg/index.js', 'hello', 'utf8')
const manifest = await addDependenciesToPackage({}, ['file:./pkg'], testDefaults())
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['file:./pkg'], testDefaults())
const expectedSpecs = { pkg: 'file:pkg' }
expect(manifest.dependencies).toStrictEqual(expectedSpecs)
@@ -96,7 +96,7 @@ test('local file via link:', async () => {
const project = prepareEmpty()
f.copy('local-pkg', path.resolve('..', 'local-pkg'))
const manifest = await addDependenciesToPackage({}, ['link:../local-pkg'], testDefaults())
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['link:../local-pkg'], testDefaults())
const expectedSpecs = { 'local-pkg': `link:..${path.sep}local-pkg` }
expect(manifest.dependencies).toStrictEqual(expectedSpecs)
@@ -132,7 +132,7 @@ test('local file with symlinked node_modules', async () => {
fs.mkdirSync(path.join('..', 'node_modules'))
await symlinkDir(path.join('..', 'node_modules'), 'node_modules')
const manifest = await addDependenciesToPackage({}, ['link:../local-pkg'], testDefaults())
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['link:../local-pkg'], testDefaults())
const expectedSpecs = { 'local-pkg': `link:..${path.sep}local-pkg` }
expect(manifest.dependencies).toStrictEqual(expectedSpecs)
@@ -173,7 +173,7 @@ test('package with a broken symlink', async () => {
test('tarball local package', async () => {
const project = prepareEmpty()
const manifest = await addDependenciesToPackage({}, [f.find('tar-pkg-1.0.0.tgz')], testDefaults({ fastUnpack: false }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, [f.find('tar-pkg-1.0.0.tgz')], testDefaults({ fastUnpack: false }))
const m = project.requireModule('tar-pkg')
@@ -197,7 +197,7 @@ test('tarball local package from project directory', async () => {
f.copy('tar-pkg-1.0.0.tgz', path.resolve('tar-pkg-1.0.0.tgz'))
const manifest = await install({
const { updatedManifest: manifest } = await install({
dependencies: {
'tar-pkg': 'file:tar-pkg-1.0.0.tgz',
},
@@ -225,7 +225,7 @@ test('update tarball local package when its integrity changes', async () => {
const project = prepareEmpty()
f.copy('tar-pkg-with-dep-1/tar-pkg-with-dep-1.0.0.tgz', path.resolve('..', 'tar.tgz'))
const manifest = await addDependenciesToPackage({}, ['../tar.tgz'], testDefaults())
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['../tar.tgz'], testDefaults())
const lockfile1 = project.readLockfile()
expect(lockfile1.snapshots['tar-pkg-with-dep@file:../tar.tgz'].dependencies!['is-positive']).toBe('1.0.0')
@@ -246,7 +246,7 @@ test('do not update deps when installing in a project that has local tarball dep
const project = prepareEmpty()
f.copy('tar-pkg-with-dep-1/tar-pkg-with-dep-1.0.0.tgz', path.resolve('..', 'tar.tgz'))
const manifest = await addDependenciesToPackage({}, ['../tar.tgz', '@pnpm.e2e/peer-a'], testDefaults({ lockfileOnly: true }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['../tar.tgz', '@pnpm.e2e/peer-a'], testDefaults({ lockfileOnly: true }))
const initialLockfile = project.readLockfile()
@@ -268,7 +268,7 @@ test('frozen-lockfile: installation fails if the integrity of a tarball dependen
prepareEmpty()
f.copy('tar-pkg-with-dep-1/tar-pkg-with-dep-1.0.0.tgz', path.resolve('..', 'tar.tgz'))
const manifest = await addDependenciesToPackage({}, ['../tar.tgz'], testDefaults())
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['../tar.tgz'], testDefaults())
rimraf('node_modules')
@@ -396,7 +396,7 @@ test('re-install should update local file dependency', async () => {
const project = prepareEmpty()
f.copy('local-pkg', path.resolve('..', 'local-pkg'))
const manifest = await addDependenciesToPackage({}, ['file:../local-pkg'], testDefaults())
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['file:../local-pkg'], testDefaults())
const expectedSpecs = { 'local-pkg': `file:..${path.sep}local-pkg` }
expect(manifest.dependencies).toStrictEqual(expectedSpecs)
@@ -505,7 +505,7 @@ test('local directory is not relinked if disableRelinkLocalDirDeps is set to tru
fs.writeFileSync('pkg/index.js', 'hello', 'utf8')
fs.writeFileSync('pkg/package.json', '{"name": "pkg"}', 'utf8')
const manifest = await addDependenciesToPackage({}, ['file:./pkg'], testDefaults())
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['file:./pkg'], testDefaults())
fs.writeFileSync('pkg/new.js', 'hello', 'utf8')

View File

@@ -14,7 +14,7 @@ const f = fixtures(__dirname)
test.skip('subsequent installation uses same lockfile directory by default', async () => {
prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['is-positive@1.0.0'], testDefaults({ lockfileDir: path.resolve('..') }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['is-positive@1.0.0'], testDefaults({ lockfileDir: path.resolve('..') }))
await addDependenciesToPackage(manifest, ['is-negative@1.0.0'], testDefaults())
@@ -26,7 +26,7 @@ test.skip('subsequent installation uses same lockfile directory by default', asy
test.skip('subsequent installation fails if a different lockfile directory is specified', async () => {
prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['is-positive@1.0.0'], testDefaults({ lockfileDir: path.resolve('..') }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['is-positive@1.0.0'], testDefaults({ lockfileDir: path.resolve('..') }))
let err!: Error & { code: string }
@@ -46,7 +46,7 @@ test(`tarball location is correctly saved to ${WANTED_LOCKFILE} when a shared ${
f.copy('tar-pkg-with-dep-2/tar-pkg-with-dep-1.0.0.tgz', 'pkg.tgz')
const lockfileDir = path.resolve('..')
const { manifest } = await mutateModulesInSingleProject({
const { updatedProject: { manifest } } = await mutateModulesInSingleProject({
allowNew: true,
dependencySelectors: ['file:pkg.tgz'],
manifest: {},

View File

@@ -16,7 +16,7 @@ test('install with lockfileOnly = true', async () => {
const project = prepareEmpty()
const opts = testDefaults({ lockfileOnly: true, pinnedVersion: 'patch' as const })
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/pkg-with-1-dep@100.0.0'], opts)
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/pkg-with-1-dep@100.0.0'], opts)
const { cafsHasNot } = assertStore(opts.storeDir)
cafsHasNot('@pnpm.e2e/pkg-with-1-dep', '100.0.0')
@@ -50,7 +50,7 @@ test('warn when installing with lockfileOnly = true and node_modules exists', as
const project = prepareEmpty()
const reporter = sinon.spy()
const manifest = await addDependenciesToPackage({}, ['is-positive'], testDefaults())
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['is-positive'], testDefaults())
await addDependenciesToPackage(manifest, ['rimraf@2.5.1'], testDefaults({
lockfileOnly: true,
reporter,

View File

@@ -146,7 +146,7 @@ test('no dependencies (lodash)', async () => {
test('only the new packages are added', async () => {
prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['@pnpm/x'], testDefaults())
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm/x'], testDefaults())
const reporter = sinon.spy()
await addDependenciesToPackage(manifest, ['@pnpm/y'], testDefaults({ reporter }))
@@ -225,7 +225,7 @@ test('update a package when installing with a dist-tag', async () => {
await addDistTag({ package: '@pnpm.e2e/dep-of-pkg-with-1-dep', version: '100.0.0', distTag: 'latest' })
await addDistTag({ package: '@pnpm.e2e/dep-of-pkg-with-1-dep', version: '100.1.0', distTag: 'beta' })
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/dep-of-pkg-with-1-dep'], testDefaults({ targetDependenciesField: 'devDependencies' }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/dep-of-pkg-with-1-dep'], testDefaults({ targetDependenciesField: 'devDependencies' }))
const reporter = sinon.spy()
@@ -274,7 +274,7 @@ test('multiple scoped modules (@rstacruz/...)', async () => {
test('installing a beta version of a package', async () => {
prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/beta-version'], testDefaults())
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/beta-version'], testDefaults())
expect(manifest.dependencies?.['@pnpm.e2e/beta-version']).toBe('1.0.0-beta.0')
})
@@ -292,7 +292,7 @@ test('idempotency', async () => {
const reporter = sinon.spy()
const opts = testDefaults({ reporter })
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/pkg-with-1-dep@100.0.0'], opts)
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/pkg-with-1-dep@100.0.0'], opts)
expect(reporter.calledWithMatch({
added: {
@@ -323,7 +323,7 @@ test('idempotency', async () => {
test('reporting adding root package', async () => {
const project = prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['magic-hook@2.0.0'], testDefaults())
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['magic-hook@2.0.0'], testDefaults())
project.storeHas('flatten', '1.0.2')
@@ -344,7 +344,7 @@ test('reporting adding root package', async () => {
test('overwriting (magic-hook@2.0.0 and @0.1.0)', async () => {
const project = prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['magic-hook@2.0.0'], testDefaults())
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['magic-hook@2.0.0'], testDefaults())
project.storeHas('flatten', '1.0.2')
@@ -360,11 +360,11 @@ test('overwriting (magic-hook@2.0.0 and @0.1.0)', async () => {
test('overwriting (is-positive@3.0.0 with is-positive@latest)', async () => {
const project = prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['is-positive@3.0.0'], testDefaults({ save: true }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['is-positive@3.0.0'], testDefaults({ save: true }))
project.storeHas('is-positive', '3.0.0')
const updatedManifest = await addDependenciesToPackage(manifest, ['is-positive@latest'], testDefaults({ save: true }))
const { updatedManifest } = await addDependenciesToPackage(manifest, ['is-positive@latest'], testDefaults({ save: true }))
project.storeHas('is-positive', '3.1.0')
expect(updatedManifest.dependencies?.['is-positive']).toBe('3.1.0')
@@ -376,14 +376,14 @@ test('keeping existing specs untouched when adding new dependency', async () =>
await addDistTag({ package: '@pnpm.e2e/bar', version: '100.1.0', distTag: 'latest' })
const manifest = await addDependenciesToPackage({ dependencies: { '@pnpm.e2e/bar': '^100.0.0' } }, ['@pnpm.e2e/foo@100.1.0'], testDefaults())
const { updatedManifest: manifest } = await addDependenciesToPackage({ dependencies: { '@pnpm.e2e/bar': '^100.0.0' } }, ['@pnpm.e2e/foo@100.1.0'], testDefaults())
expect(manifest.dependencies).toStrictEqual({ '@pnpm.e2e/bar': '^100.0.0', '@pnpm.e2e/foo': '100.1.0' })
})
test('forcing', async () => {
prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['magic-hook@2.0.0'], testDefaults({ fastUnpack: false }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['magic-hook@2.0.0'], testDefaults({ fastUnpack: false }))
const distPath = path.resolve('node_modules', 'magic-hook', 'dist')
rimraf(distPath)
@@ -396,7 +396,7 @@ test('forcing', async () => {
test('argumentless forcing', async () => {
prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['magic-hook@2.0.0'], testDefaults({ fastUnpack: false }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['magic-hook@2.0.0'], testDefaults({ fastUnpack: false }))
const distPath = path.resolve('node_modules', 'magic-hook', 'dist')
rimraf(distPath)
@@ -409,7 +409,7 @@ test('argumentless forcing', async () => {
test('no forcing', async () => {
prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['magic-hook@2.0.0'], testDefaults())
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['magic-hook@2.0.0'], testDefaults())
const distPath = path.resolve('node_modules', 'magic-hook', 'dist')
rimraf(distPath)
@@ -422,7 +422,7 @@ test('no forcing', async () => {
test('refetch package to store if it has been modified', async () => {
const project = prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['magic-hook@2.0.0'], testDefaults({ fastUnpack: false }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['magic-hook@2.0.0'], testDefaults({ fastUnpack: false }))
const distPathInStore = project.resolve('magic-hook', '2.0.0', 'dist')
rimraf(distPathInStore)
@@ -438,7 +438,7 @@ test('refetch package to store if it has been modified', async () => {
// TODO: decide what to do with this case
test.skip('relink package to project if the dependency is not linked from store', async () => {
prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['magic-hook@2.0.0'], testDefaults({ save: true, pinnedVersion: 'patch' }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['magic-hook@2.0.0'], testDefaults({ save: true, pinnedVersion: 'patch' }))
const pkgJsonPath = path.resolve('node_modules', 'magic-hook', 'package.json')
@@ -558,7 +558,7 @@ test('should update subdep on second install', async () => {
await addDistTag({ package: '@pnpm.e2e/dep-of-pkg-with-1-dep', version: '100.0.0', distTag: 'latest' })
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/pkg-with-1-dep'], testDefaults({ save: true }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/pkg-with-1-dep'], testDefaults({ save: true }))
project.storeHas('@pnpm.e2e/dep-of-pkg-with-1-dep', '100.0.0')
@@ -594,7 +594,7 @@ test('should not update subdep when depth is smaller than depth of package', asy
await addDistTag({ package: '@pnpm.e2e/dep-of-pkg-with-1-dep', version: '100.0.0', distTag: 'latest' })
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/pkg-with-1-dep'], testDefaults({ save: true }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/pkg-with-1-dep'], testDefaults({ save: true }))
project.storeHas('@pnpm.e2e/dep-of-pkg-with-1-dep', '100.0.0')
@@ -632,7 +632,7 @@ test('should install dependency in second project', async () => {
test('should throw error when trying to install using a different store then the previous one', async () => {
prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['is-positive'], testDefaults({ storeDir: 'node_modules/.store1' }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['is-positive'], testDefaults({ storeDir: 'node_modules/.store1' }))
await expect(
addDependenciesToPackage(manifest, ['is-negative'], testDefaults({ storeDir: 'node_modules/.store2' }))
@@ -652,7 +652,7 @@ test('ignores drive case in store path', async () => {
const storePathUpper: string = path.resolve('node_modules/.store1').toUpperCase()
const storePathLower: string = storePathUpper.toLowerCase()
const manifest = await addDependenciesToPackage(
const { updatedManifest: manifest } = await addDependenciesToPackage(
{},
['rimraf@2.5.1'],
testDefaults({ storeDir: storePathUpper }, null, null, { ignoreFile: () => {} }) // eslint-disable-line:no-empty
@@ -667,7 +667,7 @@ test('should not throw error if using a different store after all the packages w
test('should throw error when trying to install using a different virtual store directory then the previous one', async () => {
prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['is-positive'], testDefaults({ virtualStoreDir: 'pkgs' }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['is-positive'], testDefaults({ virtualStoreDir: 'pkgs' }))
await expect(
addDependenciesToPackage(manifest, ['is-negative'], testDefaults({ virtualStoreDir: 'pnpm' }))
@@ -686,7 +686,7 @@ test('lockfile locks npm dependencies', async () => {
await addDistTag({ package: '@pnpm.e2e/dep-of-pkg-with-1-dep', version: '100.0.0', distTag: 'latest' })
await addDistTag({ package: '@pnpm.e2e/pkg-with-1-dep', version: '100.0.0', distTag: 'latest' })
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/pkg-with-1-dep'], testDefaults({ save: true, reporter }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/pkg-with-1-dep'], testDefaults({ save: true, reporter }))
expect(reporter.calledWithMatch({
level: 'debug',
@@ -740,7 +740,7 @@ test('self-require should work', async () => {
test('install on project with lockfile and no node_modules', async () => {
const project = prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['is-negative'], testDefaults())
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['is-negative'], testDefaults())
rimraf('node_modules')
@@ -788,7 +788,7 @@ test('rewrites node_modules created by npm', async () => {
await execa('npm', ['install', 'rimraf@2.5.1', '@types/node', '--save'])
const manifest = await install({}, testDefaults())
const { updatedManifest: manifest } = await install({}, testDefaults())
const m = project.requireModule('rimraf')
expect(typeof m).toEqual('function')
@@ -824,7 +824,7 @@ test('reinstalls missing packages to node_modules', async () => {
}
const opts = testDefaults({ fastUnpack: false, reporter })
const manifest = await addDependenciesToPackage({}, ['is-positive@1.0.0'], opts)
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['is-positive@1.0.0'], opts)
expect(reporter.calledWithMatch(missingDepLog)).toBeFalsy()
@@ -854,7 +854,7 @@ test('reinstalls missing packages to node_modules during headless install', asyn
}
const opts = testDefaults({ fastUnpack: false, reporter })
const manifest = await addDependenciesToPackage({}, ['is-positive@1.0.0'], opts)
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['is-positive@1.0.0'], opts)
expect(reporter.calledWithMatch(missingDepLog)).toBeFalsy()
@@ -875,7 +875,7 @@ test('do not update deps when lockfile is present', async () => {
await addDistTag({ package: '@pnpm.e2e/peer-a', version: '1.0.0', distTag: 'latest' })
const project = prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/peer-a'], testDefaults({ lockfileOnly: true }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/peer-a'], testDefaults({ lockfileOnly: true }))
const initialLockfile = project.readLockfile()
@@ -1227,7 +1227,7 @@ test('installing a package with broken bin', async () => {
test('a package should be able to be a dependency of itself', async () => {
const project = prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['@paul-soporan/test-package-self-require-trap@2.0.0'], testDefaults())
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@paul-soporan/test-package-self-require-trap@2.0.0'], testDefaults())
const subpkg = '.pnpm/@paul-soporan+test-package-self-require-trap@2.0.0/node_modules/@paul-soporan/test-package-self-require-trap/node_modules/@paul-soporan/test-package-self-require-trap/package.json'
{

View File

@@ -12,7 +12,7 @@ import { testDefaults } from '../utils'
test('the modules cache is pruned when it expires', async () => {
const project = prepareEmpty()
let manifest = await install({
let { updatedManifest: manifest } = await install({
dependencies: {
'is-positive': '1.0.0',
'is-negative': '1.0.0',
@@ -29,7 +29,7 @@ test('the modules cache is pruned when it expires', async () => {
manifest,
mutation: 'uninstallSome',
rootDir: process.cwd() as ProjectRootDir,
}, testDefaults({}))).manifest
}, testDefaults({}))).updatedProject.manifest
project.has('.pnpm/is-negative@1.0.0/node_modules/is-negative')
@@ -49,7 +49,7 @@ test('the modules cache is pruned when it expires', async () => {
test('the modules cache is pruned when it expires and headless install is used', async () => {
const project = prepareEmpty()
let manifest = await install({
let { updatedManifest: manifest } = await install({
dependencies: {
'is-positive': '1.0.0',
'is-negative': '1.0.0',
@@ -66,9 +66,9 @@ test('the modules cache is pruned when it expires and headless install is used',
manifest,
mutation: 'uninstallSome',
rootDir: process.cwd() as ProjectRootDir,
}, testDefaults({ lockfileOnly: true }))).manifest
}, testDefaults({ lockfileOnly: true }))).updatedProject.manifest
manifest = await install(manifest, testDefaults({ frozenLockfile: true }))
manifest = (await install(manifest, testDefaults({ frozenLockfile: true }))).updatedManifest
project.has('.pnpm/is-negative@1.0.0/node_modules/is-negative')

View File

@@ -529,7 +529,7 @@ test('adding a new dev dependency to project that uses a shared lockfile', async
},
],
}))).updatedProjects
manifest = await addDependenciesToPackage(manifest, ['is-negative@1.0.0'], testDefaults({ prefix: path.resolve('project-1'), targetDependenciesField: 'devDependencies' }))
manifest = (await addDependenciesToPackage(manifest, ['is-negative@1.0.0'], testDefaults({ prefix: path.resolve('project-1'), targetDependenciesField: 'devDependencies' }))).updatedManifest
expect(manifest.dependencies).toStrictEqual({ 'is-positive': '1.0.0' })
expect(manifest.devDependencies).toStrictEqual({ 'is-negative': '1.0.0' })

View File

@@ -71,7 +71,7 @@ test('production install with --no-optional', async () => {
test('install dev dependencies only', async () => {
const project = prepareEmpty()
const manifest = await install({
const { updatedManifest: manifest } = await install({
dependencies: {
'is-positive': '1.0.0',
once: '^1.4.0',
@@ -111,7 +111,7 @@ test('fail if installing different types of dependencies in a project that uses
const lockfileDir = path.resolve('..')
const manifest = await install({
const { updatedManifest: manifest } = await install({
dependencies: {
'is-positive': '1.0.0',
once: '^1.4.0',

View File

@@ -73,7 +73,7 @@ test('skip optional dependency that does not support the current OS', async () =
const project = prepareEmpty()
const reporter = sinon.spy()
let manifest = await install({
let { updatedManifest: manifest } = await install({
optionalDependencies: {
'@pnpm.e2e/not-compatible-with-any-os': '*',
},
@@ -111,7 +111,7 @@ test('skip optional dependency that does not support the current OS', async () =
// a previously skipped package is successfully installed
manifest = await addDependenciesToPackage(manifest, ['@pnpm.e2e/dep-of-optional-pkg'], testDefaults())
manifest = (await addDependenciesToPackage(manifest, ['@pnpm.e2e/dep-of-optional-pkg'], testDefaults())).updatedManifest
project.has('@pnpm.e2e/dep-of-optional-pkg')
@@ -279,7 +279,7 @@ test('optional subdependency is skipped', async () => {
const project = prepareEmpty()
const reporter = sinon.spy()
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/pkg-with-optional', '@pnpm.e2e/dep-of-optional-pkg'], testDefaults({ reporter }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/pkg-with-optional', '@pnpm.e2e/dep-of-optional-pkg'], testDefaults({ reporter }))
{
const modulesInfo = readYamlFile<{ skipped: string[] }>(path.join('node_modules', '.modules.yaml'))
@@ -354,7 +354,7 @@ test('only that package is skipped which is an optional dependency only and not
const project = prepareEmpty()
const reporter = sinon.spy()
const manifest = await addDependenciesToPackage({}, [
const { updatedManifest: manifest } = await addDependenciesToPackage({}, [
'@pnpm.e2e/peer-c@1.0.0',
'@pnpm.e2e/has-optional-dep-with-peer',
'@pnpm.e2e/not-compatible-with-any-os-and-has-peer',
@@ -587,7 +587,7 @@ describe('supported architectures', () => {
prepareEmpty()
const opts = testDefaults({ nodeLinker })
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/has-many-optional-deps@1.0.0'], {
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/has-many-optional-deps@1.0.0'], {
...opts,
supportedArchitectures: { os: ['darwin'], cpu: ['arm64'] },
})
@@ -611,7 +611,7 @@ describe('supported architectures', () => {
prepareEmpty()
const opts = testDefaults({ modulesCacheMaxAge: 0 })
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/has-many-optional-deps@1.0.0'], {
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/has-many-optional-deps@1.0.0'], {
...opts,
supportedArchitectures: { os: ['darwin', 'linux', 'win32'], cpu: ['arm64', 'x64'] },
})
@@ -626,7 +626,7 @@ describe('supported architectures', () => {
prepareEmpty()
const opts = testDefaults({ nodeLinker: 'hoisted' })
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/has-many-optional-deps@1.0.0'], {
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/has-many-optional-deps@1.0.0'], {
...opts,
supportedArchitectures: { os: ['darwin', 'linux', 'win32'], cpu: ['arm64', 'x64'] },
})
@@ -641,7 +641,7 @@ describe('supported architectures', () => {
prepareEmpty()
const opts = testDefaults({ modulesCacheMaxAge: 0 })
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/parent-of-has-many-optional-deps@1.0.0'], {
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/parent-of-has-many-optional-deps@1.0.0'], {
...opts,
supportedArchitectures: { os: ['darwin', 'linux', 'win32'], cpu: ['arm64', 'x64'] },
})

View File

@@ -21,7 +21,7 @@ test('versions are replaced with versions specified through overrides option', a
'@pnpm.e2e/bar@^100.0.0': '100.1.0',
'@pnpm.e2e/dep-of-pkg-with-1-dep': '101.0.0',
}
const manifest = await addDependenciesToPackage({},
const { updatedManifest: manifest } = await addDependenciesToPackage({},
['@pnpm.e2e/pkg-with-1-dep@100.0.0', '@pnpm.e2e/foobar@100.0.0', '@pnpm.e2e/foobarqar@1.0.0'],
testDefaults({ overrides })
)
@@ -112,7 +112,7 @@ test('when adding a new dependency that is present in the overrides, use the spe
const overrides = {
'@pnpm.e2e/bar': '100.1.0',
}
const manifest = await addDependenciesToPackage({},
const { updatedManifest: manifest } = await addDependenciesToPackage({},
['@pnpm.e2e/bar'],
testDefaults({ overrides })
)
@@ -129,7 +129,7 @@ test('explicitly specifying a version at install will ignore overrides', async (
'@pnpm.e2e/bar': '100.1.0',
}
const EXACT_VERSION = '100.0.0'
const manifest = await addDependenciesToPackage({},
const { updatedManifest: manifest } = await addDependenciesToPackage({},
[`@pnpm.e2e/bar@${EXACT_VERSION}`],
testDefaults({ overrides })
)

View File

@@ -21,7 +21,7 @@ test('manifests are extended with fields specified by packageExtensions', async
},
},
}
const manifest = await addDependenciesToPackage(
const { updatedManifest: manifest } = await addDependenciesToPackage(
{},
['is-positive@1.0.0'],
testDefaults({ packageExtensions })

View File

@@ -32,7 +32,7 @@ test("don't fail when peer dependency is fetched from GitHub", async () => {
test('peer dependency is grouped with dependency when peer is resolved not from a top dependency 1', async () => {
const project = prepareEmpty()
const opts = testDefaults()
let manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/using-ajv'], opts)
let { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/using-ajv'], opts)
expect(fs.existsSync(path.resolve('node_modules/.pnpm/ajv-keywords@1.5.0_ajv@4.10.4/node_modules/ajv'))).toBeTruthy()
expect(deepRequireCwd(['@pnpm.e2e/using-ajv', 'ajv-keywords', 'ajv', './package.json']).version).toBe('4.10.4')
@@ -40,7 +40,7 @@ test('peer dependency is grouped with dependency when peer is resolved not from
// testing that peers are reinstalled correctly using info from the lockfile
rimraf('node_modules')
rimraf(path.resolve('..', '.store'))
manifest = await install(manifest, testDefaults())
manifest = (await install(manifest, testDefaults())).updatedManifest
expect(fs.existsSync(path.resolve('node_modules/.pnpm/ajv-keywords@1.5.0_ajv@4.10.4/node_modules/ajv'))).toBeTruthy()
expect(deepRequireCwd(['@pnpm.e2e/using-ajv', 'ajv-keywords', 'ajv', './package.json']).version).toBe('4.10.4')
@@ -63,7 +63,7 @@ test('nothing is needlessly removed from node_modules', async () => {
modulesCacheMaxAge: 0,
strictPeerDependencies: false,
})
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/using-ajv', 'ajv-keywords@1.5.0'], opts)
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/using-ajv', 'ajv-keywords@1.5.0'], opts)
expect(fs.existsSync(path.resolve('node_modules/.pnpm/ajv-keywords@1.5.0_ajv@4.10.4/node_modules/ajv'))).toBeTruthy()
expect(fs.existsSync(path.resolve('node_modules/.pnpm/ajv-keywords@1.5.0/node_modules/ajv-keywords'))).toBeTruthy()
@@ -85,7 +85,7 @@ test('peer dependency is grouped with dependent when the peer is a top dependenc
const reporter = sinon.spy()
const manifest = await addDependenciesToPackage({}, ['ajv@4.10.4', 'ajv-keywords@1.5.0'], testDefaults({ reporter }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['ajv@4.10.4', 'ajv-keywords@1.5.0'], testDefaults({ reporter }))
expect(reporter.calledWithMatch({
message: `localhost+${REGISTRY_MOCK_PORT}/ajv-keywords/1.5.0 requires a peer of ajv@>=4.10.0 but none was installed.`,
@@ -477,7 +477,7 @@ test('strict-peer-dependencies: error is thrown when bad version of resolved pee
test('top peer dependency is linked on subsequent install', async () => {
prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/peer-c@1.0.0'], testDefaults())
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/peer-c@1.0.0'], testDefaults())
await addDependenciesToPackage(manifest, ['@pnpm.e2e/abc-parent-with-ab@1.0.0'], testDefaults())
@@ -488,7 +488,7 @@ test('top peer dependency is linked on subsequent install', async () => {
test('top peer dependency is linked on subsequent install, through transitive peer', async () => {
prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/abc-grand-parent@1.0.0'], testDefaults({ strictPeerDependencies: false }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/abc-grand-parent@1.0.0'], testDefaults({ strictPeerDependencies: false }))
await addDependenciesToPackage(manifest, ['@pnpm.e2e/peer-c@1.0.0'], testDefaults({ strictPeerDependencies: false }))
@@ -499,7 +499,7 @@ test('the list of transitive peer dependencies is kept up to date', async () =>
const project = prepareEmpty()
await addDistTag({ package: '@pnpm.e2e/abc-parent-with-ab', version: '1.0.0', distTag: 'latest' })
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/abc-grand-parent@1.0.0', '@pnpm.e2e/peer-c@1.0.0'], testDefaults())
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/abc-grand-parent@1.0.0', '@pnpm.e2e/peer-c@1.0.0'], testDefaults())
await addDistTag({ package: '@pnpm.e2e/abc-parent-with-ab', version: '1.1.0', distTag: 'latest' })
@@ -526,7 +526,7 @@ test('the list of transitive peer dependencies is kept up to date', async () =>
test('top peer dependency is linked on subsequent install. Reverse order', async () => {
prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/abc-parent-with-ab@1.0.0'], testDefaults({ strictPeerDependencies: false }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/abc-parent-with-ab@1.0.0'], testDefaults({ strictPeerDependencies: false }))
await addDependenciesToPackage(manifest, ['@pnpm.e2e/peer-c@1.0.0'], testDefaults({ modulesCacheMaxAge: 0, strictPeerDependencies: false }))
@@ -547,7 +547,7 @@ test('peer dependencies are linked when running one named installation', async (
prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/abc-grand-parent-with-c', '@pnpm.e2e/abc-parent-with-ab', '@pnpm.e2e/peer-c@2.0.0'], testDefaults({ autoInstallPeers: false, strictPeerDependencies: false }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/abc-grand-parent-with-c', '@pnpm.e2e/abc-parent-with-ab', '@pnpm.e2e/peer-c@2.0.0'], testDefaults({ autoInstallPeers: false, strictPeerDependencies: false }))
const pkgVariation1 = path.join(
'node_modules/.pnpm',
@@ -585,7 +585,7 @@ test('peer dependencies are linked when running two separate named installations
await addDistTag({ package: '@pnpm.e2e/peer-c', version: '1.0.0', distTag: 'latest' })
prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/abc-grand-parent-with-c', '@pnpm.e2e/peer-c@2.0.0'], testDefaults({ strictPeerDependencies: false }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/abc-grand-parent-with-c', '@pnpm.e2e/peer-c@2.0.0'], testDefaults({ strictPeerDependencies: false }))
await addDependenciesToPackage(manifest, ['@pnpm.e2e/abc-parent-with-ab'], testDefaults({ strictPeerDependencies: false }))
const pkgVariation1 = path.join(
@@ -737,7 +737,7 @@ test('peer dependency is grouped correctly with peer installed via separate inst
const reporter = sinon.spy()
const lockfileDir = path.resolve('..')
const manifest = await install({
const { updatedManifest: manifest } = await install({
dependencies: {
'@pnpm.e2e/abc': '1.0.0',
},
@@ -757,7 +757,7 @@ test('peer dependency is grouped with dependent when the peer is a top dependenc
process.chdir('_')
const lockfileDir = path.resolve('..')
let manifest = await addDependenciesToPackage({}, ['ajv@4.10.4', 'ajv-keywords@1.5.0'], testDefaults({ lockfileDir, strictPeerDependencies: false }))
let { updatedManifest: manifest } = await addDependenciesToPackage({}, ['ajv@4.10.4', 'ajv-keywords@1.5.0'], testDefaults({ lockfileDir, strictPeerDependencies: false }))
{
const lockfile = readYamlFile<LockfileFile>(path.resolve('..', WANTED_LOCKFILE))
@@ -775,7 +775,7 @@ test('peer dependency is grouped with dependent when the peer is a top dependenc
})
}
manifest = await install(manifest, testDefaults({ lockfileDir, strictPeerDependencies: false }))
manifest = (await install(manifest, testDefaults({ lockfileDir, strictPeerDependencies: false }))).updatedManifest
{
const lockfile = readYamlFile<LockfileFile>(path.resolve('..', WANTED_LOCKFILE))
@@ -825,7 +825,7 @@ test('external lockfile: peer dependency is grouped with dependent even after a
process.chdir('_')
const lockfileDir = path.resolve('..')
const manifest = await addDependenciesToPackage({}, ['ajv@4.10.4', 'ajv-keywords@1.4.0'], testDefaults({ lockfileDir }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['ajv@4.10.4', 'ajv-keywords@1.4.0'], testDefaults({ lockfileDir }))
{
const lockfile = readYamlFile<LockfileFile>(path.resolve('..', WANTED_LOCKFILE))
@@ -868,7 +868,7 @@ test('external lockfile: peer dependency is grouped with dependent even after a
process.chdir('_')
const lockfileDir = path.resolve('..')
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/peer-c@1.0.0', '@pnpm.e2e/abc-parent-with-ab@1.0.0'], testDefaults({ lockfileDir, strictPeerDependencies: false }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/peer-c@1.0.0', '@pnpm.e2e/abc-parent-with-ab@1.0.0'], testDefaults({ lockfileDir, strictPeerDependencies: false }))
{
const lockfile = readYamlFile<LockfileFile>(path.resolve('..', WANTED_LOCKFILE))
@@ -915,7 +915,7 @@ test('regular dependencies are not removed on update from transitive packages th
await addDistTag({ package: '@pnpm.e2e/abc-parent-with-ab', version: '1.0.1', distTag: 'latest' })
await addDistTag({ package: '@pnpm.e2e/peer-c', version: '1.0.0', distTag: 'latest' })
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/abc-grand-parent-with-c@1.0.0'], testDefaults({ lockfileDir }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/abc-grand-parent-with-c@1.0.0'], testDefaults({ lockfileDir }))
await addDistTag({ package: '@pnpm.e2e/peer-c', version: '1.0.1', distTag: 'latest' })
await install(manifest, testDefaults({ lockfileDir, update: true, depth: 2 }))
@@ -949,7 +949,7 @@ test('transitive peerDependencies field does not break the lockfile on subsequen
name: 'pkg',
},
])
const { manifest } = await mutateModulesInSingleProject({
const { updatedProject: { manifest } } = await mutateModulesInSingleProject({
dependencySelectors: ['most@1.7.3'],
manifest: {},
mutation: 'installSome',
@@ -995,7 +995,7 @@ test('peer dependency is resolved from parent package via its alias', async () =
test('peer dependency is saved', async () => {
prepareEmpty()
const manifest = await addDependenciesToPackage(
const { updatedManifest: manifest } = await addDependenciesToPackage(
{},
['is-positive@1.0.0'],
testDefaults({
@@ -1011,14 +1011,14 @@ test('peer dependency is saved', async () => {
}
)
const mutatedImporter = await mutateModulesInSingleProject({
const { updatedProject } = await mutateModulesInSingleProject({
dependencyNames: ['is-positive'],
manifest,
mutation: 'uninstallSome',
rootDir: process.cwd() as ProjectRootDir,
}, testDefaults())
expect(mutatedImporter.manifest).toStrictEqual(
expect(updatedProject.manifest).toStrictEqual(
{
devDependencies: {},
peerDependencies: {},
@@ -1175,7 +1175,7 @@ test('local tarball dependency with peer dependency', async () => {
const reporter = sinon.spy()
const manifest = await addDependenciesToPackage({}, [
const { updatedManifest: manifest } = await addDependenciesToPackage({}, [
`file:${f.find('tar-pkg-with-peers-1.0.0.tgz')}`,
'bar@npm:@pnpm.e2e/bar@100.0.0',
'foo@npm:@pnpm.e2e/foo@100.0.0',
@@ -1404,7 +1404,7 @@ test('resolve peer dependency from aliased direct dependency', async () => {
prepareEmpty()
const opts = testDefaults({ autoInstallPeers: false, strictPeerDependencies: false })
const manifest = await addDependenciesToPackage({}, ['peer-a@npm:@pnpm.e2e/peer-a@1.0.0'], opts)
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['peer-a@npm:@pnpm.e2e/peer-a@1.0.0'], opts)
await addDependenciesToPackage(manifest, ['@pnpm.e2e/abc@1.0.0'], opts)
const lockfile = readYamlFile<any>(path.resolve(WANTED_LOCKFILE)) // eslint-disable-line
@@ -1415,7 +1415,7 @@ test('resolve peer dependency using the alias that differs from the real name of
prepareEmpty()
const opts = testDefaults({ autoInstallPeers: false, strictPeerDependencies: false })
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/peer-b@npm:@pnpm.e2e/peer-a@1.0.0'], opts)
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/peer-b@npm:@pnpm.e2e/peer-a@1.0.0'], opts)
await addDependenciesToPackage(manifest, ['@pnpm.e2e/abc@1.0.0'], opts)
const lockfile = readYamlFile<any>(path.resolve(WANTED_LOCKFILE)) // eslint-disable-line
@@ -1428,7 +1428,7 @@ test('when there are several aliased dependencies of the same package, pick the
prepareEmpty()
const opts = testDefaults({ autoInstallPeers: false, strictPeerDependencies: false })
const manifest = await addDependenciesToPackage({}, [
const { updatedManifest: manifest } = await addDependenciesToPackage({}, [
'peer-c3@npm:@pnpm.e2e/peer-c@1.0.0',
'peer-c2@npm:@pnpm.e2e/peer-c@1.0.1',
'peer-c1@npm:@pnpm.e2e/peer-c@2.0.0',
@@ -1443,7 +1443,7 @@ test('when there is an aliases dependency and a non-aliased one, prefer the non-
prepareEmpty()
const opts = testDefaults({ autoInstallPeers: false, strictPeerDependencies: false })
const manifest = await addDependenciesToPackage({}, [
const { updatedManifest: manifest } = await addDependenciesToPackage({}, [
'@pnpm.e2e/peer-c@1.0.0',
'peer-c@npm:@pnpm.e2e/peer-c@2.0.0',
], opts)

View File

@@ -10,7 +10,7 @@ test('reports warning when installing deprecated packages', async () => {
const project = prepareEmpty()
const reporter = jest.fn()
const manifest = await addDependenciesToPackage({}, ['express@0.14.1'], testDefaults({ fastUnpack: false, reporter }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['express@0.14.1'], testDefaults({ fastUnpack: false, reporter }))
expect(reporter).toHaveBeenCalledWith(expect.objectContaining({
deprecated: 'express 0.x series is deprecated',

View File

@@ -38,7 +38,7 @@ test('the lowest version of a direct dependency is installed when resolution mod
await addDistTag({ package: '@pnpm.e2e/foo', version: '100.1.0', distTag: 'latest' })
const project = prepareEmpty()
let manifest = await install({
let { updatedManifest: manifest } = await install({
dependencies: {
'@pnpm.e2e/foo': '^100.0.0',
},
@@ -49,7 +49,7 @@ test('the lowest version of a direct dependency is installed when resolution mod
expect(lockfile.packages['@pnpm.e2e/foo@100.0.0']).toBeTruthy()
}
manifest = await install(manifest, testDefaults({ resolutionMode: 'time-based', update: true }))
manifest = (await install(manifest, testDefaults({ resolutionMode: 'time-based', update: true }))).updatedManifest
{
const lockfile = project.readLockfile()
@@ -70,7 +70,7 @@ test('the lowest version of a direct dependency is installed when resolution mod
await addDistTag({ package: '@pnpm.e2e/dep-of-pkg-with-1-dep', version: '100.1.0', distTag: 'latest' })
const project = prepareEmpty()
let manifest = await install({
let { updatedManifest: manifest } = await install({
dependencies: {
'@pnpm.e2e/pkg-with-1-dep': '^100.0.0',
},
@@ -82,7 +82,7 @@ test('the lowest version of a direct dependency is installed when resolution mod
expect(lockfile.packages['@pnpm.e2e/dep-of-pkg-with-1-dep@100.1.0']).toBeTruthy()
}
manifest = await install(manifest, testDefaults({ resolutionMode: 'lowest-direct', update: true }))
manifest = (await install(manifest, testDefaults({ resolutionMode: 'lowest-direct', update: true }))).updatedManifest
{
const lockfile = project.readLockfile()

View File

@@ -21,14 +21,14 @@ test.skip('caching side effects of native package', async () => {
sideEffectsCacheRead: true,
sideEffectsCacheWrite: true,
})
let manifest = await addDependenciesToPackage({}, ['diskusage@1.1.3'], opts)
let { updatedManifest: manifest } = await addDependenciesToPackage({}, ['diskusage@1.1.3'], opts)
const cacheBuildDir = path.join(opts.storeDir, `localhost+${REGISTRY_MOCK_PORT}/diskusage/1.1.3/side_effects/${ENGINE_DIR}/package/build`)
const stat1 = fs.statSync(cacheBuildDir)
expect(fs.existsSync('node_modules/diskusage/build')).toBeTruthy()
expect(fs.existsSync(cacheBuildDir)).toBeTruthy()
manifest = await addDependenciesToPackage(manifest, ['diskusage@1.1.3'], opts)
manifest = (await addDependenciesToPackage(manifest, ['diskusage@1.1.3'], opts)).updatedManifest
const stat2 = fs.statSync(cacheBuildDir)
expect(stat1.ino).toBe(stat2.ino)
@@ -49,7 +49,7 @@ test.skip('caching side effects of native package when hoisting is used', async
sideEffectsCacheRead: true,
sideEffectsCacheWrite: true,
})
const manifest = await addDependenciesToPackage({}, ['expire-fs@2.2.3'], opts)
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['expire-fs@2.2.3'], opts)
const cacheBuildDir = path.join(opts.storeDir, `localhost+${REGISTRY_MOCK_PORT}/diskusage/1.1.3/side_effects/${ENGINE_DIR}/package/build`)
const stat1 = fs.statSync(cacheBuildDir)
@@ -80,7 +80,7 @@ test('using side effects cache', async () => {
sideEffectsCacheWrite: true,
verifyStoreIntegrity: false,
}, {}, {}, { packageImportMethod: 'copy' })
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/pre-and-postinstall-scripts-example@1.0.0'], opts)
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/pre-and-postinstall-scripts-example@1.0.0'], opts)
const filesIndexFile = getIndexFilePathInCafs(opts.storeDir, getIntegrity('@pnpm.e2e/pre-and-postinstall-scripts-example', '1.0.0'), '@pnpm.e2e/pre-and-postinstall-scripts-example@1.0.0')
const filesIndex = loadJsonFile.sync<PackageFilesIndex>(filesIndexFile)
@@ -115,7 +115,7 @@ test.skip('readonly side effects cache', async () => {
sideEffectsCacheWrite: true,
verifyStoreIntegrity: false,
})
let manifest = await addDependenciesToPackage({}, ['diskusage@1.1.3'], opts1)
let { updatedManifest: manifest } = await addDependenciesToPackage({}, ['diskusage@1.1.3'], opts1)
// Modify the side effects cache to make sure we are using it
const cacheBuildDir = path.join(opts1.storeDir, `localhost+${REGISTRY_MOCK_PORT}/diskusage/1.1.3/side_effects/${ENGINE_DIR}/package/build`)
@@ -128,7 +128,7 @@ test.skip('readonly side effects cache', async () => {
sideEffectsCacheWrite: false,
verifyStoreIntegrity: false,
}, {}, {}, { packageImportMethod: 'copy' })
manifest = await addDependenciesToPackage(manifest, ['diskusage@1.1.3'], opts2)
manifest = (await addDependenciesToPackage(manifest, ['diskusage@1.1.3'], opts2)).updatedManifest
expect(fs.existsSync('node_modules/diskusage/build/new-file.txt')).toBeTruthy()
@@ -192,7 +192,7 @@ test('a corrupted side-effects cache is ignored', async () => {
sideEffectsCacheRead: true,
sideEffectsCacheWrite: true,
})
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/pre-and-postinstall-scripts-example@1.0.0'], opts)
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/pre-and-postinstall-scripts-example@1.0.0'], opts)
const filesIndexFile = getIndexFilePathInCafs(opts.storeDir, getIntegrity('@pnpm.e2e/pre-and-postinstall-scripts-example', '1.0.0'), '@pnpm.e2e/pre-and-postinstall-scripts-example@1.0.0')
const filesIndex = loadJsonFile.sync<PackageFilesIndex>(filesIndexFile)

View File

@@ -19,7 +19,7 @@ test('preserve subdeps on update', async () => {
addDistTag({ package: '@pnpm.e2e/peer-c', version: '1.0.0', distTag: 'latest' }),
])
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/foobarqar', '@pnpm.e2e/abc-grand-parent-with-c'], testDefaults())
const { updatedManifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/foobarqar', '@pnpm.e2e/abc-grand-parent-with-c'], testDefaults())
await Promise.all([
addDistTag({ package: '@pnpm.e2e/abc-grand-parent-with-c', version: '1.0.1', distTag: 'latest' }),
@@ -29,7 +29,7 @@ test('preserve subdeps on update', async () => {
addDistTag({ package: '@pnpm.e2e/foobarqar', version: '1.0.1', distTag: 'latest' }),
])
await install(manifest, testDefaults({ update: true, depth: 0 }))
await install(updatedManifest, testDefaults({ update: true, depth: 0 }))
const lockfile = project.readLockfile()
@@ -55,7 +55,7 @@ test('preserve subdeps on update when no node_modules is present', async () => {
addDistTag({ package: '@pnpm.e2e/peer-c', version: '1.0.0', distTag: 'latest' }),
])
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/foobarqar', '@pnpm.e2e/abc-grand-parent-with-c'], testDefaults({ lockfileOnly: true }))
const { updatedManifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/foobarqar', '@pnpm.e2e/abc-grand-parent-with-c'], testDefaults({ lockfileOnly: true }))
await Promise.all([
addDistTag({ package: '@pnpm.e2e/abc-grand-parent-with-c', version: '1.0.1', distTag: 'latest' }),
@@ -65,7 +65,7 @@ test('preserve subdeps on update when no node_modules is present', async () => {
addDistTag({ package: '@pnpm.e2e/foobarqar', version: '1.0.1', distTag: 'latest' }),
])
await install(manifest, testDefaults({ update: true, depth: 0 }))
await install(updatedManifest, testDefaults({ update: true, depth: 0 }))
const lockfile = project.readLockfile()
@@ -82,7 +82,7 @@ test('preserve subdeps on update when no node_modules is present', async () => {
test('update does not fail when package has only peer dependencies', async () => {
prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/has-pkg-with-peer-only'], testDefaults())
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/has-pkg-with-peer-only'], testDefaults())
await install(manifest, testDefaults({ update: true, depth: Infinity }))
})
@@ -104,7 +104,7 @@ test('update dependency when external lockfile directory is used', async () => {
await addDistTag({ package: '@pnpm.e2e/foo', version: '100.0.0', distTag: 'latest' })
const lockfileDir = path.resolve('..')
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/foo'], testDefaults({ lockfileDir }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/foo'], testDefaults({ lockfileDir }))
await addDistTag({ package: '@pnpm.e2e/foo', version: '100.1.0', distTag: 'latest' })
@@ -128,7 +128,7 @@ test('preserve subdeps when installing on a package that has one dependency spec
addDistTag({ package: '@pnpm.e2e/peer-c', version: '1.0.0', distTag: 'latest' }),
])
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/foobarqar', '@pnpm.e2e/abc-grand-parent-with-c'], testDefaults())
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/foobarqar', '@pnpm.e2e/abc-grand-parent-with-c'], testDefaults())
manifest.dependencies!['@pnpm.e2e/foobarqar'] = '^1.0.1'
@@ -159,12 +159,12 @@ test('update only the packages that were requested to be updated when hoisting i
await addDistTag({ package: '@pnpm.e2e/bar', version: '100.0.0', distTag: 'latest' })
await addDistTag({ package: '@pnpm.e2e/foo', version: '100.0.0', distTag: 'latest' })
let manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/bar', '@pnpm.e2e/foo'], testDefaults({ hoistPattern: ['*'] }))
let { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/bar', '@pnpm.e2e/foo'], testDefaults({ hoistPattern: ['*'] }))
await addDistTag({ package: '@pnpm.e2e/bar', version: '100.1.0', distTag: 'latest' })
await addDistTag({ package: '@pnpm.e2e/foo', version: '100.1.0', distTag: 'latest' })
manifest = await addDependenciesToPackage(manifest, ['@pnpm.e2e/foo'], testDefaults({ allowNew: false, update: true, hoistPattern: ['*'] }))
manifest = (await addDependenciesToPackage(manifest, ['@pnpm.e2e/foo'], testDefaults({ allowNew: false, update: true, hoistPattern: ['*'] }))).updatedManifest
expect(manifest.dependencies).toStrictEqual({ '@pnpm.e2e/bar': '^100.0.0', '@pnpm.e2e/foo': '^100.1.0' })
@@ -184,7 +184,7 @@ test('update only the specified package', async () => {
addDistTag({ package: '@pnpm.e2e/peer-c', version: '1.0.0', distTag: 'latest' }),
])
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/foobarqar', '@pnpm.e2e/abc-grand-parent-with-c'], testDefaults())
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/foobarqar', '@pnpm.e2e/abc-grand-parent-with-c'], testDefaults())
await Promise.all([
addDistTag({ package: '@pnpm.e2e/abc-grand-parent-with-c', version: '1.0.1', distTag: 'latest' }),
@@ -213,7 +213,7 @@ test('update only the specified package', async () => {
test('peer dependency is not added to prod deps on update', async () => {
prepareEmpty()
const manifest = await install({
const { updatedManifest: manifest } = await install({
peerDependencies: {
'is-positive': '^3.0.0',
},

View File

@@ -10,7 +10,7 @@ import { testDefaults } from '../utils'
test('save to package.json (is-positive@^1.0.0)', async () => {
const project = prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['is-positive@^1.0.0'], testDefaults({ save: true }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['is-positive@^1.0.0'], testDefaults({ save: true }))
project.has('is-positive')
@@ -20,15 +20,15 @@ test('save to package.json (is-positive@^1.0.0)', async () => {
// NOTE: this works differently for global installations. See similar tests in global.ts
test("don't override existing spec in package.json on named installation", async () => {
const project = prepareEmpty()
let manifest = await addDependenciesToPackage({
let { updatedManifest: manifest } = await addDependenciesToPackage({
dependencies: {
'is-negative': '^1.0.0', // this will be updated
'is-positive': '^2.0.0', // this will be kept as no newer version is available from the range
sec: 'sindresorhus/sec#main',
},
}, ['is-positive'], testDefaults())
manifest = await addDependenciesToPackage(manifest, ['is-negative'], testDefaults())
manifest = await addDependenciesToPackage(manifest, ['sec'], testDefaults())
manifest = (await addDependenciesToPackage(manifest, ['is-negative'], testDefaults())).updatedManifest
manifest = (await addDependenciesToPackage(manifest, ['sec'], testDefaults())).updatedManifest
expect(project.requireModule('is-positive/package.json').version).toBe('2.0.0')
expect(project.requireModule('is-negative/package.json').version).toBe('1.0.1')
@@ -42,7 +42,7 @@ test("don't override existing spec in package.json on named installation", async
test('saveDev scoped module to package.json (@rstacruz/tap-spec)', async () => {
const project = prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['@rstacruz/tap-spec'], testDefaults({ fastUnpack: false, targetDependenciesField: 'devDependencies' }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@rstacruz/tap-spec'], testDefaults({ fastUnpack: false, targetDependenciesField: 'devDependencies' }))
const m = project.requireModule('@rstacruz/tap-spec')
expect(typeof m).toBe('function')
@@ -55,7 +55,7 @@ test('dependency should not be added to package.json if it is already there', as
await addDistTag({ package: '@pnpm.e2e/bar', version: '100.0.0', distTag: 'latest' })
const project = prepareEmpty()
const manifest = await addDependenciesToPackage({
const { updatedManifest: manifest } = await addDependenciesToPackage({
devDependencies: {
'@pnpm.e2e/foo': '^100.0.0',
},
@@ -86,7 +86,7 @@ test('dependencies should be updated in the fields where they already are', asyn
await addDistTag({ package: '@pnpm.e2e/bar', version: '100.1.0', distTag: 'latest' })
prepareEmpty()
const manifest = await addDependenciesToPackage({
const { updatedManifest: manifest } = await addDependenciesToPackage({
devDependencies: {
'@pnpm.e2e/foo': '^100.0.0',
},
@@ -111,7 +111,7 @@ test('dependency should be removed from the old field when installing it as a di
await addDistTag({ package: '@pnpm.e2e/qar', version: '100.0.0', distTag: 'latest' })
const project = prepareEmpty()
let manifest = await addDependenciesToPackage({
let { updatedManifest: manifest } = await addDependenciesToPackage({
dependencies: {
'@pnpm.e2e/foo': '^100.0.0',
},
@@ -122,8 +122,8 @@ test('dependency should be removed from the old field when installing it as a di
'@pnpm.e2e/qar': '^100.0.0',
},
}, ['@pnpm.e2e/foo'], testDefaults({ targetDependenciesField: 'optionalDependencies' }))
manifest = await addDependenciesToPackage(manifest, ['@pnpm.e2e/bar'], testDefaults({ targetDependenciesField: 'dependencies' }))
manifest = await addDependenciesToPackage(manifest, ['@pnpm.e2e/qar'], testDefaults({ targetDependenciesField: 'devDependencies' }))
manifest = (await addDependenciesToPackage(manifest, ['@pnpm.e2e/bar'], testDefaults({ targetDependenciesField: 'dependencies' }))).updatedManifest
manifest = (await addDependenciesToPackage(manifest, ['@pnpm.e2e/qar'], testDefaults({ targetDependenciesField: 'devDependencies' }))).updatedManifest
expect(manifest).toStrictEqual({
dependencies: {
@@ -137,7 +137,7 @@ test('dependency should be removed from the old field when installing it as a di
},
})
manifest = await addDependenciesToPackage(manifest, ['@pnpm.e2e/bar', '@pnpm.e2e/foo', '@pnpm.e2e/qar'], testDefaults({ targetDependenciesField: 'dependencies' }))
manifest = (await addDependenciesToPackage(manifest, ['@pnpm.e2e/bar', '@pnpm.e2e/foo', '@pnpm.e2e/qar'], testDefaults({ targetDependenciesField: 'dependencies' }))).updatedManifest
expect(manifest).toStrictEqual({
dependencies: {
@@ -170,7 +170,7 @@ test('dependency should be removed from the old field when installing it as a di
test('multiple save to package.json with `exact` versions (@rstacruz/tap-spec & rimraf@2.5.1) (in sorted order)', async () => {
const project = prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['is-positive@1.0.0', '@zkochan/foo@latest'], testDefaults({ save: true, pinnedVersion: 'patch' }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['is-positive@1.0.0', '@zkochan/foo@latest'], testDefaults({ save: true, pinnedVersion: 'patch' }))
project.has('@zkochan/foo')
project.has('is-positive')
@@ -186,7 +186,7 @@ test('multiple save to package.json with `exact` versions (@rstacruz/tap-spec &
test('save to package.json with save prefix ~', async () => {
await addDistTag({ package: '@pnpm.e2e/pkg-with-1-dep', version: '100.0.0', distTag: 'latest' })
prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/pkg-with-1-dep'], testDefaults({ pinnedVersion: 'minor' }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/pkg-with-1-dep'], testDefaults({ pinnedVersion: 'minor' }))
expect(manifest.dependencies).toStrictEqual({ '@pnpm.e2e/pkg-with-1-dep': '~100.0.0' })
})
@@ -198,7 +198,7 @@ test('an update bumps the versions in the manifest', async () => {
prepareEmpty()
const { manifest } = await mutateModulesInSingleProject({
const { updatedProject: { manifest } } = await mutateModulesInSingleProject({
manifest: {
dependencies: {
'@pnpm.e2e/peer-a': '~1.0.0',

View File

@@ -6,7 +6,7 @@ import { testDefaults } from '../utils'
test('setting a custom virtual store directory max length', async () => {
prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['@babel/helper-member-expression-to-functions@7.23.0'], testDefaults({
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@babel/helper-member-expression-to-functions@7.23.0'], testDefaults({
virtualStoreDirMaxLength: 50,
}))

View File

@@ -61,7 +61,7 @@ test('relative link is rewritten by named installation to regular dependency', a
f.copy(linkedPkgName, linkedPkgPath)
symlinkDir.sync(linkedPkgPath, path.resolve('node_modules/@pnpm.e2e/hello-world-js-bin'))
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/hello-world-js-bin'], opts)
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/hello-world-js-bin'], opts)
expect(manifest.dependencies).toStrictEqual({ '@pnpm.e2e/hello-world-js-bin': '^1.0.0' })

View File

@@ -127,7 +127,7 @@ test("lockfile doesn't lock subdependencies that don't satisfy the new specs", a
const project = prepareEmpty()
// depends on react-onclickoutside@5.9.0
const manifest = await addDependenciesToPackage({}, ['react-datetime@2.8.8'], testDefaults({
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['react-datetime@2.8.8'], testDefaults({
autoInstallPeers: false,
fastUnpack: false,
save: true,
@@ -287,7 +287,7 @@ test(`doing named installation when ${WANTED_LOCKFILE} exists already`, async ()
const reporter = sinon.spy()
const manifest = await addDependenciesToPackage({
const { updatedManifest: manifest } = await addDependenciesToPackage({
dependencies: {
'@types/semver': '5.3.31',
'is-negative': '^2.1.0',
@@ -315,11 +315,11 @@ test(`respects ${WANTED_LOCKFILE} for top dependencies`, async () => {
const pkgs = ['@pnpm.e2e/foo', '@pnpm.e2e/bar', '@pnpm.e2e/qar']
await Promise.all(pkgs.map(async (pkgName) => addDistTag({ package: pkgName, version: '100.0.0', distTag: 'latest' })))
let manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/foo'], testDefaults({ save: true, reporter }))
let { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/foo'], testDefaults({ save: true, reporter }))
// t.equal(reporter.withArgs(fooProgress).callCount, 1, 'reported foo once')
manifest = await addDependenciesToPackage(manifest, ['@pnpm.e2e/bar'], testDefaults({ targetDependenciesField: 'optionalDependencies' }))
manifest = await addDependenciesToPackage(manifest, ['@pnpm.e2e/qar'], testDefaults({ addDependenciesToPackage: 'devDependencies' }))
manifest = await addDependenciesToPackage(manifest, ['@pnpm.e2e/foobar'], testDefaults({ save: true }))
manifest = (await addDependenciesToPackage(manifest, ['@pnpm.e2e/bar'], testDefaults({ targetDependenciesField: 'optionalDependencies' }))).updatedManifest
manifest = (await addDependenciesToPackage(manifest, ['@pnpm.e2e/qar'], testDefaults({ addDependenciesToPackage: 'devDependencies' }))).updatedManifest
manifest = (await addDependenciesToPackage(manifest, ['@pnpm.e2e/foobar'], testDefaults({ save: true }))).updatedManifest
expect((await readPackageJsonFromDir(path.resolve('node_modules', '@pnpm.e2e/foo'))).version).toBe('100.0.0')
expect((await readPackageJsonFromDir(path.resolve('node_modules', '@pnpm.e2e/bar'))).version).toBe('100.0.0')
@@ -360,7 +360,7 @@ test(`subdeps are updated on repeat install if outer ${WANTED_LOCKFILE} does not
await addDistTag({ package: '@pnpm.e2e/pkg-with-1-dep', version: '100.0.0', distTag: 'latest' })
await addDistTag({ package: '@pnpm.e2e/dep-of-pkg-with-1-dep', version: '100.0.0', distTag: 'latest' })
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/pkg-with-1-dep'], testDefaults())
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/pkg-with-1-dep'], testDefaults())
project.storeHas('@pnpm.e2e/dep-of-pkg-with-1-dep', '100.0.0')
@@ -388,9 +388,9 @@ test(`subdeps are updated on repeat install if outer ${WANTED_LOCKFILE} does not
test("recreates lockfile if it doesn't match the dependencies in package.json", async () => {
const project = prepareEmpty()
let manifest = await addDependenciesToPackage({}, ['is-negative@1.0.0'], testDefaults({ pinnedVersion: 'patch', targetDependenciesField: 'dependencies' }))
manifest = await addDependenciesToPackage(manifest, ['is-positive@1.0.0'], testDefaults({ pinnedVersion: 'patch', targetDependenciesField: 'devDependencies' }))
manifest = await addDependenciesToPackage(manifest, ['map-obj@1.0.0'], testDefaults({ pinnedVersion: 'patch', targetDependenciesField: 'optionalDependencies' }))
let { updatedManifest: manifest } = await addDependenciesToPackage({}, ['is-negative@1.0.0'], testDefaults({ pinnedVersion: 'patch', targetDependenciesField: 'dependencies' }))
manifest = (await addDependenciesToPackage(manifest, ['is-positive@1.0.0'], testDefaults({ pinnedVersion: 'patch', targetDependenciesField: 'devDependencies' }))).updatedManifest
manifest = (await addDependenciesToPackage(manifest, ['map-obj@1.0.0'], testDefaults({ pinnedVersion: 'patch', targetDependenciesField: 'optionalDependencies' }))).updatedManifest
const lockfile1 = project.readLockfile()
expect(lockfile1.importers['.'].dependencies?.['is-negative'].version).toBe('1.0.0')
@@ -418,7 +418,7 @@ test("recreates lockfile if it doesn't match the dependencies in package.json",
test('repeat install with lockfile should not mutate lockfile when dependency has version specified with v prefix', async () => {
const project = prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['highmaps-release@5.0.11'], testDefaults())
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['highmaps-release@5.0.11'], testDefaults())
const lockfile1 = project.readLockfile()
@@ -439,7 +439,7 @@ test('package is not marked optional if it is also a subdep of a regular depende
await addDistTag({ package: '@pnpm.e2e/pkg-with-1-dep', version: '100.0.0', distTag: 'latest' })
await addDistTag({ package: '@pnpm.e2e/dep-of-pkg-with-1-dep', version: '100.0.0', distTag: 'latest' })
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/pkg-with-1-dep'], testDefaults())
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/pkg-with-1-dep'], testDefaults())
await addDependenciesToPackage(manifest, ['@pnpm.e2e/dep-of-pkg-with-1-dep'], testDefaults({ targetDependenciesField: 'optionalDependencies' }))
const lockfile = project.readLockfile()
@@ -535,7 +535,7 @@ test('scoped module from different registry', async () => {
test('repeat install with no inner lockfile should not rewrite packages in node_modules', async () => {
const project = prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['is-negative@1.0.0'], testDefaults())
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['is-negative@1.0.0'], testDefaults())
rimraf('node_modules/.pnpm/lock.yaml')
@@ -588,14 +588,14 @@ test('packages are placed in devDependencies even if they are present as non-dev
test('updating package that has a github-hosted dependency', async () => {
prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/has-github-dep@1'], testDefaults())
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/has-github-dep@1'], testDefaults())
await addDependenciesToPackage(manifest, ['@pnpm.e2e/has-github-dep@latest'], testDefaults())
})
test('updating package that has deps with peers', async () => {
prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/abc-grand-parent-with-c@0'], testDefaults())
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/abc-grand-parent-with-c@0'], testDefaults())
await addDependenciesToPackage(manifest, ['@pnpm.e2e/abc-grand-parent-with-c@1'], testDefaults())
})
@@ -625,7 +625,7 @@ test('pendingBuilds gets updated if install removes packages', async () => {
test('optional properties are correctly updated on named install', async () => {
const project = prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['inflight@1.0.6'], testDefaults({ targetDependenciesField: 'optionalDependencies' }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['inflight@1.0.6'], testDefaults({ targetDependenciesField: 'optionalDependencies' }))
await addDependenciesToPackage(manifest, ['foo@npm:inflight@1.0.6'], testDefaults({}))
const lockfile = project.readLockfile()
@@ -688,7 +688,7 @@ test(`don't update ${WANTED_LOCKFILE} during uninstall when useLockfile: false`,
{
const reporter = sinon.spy()
manifest = await addDependenciesToPackage({}, ['is-positive'], testDefaults({ reporter }))
manifest = (await addDependenciesToPackage({}, ['is-positive'], testDefaults({ reporter }))).updatedManifest
expect(reporter.calledWithMatch(LOCKFILE_WARN_LOG)).toBeFalsy()
}
@@ -725,7 +725,7 @@ test('fail when installing with useLockfile: false and lockfileOnly: true', asyn
test("don't remove packages during named install when useLockfile: false", async () => {
const project = prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['is-positive'], testDefaults({ useLockfile: false }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['is-positive'], testDefaults({ useLockfile: false }))
await addDependenciesToPackage(manifest, ['is-negative'], testDefaults({ useLockfile: false }))
project.has('is-positive')
@@ -809,7 +809,7 @@ test('lockfile file has correct format when lockfile directory does not equal th
const storeDir = path.resolve('..', '.store')
const manifest = await addDependenciesToPackage(
const { updatedManifest: manifest } = await addDependenciesToPackage(
{},
[
'@pnpm.e2e/pkg-with-1-dep',
@@ -937,14 +937,14 @@ test(`doing named installation when shared ${WANTED_LOCKFILE} exists already`, a
},
}, { lineWidth: 1000 })
pkg2 = await addDependenciesToPackage(
pkg2 = (await addDependenciesToPackage(
pkg2,
['is-positive'],
testDefaults({
dir: path.resolve('pkg2'),
lockfileDir: process.cwd(),
})
)
)).updatedManifest
const currentLockfile = readYamlFile<LockfileFile>(path.resolve('node_modules/.pnpm/lock.yaml'))
@@ -985,7 +985,7 @@ test(`doing named installation when shared ${WANTED_LOCKFILE} exists already`, a
test(`use current ${WANTED_LOCKFILE} as initial wanted one, when wanted was removed`, async () => {
const project = prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['lodash@4.17.11', 'underscore@1.9.0'], testDefaults())
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['lodash@4.17.11', 'underscore@1.9.0'], testDefaults())
rimraf(WANTED_LOCKFILE)
@@ -1002,7 +1002,7 @@ test('existing dependencies are preserved when updating a lockfile to a newer fo
await addDistTag({ package: '@pnpm.e2e/dep-of-pkg-with-1-dep', version: '100.0.0', distTag: 'latest' })
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/pkg-with-1-dep'], testDefaults())
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/pkg-with-1-dep'], testDefaults())
const initialLockfile = project.readLockfile()
writeYamlFile(WANTED_LOCKFILE, { ...initialLockfile, lockfileVersion: '6.0' }, { lineWidth: 1000 })
@@ -1025,7 +1025,7 @@ test('broken lockfile is fixed even if it seems like up to date at first. Unless
await addDistTag({ package: '@pnpm.e2e/pkg-with-1-dep', version: '100.0.0', distTag: 'latest' })
await addDistTag({ package: '@pnpm.e2e/dep-of-pkg-with-1-dep', version: '100.0.0', distTag: 'latest' })
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/pkg-with-1-dep'], testDefaults({ lockfileOnly: true }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/pkg-with-1-dep'], testDefaults({ lockfileOnly: true }))
{
const lockfile = project.readLockfile()
expect(lockfile.packages).toHaveProperty(['@pnpm.e2e/dep-of-pkg-with-1-dep@100.0.0'])
@@ -1320,7 +1320,7 @@ packages:
test('a broken private lockfile is ignored', async () => {
prepareEmpty()
const manifest = await install({
const { updatedManifest: manifest } = await install({
dependencies: {
'@pnpm.e2e/dep-of-pkg-with-1-dep': '100.0.0',
},
@@ -1362,7 +1362,7 @@ test('build metadata is always ignored in versions and the lockfile is not flick
await addDistTag({ package: '@monorepolint/core', version: '0.5.0-alpha.51', distTag: 'latest' })
const project = prepareEmpty()
const manifest = await addDependenciesToPackage({},
const { updatedManifest: manifest } = await addDependenciesToPackage({},
[
'@monorepolint/cli@0.5.0-alpha.51',
], testDefaults({ lockfileOnly: true }))
@@ -1384,7 +1384,7 @@ test('a broken lockfile should not break the store', async () => {
prepareEmpty()
const opts = testDefaults()
const manifest = await addDependenciesToPackage({}, ['is-positive@1.0.0'], { ...opts, lockfileOnly: true })
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['is-positive@1.0.0'], { ...opts, lockfileOnly: true })
const lockfile: LockfileObject = readYamlFile(WANTED_LOCKFILE)
lockfile.packages!['is-positive@1.0.0' as DepPath].name = 'bad-name'
@@ -1425,7 +1425,7 @@ test('include tarball URL', async () => {
test('lockfile v6', async () => {
prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/pkg-with-1-dep@100.0.0'], testDefaults({ useLockfileV6: true }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/pkg-with-1-dep@100.0.0'], testDefaults({ useLockfileV6: true }))
{
const lockfile = readYamlFile<any>(WANTED_LOCKFILE) // eslint-disable-line @typescript-eslint/no-explicit-any
@@ -1554,7 +1554,7 @@ test('update the lockfile when a new project is added to the workspace and lockf
test('lockfile is not written when it has no changes', async () => {
prepareEmpty()
const manifest = await install({
const { updatedManifest: manifest } = await install({
dependencies: {
'@types/semver': '^5.3.31',
},
@@ -1570,7 +1570,7 @@ test('lockfile is not written when it has no changes', async () => {
test('installation should work with packages that have () in the scope name', async () => {
prepareEmpty()
const opts = testDefaults()
const manifest = await addDependenciesToPackage({}, ['@(-.-)/env@0.3.1'], opts)
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@(-.-)/env@0.3.1'], opts)
await install(manifest, opts)
})

View File

@@ -17,7 +17,7 @@ test('offline installation fails when package meta not found in local registry m
test('offline installation fails when package tarball not found in local registry mirror', async () => {
prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['is-positive@3.0.0'], testDefaults())
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['is-positive@3.0.0'], testDefaults())
rimraf('node_modules')
@@ -32,7 +32,7 @@ test('offline installation fails when package tarball not found in local registr
test('successful offline installation', async () => {
const project = prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['is-positive@3.0.0'], testDefaults({ save: true }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['is-positive@3.0.0'], testDefaults({ save: true }))
rimraf('node_modules')

View File

@@ -19,10 +19,10 @@ test('prune removes extraneous packages', async () => {
const project = prepareEmpty()
const opts = testDefaults()
let manifest = await addDependenciesToPackage({}, ['is-negative@2.1.0'], { ...opts, targetDependenciesField: 'dependencies' })
manifest = await addDependenciesToPackage(manifest, ['applyq@0.2.1'], { ...opts, targetDependenciesField: 'devDependencies' })
manifest = await addDependenciesToPackage(manifest, ['fnumber@0.1.0'], { ...opts, targetDependenciesField: 'optionalDependencies' })
manifest = await addDependenciesToPackage(manifest, ['is-positive@2.0.0', '@zkochan/logger@0.1.0'], opts)
let { updatedManifest: manifest } = await addDependenciesToPackage({}, ['is-negative@2.1.0'], { ...opts, targetDependenciesField: 'dependencies' })
manifest = (await addDependenciesToPackage(manifest, ['applyq@0.2.1'], { ...opts, targetDependenciesField: 'devDependencies' })).updatedManifest
manifest = (await addDependenciesToPackage(manifest, ['fnumber@0.1.0'], { ...opts, targetDependenciesField: 'optionalDependencies' })).updatedManifest
manifest = (await addDependenciesToPackage(manifest, ['is-positive@2.0.0', '@zkochan/logger@0.1.0'], opts)).updatedManifest
symlinkDir.sync(linkedPkg, path.resolve('node_modules/@pnpm.e2e/hello-world-js-bin'))
project.has('@pnpm.e2e/hello-world-js-bin') // external link added
@@ -74,9 +74,9 @@ test('prune removes extraneous packages', async () => {
test('prune removes dev dependencies in production', async () => {
const project = prepareEmpty()
let manifest = await addDependenciesToPackage({}, ['is-positive@2.0.0'], testDefaults({ targetDependenciesField: 'devDependencies' }))
manifest = await addDependenciesToPackage(manifest, ['is-negative@2.1.0'], testDefaults({ targetDependenciesField: 'dependencies' }))
manifest = await addDependenciesToPackage(manifest, ['fnumber@0.1.0'], testDefaults({ targetDependenciesField: 'optionalDependencies' }))
let { updatedManifest: manifest } = await addDependenciesToPackage({}, ['is-positive@2.0.0'], testDefaults({ targetDependenciesField: 'devDependencies' }))
manifest = (await addDependenciesToPackage(manifest, ['is-negative@2.1.0'], testDefaults({ targetDependenciesField: 'dependencies' }))).updatedManifest
manifest = (await addDependenciesToPackage(manifest, ['fnumber@0.1.0'], testDefaults({ targetDependenciesField: 'optionalDependencies' }))).updatedManifest
await install(manifest, testDefaults({
include: {
dependencies: true,

View File

@@ -28,7 +28,7 @@ const f = fixtures(__dirname)
test('uninstall package with no dependencies', async () => {
const project = prepareEmpty()
let manifest = await addDependenciesToPackage({}, ['is-negative@2.1.0'], testDefaults({ save: true }))
let { updatedManifest: manifest } = await addDependenciesToPackage({}, ['is-negative@2.1.0'], testDefaults({ save: true }))
const reporter = sinon.spy()
manifest = (await mutateModulesInSingleProject({
@@ -36,7 +36,7 @@ test('uninstall package with no dependencies', async () => {
manifest,
mutation: 'uninstallSome',
rootDir: process.cwd() as ProjectRootDir,
}, testDefaults({ save: true, reporter }))).manifest
}, testDefaults({ save: true, reporter }))).updatedProject.manifest
expect(reporter.calledWithMatch({
initial: {
@@ -102,13 +102,13 @@ test('uninstall a dependency that is not present in node_modules', async () => {
test('uninstall scoped package', async () => {
const project = prepareEmpty()
let manifest = await addDependenciesToPackage({}, ['@zkochan/logger@0.1.0'], testDefaults({ save: true }))
let { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@zkochan/logger@0.1.0'], testDefaults({ save: true }))
manifest = (await mutateModulesInSingleProject({
dependencyNames: ['@zkochan/logger'],
manifest,
mutation: 'uninstallSome',
rootDir: process.cwd() as ProjectRootDir,
}, testDefaults({ save: true }))).manifest
}, testDefaults({ save: true }))).updatedProject.manifest
project.storeHas('@zkochan/logger', '0.1.0')
@@ -121,13 +121,13 @@ test('uninstall tarball dependency', async () => {
const project = prepareEmpty()
const opts = testDefaults({ save: true })
let manifest = await addDependenciesToPackage({}, [`http://localhost:${REGISTRY_MOCK_PORT}/is-array/-/is-array-1.0.1.tgz`], opts)
let { updatedManifest: manifest } = await addDependenciesToPackage({}, [`http://localhost:${REGISTRY_MOCK_PORT}/is-array/-/is-array-1.0.1.tgz`], opts)
manifest = (await mutateModulesInSingleProject({
dependencyNames: ['is-array'],
manifest,
mutation: 'uninstallSome',
rootDir: process.cwd() as ProjectRootDir,
}, opts)).manifest
}, opts)).updatedProject.manifest
project.storeHas('is-array', '1.0.1')
project.hasNot('is-array')
@@ -137,13 +137,13 @@ test('uninstall tarball dependency', async () => {
test('uninstall package with dependencies and do not touch other deps', async () => {
const project = prepareEmpty()
let manifest = await addDependenciesToPackage({}, ['is-negative@2.1.0', 'camelcase-keys@3.0.0'], testDefaults({ save: true }))
let { updatedManifest: manifest } = await addDependenciesToPackage({}, ['is-negative@2.1.0', 'camelcase-keys@3.0.0'], testDefaults({ save: true }))
manifest = (await mutateModulesInSingleProject({
dependencyNames: ['camelcase-keys'],
manifest,
mutation: 'uninstallSome',
rootDir: process.cwd() as ProjectRootDir,
}, testDefaults({ pruneStore: true, save: true }))).manifest
}, testDefaults({ pruneStore: true, save: true }))).updatedProject.manifest
project.storeHasNot('camelcase-keys', '3.0.0')
project.hasNot('camelcase-keys')
@@ -170,7 +170,7 @@ test('uninstall package with dependencies and do not touch other deps', async ()
test('uninstall package with its bin files', async () => {
prepareEmpty()
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/sh-hello-world@1.0.1'], testDefaults({ fastUnpack: false, save: true }))
const { updatedManifest: manifest } = await addDependenciesToPackage({}, ['@pnpm.e2e/sh-hello-world@1.0.1'], testDefaults({ fastUnpack: false, save: true }))
await mutateModulesInSingleProject({
dependencyNames: ['@pnpm.e2e/sh-hello-world'],
manifest,
@@ -210,7 +210,7 @@ test('relative link is uninstalled', async () => {
test('pendingBuilds gets updated after uninstall', async () => {
const project = prepareEmpty()
const manifest = await addDependenciesToPackage({},
const { updatedManifest: manifest } = await addDependenciesToPackage({},
['@pnpm.e2e/pre-and-postinstall-scripts-example', '@pnpm.e2e/with-postinstall-b'],
testDefaults({ fastUnpack: false, save: true, ignoreScripts: true })
)

View File

@@ -184,6 +184,7 @@ export interface InstallationResultStats {
export interface InstallationResult {
stats: InstallationResultStats
ignoredBuilds: string[] | undefined
}
export async function headlessInstall (opts: HeadlessOptions): Promise<InstallationResult> {
@@ -667,6 +668,7 @@ export async function headlessInstall (opts: HeadlessOptions): Promise<Installat
removed,
linkedToRoot,
},
ignoredBuilds,
}
}

View File

@@ -0,0 +1,9 @@
import { PnpmError } from '@pnpm/error'
export class IgnoredBuildsError extends PnpmError {
constructor (ignoredBuilds: string[]) {
super('IGNORED_BUILDS', `Ignored build scripts: ${ignoredBuilds.join(', ')}`, {
hint: 'Run "pnpm approve-builds" to pick which dependencies should be allowed to run scripts.',
})
}
}

View File

@@ -26,6 +26,7 @@ import { sequenceGraph } from '@pnpm/sort-packages'
import { createPkgGraph } from '@pnpm/workspace.pkgs-graph'
import { updateWorkspaceState, type WorkspaceStateSettings } from '@pnpm/workspace.state'
import isSubdir from 'is-subdir'
import { IgnoredBuildsError } from './errors'
import { getPinnedVersion } from './getPinnedVersion'
import { getSaveType } from './getSaveType'
import { getNodeExecPath } from './nodeExecPath'
@@ -133,7 +134,7 @@ export type InstallDepsOptions = Pick<Config,
includeOnlyPackageFiles?: boolean
prepareExecutionEnv: PrepareExecutionEnv
fetchFullMetadata?: boolean
} & Partial<Pick<Config, 'pnpmHomeDir'>>
} & Partial<Pick<Config, 'pnpmHomeDir' | 'strictDepBuilds'>>
export async function installDeps (
opts: InstallDepsOptions,
@@ -334,9 +335,9 @@ when running add/update with the --workspace option')
rootDir: opts.dir as ProjectRootDir,
targetDependenciesField: getSaveType(opts),
}
const updatedImporter = await mutateModulesInSingleProject(mutatedProject, installOpts)
const { updatedProject, ignoredBuilds } = await mutateModulesInSingleProject(mutatedProject, installOpts)
if (opts.save !== false) {
await writeProjectManifest(updatedImporter.manifest)
await writeProjectManifest(updatedProject.manifest)
}
if (!opts.lockfileOnly) {
await updateWorkspaceState({
@@ -348,13 +349,19 @@ when running add/update with the --workspace option')
configDependencies: opts.rootProjectManifest?.pnpm?.configDependencies,
})
}
if (opts.strictDepBuilds && ignoredBuilds?.length) {
throw new IgnoredBuildsError(ignoredBuilds)
}
return
}
const updatedManifest = await install(manifest, installOpts)
const { updatedManifest, ignoredBuilds } = await install(manifest, installOpts)
if (opts.update === true && opts.save !== false) {
await writeProjectManifest(updatedManifest)
}
if (opts.strictDepBuilds && ignoredBuilds?.length) {
throw new IgnoredBuildsError(ignoredBuilds)
}
if (opts.linkWorkspacePackages && opts.workspaceDir) {
const { selectedProjectsGraph } = await filterPkgsBySelectorObjects(allProjects, [

View File

@@ -42,6 +42,7 @@ import { createWorkspaceSpecs, updateToWorkspacePackagesFromManifest } from './u
import { getSaveType } from './getSaveType'
import { getPinnedVersion } from './getPinnedVersion'
import { type PreferredVersions } from '@pnpm/resolver-base'
import { IgnoredBuildsError } from './errors'
export type RecursiveOptions = CreateStoreControllerOptions & Pick<Config,
| 'bail'
@@ -97,6 +98,7 @@ export type RecursiveOptions = CreateStoreControllerOptions & Pick<Config,
} & Partial<
Pick<Config,
| 'sort'
| 'strictDepBuilds'
| 'workspaceConcurrency'
>
> & Required<
@@ -264,7 +266,7 @@ export async function recursive (
throw new PnpmError('NO_PACKAGE_IN_DEPENDENCIES',
'None of the specified packages were found in the dependencies of any of the projects.')
}
const { updatedProjects: mutatedPkgs } = await mutateModules(mutatedImporters, {
const { updatedProjects: mutatedPkgs, ignoredBuilds } = await mutateModules(mutatedImporters, {
...installOpts,
storeController: store.ctrl,
})
@@ -276,6 +278,9 @@ export async function recursive (
})
)
}
if (opts.strictDepBuilds && ignoredBuilds?.length) {
throw new IgnoredBuildsError(ignoredBuilds)
}
return true
}
@@ -328,7 +333,7 @@ export async function recursive (
rootDir,
},
], opts)
return mutationResult.updatedProjects[0].manifest
return { updatedManifest: mutationResult.updatedProjects[0].manifest, ignoredBuilds: mutationResult.ignoredBuilds }
}
break
default:
@@ -339,7 +344,7 @@ export async function recursive (
}
const localConfig = await memReadLocalConfig(rootDir)
const newManifest = await action(
const { updatedManifest: newManifest, ignoredBuilds } = await action(
manifest,
{
...installOpts,
@@ -364,6 +369,9 @@ export async function recursive (
if (opts.save !== false) {
await writeProjectManifest(newManifest)
}
if (opts.strictDepBuilds && ignoredBuilds?.length) {
throw new IgnoredBuildsError(ignoredBuilds)
}
result[rootDir].status = 'passed'
} catch (err: any) { // eslint-disable-line
logger.info(err)

View File

@@ -228,5 +228,5 @@ export async function handler (
},
removeOpts
)
await writeProjectManifest(mutationResult.manifest)
await writeProjectManifest(mutationResult.updatedProject.manifest)
}

View File

@@ -1,7 +1,7 @@
import fs from 'fs'
import path from 'path'
import { prepare, preparePackages } from '@pnpm/prepare'
import { type PackageManifest } from '@pnpm/types'
import { type PackageManifest, type ProjectManifest } from '@pnpm/types'
import { sync as rimraf } from '@zkochan/rimraf'
import PATH from 'path-name'
import loadJsonFile from 'load-json-file'
@@ -284,3 +284,22 @@ test('preinstall script does not trigger verify-deps-before-run (#8954)', async
expect(output.status).toBe(0)
expect(output.stdout.toString()).toContain('hello world')
})
test('throw an error when strict-dep-builds is true and there are ignored scripts', async () => {
const project = prepare({})
const result = execPnpmSync(['add', '@pnpm.e2e/pre-and-postinstall-scripts-example@1.0.0', '--config.strict-dep-builds=true'])
expect(result.status).toBe(1)
expect(result.stdout.toString()).toContain('Ignored build scripts:')
project.has('@pnpm.e2e/pre-and-postinstall-scripts-example')
expect(fs.existsSync('node_modules/@pnpm.e2e/pre-and-postinstall-scripts-example/generated-by-preinstall.js')).toBeFalsy()
expect(fs.existsSync('node_modules/@pnpm.e2e/pre-and-postinstall-scripts-example/generated-by-postinstall.js')).toBeFalsy()
expect(fs.existsSync('pnpm-lock.yaml')).toBeTruthy()
const manifest = loadJsonFile.sync<ProjectManifest>('package.json')
expect(manifest.dependencies).toStrictEqual({
'@pnpm.e2e/pre-and-postinstall-scripts-example': '1.0.0',
})
})