diff --git a/packages/shrinkwrap/src/prune.ts b/packages/shrinkwrap/src/prune.ts index a05a091308..fea785cbd1 100644 --- a/packages/shrinkwrap/src/prune.ts +++ b/packages/shrinkwrap/src/prune.ts @@ -72,7 +72,12 @@ export function prune ( }) if (importer.dependencies) { for (const dep of R.keys(importer.dependencies)) { - if (!shrDependencies[dep] && importer.dependencies[dep].startsWith('link:')) { + if ( + !shrDependencies[dep] && importer.dependencies[dep].startsWith('link:') && + // If the linked dependency was removed from package.json + // then it is removed from shrinkwrap.yaml as well + !(shrSpecs[dep] && !allDeps[dep]) + ) { shrDependencies[dep] = importer.dependencies[dep] } } diff --git a/packages/shrinkwrap/test/prune.ts b/packages/shrinkwrap/test/prune.ts index 077cc08d61..df02cf3251 100644 --- a/packages/shrinkwrap/test/prune.ts +++ b/packages/shrinkwrap/test/prune.ts @@ -71,6 +71,38 @@ test('remove one redundant package', t => { t.end() }) +test('remove redundant linked package', t => { + t.deepEqual(prune({ + shrinkwrapVersion: 3, + registry: 'https://registry.npmjs.org', + importers: { + '.': { + dependencies: { + 'is-positive': 'link:../is-positive' + }, + specifiers: { + 'is-positive': '^1.0.0' + }, + }, + }, + packages: {}, + }, { + name: 'foo', + version: '1.0.0', + dependencies: {} + }, '.', DEFAULT_OPTS), { + shrinkwrapVersion: 3, + registry: 'https://registry.npmjs.org', + importers: { + '.': { + specifiers: {}, + }, + }, + }) + + t.end() +}) + test('keep all', t => { t.deepEqual(prune({ shrinkwrapVersion: 3, diff --git a/packages/supi/test/uninstall.ts b/packages/supi/test/uninstall.ts index e57430fc38..5cf6487424 100644 --- a/packages/supi/test/uninstall.ts +++ b/packages/supi/test/uninstall.ts @@ -190,6 +190,7 @@ test('uninstalling a dependency from package that uses shared shrinkwrap', async version: '1.0.0', dependencies: { 'is-positive': '1.0.0', + 'project-2': '1.0.0', }, }, { @@ -210,12 +211,28 @@ test('uninstalling a dependency from package that uses shared shrinkwrap', async }, ] - await install(await testDefaults({ importers })) + await install(await testDefaults({ + importers, + localPackages: { + 'project-2': { + '1.0.0': { + directory: path.resolve('project-2'), + package: { + name: 'project-2', + version: '1.0.0', + dependencies: { + 'is-negative': '1.0.0', + }, + }, + }, + }, + }, + })) await projects['project-1'].has('is-positive') await projects['project-2'].has('is-negative') - await uninstall(['is-positive'], await testDefaults({ + await uninstall(['is-positive', 'project-2'], await testDefaults({ prefix: importers[0].prefix, shrinkwrapDirectory: process.cwd(), }))