mirror of
https://github.com/pnpm/pnpm.git
synced 2025-12-24 07:38:12 -05:00
18
.changeset/pretty-tips-crash.md
Normal file
18
.changeset/pretty-tips-crash.md
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
"@pnpm/config": major
|
||||
"@pnpm/get-context": major
|
||||
"@pnpm/headless": major
|
||||
"@pnpm/hoist": major
|
||||
"@pnpm/modules-yaml": major
|
||||
"@pnpm/plugin-commands-installation": major
|
||||
"@pnpm/plugin-commands-listing": major
|
||||
"@pnpm/plugin-commands-outdated": major
|
||||
"@pnpm/plugin-commands-rebuild": major
|
||||
"@pnpm/plugin-commands-store": major
|
||||
"pnpm": major
|
||||
"@pnpm/read-projects-context": major
|
||||
"@pnpm/resolve-dependencies": major
|
||||
"supi": minor
|
||||
---
|
||||
|
||||
Remove `independent-leaves` support.
|
||||
8
.changeset/sharp-crabs-change.md
Normal file
8
.changeset/sharp-crabs-change.md
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
"@pnpm/package-requester": major
|
||||
"@pnpm/package-store": major
|
||||
"@pnpm/server": major
|
||||
"@pnpm/store-controller-types": major
|
||||
---
|
||||
|
||||
`getPackageLocation()` removed from store. Remove `inStoreLocation` from the result of `fetchPackage()`.
|
||||
@@ -24,6 +24,9 @@
|
||||
{
|
||||
"path": "../types"
|
||||
},
|
||||
{
|
||||
"path": "../constants"
|
||||
},
|
||||
{
|
||||
"path": "../lockfile-file"
|
||||
}
|
||||
|
||||
@@ -96,7 +96,6 @@ export interface Config {
|
||||
repeatInstallDepth?: number,
|
||||
ignorePnpmfile?: boolean,
|
||||
pnpmfile: string,
|
||||
independentLeaves?: boolean,
|
||||
packageImportMethod?: 'auto' | 'hardlink' | 'copy' | 'clone',
|
||||
hoistPattern?: string[],
|
||||
useStoreServer?: boolean,
|
||||
|
||||
@@ -44,7 +44,6 @@ export const types = Object.assign({
|
||||
'hoist-pattern': Array,
|
||||
'ignore-pnpmfile': Boolean,
|
||||
'ignore-workspace-root-check': Boolean,
|
||||
'independent-leaves': Boolean,
|
||||
'link-workspace-packages': [Boolean, 'deep'],
|
||||
'lockfile': Boolean,
|
||||
'lockfile-dir': String,
|
||||
@@ -230,19 +229,11 @@ export default async (
|
||||
pnpmConfig.saveProd = true
|
||||
pnpmConfig.saveDev = false
|
||||
pnpmConfig.saveOptional = false
|
||||
if (pnpmConfig.independentLeaves) {
|
||||
if (opts.cliOptions['independent-leaves']) {
|
||||
throw new PnpmError('CONFIG_CONFLICT_INDEPENDENT_LEAVES_WITH_GLOBAL',
|
||||
'Configuration conflict. "independent-leaves" may not be used with "global"')
|
||||
}
|
||||
pnpmConfig.independentLeaves = false
|
||||
}
|
||||
if (pnpmConfig.hoistPattern && (pnpmConfig.hoistPattern.length > 1 || pnpmConfig.hoistPattern[0] !== '*')) {
|
||||
if (opts.cliOptions['hoist-pattern']) {
|
||||
throw new PnpmError('CONFIG_CONFLICT_HOIST_PATTERN_WITH_GLOBAL',
|
||||
'Configuration conflict. "hoist-pattern" may not be used with "global"')
|
||||
}
|
||||
pnpmConfig.independentLeaves = false
|
||||
}
|
||||
if (pnpmConfig.linkWorkspacePackages) {
|
||||
if (opts.cliOptions['link-workspace-packages']) {
|
||||
@@ -320,9 +311,6 @@ export default async (
|
||||
}
|
||||
if (pnpmConfig['hoist'] === false) {
|
||||
delete pnpmConfig.hoistPattern
|
||||
} else if (pnpmConfig.independentLeaves === true) {
|
||||
throw new PnpmError('CONFIG_CONFLICT_INDEPENDENT_LEAVES_AND_HOIST',
|
||||
'"independent-leaves=true" can only be used when hoisting is off, so "hoist=false"')
|
||||
}
|
||||
if (typeof pnpmConfig['color'] === 'boolean') {
|
||||
switch (pnpmConfig['color']) {
|
||||
|
||||
@@ -11,7 +11,6 @@ import './findBestGlobalPrefixOnWindows'
|
||||
// To override any local settings,
|
||||
// we force the default values of config
|
||||
delete process.env['npm_config_depth']
|
||||
process.env['npm_config_independent_leaves'] = 'false'
|
||||
process.env['npm_config_hoist'] = 'true'
|
||||
delete process.env['npm_config_registry']
|
||||
delete process.env['npm_config_virtual_store_dir']
|
||||
@@ -90,25 +89,6 @@ test('throw error if --lockfile-dir is used with --global', async (t) => {
|
||||
}
|
||||
})
|
||||
|
||||
test('throw error if --independent-leaves is used with --global', async (t) => {
|
||||
try {
|
||||
await getConfig({
|
||||
cliOptions: {
|
||||
'global': true,
|
||||
'independent-leaves': true,
|
||||
},
|
||||
packageManager: {
|
||||
name: 'pnpm',
|
||||
version: '1.0.0',
|
||||
},
|
||||
})
|
||||
} catch (err) {
|
||||
t.equal(err.message, 'Configuration conflict. "independent-leaves" may not be used with "global"')
|
||||
t.equal((err as PnpmError).code, 'ERR_PNPM_CONFIG_CONFLICT_INDEPENDENT_LEAVES_WITH_GLOBAL')
|
||||
t.end()
|
||||
}
|
||||
})
|
||||
|
||||
test('throw error if --hoist-pattern is used with --global', async (t) => {
|
||||
try {
|
||||
await getConfig({
|
||||
@@ -442,47 +422,13 @@ test('throw error if --no-hoist is used with --hoist-pattern', async (t) => {
|
||||
}
|
||||
})
|
||||
|
||||
test('throw error if --independent-leaves is used without --no-hoist', async (t) => {
|
||||
try {
|
||||
await getConfig({
|
||||
cliOptions: {
|
||||
'independent-leaves': true,
|
||||
},
|
||||
packageManager: {
|
||||
name: 'pnpm',
|
||||
version: '1.0.0',
|
||||
},
|
||||
})
|
||||
} catch (err) {
|
||||
t.equal(err.message, '"independent-leaves=true" can only be used when hoisting is off, so "hoist=false"')
|
||||
t.equal((err as PnpmError).code, 'ERR_PNPM_CONFIG_CONFLICT_INDEPENDENT_LEAVES_AND_HOIST')
|
||||
t.end()
|
||||
}
|
||||
})
|
||||
|
||||
test('do not throw error if --independent-leaves is used with --no-hoist', async (t) => {
|
||||
const { config } = await getConfig({
|
||||
cliOptions: {
|
||||
'hoist': false,
|
||||
'independent-leaves': true,
|
||||
},
|
||||
packageManager: {
|
||||
name: 'pnpm',
|
||||
version: '1.0.0',
|
||||
},
|
||||
})
|
||||
t.ok(config.independentLeaves)
|
||||
t.notOk(config.hoistPattern)
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('rawLocalConfig in a workspace', async (t) => {
|
||||
const tmp = tempy.directory()
|
||||
t.comment(`temp dir created: ${tmp}`)
|
||||
|
||||
process.chdir(tmp)
|
||||
const workspaceDir = process.cwd()
|
||||
await fs.writeFile('.npmrc', 'independent-leaves=true\nhoist-pattern=*', 'utf8')
|
||||
await fs.writeFile('.npmrc', 'hoist-pattern=*', 'utf8')
|
||||
await fs.mkdir('package')
|
||||
process.chdir('package')
|
||||
await fs.writeFile('.npmrc', 'hoist-pattern=eslint-*', 'utf8')
|
||||
@@ -501,7 +447,6 @@ test('rawLocalConfig in a workspace', async (t) => {
|
||||
|
||||
t.deepEqual(config.rawLocalConfig, {
|
||||
'hoist-pattern': 'eslint-*',
|
||||
'independent-leaves': true,
|
||||
'save-exact': true,
|
||||
})
|
||||
}
|
||||
@@ -523,7 +468,6 @@ test('rawLocalConfig in a workspace', async (t) => {
|
||||
|
||||
t.deepEqual(config.rawLocalConfig, {
|
||||
'hoist-pattern': '*',
|
||||
'independent-leaves': true,
|
||||
'save-exact': true,
|
||||
})
|
||||
}
|
||||
@@ -535,7 +479,7 @@ test('rawLocalConfig', async (t) => {
|
||||
t.comment(`temp dir created: ${tmp}`)
|
||||
|
||||
process.chdir(tmp)
|
||||
await fs.writeFile('.npmrc', 'independent-leaves=true', 'utf8')
|
||||
await fs.writeFile('.npmrc', 'modules-dir=modules', 'utf8')
|
||||
|
||||
const { config } = await getConfig({
|
||||
cliOptions: {
|
||||
@@ -548,7 +492,7 @@ test('rawLocalConfig', async (t) => {
|
||||
})
|
||||
|
||||
t.deepEqual(config.rawLocalConfig, {
|
||||
'independent-leaves': true,
|
||||
'modules-dir': 'modules',
|
||||
'save-exact': true,
|
||||
})
|
||||
t.end()
|
||||
|
||||
1
packages/dependencies-hierarchy/example/node_modules/.modules.yaml
generated
vendored
1
packages/dependencies-hierarchy/example/node_modules/.modules.yaml
generated
vendored
@@ -1,4 +1,3 @@
|
||||
independentLeaves: false
|
||||
layoutVersion: 1
|
||||
packageManager: pnpm@1.4.0
|
||||
skipped: []
|
||||
|
||||
1
packages/dependencies-hierarchy/fixtureMonorepo/node_modules/.modules.yaml
generated
vendored
1
packages/dependencies-hierarchy/fixtureMonorepo/node_modules/.modules.yaml
generated
vendored
@@ -6,7 +6,6 @@ included:
|
||||
dependencies: true
|
||||
devDependencies: true
|
||||
optionalDependencies: true
|
||||
independentLeaves: true
|
||||
layoutVersion: 1
|
||||
packageManager: pnpm@2.25.5
|
||||
pendingBuilds: []
|
||||
|
||||
@@ -28,7 +28,6 @@ export interface PnpmContext<T> {
|
||||
extraBinPaths: string[],
|
||||
hoistedAliases: {[depPath: string]: string[]}
|
||||
include: IncludedDependencies,
|
||||
independentLeaves: boolean,
|
||||
modulesFile: Modules | null,
|
||||
pendingBuilds: string[],
|
||||
projects: Array<{
|
||||
@@ -72,9 +71,6 @@ export default async function getContext<T> (
|
||||
useLockfile: boolean,
|
||||
virtualStoreDir?: string,
|
||||
|
||||
independentLeaves?: boolean,
|
||||
forceIndependentLeaves?: boolean,
|
||||
|
||||
hoistPattern?: string[] | undefined,
|
||||
forceHoistPattern?: boolean,
|
||||
|
||||
@@ -97,9 +93,6 @@ export default async function getContext<T> (
|
||||
storeDir: opts.storeDir,
|
||||
virtualStoreDir,
|
||||
|
||||
forceIndependentLeaves: opts.forceIndependentLeaves,
|
||||
independentLeaves: opts.independentLeaves,
|
||||
|
||||
forceHoistPattern: opts.forceHoistPattern,
|
||||
hoistPattern: opts.hoistPattern,
|
||||
|
||||
@@ -144,7 +137,6 @@ export default async function getContext<T> (
|
||||
hoistedModulesDir,
|
||||
hoistPattern: opts.hoistPattern,
|
||||
include: opts.include || importersContext.include,
|
||||
independentLeaves: Boolean(typeof importersContext.independentLeaves === 'undefined' ? opts.independentLeaves : importersContext.independentLeaves),
|
||||
lockfileDir: opts.lockfileDir,
|
||||
modulesFile: importersContext.modules,
|
||||
pendingBuilds: importersContext.pendingBuilds,
|
||||
@@ -189,9 +181,6 @@ async function validateModules (
|
||||
storeDir: string,
|
||||
virtualStoreDir: string,
|
||||
|
||||
independentLeaves?: boolean,
|
||||
forceIndependentLeaves?: boolean,
|
||||
|
||||
hoistPattern?: string[] | undefined,
|
||||
forceHoistPattern?: boolean,
|
||||
|
||||
@@ -218,30 +207,6 @@ async function validateModules (
|
||||
+ ' You must remove that option, or else "pnpm install" to recreate the modules directory.'
|
||||
)
|
||||
}
|
||||
if (opts.forceIndependentLeaves && Boolean(modules.independentLeaves) !== opts.independentLeaves) {
|
||||
if (opts.forceNewModules) {
|
||||
await Promise.all(projects.map(purgeModulesDirsOfImporter))
|
||||
if (!rootProject) {
|
||||
await purgeModulesDirsOfImporter({
|
||||
modulesDir: path.join(opts.lockfileDir, opts.modulesDir),
|
||||
rootDir: opts.lockfileDir,
|
||||
})
|
||||
}
|
||||
return { purged: true }
|
||||
}
|
||||
if (modules.independentLeaves) {
|
||||
throw new PnpmError(
|
||||
'INDEPENDENT_LEAVES_WANTED',
|
||||
'This modules directory was created using the --independent-leaves option.'
|
||||
+ ' You must add that option, or else run "pnpm install" to recreate the modules directory.'
|
||||
)
|
||||
}
|
||||
throw new PnpmError(
|
||||
'INDEPENDENT_LEAVES_NOT_WANTED',
|
||||
'This modules directory was created without the --independent-leaves option.'
|
||||
+ ' You must remove that option, or else "pnpm install" to recreate the modules directory.'
|
||||
)
|
||||
}
|
||||
let purged = false
|
||||
if (opts.forceHoistPattern && rootProject) {
|
||||
try {
|
||||
@@ -338,7 +303,6 @@ export interface PnpmSingleContext {
|
||||
importerId: string,
|
||||
prefix: string,
|
||||
include: IncludedDependencies,
|
||||
independentLeaves: boolean,
|
||||
modulesFile: Modules | null,
|
||||
pendingBuilds: string[],
|
||||
registries: Registries,
|
||||
@@ -375,9 +339,6 @@ export async function getContextForSingleImporter (
|
||||
|
||||
shamefullyHoist?: boolean,
|
||||
forceShamefullyHoist?: boolean,
|
||||
|
||||
independentLeaves?: boolean,
|
||||
forceIndependentLeaves?: boolean,
|
||||
},
|
||||
alreadyPurged: boolean = false
|
||||
): Promise<PnpmSingleContext> {
|
||||
@@ -386,7 +347,6 @@ export async function getContextForSingleImporter (
|
||||
hoistedAliases,
|
||||
projects,
|
||||
include,
|
||||
independentLeaves,
|
||||
modules,
|
||||
pendingBuilds,
|
||||
registries,
|
||||
@@ -426,9 +386,6 @@ export async function getContextForSingleImporter (
|
||||
forceHoistPattern: opts.forceHoistPattern,
|
||||
hoistPattern: opts.hoistPattern,
|
||||
|
||||
forceIndependentLeaves: opts.forceIndependentLeaves,
|
||||
independentLeaves: opts.independentLeaves,
|
||||
|
||||
forceShamefullyHoist: opts.forceShamefullyHoist,
|
||||
shamefullyHoist: opts.shamefullyHoist,
|
||||
})
|
||||
@@ -454,7 +411,6 @@ export async function getContextForSingleImporter (
|
||||
hoistPattern: opts.hoistPattern,
|
||||
importerId,
|
||||
include: opts.include || include,
|
||||
independentLeaves: Boolean(typeof independentLeaves === 'undefined' ? opts.independentLeaves : independentLeaves),
|
||||
lockfileDir: opts.lockfileDir,
|
||||
manifest: opts.hooks?.readPackage?.(manifest) ?? manifest,
|
||||
modulesDir,
|
||||
|
||||
@@ -30,7 +30,6 @@ import {
|
||||
import {
|
||||
nameVerFromPkgSnapshot,
|
||||
packageIdFromSnapshot,
|
||||
packageIsIndependent,
|
||||
pkgSnapshotToResolution,
|
||||
satisfiesPackageManifest,
|
||||
} from '@pnpm/lockfile-utils'
|
||||
@@ -76,7 +75,6 @@ export interface HeadlessOptions {
|
||||
extraBinPaths?: string[],
|
||||
ignoreScripts: boolean,
|
||||
include: IncludedDependencies,
|
||||
independentLeaves: boolean,
|
||||
projects: Array<{
|
||||
binsDir: string,
|
||||
buildIndex: number,
|
||||
@@ -246,15 +244,6 @@ export default async (opts: HeadlessOptions) => {
|
||||
let newHoistedAliases!: {[depPath: string]: string[]}
|
||||
if (rootImporterWithFlatModules) {
|
||||
newHoistedAliases = await hoist(matcher(opts.hoistPattern!), {
|
||||
getIndependentPackageLocation: opts.independentLeaves
|
||||
? async (packageId: string, packageName: string) => {
|
||||
const { dir } = await opts.storeController.getPackageLocation(packageId, packageName, {
|
||||
lockfileDir,
|
||||
targetEngine: opts.sideEffectsCacheRead && ENGINE_NAME || undefined,
|
||||
})
|
||||
return dir
|
||||
}
|
||||
: undefined,
|
||||
lockfile: filteredLockfile,
|
||||
lockfileDir,
|
||||
modulesDir: hoistedModulesDir,
|
||||
@@ -341,7 +330,6 @@ export default async (opts: HeadlessOptions) => {
|
||||
hoistedAliases: newHoistedAliases,
|
||||
hoistPattern: opts.hoistPattern,
|
||||
included: opts.include,
|
||||
independentLeaves: !!opts.independentLeaves,
|
||||
layoutVersion: LAYOUT_VERSION,
|
||||
packageManager: `${opts.packageManager.name}@${opts.packageManager.version}`,
|
||||
pendingBuilds: opts.pendingBuilds,
|
||||
@@ -468,7 +456,6 @@ async function linkRootPackages (
|
||||
interface LockfileToDepGraphOptions {
|
||||
force: boolean,
|
||||
include: IncludedDependencies,
|
||||
independentLeaves: boolean,
|
||||
importerIds: string[],
|
||||
lockfileDir: string,
|
||||
skipped: Set<string>,
|
||||
@@ -497,15 +484,8 @@ async function lockfileToDepGraph (
|
||||
const pkgName = nameVerFromPkgSnapshot(depPath, pkgSnapshot).name
|
||||
const modules = path.join(opts.virtualStoreDir, pkgIdToFilename(depPath, opts.lockfileDir), 'node_modules')
|
||||
const packageId = packageIdFromSnapshot(depPath, pkgSnapshot, opts.registries)
|
||||
const pkgLocation = await opts.storeController.getPackageLocation(packageId, pkgName, {
|
||||
lockfileDir: opts.lockfileDir,
|
||||
targetEngine: opts.sideEffectsCacheRead && !opts.force && ENGINE_NAME || undefined,
|
||||
})
|
||||
|
||||
const independent = opts.independentLeaves && packageIsIndependent(pkgSnapshot)
|
||||
const peripheralLocation = !independent
|
||||
? path.join(modules, pkgName)
|
||||
: pkgLocation.dir
|
||||
const peripheralLocation = path.join(modules, pkgName)
|
||||
if (
|
||||
currentPackages[depPath] && R.equals(currentPackages[depPath].dependencies, lockfile.packages![depPath].dependencies) &&
|
||||
R.equals(currentPackages[depPath].optionalDependencies, lockfile.packages![depPath].optionalDependencies)
|
||||
@@ -551,7 +531,6 @@ async function lockfileToDepGraph (
|
||||
finishing: fetchResponse.finishing,
|
||||
hasBin: pkgSnapshot.hasBin === true,
|
||||
hasBundledDependencies: !!pkgSnapshot.bundledDependencies,
|
||||
independent,
|
||||
modules,
|
||||
name: pkgName,
|
||||
optional: !!pkgSnapshot.optional,
|
||||
@@ -567,7 +546,6 @@ async function lockfileToDepGraph (
|
||||
const ctx = {
|
||||
force: opts.force,
|
||||
graph,
|
||||
independentLeaves: opts.independentLeaves,
|
||||
lockfileDir: opts.lockfileDir,
|
||||
pkgSnapshotsByDepPaths: lockfile.packages,
|
||||
registries: opts.registries,
|
||||
@@ -605,7 +583,6 @@ async function getChildrenPaths (
|
||||
force: boolean,
|
||||
registries: Registries,
|
||||
virtualStoreDir: string,
|
||||
independentLeaves: boolean,
|
||||
storeDir: string,
|
||||
skipped: Set<string>,
|
||||
pkgSnapshotsByDepPaths: Record<string, PackageSnapshot>,
|
||||
@@ -627,18 +604,8 @@ async function getChildrenPaths (
|
||||
if (ctx.graph[childRelDepPath]) {
|
||||
children[alias] = ctx.graph[childRelDepPath].peripheralLocation
|
||||
} else if (childPkgSnapshot) {
|
||||
if (ctx.independentLeaves && packageIsIndependent(childPkgSnapshot)) {
|
||||
const pkgId = childPkgSnapshot.id || childDepPath
|
||||
const pkgName = nameVerFromPkgSnapshot(childRelDepPath, childPkgSnapshot).name
|
||||
const pkgLocation = await ctx.storeController.getPackageLocation(pkgId, pkgName, {
|
||||
lockfileDir: ctx.lockfileDir,
|
||||
targetEngine: ctx.sideEffectsCacheRead && !ctx.force && ENGINE_NAME || undefined,
|
||||
})
|
||||
children[alias] = pkgLocation.dir
|
||||
} else {
|
||||
const pkgName = nameVerFromPkgSnapshot(childRelDepPath, childPkgSnapshot).name
|
||||
children[alias] = path.join(ctx.virtualStoreDir, pkgIdToFilename(childRelDepPath, ctx.lockfileDir), 'node_modules', pkgName)
|
||||
}
|
||||
const pkgName = nameVerFromPkgSnapshot(childRelDepPath, childPkgSnapshot).name
|
||||
children[alias] = path.join(ctx.virtualStoreDir, pkgIdToFilename(childRelDepPath, ctx.lockfileDir), 'node_modules', pkgName)
|
||||
} else if (allDeps[alias].indexOf('file:') === 0) {
|
||||
children[alias] = path.resolve(ctx.lockfileDir, allDeps[alias].substr(5))
|
||||
} else if (!ctx.skipped.has(childRelDepPath)) {
|
||||
@@ -656,9 +623,6 @@ export interface DependenciesGraphNode {
|
||||
finishing: () => Promise<void>,
|
||||
peripheralLocation: string,
|
||||
children: {[alias: string]: string},
|
||||
// an independent package is a package that
|
||||
// has neither regular nor peer dependencies
|
||||
independent: boolean,
|
||||
optionalDependencies: Set<string>,
|
||||
optional: boolean,
|
||||
depPath: string, // this option is only needed for saving pendingBuild when running with --ignore-scripts flag
|
||||
@@ -754,7 +718,6 @@ async function linkAllModules (
|
||||
) {
|
||||
return Promise.all(
|
||||
depNodes
|
||||
.filter(({ independent }) => !independent)
|
||||
.map(async (depNode) => {
|
||||
const childrenToLink = opts.optional
|
||||
? depNode.children
|
||||
|
||||
@@ -42,8 +42,7 @@ test('installing a simple project', async (t) => {
|
||||
t.ok(project.requireModule('is-negative'), 'dev dep installed')
|
||||
t.ok(project.requireModule('colors'), 'optional dep installed')
|
||||
|
||||
// test that independent leaves is false by default
|
||||
await project.has(`.pnpm/colors@1.2.0`) // colors is not symlinked from the store
|
||||
await project.has(`.pnpm/colors@1.2.0`)
|
||||
|
||||
await project.isExecutable('.bin/rimraf')
|
||||
|
||||
@@ -245,70 +244,6 @@ test('not installing optional deps', async (t) => {
|
||||
t.end()
|
||||
})
|
||||
|
||||
// Covers https://github.com/pnpm/pnpm/issues/1547
|
||||
test('installing with independent-leaves and hoistPattern=*', async (t) => {
|
||||
const lockfileDir = path.join(fixtures, 'with-1-dep')
|
||||
await rimraf(path.join(lockfileDir, 'node_modules'))
|
||||
|
||||
const { projects } = await readprojectsContext(
|
||||
[
|
||||
{
|
||||
rootDir: lockfileDir,
|
||||
},
|
||||
],
|
||||
{ lockfileDir }
|
||||
)
|
||||
|
||||
await headless(await testDefaults({
|
||||
hoistPattern: '*',
|
||||
independentLeaves: true,
|
||||
lockfileDir: lockfileDir,
|
||||
projects: await Promise.all(
|
||||
projects.map(async (project) => ({ ...project, manifest: await readPackageJsonFromDir(project.rootDir) }))
|
||||
),
|
||||
}))
|
||||
|
||||
const project = assertProject(t, lockfileDir)
|
||||
await project.has('rimraf')
|
||||
await project.has('.pnpm/node_modules/glob')
|
||||
await project.has('.pnpm/node_modules/path-is-absolute')
|
||||
|
||||
// wrappy is linked directly from the store
|
||||
await project.hasNot(`.pnpm/wrappy@1.0.2`)
|
||||
await project.storeHas('wrappy', '1.0.2')
|
||||
|
||||
await project.has(`.pnpm/rimraf@2.5.1`)
|
||||
|
||||
await project.isExecutable('.bin/rimraf')
|
||||
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('installing with independent-leaves when an optional subdep is skipped', async (t) => {
|
||||
const prefix = path.join(fixtures, 'has-incompatible-optional-subdep')
|
||||
await rimraf(path.join(prefix, 'node_modules'))
|
||||
|
||||
await headless(await testDefaults({
|
||||
independentLeaves: true,
|
||||
lockfileDir: prefix,
|
||||
}))
|
||||
|
||||
const modulesInfo = await readYamlFile<{ skipped: string[] }>(path.join(prefix, 'node_modules', '.modules.yaml'))
|
||||
t.deepEqual(
|
||||
modulesInfo.skipped,
|
||||
[
|
||||
'/dep-of-optional-pkg/1.0.0',
|
||||
'/not-compatible-with-any-os/1.0.0',
|
||||
],
|
||||
'optional subdeps skipped'
|
||||
)
|
||||
|
||||
const project = assertProject(t, prefix)
|
||||
await project.has('pkg-with-optional')
|
||||
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('run pre/postinstall scripts', async (t) => {
|
||||
const prefix = path.join(fixtures, 'deps-have-lifecycle-scripts')
|
||||
const outputJsonPath = path.join(prefix, 'output.json')
|
||||
@@ -544,53 +479,6 @@ test('installation of a dependency that has a resolved peer in subdeps', async (
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('independent-leaves: installing a simple project', async (t) => {
|
||||
const prefix = path.join(fixtures, 'simple')
|
||||
await rimraf(path.join(prefix, 'node_modules'))
|
||||
const reporter = sinon.spy()
|
||||
|
||||
await headless(await testDefaults({ lockfileDir: prefix, reporter, independentLeaves: true }))
|
||||
|
||||
const project = assertProject(t, prefix)
|
||||
t.ok(project.requireModule('is-positive'), 'prod dep installed')
|
||||
t.ok(project.requireModule('rimraf'), 'prod dep installed')
|
||||
t.ok(project.requireModule('is-negative'), 'dev dep installed')
|
||||
t.ok(project.requireModule('colors'), 'optional dep installed')
|
||||
await project.has(`.pnpm/rimraf@2.7.1`) // rimraf is not symlinked from the store
|
||||
await project.hasNot(`.pnpm/colors@1.2.0`) // colors is symlinked from the store
|
||||
|
||||
await project.isExecutable('.bin/rimraf')
|
||||
|
||||
t.ok(await project.readCurrentLockfile())
|
||||
t.ok(await project.readModulesManifest())
|
||||
|
||||
t.ok(reporter.calledWithMatch({
|
||||
level: 'debug',
|
||||
name: 'pnpm:package-manifest',
|
||||
updated: require(path.join(prefix, 'package.json')),
|
||||
} as PackageManifestLog), 'updated package.json logged')
|
||||
t.ok(reporter.calledWithMatch({
|
||||
added: 15,
|
||||
level: 'debug',
|
||||
name: 'pnpm:stats',
|
||||
prefix,
|
||||
} as StatsLog), 'added stat')
|
||||
t.ok(reporter.calledWithMatch({
|
||||
level: 'debug',
|
||||
name: 'pnpm:stats',
|
||||
prefix,
|
||||
removed: 0,
|
||||
} as StatsLog), 'removed stat')
|
||||
t.ok(reporter.calledWithMatch({
|
||||
level: 'debug',
|
||||
name: 'pnpm:stage',
|
||||
prefix,
|
||||
stage: 'importing_done',
|
||||
} as StageLog), 'importing stage done logged')
|
||||
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('installing with hoistPattern=*', async (t) => {
|
||||
const prefix = path.join(fixtures, 'simple-shamefully-flatten')
|
||||
const reporter = sinon.spy()
|
||||
@@ -604,8 +492,7 @@ test('installing with hoistPattern=*', async (t) => {
|
||||
t.ok(project.requireModule('is-negative'), 'dev dep installed')
|
||||
t.ok(project.requireModule('colors'), 'optional dep installed')
|
||||
|
||||
// test that independent leaves is false by default
|
||||
await project.has(`.pnpm/colors@1.2.0`) // colors is not symlinked from the store
|
||||
await project.has(`.pnpm/colors@1.2.0`)
|
||||
|
||||
await project.isExecutable('.bin/rimraf')
|
||||
await project.isExecutable('.pnpm/node_modules/.bin/hello-world-js-bin')
|
||||
@@ -664,8 +551,7 @@ test('installing with hoistPattern=* and shamefullyHoist=true', async (t) => {
|
||||
t.ok(project.requireModule('is-negative'), 'dev dep installed')
|
||||
t.ok(project.requireModule('colors'), 'optional dep installed')
|
||||
|
||||
// test that independent leaves is false by default
|
||||
await project.has(`.pnpm/colors@1.2.0`) // colors is not symlinked from the store
|
||||
await project.has(`.pnpm/colors@1.2.0`)
|
||||
|
||||
await project.isExecutable('.bin/rimraf')
|
||||
await project.isExecutable('.bin/hello-world-js-bin')
|
||||
@@ -835,34 +721,3 @@ test('installing in a workspace', async (t) => {
|
||||
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('independent-leaves: installing in a workspace', async (t) => {
|
||||
const workspaceFixture = path.join(__dirname, 'workspace-fixture2')
|
||||
|
||||
const { projects } = await readprojectsContext(
|
||||
[
|
||||
{
|
||||
rootDir: path.join(workspaceFixture, 'foo'),
|
||||
},
|
||||
{
|
||||
rootDir: path.join(workspaceFixture, 'bar'),
|
||||
},
|
||||
],
|
||||
{ lockfileDir: workspaceFixture }
|
||||
)
|
||||
|
||||
await headless(await testDefaults({
|
||||
independentLeaves: true,
|
||||
lockfileDir: workspaceFixture,
|
||||
projects: await Promise.all(
|
||||
projects.map(async (project) => ({ ...project, manifest: await readPackageJsonFromDir(project.rootDir) }))
|
||||
),
|
||||
}))
|
||||
|
||||
const projectBar = assertProject(t, path.join(workspaceFixture, 'bar'))
|
||||
|
||||
await projectBar.has('foo')
|
||||
t.ok(await exists(path.join(workspaceFixture, `node_modules/.pnpm/express@4.16.4/node_modules/array-flatten`)), 'independent package linked')
|
||||
|
||||
t.end()
|
||||
})
|
||||
|
||||
@@ -65,7 +65,6 @@ export default async function testDefaults (
|
||||
engineStrict: false,
|
||||
force: false,
|
||||
include,
|
||||
independentLeaves: false,
|
||||
lockfileDir,
|
||||
packageManager: {
|
||||
name: 'pnpm',
|
||||
|
||||
@@ -3,7 +3,6 @@ import linkBins, { WarnFunction } from '@pnpm/link-bins'
|
||||
import {
|
||||
Lockfile,
|
||||
nameVerFromPkgSnapshot,
|
||||
packageIsIndependent,
|
||||
} from '@pnpm/lockfile-utils'
|
||||
import lockfileWalker, { LockfileWalkerStep } from '@pnpm/lockfile-walker'
|
||||
import logger from '@pnpm/logger'
|
||||
@@ -17,7 +16,6 @@ import R = require('ramda')
|
||||
export default async function hoistByLockfile (
|
||||
match: (dependencyName: string) => boolean,
|
||||
opts: {
|
||||
getIndependentPackageLocation?: (packageId: string, packageName: string) => Promise<string>,
|
||||
lockfile: Lockfile,
|
||||
lockfileDir: string,
|
||||
modulesDir: string,
|
||||
@@ -48,7 +46,6 @@ export default async function hoistByLockfile (
|
||||
step,
|
||||
0,
|
||||
{
|
||||
getIndependentPackageLocation: opts.getIndependentPackageLocation,
|
||||
lockfileDir: opts.lockfileDir,
|
||||
registries: opts.registries,
|
||||
virtualStoreDir: opts.virtualStoreDir,
|
||||
@@ -83,7 +80,6 @@ async function getDependencies (
|
||||
step: LockfileWalkerStep,
|
||||
depth: number,
|
||||
opts: {
|
||||
getIndependentPackageLocation?: (packageId: string, packageName: string) => Promise<string>,
|
||||
registries: Registries,
|
||||
lockfileDir: string,
|
||||
virtualStoreDir: string,
|
||||
@@ -92,10 +88,8 @@ async function getDependencies (
|
||||
const deps: Dependency[] = []
|
||||
const nextSteps: LockfileWalkerStep[] = []
|
||||
for (const { pkgSnapshot, relDepPath, next } of step.dependencies) {
|
||||
const absolutePath = dp.resolve(opts.registries, relDepPath)
|
||||
const pkgName = nameVerFromPkgSnapshot(relDepPath, pkgSnapshot).name
|
||||
const modules = path.join(opts.virtualStoreDir, pkgIdToFilename(relDepPath, opts.lockfileDir), 'node_modules')
|
||||
const independent = opts.getIndependentPackageLocation && packageIsIndependent(pkgSnapshot)
|
||||
const allDeps = {
|
||||
...pkgSnapshot.dependencies,
|
||||
...pkgSnapshot.optionalDependencies,
|
||||
@@ -107,9 +101,7 @@ async function getDependencies (
|
||||
}, {}),
|
||||
depPath: relDepPath,
|
||||
depth,
|
||||
location: !independent
|
||||
? path.join(modules, pkgName)
|
||||
: await opts.getIndependentPackageLocation!(pkgSnapshot.id || absolutePath, pkgName),
|
||||
location: path.join(modules, pkgName),
|
||||
})
|
||||
|
||||
nextSteps.push(next())
|
||||
|
||||
1
packages/list/example/node_modules/.modules.yaml
generated
vendored
1
packages/list/example/node_modules/.modules.yaml
generated
vendored
@@ -1,4 +1,3 @@
|
||||
independentLeaves: false
|
||||
layoutVersion: 1
|
||||
packageManager: pnpm@1.4.0
|
||||
skipped: []
|
||||
|
||||
@@ -14,9 +14,7 @@ export default async function getPkgInfo (
|
||||
try {
|
||||
manifest = await readPkg(path.join(pkg.path, 'node_modules', pkg.name, 'package.json'))
|
||||
} catch (err) {
|
||||
// This is a temporary workaround.
|
||||
// If the package.json is not found inside node_modules, it should be read from the store.
|
||||
// This frequently happens when the independent-leaves config is true.
|
||||
// This will probably never happen
|
||||
manifest = {
|
||||
description: '[Could not find additional info about this dependency]',
|
||||
}
|
||||
|
||||
1
packages/list/test/fixture-with-external-shrinkwrap/node_modules/.modules.yaml
generated
vendored
1
packages/list/test/fixture-with-external-shrinkwrap/node_modules/.modules.yaml
generated
vendored
@@ -6,7 +6,6 @@ included:
|
||||
dependencies: true
|
||||
devDependencies: true
|
||||
optionalDependencies: true
|
||||
independentLeaves: false
|
||||
layoutVersion: 1
|
||||
packageManager: pnpm@2.17.0-4
|
||||
pendingBuilds: []
|
||||
|
||||
@@ -2,7 +2,6 @@ included:
|
||||
dependencies: true
|
||||
devDependencies: true
|
||||
optionalDependencies: true
|
||||
independentLeaves: true
|
||||
layoutVersion: 3
|
||||
packageManager: pnpm@3.8.1
|
||||
pendingBuilds: []
|
||||
|
||||
1
packages/list/test/fixture-with-no-pkg-version/node_modules/.modules.yaml
generated
vendored
1
packages/list/test/fixture-with-no-pkg-version/node_modules/.modules.yaml
generated
vendored
@@ -2,7 +2,6 @@ included:
|
||||
dependencies: true
|
||||
devDependencies: true
|
||||
optionalDependencies: true
|
||||
independentLeaves: true
|
||||
layoutVersion: 3
|
||||
packageManager: pnpm@3.8.1
|
||||
pendingBuilds: []
|
||||
|
||||
1
packages/list/test/fixture/node_modules/.modules.yaml
generated
vendored
1
packages/list/test/fixture/node_modules/.modules.yaml
generated
vendored
@@ -2,7 +2,6 @@ included:
|
||||
dependencies: true
|
||||
devDependencies: true
|
||||
optionalDependencies: true
|
||||
independentLeaves: true
|
||||
layoutVersion: 3
|
||||
packageManager: pnpm@3.8.1
|
||||
pendingBuilds: []
|
||||
|
||||
1
packages/list/test/with-aliased-dep/node_modules/.modules.yaml
generated
vendored
1
packages/list/test/with-aliased-dep/node_modules/.modules.yaml
generated
vendored
@@ -2,7 +2,6 @@ included:
|
||||
dependencies: true
|
||||
devDependencies: true
|
||||
optionalDependencies: true
|
||||
independentLeaves: true
|
||||
layoutVersion: 3
|
||||
packageManager: pnpm@3.8.1
|
||||
pendingBuilds: []
|
||||
|
||||
@@ -19,13 +19,12 @@ import {write, read} from '@pnpm/modules-yaml'
|
||||
|
||||
await write('node_modules', {
|
||||
hoistedAliases: {}
|
||||
independentLeaves: false,
|
||||
layoutVersion: 1,
|
||||
packageManager: 'pnpm@1.0.0',
|
||||
pendingBuilds: [],
|
||||
shamefullyFlatten: false,
|
||||
skipped: [],
|
||||
store: '/home/user/.pnpm-store',
|
||||
storeDir: '/home/user/.pnpm-store',
|
||||
})
|
||||
|
||||
const modulesYaml = await read(`node_modules`)
|
||||
|
||||
@@ -16,7 +16,6 @@ export interface Modules {
|
||||
hoistedAliases: {[depPath: string]: string[]}
|
||||
hoistPattern?: string[]
|
||||
included: IncludedDependencies,
|
||||
independentLeaves: boolean,
|
||||
layoutVersion: number,
|
||||
packageManager: string,
|
||||
pendingBuilds: string[],
|
||||
|
||||
@@ -15,7 +15,6 @@ test('write() and read()', async (t) => {
|
||||
devDependencies: true,
|
||||
optionalDependencies: true,
|
||||
},
|
||||
independentLeaves: false,
|
||||
layoutVersion: 1,
|
||||
packageManager: 'pnpm@2',
|
||||
pendingBuilds: [],
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
import packageRequester from './packageRequester'
|
||||
|
||||
export {
|
||||
getCacheByEngine,
|
||||
} from './packageRequester'
|
||||
|
||||
export default packageRequester
|
||||
|
||||
export { PackageResponse, PackageFilesResponse } from '@pnpm/store-controller-types'
|
||||
|
||||
@@ -198,7 +198,6 @@ async function resolveAndFetch (
|
||||
return {
|
||||
body: {
|
||||
id,
|
||||
inStoreLocation: path.join(ctx.storeDir, pkgIdToFilename(id, options.lockfileDir)),
|
||||
isLocal: false as const,
|
||||
latest,
|
||||
manifest,
|
||||
@@ -221,7 +220,6 @@ async function resolveAndFetch (
|
||||
return {
|
||||
body: {
|
||||
id,
|
||||
inStoreLocation: fetchResult.inStoreLocation,
|
||||
isLocal: false as const,
|
||||
latest,
|
||||
manifest,
|
||||
@@ -245,7 +243,6 @@ type FetchLock = {
|
||||
files: Promise<PackageFilesResponse>,
|
||||
filesIndexFile: string,
|
||||
finishing: Promise<void>,
|
||||
inStoreLocation: string,
|
||||
}
|
||||
|
||||
function fetchToStore (
|
||||
@@ -278,7 +275,6 @@ function fetchToStore (
|
||||
filesIndexFile: string,
|
||||
files: () => Promise<PackageFilesResponse>,
|
||||
finishing: () => Promise<void>,
|
||||
inStoreLocation: string,
|
||||
} {
|
||||
const targetRelative = pkgIdToFilename(opts.pkgId, opts.lockfileDir)
|
||||
const target = path.join(ctx.storeDir, targetRelative)
|
||||
@@ -299,14 +295,12 @@ function fetchToStore (
|
||||
files: removeKeyOnFail(files.promise),
|
||||
filesIndexFile,
|
||||
finishing: removeKeyOnFail(finishing.promise),
|
||||
inStoreLocation: target,
|
||||
})
|
||||
} else {
|
||||
ctx.fetchingLocker.set(opts.pkgId, {
|
||||
files: removeKeyOnFail(files.promise),
|
||||
filesIndexFile,
|
||||
finishing: removeKeyOnFail(finishing.promise),
|
||||
inStoreLocation: target,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -358,7 +352,6 @@ function fetchToStore (
|
||||
files: pShare(result.files),
|
||||
filesIndexFile: result.filesIndexFile,
|
||||
finishing: pShare(result.finishing),
|
||||
inStoreLocation: result.inStoreLocation,
|
||||
}
|
||||
|
||||
async function removeKeyOnFail<T> (p: Promise<T>): Promise<T> {
|
||||
@@ -551,24 +544,3 @@ async function fetcher (
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: cover with tests
|
||||
export async function getCacheByEngine (storeDir: string, id: string): Promise<Map<string, string>> {
|
||||
const map = new Map<string, string>()
|
||||
|
||||
const cacheRoot = path.join(storeDir, id, 'side_effects')
|
||||
if (!await fs.exists(cacheRoot)) {
|
||||
return map
|
||||
}
|
||||
|
||||
const dirContents = (await fs.readdir(cacheRoot)).map((content: string) => path.join(cacheRoot, content))
|
||||
await Promise.all(dirContents.map(async (dir: string) => {
|
||||
if (!(await fs.lstat(dir)).isDirectory()) {
|
||||
return
|
||||
}
|
||||
const engineName = path.basename(dir)
|
||||
map[engineName] = path.join(dir, 'package')
|
||||
}))
|
||||
|
||||
return map
|
||||
}
|
||||
|
||||
@@ -61,7 +61,6 @@ test('request package', async t => {
|
||||
|
||||
t.equal(pkgResponse.body.id, 'registry.npmjs.org/is-positive/1.0.0', 'responded with correct package ID')
|
||||
t.equal(pkgResponse.body.resolvedVia, 'npm-registry', 'responded with correct resolvedVia')
|
||||
t.equal(pkgResponse.body.inStoreLocation, path.join(storeDir, 'registry.npmjs.org', 'is-positive@1.0.0'), 'package location in store returned')
|
||||
t.equal(pkgResponse.body.isLocal, false, 'package is not local')
|
||||
t.equal(typeof pkgResponse.body.latest, 'string', 'latest is returned')
|
||||
t.equal(pkgResponse.body.manifest.name, 'is-positive', 'package manifest returned')
|
||||
@@ -104,7 +103,6 @@ test('request package but skip fetching', async t => {
|
||||
t.ok(pkgResponse.body, 'response has body')
|
||||
|
||||
t.equal(pkgResponse.body.id, 'registry.npmjs.org/is-positive/1.0.0', 'responded with correct package ID')
|
||||
t.equal(pkgResponse.body.inStoreLocation, path.join('.store', 'registry.npmjs.org', 'is-positive@1.0.0'), 'package location in store returned')
|
||||
t.equal(pkgResponse.body.isLocal, false, 'package is not local')
|
||||
t.equal(typeof pkgResponse.body.latest, 'string', 'latest is returned')
|
||||
t.equal(pkgResponse.body.manifest.name, 'is-positive', 'package manifest returned')
|
||||
@@ -146,7 +144,6 @@ test('request package but skip fetching, when resolution is already available',
|
||||
update: false,
|
||||
}) as PackageResponse & {
|
||||
body: {
|
||||
inStoreLocation: string,
|
||||
latest: string,
|
||||
manifest: {name: string},
|
||||
},
|
||||
@@ -158,7 +155,6 @@ test('request package but skip fetching, when resolution is already available',
|
||||
t.ok(pkgResponse.body, 'response has body')
|
||||
|
||||
t.equal(pkgResponse.body.id, 'registry.npmjs.org/is-positive/1.0.0', 'responded with correct package ID')
|
||||
t.equal(pkgResponse.body.inStoreLocation, path.join('.store', 'registry.npmjs.org', 'is-positive@1.0.0'), 'package location in store returned')
|
||||
t.equal(pkgResponse.body.isLocal, false, 'package is not local')
|
||||
t.equal(typeof pkgResponse.body.latest, 'string', 'latest is returned')
|
||||
t.equal(pkgResponse.body.manifest.name, 'is-positive', 'package manifest returned')
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
"@pnpm/core-loggers": "workspace:4.0.2-alpha.0",
|
||||
"@pnpm/fetcher-base": "workspace:7.0.0-alpha.3",
|
||||
"@pnpm/package-requester": "workspace:12.0.0-alpha.5",
|
||||
"@pnpm/pkgid-to-filename": "3.0.0",
|
||||
"@pnpm/resolver-base": "workspace:7.0.1-alpha.0",
|
||||
"@pnpm/store-controller-types": "workspace:8.0.0-alpha.4",
|
||||
"@pnpm/types": "workspace:6.0.0-alpha.0",
|
||||
|
||||
@@ -4,8 +4,7 @@ import {
|
||||
PackageFilesIndex,
|
||||
} from '@pnpm/cafs'
|
||||
import { FetchFunction } from '@pnpm/fetcher-base'
|
||||
import createPackageRequester, { getCacheByEngine } from '@pnpm/package-requester'
|
||||
import pkgIdToFilename from '@pnpm/pkgid-to-filename'
|
||||
import createPackageRequester from '@pnpm/package-requester'
|
||||
import { ResolveFunction } from '@pnpm/resolver-base'
|
||||
import {
|
||||
ImportPackageFunction,
|
||||
@@ -64,37 +63,12 @@ export default async function (
|
||||
return {
|
||||
close: async () => {}, // tslint:disable-line:no-empty
|
||||
fetchPackage: packageRequester.fetchPackageToStore,
|
||||
getPackageLocation,
|
||||
importPackage,
|
||||
prune: prune.bind(null, storeDir),
|
||||
requestPackage: packageRequester.requestPackage,
|
||||
upload,
|
||||
}
|
||||
|
||||
async function getPackageLocation (
|
||||
packageId: string,
|
||||
packageName: string,
|
||||
opts: {
|
||||
lockfileDir: string,
|
||||
targetEngine?: string,
|
||||
}
|
||||
) {
|
||||
if (opts.targetEngine) {
|
||||
const sideEffectsCacheLocation = (await getCacheByEngine(initOpts.storeDir, packageId))[opts.targetEngine]
|
||||
if (sideEffectsCacheLocation) {
|
||||
return {
|
||||
dir: sideEffectsCacheLocation,
|
||||
isBuilt: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
dir: path.join(initOpts.storeDir, pkgIdToFilename(packageId, opts.lockfileDir), 'node_modules', packageName),
|
||||
isBuilt: false,
|
||||
}
|
||||
}
|
||||
|
||||
async function upload (builtPkgLocation: string, opts: {filesIndexFile: string, engine: string}) {
|
||||
const sideEffectsIndex = await packageRequester.cafs.addFilesFromDir(builtPkgLocation)
|
||||
// TODO: move this to a function
|
||||
|
||||
@@ -21,7 +21,6 @@ export function rcOptionsTypes () {
|
||||
'ignore-pnpmfile',
|
||||
'ignore-scripts',
|
||||
'ignore-workspace-root-check',
|
||||
'independent-leaves',
|
||||
'link-workspace-packages',
|
||||
'lockfile-dir',
|
||||
'lockfile-directory',
|
||||
|
||||
@@ -22,7 +22,6 @@ export function rcOptionsTypes () {
|
||||
'hoist-pattern',
|
||||
'ignore-pnpmfile',
|
||||
'ignore-scripts',
|
||||
'independent-leaves',
|
||||
'link-workspace-packages',
|
||||
'lockfile-dir',
|
||||
'lockfile-directory',
|
||||
@@ -158,10 +157,6 @@ export function help () {
|
||||
description: 'Disable pnpm hooks defined in pnpmfile.js',
|
||||
name: '--ignore-pnpmfile',
|
||||
},
|
||||
{
|
||||
description: 'Symlinks leaf dependencies directly from the global store',
|
||||
name: '--independent-leaves',
|
||||
},
|
||||
{
|
||||
description: "If false, doesn't check whether packages in the store were mutated",
|
||||
name: '--[no-]verify-store-integrity',
|
||||
@@ -260,7 +255,6 @@ export type InstallCommandOptions = Pick<Config,
|
||||
| 'globalPnpmfile'
|
||||
| 'ignorePnpmfile'
|
||||
| 'ignoreScripts'
|
||||
| 'independentLeaves'
|
||||
| 'linkWorkspacePackages'
|
||||
| 'rawLocalConfig'
|
||||
| 'lockfileDir'
|
||||
|
||||
@@ -38,7 +38,6 @@ export type InstallDepsOptions = Pick<Config,
|
||||
| 'globalPnpmfile'
|
||||
| 'ignorePnpmfile'
|
||||
| 'ignoreScripts'
|
||||
| 'independentLeaves'
|
||||
| 'linkWorkspacePackages'
|
||||
| 'lockfileDir'
|
||||
| 'lockfileOnly'
|
||||
@@ -146,7 +145,6 @@ export default async function handler (
|
||||
workspacePackages,
|
||||
|
||||
forceHoistPattern: typeof opts.rawLocalConfig['hoist-pattern'] !== 'undefined' || typeof opts.rawLocalConfig['hoist'] !== 'undefined',
|
||||
forceIndependentLeaves: typeof opts.rawLocalConfig['independent-leaves'] !== 'undefined',
|
||||
forceShamefullyHoist: typeof opts.rawLocalConfig['shamefully-hoist'] !== 'undefined',
|
||||
}
|
||||
if (!opts.ignorePnpmfile) {
|
||||
|
||||
@@ -120,7 +120,6 @@ export default async function recursive (
|
||||
workspacePackages,
|
||||
|
||||
forceHoistPattern: typeof opts.rawLocalConfig['hoist-pattern'] !== 'undefined' || typeof opts.rawLocalConfig['hoist'] !== 'undefined',
|
||||
forceIndependentLeaves: typeof opts.rawLocalConfig['independent-leaves'] !== 'undefined',
|
||||
forceShamefullyHoist: typeof opts.rawLocalConfig['shamefully-hoist'] !== 'undefined',
|
||||
}) as InstallOptions
|
||||
|
||||
|
||||
@@ -81,40 +81,6 @@ test('listing packages', async (t) => {
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('independent-leaves=true: pnpm list --long', async (t) => {
|
||||
prepare(t, {
|
||||
dependencies: {
|
||||
'is-positive': '1.0.0',
|
||||
},
|
||||
devDependencies: {
|
||||
'is-negative': '1.0.0',
|
||||
},
|
||||
})
|
||||
|
||||
await execa('node', [pnpmBin, 'install', '--independent-leaves', '--no-hoist'])
|
||||
|
||||
const output = await list.handler({
|
||||
dir: process.cwd(),
|
||||
long: true,
|
||||
}, [])
|
||||
|
||||
// TODO: the --long flag should work with --independent-leaves
|
||||
t.equal(stripAnsi(output), stripIndent`
|
||||
Legend: production dependency, optional only, dev only
|
||||
|
||||
project@0.0.0 ${process.cwd()}
|
||||
|
||||
dependencies:
|
||||
is-positive 1.0.0
|
||||
[Could not find additional info about this dependency]
|
||||
|
||||
devDependencies:
|
||||
is-negative 1.0.0
|
||||
[Could not find additional info about this dependency]
|
||||
`)
|
||||
t.end()
|
||||
})
|
||||
|
||||
test(`listing packages of a project that has an external ${WANTED_LOCKFILE}`, async (t) => {
|
||||
preparePackages(t, [
|
||||
{
|
||||
|
||||
@@ -138,7 +138,6 @@ export type OutdatedCommandOptions = {
|
||||
| 'fetchRetryMintimeout'
|
||||
| 'global'
|
||||
| 'httpsProxy'
|
||||
| 'independentLeaves'
|
||||
| 'key'
|
||||
| 'localAddress'
|
||||
| 'lockfileDir'
|
||||
|
||||
@@ -27,7 +27,6 @@ const OUTDATED_OPTIONS = {
|
||||
fetchRetryMaxtimeout: 60,
|
||||
fetchRetryMintimeout: 10,
|
||||
global: false,
|
||||
independentLeaves: false,
|
||||
networkConcurrency: 16,
|
||||
offline: false,
|
||||
rawConfig: { registry: REGISTRY_URL },
|
||||
|
||||
@@ -23,7 +23,6 @@ export const DEFAULT_OPTS = {
|
||||
devDependencies: true,
|
||||
optionalDependencies: true,
|
||||
},
|
||||
independentLeaves: false,
|
||||
key: undefined,
|
||||
linkWorkspacePackages: true,
|
||||
localAddress: undefined,
|
||||
|
||||
@@ -175,7 +175,6 @@ export async function rebuild (
|
||||
hoistedAliases: ctx.hoistedAliases,
|
||||
hoistPattern: ctx.hoistPattern,
|
||||
included: ctx.include,
|
||||
independentLeaves: ctx.independentLeaves,
|
||||
layoutVersion: LAYOUT_VERSION,
|
||||
packageManager: `${opts.packageManager.name}@${opts.packageManager.version}`,
|
||||
pendingBuilds: ctx.pendingBuilds,
|
||||
@@ -224,7 +223,6 @@ async function _rebuild (
|
||||
rootModulesDir: string,
|
||||
currentLockfile: Lockfile,
|
||||
projects: Array<{ id: string, rootDir: string }>,
|
||||
independentLeaves: boolean,
|
||||
extraBinPaths: string[],
|
||||
},
|
||||
opts: StrictRebuildOptions
|
||||
@@ -268,24 +266,11 @@ async function _rebuild (
|
||||
const pkgSnapshot = pkgSnapshots[relDepPath]
|
||||
const depPath = dp.resolve(opts.registries, relDepPath)
|
||||
const pkgInfo = nameVerFromPkgSnapshot(relDepPath, pkgSnapshot)
|
||||
const independent = ctx.independentLeaves && packageIsIndependent(pkgSnapshot)
|
||||
const pkgRoot = !independent
|
||||
? path.join(ctx.virtualStoreDir, pkgIdToFilename(relDepPath, opts.lockfileDir), 'node_modules', pkgInfo.name)
|
||||
: await (
|
||||
async () => {
|
||||
const { dir } = await opts.storeController.getPackageLocation(pkgSnapshot.id || depPath, pkgInfo.name, {
|
||||
lockfileDir: opts.lockfileDir,
|
||||
targetEngine: opts.sideEffectsCacheRead && !opts.force && ENGINE_NAME || undefined,
|
||||
})
|
||||
return dir
|
||||
}
|
||||
)()
|
||||
const pkgRoot = path.join(ctx.virtualStoreDir, pkgIdToFilename(relDepPath, opts.lockfileDir), 'node_modules', pkgInfo.name)
|
||||
try {
|
||||
if (!independent) {
|
||||
const modules = path.join(ctx.virtualStoreDir, pkgIdToFilename(relDepPath, opts.lockfileDir), 'node_modules')
|
||||
const binPath = path.join(pkgRoot, 'node_modules', '.bin')
|
||||
await linkBins(modules, binPath, { warn })
|
||||
}
|
||||
const modules = path.join(ctx.virtualStoreDir, pkgIdToFilename(relDepPath, opts.lockfileDir), 'node_modules')
|
||||
const binPath = path.join(pkgRoot, 'node_modules', '.bin')
|
||||
await linkBins(modules, binPath, { warn })
|
||||
await runPostinstallHooks({
|
||||
depPath,
|
||||
extraBinPaths: ctx.extraBinPaths,
|
||||
@@ -325,7 +310,6 @@ async function _rebuild (
|
||||
.keys(pkgSnapshots)
|
||||
.filter((relDepPath) => !packageIsIndependent(pkgSnapshots[relDepPath]))
|
||||
.map((relDepPath) => limitLinking(() => {
|
||||
const depPath = dp.resolve(opts.registries, relDepPath)
|
||||
const pkgSnapshot = pkgSnapshots[relDepPath]
|
||||
const pkgInfo = nameVerFromPkgSnapshot(relDepPath, pkgSnapshot)
|
||||
const modules = path.join(ctx.virtualStoreDir, pkgIdToFilename(relDepPath, opts.lockfileDir), 'node_modules')
|
||||
|
||||
@@ -70,7 +70,6 @@ export async function handler (
|
||||
| 'allProjects'
|
||||
| 'dir'
|
||||
| 'engineStrict'
|
||||
| 'independentLeaves'
|
||||
| 'rawLocalConfig'
|
||||
| 'registries'
|
||||
| 'selectedProjectsGraph'
|
||||
|
||||
@@ -235,46 +235,6 @@ test('rebuild dependencies in correct order', async (t) => {
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('rebuild dependencies in correct order when node_modules uses independent-leaves', async (t) => {
|
||||
const project = prepareEmpty(t)
|
||||
const storeDir = path.resolve('store')
|
||||
|
||||
await execa('node', [
|
||||
pnpmBin,
|
||||
'add',
|
||||
'with-postinstall-a',
|
||||
'--registry',
|
||||
REGISTRY,
|
||||
'--store-dir',
|
||||
storeDir,
|
||||
'--ignore-scripts',
|
||||
'--independent-leaves',
|
||||
'--no-hoist',
|
||||
])
|
||||
|
||||
let modules = await project.readModulesManifest()
|
||||
t.ok(modules)
|
||||
t.doesNotEqual(modules!.pendingBuilds.length, 0)
|
||||
|
||||
await project.hasNot(`.pnpm/with-postinstall-b@1.0.0/node_modules/with-postinstall-b/output.json`)
|
||||
await project.hasNot('with-postinstall-a/output.json')
|
||||
|
||||
await rebuild.handler({
|
||||
...DEFAULT_OPTS,
|
||||
dir: process.cwd(),
|
||||
independentLeaves: true,
|
||||
pending: true,
|
||||
storeDir,
|
||||
}, [])
|
||||
|
||||
modules = await project.readModulesManifest()
|
||||
t.ok(modules)
|
||||
t.equal(modules!.pendingBuilds.length, 0)
|
||||
|
||||
t.ok(+project.requireModule(`.pnpm/with-postinstall-b@1.0.0/node_modules/with-postinstall-b/output.json`)[0] < +project.requireModule('with-postinstall-a/output.json')[0])
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('rebuild links bins', async (t) => {
|
||||
const project = prepareEmpty(t)
|
||||
const storeDir = path.resolve('store')
|
||||
|
||||
@@ -7,7 +7,6 @@ export interface StrictStoreStatusOptions {
|
||||
lockfileDir: string,
|
||||
dir: string,
|
||||
storeDir: string,
|
||||
independentLeaves: boolean,
|
||||
force: boolean,
|
||||
forceSharedLockfile: boolean,
|
||||
useLockfile: boolean,
|
||||
@@ -32,7 +31,6 @@ const defaults = async (opts: StoreStatusOptions) => {
|
||||
dir,
|
||||
force: false,
|
||||
forceSharedLockfile: false,
|
||||
independentLeaves: false,
|
||||
lockfileDir,
|
||||
registries: DEFAULT_REGISTRIES,
|
||||
shamefullyHoist: false,
|
||||
|
||||
@@ -29,7 +29,7 @@ export function help () {
|
||||
],
|
||||
},
|
||||
],
|
||||
usages: ['pnpm root [-g [--independent-leaves]]'],
|
||||
usages: ['pnpm root [-g]'],
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -94,18 +94,6 @@ test('command fails when an unsupported flag is used', async (t) => {
|
||||
t.ok(stderr.toString().includes("Unknown option 'save-dev'"))
|
||||
})
|
||||
|
||||
test('adding new dep does not fail if node_modules was created with --no-hoist and --independent-leaves', async (t: tape.Test) => {
|
||||
const project = prepare(t)
|
||||
|
||||
await execPnpm(['add', 'is-positive', '--no-hoist', '--independent-leaves'])
|
||||
|
||||
t.equal(execPnpmSync(['add', 'is-negative', '--hoist']).status, 1)
|
||||
t.equal(execPnpmSync(['add', 'is-negative', '--no-independent-leaves']).status, 1)
|
||||
t.equal(execPnpmSync(['add', 'is-negative']).status, 0)
|
||||
|
||||
await project.has('is-negative')
|
||||
})
|
||||
|
||||
test('adding new dep does not fail if node_modules was created with --hoist-pattern=eslint-* and --shamefully-hoist', async (t: tape.Test) => {
|
||||
const project = prepare(t)
|
||||
|
||||
|
||||
@@ -86,7 +86,6 @@ function createEnv (opts?: {storeDir?: string}): NodeJS.ProcessEnv {
|
||||
const env = {
|
||||
npm_config_fetch_retries: '4',
|
||||
npm_config_hoist: 'true',
|
||||
npm_config_independent_leaves: 'false',
|
||||
npm_config_registry: `http://localhost:${REGISTRY_MOCK_PORT}/`,
|
||||
npm_config_silent: 'true',
|
||||
npm_config_store_dir: opts && opts.storeDir || '../store',
|
||||
|
||||
@@ -25,7 +25,6 @@ export default async function <T>(
|
||||
id: string,
|
||||
} & T & Required<ProjectOptions>>,
|
||||
include: Record<DependenciesField, boolean>,
|
||||
independentLeaves: boolean | undefined,
|
||||
modules: Modules | null,
|
||||
pendingBuilds: string[],
|
||||
registries: Registries | null | undefined,
|
||||
@@ -41,7 +40,6 @@ export default async function <T>(
|
||||
hoist: !modules ? undefined : Boolean(modules.hoistPattern),
|
||||
hoistedAliases: modules?.hoistedAliases || {},
|
||||
include: modules?.included || { dependencies: true, devDependencies: true, optionalDependencies: true },
|
||||
independentLeaves: modules?.independentLeaves || undefined,
|
||||
modules,
|
||||
pendingBuilds: modules?.pendingBuilds || [],
|
||||
projects: await Promise.all(
|
||||
|
||||
@@ -175,14 +175,12 @@ export interface ResolvedPackage {
|
||||
fetchingBundledManifest?: () => Promise<DependencyManifest>,
|
||||
filesIndexFile: string,
|
||||
finishing: () => Promise<void>,
|
||||
path: string,
|
||||
name: string,
|
||||
version: string,
|
||||
peerDependencies: Dependencies,
|
||||
optionalDependencies: Set<string>,
|
||||
hasBin: boolean,
|
||||
hasBundledDependencies: boolean,
|
||||
independent: boolean,
|
||||
prepare: boolean,
|
||||
depPath: string,
|
||||
requiresBuild: boolean | undefined, // added to fix issue #1201
|
||||
@@ -784,13 +782,9 @@ function getResolvedPackage (
|
||||
hasBin: options.hasBin,
|
||||
hasBundledDependencies: !!(options.pkg.bundledDependencies || options.pkg.bundleDependencies),
|
||||
id: options.pkgResponse.body.id,
|
||||
independent: (options.pkg.dependencies === undefined || R.isEmpty(options.pkg.dependencies)) &&
|
||||
(options.pkg.optionalDependencies === undefined || R.isEmpty(options.pkg.optionalDependencies)) &&
|
||||
(options.pkg.peerDependencies === undefined || R.isEmpty(options.pkg.peerDependencies)),
|
||||
name: options.pkg.name,
|
||||
optional: options.wantedDependency.optional,
|
||||
optionalDependencies: new Set(R.keys(options.pkg.optionalDependencies)),
|
||||
path: options.pkgResponse.body.inStoreLocation!,
|
||||
peerDependencies: peerDependencies ?? {},
|
||||
prepare: options.prepare,
|
||||
prod: !options.wantedDependency.dev && !options.wantedDependency.optional,
|
||||
|
||||
@@ -30,20 +30,6 @@ export default function (
|
||||
resolve({
|
||||
close: async () => { return },
|
||||
fetchPackage: fetchPackage.bind(null, remotePrefix, limitedFetch),
|
||||
getPackageLocation: async (
|
||||
packageId: string,
|
||||
packageName: string,
|
||||
opts: {
|
||||
lockfileDir: string,
|
||||
targetEngine?: string,
|
||||
}
|
||||
): Promise<{ dir: string, isBuilt: boolean }> => {
|
||||
return await limitedFetch(`${remotePrefix}/getPackageLocation`, {
|
||||
opts,
|
||||
packageId,
|
||||
packageName,
|
||||
}) as { dir: string, isBuilt: boolean }
|
||||
},
|
||||
importPackage: async (to: string, opts: {
|
||||
filesResponse: PackageFilesResponse,
|
||||
force: boolean,
|
||||
|
||||
@@ -103,7 +103,7 @@ export default function (
|
||||
if (pkgResponse['files']) { // tslint:disable-line
|
||||
filesPromises[body.msgId] = pkgResponse['files'] // tslint:disable-line
|
||||
}
|
||||
res.end(JSON.stringify({ inStoreLocation: pkgResponse.inStoreLocation }))
|
||||
res.end(JSON.stringify({ filesIndexFile: pkgResponse.filesIndexFile }))
|
||||
} catch (err) {
|
||||
res.end(JSON.stringify({
|
||||
error: {
|
||||
@@ -158,12 +158,6 @@ export default function (
|
||||
res.end(JSON.stringify('OK'))
|
||||
globalInfo('Server stopped')
|
||||
break
|
||||
case '/getPackageLocation': {
|
||||
const { packageId, packageName, opts } = (await bodyPromise) as any // tslint:disable-line:no-any
|
||||
const pkgLocation = await store.getPackageLocation(packageId, packageName, opts)
|
||||
res.end(JSON.stringify(pkgLocation))
|
||||
break
|
||||
}
|
||||
default:
|
||||
res.statusCode = 404
|
||||
const error = { error: `${req.url} does not match any route` }
|
||||
|
||||
@@ -103,7 +103,7 @@ test('fetchPackage', async t => {
|
||||
},
|
||||
})
|
||||
|
||||
t.equal(typeof response.inStoreLocation, 'string', 'location in store returned')
|
||||
t.equal(typeof response.filesIndexFile, 'string', 'index file location in store returned')
|
||||
|
||||
t.ok(await response.bundledManifest!())
|
||||
|
||||
@@ -116,16 +116,6 @@ test('fetchPackage', async t => {
|
||||
|
||||
t.comment('getPackageLocation()')
|
||||
|
||||
t.deepEqual(
|
||||
await storeCtrl.getPackageLocation(pkgId, 'is-positive', {
|
||||
lockfileDir: process.cwd(),
|
||||
}),
|
||||
{
|
||||
dir: path.join(storeDir, 'registry.npmjs.org/is-positive@1.0.0/node_modules/is-positive'),
|
||||
isBuilt: false,
|
||||
}
|
||||
)
|
||||
|
||||
await server.close()
|
||||
await storeCtrl.close()
|
||||
t.end()
|
||||
|
||||
@@ -29,14 +29,6 @@ export type BundledManifest = Pick<
|
||||
>
|
||||
|
||||
export interface StoreController {
|
||||
getPackageLocation (
|
||||
packageId: string,
|
||||
packageName: string,
|
||||
opts: {
|
||||
lockfileDir: string,
|
||||
targetEngine?: string,
|
||||
}
|
||||
): Promise<{ dir: string, isBuilt: boolean }>,
|
||||
requestPackage: RequestPackageFunction,
|
||||
fetchPackage: FetchPackageToStoreFunction,
|
||||
importPackage: ImportPackageFunction,
|
||||
@@ -52,7 +44,6 @@ export type FetchPackageToStoreFunction = (
|
||||
filesIndexFile: string,
|
||||
files: () => Promise<PackageFilesResponse>,
|
||||
finishing: () => Promise<void>,
|
||||
inStoreLocation: string,
|
||||
}
|
||||
|
||||
export interface FetchPackageToStoreOptions {
|
||||
@@ -118,7 +109,6 @@ export type PackageResponse = {
|
||||
normalizedPref?: string,
|
||||
updated: boolean,
|
||||
resolvedVia?: string,
|
||||
inStoreLocation?: string,
|
||||
// This is useful for recommending updates.
|
||||
// If latest does not equal the version of the
|
||||
// resolved package, it is out-of-date.
|
||||
|
||||
@@ -71,9 +71,6 @@ export interface StrictInstallOptions {
|
||||
shamefullyHoist: boolean,
|
||||
forceShamefullyHoist: boolean,
|
||||
|
||||
independentLeaves: boolean,
|
||||
forceIndependentLeaves: boolean,
|
||||
|
||||
global: boolean,
|
||||
}
|
||||
|
||||
@@ -106,7 +103,6 @@ const defaults = async (opts: InstallOptions) => {
|
||||
devDependencies: true,
|
||||
optionalDependencies: true,
|
||||
},
|
||||
independentLeaves: false,
|
||||
lockfileDir: opts.lockfileDir || opts.dir || process.cwd(),
|
||||
lockfileOnly: false,
|
||||
nodeVersion: process.version,
|
||||
|
||||
@@ -194,7 +194,6 @@ export async function mutateModules (
|
||||
hoistPattern: ctx.hoistPattern,
|
||||
ignoreScripts: opts.ignoreScripts,
|
||||
include: opts.include,
|
||||
independentLeaves: opts.independentLeaves,
|
||||
lockfileDir: ctx.lockfileDir,
|
||||
modulesDir: opts.modulesDir,
|
||||
ownLifecycleHooksStdio: opts.ownLifecycleHooksStdio,
|
||||
@@ -428,9 +427,7 @@ export async function mutateModules (
|
||||
async function isExternalLink (storeDir: string, modules: string, pkgName: string) {
|
||||
const link = await isInnerLink(modules, pkgName)
|
||||
|
||||
// checking whether the link is pointing to the store is needed
|
||||
// because packages are linked to store when independent-leaves = true
|
||||
return !link.isInner && !isSubdir(storeDir, link.target)
|
||||
return !link.isInner
|
||||
}
|
||||
|
||||
function pkgHasDependencies (manifest: ProjectManifest) {
|
||||
@@ -712,7 +709,6 @@ async function installInContext (
|
||||
hoistedModulesDir: ctx.hoistedModulesDir,
|
||||
hoistPattern: ctx.hoistPattern,
|
||||
include: opts.include,
|
||||
independentLeaves: opts.independentLeaves,
|
||||
lockfileDir: opts.lockfileDir,
|
||||
makePartialCurrentLockfile: opts.makePartialCurrentLockfile,
|
||||
outdatedDependencies,
|
||||
@@ -818,7 +814,6 @@ async function installInContext (
|
||||
hoistedAliases: result.newHoistedAliases,
|
||||
hoistPattern: ctx.hoistPattern,
|
||||
included: ctx.include,
|
||||
independentLeaves: ctx.independentLeaves,
|
||||
layoutVersion: LAYOUT_VERSION,
|
||||
packageManager: `${opts.packageManager.name}@${opts.packageManager.version}`,
|
||||
pendingBuilds: ctx.pendingBuilds,
|
||||
|
||||
@@ -64,7 +64,6 @@ export default async function linkPackages (
|
||||
hoistedModulesDir: string,
|
||||
hoistPattern?: string[],
|
||||
include: IncludedDependencies,
|
||||
independentLeaves: boolean,
|
||||
lockfileDir: string,
|
||||
makePartialCurrentLockfile: boolean,
|
||||
outdatedDependencies: {[pkgId: string]: string},
|
||||
@@ -94,7 +93,6 @@ export default async function linkPackages (
|
||||
// logger.info(`Creating dependency graph`)
|
||||
const { depGraph, projectsDirectPathsByAlias } = resolvePeers({
|
||||
dependenciesTree,
|
||||
independentLeaves: opts.independentLeaves,
|
||||
lockfileDir: opts.lockfileDir,
|
||||
projects,
|
||||
strictPeerDependencies: opts.strictPeerDependencies,
|
||||
@@ -308,15 +306,6 @@ export default async function linkPackages (
|
||||
let newHoistedAliases: Record<string, string[]> = {}
|
||||
if (opts.hoistPattern && (newDepPaths.length > 0 || removedDepPaths.size > 0)) {
|
||||
newHoistedAliases = await hoist(matcher(opts.hoistPattern!), {
|
||||
getIndependentPackageLocation: opts.independentLeaves
|
||||
? async (packageId: string, packageName: string) => {
|
||||
const { dir } = await opts.storeController.getPackageLocation(packageId, packageName, {
|
||||
lockfileDir: opts.lockfileDir,
|
||||
targetEngine: opts.sideEffectsCacheRead && ENGINE_NAME || undefined,
|
||||
})
|
||||
return dir
|
||||
}
|
||||
: undefined,
|
||||
lockfile: currentLockfile,
|
||||
lockfileDir: opts.lockfileDir,
|
||||
modulesDir: opts.hoistedModulesDir,
|
||||
@@ -501,7 +490,6 @@ async function linkAllModules (
|
||||
) {
|
||||
return Promise.all(
|
||||
depNodes
|
||||
.filter(({ independent }) => !independent)
|
||||
.map(async ({ children, optionalDependencies, name, modules }) => {
|
||||
const childrenToLink = opts.optional
|
||||
? children
|
||||
|
||||
@@ -31,9 +31,6 @@ export interface DependenciesGraphNode {
|
||||
resolution: Resolution,
|
||||
peripheralLocation: string,
|
||||
children: {[alias: string]: string},
|
||||
// an independent package is a package that
|
||||
// has neither regular nor peer dependencies
|
||||
independent: boolean,
|
||||
optionalDependencies: Set<string>,
|
||||
depth: number,
|
||||
depPath: string,
|
||||
@@ -75,7 +72,6 @@ export default function (
|
||||
id: string,
|
||||
}>,
|
||||
dependenciesTree: DependenciesTree,
|
||||
independentLeaves: boolean,
|
||||
virtualStoreDir: string,
|
||||
lockfileDir: string,
|
||||
strictPeerDependencies: boolean,
|
||||
@@ -112,7 +108,6 @@ export default function (
|
||||
resolvePeersOfChildren(directNodeIdsByAlias, pkgsByName, {
|
||||
dependenciesTree: opts.dependenciesTree,
|
||||
depGraph,
|
||||
independentLeaves: opts.independentLeaves,
|
||||
lockfileDir: opts.lockfileDir,
|
||||
pathsByNodeId,
|
||||
purePkgs: new Set(),
|
||||
@@ -149,7 +144,6 @@ function resolvePeersOfNode (
|
||||
dependenciesTree: DependenciesTree,
|
||||
pathsByNodeId: {[nodeId: string]: string},
|
||||
depGraph: DependenciesGraph,
|
||||
independentLeaves: boolean,
|
||||
virtualStoreDir: string,
|
||||
purePkgs: Set<string>, // pure packages are those that don't rely on externally resolved peers
|
||||
rootDir: string,
|
||||
@@ -216,11 +210,7 @@ function resolvePeersOfNode (
|
||||
|
||||
ctx.pathsByNodeId[nodeId] = depPath
|
||||
if (!ctx.depGraph[depPath] || ctx.depGraph[depPath].depth > node.depth) {
|
||||
const independent = ctx.independentLeaves && resolvedPackage.independent
|
||||
const centralLocation = path.join(resolvedPackage.path, 'node_modules', resolvedPackage.name)
|
||||
const peripheralLocation = !independent
|
||||
? path.join(modules, resolvedPackage.name)
|
||||
: centralLocation
|
||||
const peripheralLocation = path.join(modules, resolvedPackage.name)
|
||||
|
||||
const unknownPeers = Object.keys(unknownResolvedPeersOfChildren)
|
||||
if (unknownPeers.length) {
|
||||
@@ -244,7 +234,6 @@ function resolvePeersOfNode (
|
||||
filesIndexFile: resolvedPackage.filesIndexFile,
|
||||
hasBin: resolvedPackage.hasBin,
|
||||
hasBundledDependencies: resolvedPackage.hasBundledDependencies,
|
||||
independent,
|
||||
installable: node.installable,
|
||||
isPure,
|
||||
modules,
|
||||
@@ -270,7 +259,6 @@ function resolvePeersOfChildren (
|
||||
parentPkgs: ParentRefs,
|
||||
ctx: {
|
||||
pathsByNodeId: {[nodeId: string]: string},
|
||||
independentLeaves: boolean,
|
||||
virtualStoreDir: string,
|
||||
purePkgs: Set<string>,
|
||||
depGraph: DependenciesGraph,
|
||||
|
||||
@@ -28,9 +28,6 @@ interface StrictLinkOptions {
|
||||
|
||||
shamefullyHoist: boolean,
|
||||
forceShamefullyHoist: boolean,
|
||||
|
||||
independentLeaves: boolean,
|
||||
forceIndependentLeaves: boolean,
|
||||
}
|
||||
|
||||
export type LinkOptions = Partial<StrictLinkOptions> &
|
||||
@@ -58,7 +55,6 @@ async function defaults (opts: LinkOptions) {
|
||||
force: false,
|
||||
forceSharedLockfile: false,
|
||||
hoistPattern: undefined,
|
||||
independentLeaves: false,
|
||||
lockfileDir: opts.lockfileDir || dir,
|
||||
registries: DEFAULT_REGISTRIES,
|
||||
shamefullyHoist: false,
|
||||
|
||||
@@ -52,7 +52,7 @@ test("don't fail on non-compatible node_modules when forced in a workspace", asy
|
||||
|
||||
process.chdir('..')
|
||||
|
||||
await fs.writeFile('node_modules/.modules.yaml', `packageManager: pnpm@${3}\nstore: ${opts.storeDir}\nindependentLeaves: false\nlayoutVersion: 1`)
|
||||
await fs.writeFile('node_modules/.modules.yaml', `packageManager: pnpm@${3}\nstore: ${opts.storeDir}\nlayoutVersion: 1`)
|
||||
|
||||
await install(manifest, { ...opts, dir: path.resolve('pkg'), lockfileDir: process.cwd() })
|
||||
|
||||
@@ -108,7 +108,7 @@ test('do not fail on non-compatible store when forced during named installation'
|
||||
|
||||
async function saveModulesYaml (pnpmVersion: string, storeDir: string) {
|
||||
await fs.mkdir('node_modules')
|
||||
await fs.writeFile('node_modules/.modules.yaml', `packageManager: pnpm@${pnpmVersion}\nstoreDir: ${storeDir}\nindependentLeaves: false`)
|
||||
await fs.writeFile('node_modules/.modules.yaml', `packageManager: pnpm@${pnpmVersion}\nstoreDir: ${storeDir}`)
|
||||
}
|
||||
|
||||
test(`fail on non-compatible ${WANTED_LOCKFILE}`, async (t: tape.Test) => {
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
import { prepareEmpty } from '@pnpm/prepare'
|
||||
import { REGISTRY_MOCK_PORT } from '@pnpm/registry-mock'
|
||||
import isSubdir = require('is-subdir')
|
||||
import path = require('path')
|
||||
import resolveLinkTarget = require('resolve-link-target')
|
||||
import { addDependenciesToPackage, install } from 'supi'
|
||||
import tape = require('tape')
|
||||
import promisifyTape from 'tape-promise'
|
||||
import { testDefaults } from '../utils'
|
||||
|
||||
const test = promisifyTape(tape)
|
||||
|
||||
test('install with --independent-leaves', async (t: tape.Test) => {
|
||||
const project = prepareEmpty(t)
|
||||
const manifest = await addDependenciesToPackage({}, ['pkg-with-1-dep@100.0.0'], await testDefaults({ independentLeaves: true }))
|
||||
|
||||
await project.has('pkg-with-1-dep')
|
||||
|
||||
await install(manifest, await testDefaults({ independentLeaves: true, preferFrozenLockfile: false }))
|
||||
|
||||
t.ok(isSubdir(path.resolve('node_modules'), await resolveLinkTarget(path.resolve('node_modules/pkg-with-1-dep'))), 'non-independent package is not symlinked directly from store')
|
||||
})
|
||||
|
||||
test('--independent-leaves throws exception when executed on node_modules installed w/o the option', async (t: tape.Test) => {
|
||||
const project = prepareEmpty(t)
|
||||
const opts = await testDefaults({ independentLeaves: false })
|
||||
const manifest = await addDependenciesToPackage({}, ['is-positive'], opts)
|
||||
|
||||
try {
|
||||
await addDependenciesToPackage(manifest, ['is-negative'], {
|
||||
...opts,
|
||||
forceIndependentLeaves: true,
|
||||
independentLeaves: true,
|
||||
})
|
||||
t.fail('installation should have failed')
|
||||
} catch (err) {
|
||||
t.equal(err['code'], 'ERR_PNPM_INDEPENDENT_LEAVES_NOT_WANTED') // tslint:disable-line:no-string-literal
|
||||
t.ok(err.message.indexOf('This modules directory was created without the --independent-leaves option.') === 0)
|
||||
}
|
||||
|
||||
// Install doesn't fail if independentLeaves is not forced
|
||||
await addDependenciesToPackage(manifest, ['is-negative'], {
|
||||
...opts,
|
||||
forceIndependentLeaves: false,
|
||||
independentLeaves: true,
|
||||
})
|
||||
|
||||
await project.has('is-negative')
|
||||
})
|
||||
|
||||
test('--no-independent-leaves throws exception when executed on node_modules installed with --independent-leaves', async (t: tape.Test) => {
|
||||
prepareEmpty(t)
|
||||
const manifest = await addDependenciesToPackage({}, ['is-positive'], await testDefaults({ independentLeaves: true }))
|
||||
|
||||
try {
|
||||
await addDependenciesToPackage(manifest, ['is-negative'], await testDefaults({
|
||||
forceIndependentLeaves: true,
|
||||
independentLeaves: false,
|
||||
}))
|
||||
t.fail('installation should have failed')
|
||||
} catch (err) {
|
||||
t.equal(err['code'], 'ERR_PNPM_INDEPENDENT_LEAVES_WANTED') // tslint:disable-line:no-string-literal
|
||||
t.ok(err.message.indexOf('This modules directory was created using the --independent-leaves option.') === 0)
|
||||
}
|
||||
})
|
||||
|
||||
// Covers https://github.com/pnpm/pnpm/issues/1547
|
||||
test('installing with independent-leaves and hoistPattern', async (t) => {
|
||||
const project = prepareEmpty(t)
|
||||
await addDependenciesToPackage({}, ['pkg-with-1-dep@100.0.0'], await testDefaults({
|
||||
hoistPattern: '*',
|
||||
independentLeaves: true,
|
||||
}))
|
||||
|
||||
await project.has('pkg-with-1-dep')
|
||||
await project.has('.pnpm/node_modules/dep-of-pkg-with-1-dep')
|
||||
|
||||
// wrappy is linked directly from the store
|
||||
await project.hasNot(`.pnpm/dep-of-pkg-with-1-dep@100.0.0`)
|
||||
await project.storeHas('dep-of-pkg-with-1-dep', '100.0.0')
|
||||
|
||||
await project.has(`.pnpm/pkg-with-1-dep@100.0.0`)
|
||||
})
|
||||
@@ -6,7 +6,6 @@ import './fromTarball'
|
||||
import './frozenLockfile'
|
||||
import './hoist'
|
||||
import './hooks'
|
||||
import './independentLeaves'
|
||||
import './installationChecks'
|
||||
import './lifecycleScripts'
|
||||
import './local'
|
||||
|
||||
@@ -282,28 +282,3 @@ test("don't unlink package that is not a link", async (t: tape.Test) => {
|
||||
message: 'is-positive is not an external link',
|
||||
}), 'reported warning')
|
||||
})
|
||||
|
||||
test("don't unlink package that is not a link when independent-leaves = true", async (t: tape.Test) => {
|
||||
prepareEmpty(t)
|
||||
|
||||
const reporter = sinon.spy()
|
||||
|
||||
const manifest = await addDependenciesToPackage({}, ['is-positive'], await testDefaults({ independentLeaves: true }))
|
||||
|
||||
await mutateModules(
|
||||
[
|
||||
{
|
||||
dependencyNames: ['is-positive'],
|
||||
manifest,
|
||||
mutation: 'unlinkSome',
|
||||
rootDir: process.cwd(),
|
||||
},
|
||||
],
|
||||
await testDefaults({ independentLeaves: true, reporter })
|
||||
)
|
||||
|
||||
t.ok(reporter.calledWithMatch({
|
||||
level: 'warn',
|
||||
message: 'is-positive is not an external link',
|
||||
}), 'reported warning')
|
||||
})
|
||||
|
||||
5
pnpm-lock.yaml
generated
5
pnpm-lock.yaml
generated
@@ -1300,7 +1300,6 @@ importers:
|
||||
'@pnpm/core-loggers': 'link:../core-loggers'
|
||||
'@pnpm/fetcher-base': 'link:../fetcher-base'
|
||||
'@pnpm/package-requester': 'link:../package-requester'
|
||||
'@pnpm/pkgid-to-filename': 3.0.0
|
||||
'@pnpm/resolver-base': 'link:../resolver-base'
|
||||
'@pnpm/store-controller-types': 'link:../store-controller-types'
|
||||
'@pnpm/types': 'link:../types'
|
||||
@@ -1337,7 +1336,6 @@ importers:
|
||||
'@pnpm/npm-resolver': 'workspace:*'
|
||||
'@pnpm/package-requester': 'workspace:12.0.0-alpha.5'
|
||||
'@pnpm/package-store': 'link:'
|
||||
'@pnpm/pkgid-to-filename': 3.0.0
|
||||
'@pnpm/resolver-base': 'workspace:7.0.1-alpha.0'
|
||||
'@pnpm/store-controller-types': 'workspace:8.0.0-alpha.4'
|
||||
'@pnpm/tarball-fetcher': 'workspace:*'
|
||||
@@ -3862,7 +3860,6 @@ packages:
|
||||
dependencies:
|
||||
async-retry: 1.3.1
|
||||
debug: 3.2.6
|
||||
node-fetch: 2.6.0
|
||||
dev: false
|
||||
peerDependencies:
|
||||
node-fetch: '*'
|
||||
@@ -11928,7 +11925,6 @@ packages:
|
||||
diff: 4.0.2
|
||||
make-error: 1.3.6
|
||||
source-map-support: 0.5.19
|
||||
typescript: 3.9.3
|
||||
yn: 3.1.1
|
||||
dev: true
|
||||
engines:
|
||||
@@ -11978,7 +11974,6 @@ packages:
|
||||
semver: 5.7.1
|
||||
tslib: 1.13.0
|
||||
tsutils: 2.29.0_typescript@3.9.3
|
||||
typescript: 3.9.3
|
||||
deprecated: 'TSLint has been deprecated in favor of ESLint. Please see https://github.com/palantir/tslint/issues/4534 for more information.'
|
||||
dev: true
|
||||
engines:
|
||||
|
||||
Reference in New Issue
Block a user