mirror of
https://github.com/pnpm/pnpm.git
synced 2026-03-06 08:18:16 -05:00
6
.changeset/khaki-carrots-smile.md
Normal file
6
.changeset/khaki-carrots-smile.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@pnpm/plugin-commands-installation": patch
|
||||
"pnpm": patch
|
||||
---
|
||||
|
||||
`pnpm prune` works in a workspace [#4647](https://github.com/pnpm/pnpm/pull/4691).
|
||||
6
.changeset/shiny-buses-breathe.md
Normal file
6
.changeset/shiny-buses-breathe.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@pnpm/plugin-commands-installation": patch
|
||||
"pnpm": patch
|
||||
---
|
||||
|
||||
`pnpm prune` does not remove hoisted dependencies.
|
||||
5
.changeset/silver-falcons-care.md
Normal file
5
.changeset/silver-falcons-care.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@pnpm/modules-cleaner": patch
|
||||
---
|
||||
|
||||
Do not remove hoisted dependencies, when pruneDirectDependencies is set to `true`.
|
||||
5
.changeset/thirty-pumpkins-rule.md
Normal file
5
.changeset/thirty-pumpkins-rule.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@pnpm/core": minor
|
||||
---
|
||||
|
||||
The `install()` function accepts the `pruneDirectDependencies` option.
|
||||
@@ -119,6 +119,7 @@ export async function install (
|
||||
manifest: ProjectManifest,
|
||||
opts: InstallOptions & {
|
||||
preferredVersions?: PreferredVersions
|
||||
pruneDirectDependencies?: boolean
|
||||
}
|
||||
) {
|
||||
const projects = await mutateModules(
|
||||
@@ -127,6 +128,7 @@ export async function install (
|
||||
buildIndex: 0,
|
||||
manifest,
|
||||
mutation: 'install',
|
||||
pruneDirectDependencies: opts.pruneDirectDependencies,
|
||||
rootDir: opts.dir ?? process.cwd(),
|
||||
},
|
||||
],
|
||||
|
||||
@@ -74,10 +74,11 @@ export default async function prune (
|
||||
...difference(currentPkgs, wantedPkgs).map(([depName]) => depName),
|
||||
])
|
||||
if (pruneDirectDependencies) {
|
||||
const publiclyHoistedDeps = getPubliclyHoistedDependencies(opts.hoistedDependencies)
|
||||
if (allCurrentPackages.size > 0) {
|
||||
const newPkgsSet = new Set<string>(wantedPkgs.map(([depName]) => depName))
|
||||
for (const currentPackage of Array.from(allCurrentPackages)) {
|
||||
if (!newPkgsSet.has(currentPackage)) {
|
||||
if (!newPkgsSet.has(currentPackage) && !publiclyHoistedDeps.has(currentPackage)) {
|
||||
depsToRemove.add(currentPackage)
|
||||
}
|
||||
}
|
||||
@@ -245,3 +246,15 @@ function getPkgsDepPathsOwnedOnlyByImporters (
|
||||
const packagesOfSelectedOnly = pickAll(difference(Object.keys(selected.packages!), Object.keys(other.packages!)), selected.packages!) as PackageSnapshots
|
||||
return getPkgsDepPaths(registries, packagesOfSelectedOnly, skipped)
|
||||
}
|
||||
|
||||
function getPubliclyHoistedDependencies (hoistedDependencies: HoistedDependencies): Set<string> {
|
||||
const publiclyHoistedDeps = new Set<string>()
|
||||
for (const hoistedAliases of Object.values(hoistedDependencies)) {
|
||||
for (const [alias, hoistType] of Object.entries(hoistedAliases)) {
|
||||
if (hoistType === 'public') {
|
||||
publiclyHoistedDeps.add(alias)
|
||||
}
|
||||
}
|
||||
}
|
||||
return publiclyHoistedDeps
|
||||
}
|
||||
|
||||
@@ -274,9 +274,11 @@ export type InstallCommandOptions = Pick<Config,
|
||||
}
|
||||
fixLockfile?: boolean
|
||||
useBetaCli?: boolean
|
||||
pruneDirectDependencies?: boolean
|
||||
pruneStore?: boolean
|
||||
recursive?: boolean
|
||||
workspace?: boolean
|
||||
} & Partial<Pick<Config, 'pnpmHomeDir' | 'preferWorkspacePackages'>>
|
||||
} & Partial<Pick<Config, 'modulesCacheMaxAge' | 'pnpmHomeDir' | 'preferWorkspacePackages'>>
|
||||
|
||||
export async function handler (
|
||||
opts: InstallCommandOptions
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import { docsUrl, readProjectManifestOnly } from '@pnpm/cli-utils'
|
||||
import { docsUrl } from '@pnpm/cli-utils'
|
||||
import { UNIVERSAL_OPTIONS } from '@pnpm/common-cli-options-help'
|
||||
import { Config, types as allTypes } from '@pnpm/config'
|
||||
import { createOrConnectStoreController, CreateStoreControllerOptions } from '@pnpm/store-connection-manager'
|
||||
import { InstallOptions, mutateModules } from '@pnpm/core'
|
||||
import { types as allTypes } from '@pnpm/config'
|
||||
import pick from 'ramda/src/pick'
|
||||
import renderHelp from 'render-help'
|
||||
import getOptionsFromRootManifest from './getOptionsFromRootManifest'
|
||||
import * as install from './install'
|
||||
|
||||
export const rcOptionsTypes = cliOptionsTypes
|
||||
|
||||
@@ -45,29 +43,12 @@ export function help () {
|
||||
}
|
||||
|
||||
export async function handler (
|
||||
opts: Pick<Config, 'dev' | 'engineStrict' | 'optional' | 'production' | 'rootProjectManifest'> & CreateStoreControllerOptions
|
||||
opts: install.InstallCommandOptions
|
||||
) {
|
||||
const store = await createOrConnectStoreController(opts)
|
||||
const manifest = await readProjectManifestOnly(process.cwd(), opts)
|
||||
return mutateModules([
|
||||
{
|
||||
buildIndex: 0,
|
||||
manifest,
|
||||
mutation: 'install',
|
||||
pruneDirectDependencies: true,
|
||||
rootDir: process.cwd(),
|
||||
},
|
||||
], {
|
||||
return install.handler({
|
||||
...opts,
|
||||
...getOptionsFromRootManifest(opts.rootProjectManifest ?? {}),
|
||||
include: {
|
||||
dependencies: opts.production !== false,
|
||||
devDependencies: opts.dev !== false,
|
||||
optionalDependencies: opts.optional !== false,
|
||||
},
|
||||
modulesCacheMaxAge: 0,
|
||||
pruneDirectDependencies: true,
|
||||
pruneStore: true,
|
||||
storeController: store.ctrl,
|
||||
storeDir: store.dir,
|
||||
} as InstallOptions)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -80,6 +80,7 @@ type RecursiveOptions = CreateStoreControllerOptions & Pick<Config,
|
||||
useBetaCli?: boolean
|
||||
selectedProjectsGraph: ProjectsGraph
|
||||
preferredVersions?: PreferredVersions
|
||||
pruneDirectDependencies?: boolean
|
||||
} & Partial<
|
||||
Pick<Config,
|
||||
| 'sort'
|
||||
@@ -258,6 +259,7 @@ export default async function recursive (
|
||||
manifest,
|
||||
modulesDir,
|
||||
mutation,
|
||||
pruneDirectDependencies: opts.pruneDirectDependencies,
|
||||
rootDir,
|
||||
} as MutatedProject)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import path from 'path'
|
||||
import { install, link, prune } from '@pnpm/plugin-commands-installation'
|
||||
import { add, install, link, prune } from '@pnpm/plugin-commands-installation'
|
||||
import prepare from '@pnpm/prepare'
|
||||
import { REGISTRY_MOCK_PORT } from '@pnpm/registry-mock'
|
||||
import fixtures from '@pnpm/test-fixtures'
|
||||
@@ -20,6 +20,7 @@ const DEFAULT_OPTIONS = {
|
||||
optionalDependencies: true,
|
||||
},
|
||||
lock: true,
|
||||
linkWorkspacePackages: true,
|
||||
pnpmfile: '.pnpmfile.cjs',
|
||||
pnpmHomeDir: '',
|
||||
rawConfig: { registry: REGISTRY_URL },
|
||||
@@ -56,6 +57,28 @@ test('prune removes external link that is not in package.json', async () => {
|
||||
await project.hasNot('local-pkg')
|
||||
})
|
||||
|
||||
test('prune keeps hoisted dependencies', async () => {
|
||||
const project = prepare(undefined)
|
||||
const storeDir = path.resolve('store')
|
||||
const cacheDir = path.resolve('cache')
|
||||
|
||||
await add.handler({
|
||||
...DEFAULT_OPTIONS,
|
||||
cacheDir,
|
||||
dir: process.cwd(),
|
||||
storeDir,
|
||||
}, ['pkg-with-1-dep@100.0.0'])
|
||||
|
||||
await prune.handler({
|
||||
...DEFAULT_OPTIONS,
|
||||
cacheDir,
|
||||
dir: process.cwd(),
|
||||
storeDir,
|
||||
})
|
||||
|
||||
await project.hasNot('dep-of-pkg-with-1-dep')
|
||||
})
|
||||
|
||||
test('prune removes dev dependencies', async () => {
|
||||
const project = prepare({
|
||||
dependencies: { 'is-positive': '1.0.0' },
|
||||
|
||||
Reference in New Issue
Block a user