diff --git a/src/io.ts b/src/io.ts index 7a94f83af2..c9ddd26a5a 100644 --- a/src/io.ts +++ b/src/io.ts @@ -99,7 +99,7 @@ export function save (pkgPath: string, shrinkwrap: Shrinkwrap) { const privateShrinkwrapPath = path.join(pkgPath, PRIVATE_SHRINKWRAP_FILENAME) // empty shrinkwrap is not saved - if (Object.keys(shrinkwrap.dependencies).length === 0) { + if (Object.keys(shrinkwrap.specifiers).length === 0) { return Promise.all([ rimraf(shrinkwrapPath), rimraf(privateShrinkwrapPath), diff --git a/src/prune.ts b/src/prune.ts index d2a7b4a99c..68d7290ae2 100644 --- a/src/prune.ts +++ b/src/prune.ts @@ -15,25 +15,6 @@ export default function prune (shr: Shrinkwrap, pkg: Package): Shrinkwrap { const dependencies = R.difference(R.keys(pkg.dependencies), optionalDependencies) const devDependencies = R.difference(R.difference(R.keys(pkg.devDependencies), optionalDependencies), dependencies) - if (shr.optionalDependencies) { - let optionalPkgIds: string[] = R.keys(shr.optionalDependencies) - .map((pkgName: string) => getPkgShortId(shr!.optionalDependencies![pkgName], pkgName)) - copyDependencySubTree(packages, optionalPkgIds, shr, [], {registry: shr.registry, optional: true}) - } - - if (shr.devDependencies) { - let devPkgIds: string[] = R.keys(shr.devDependencies) - .map((pkgName: string) => getPkgShortId(shr!.devDependencies![pkgName], pkgName)) - copyDependencySubTree(packages, devPkgIds, shr, [], {registry: shr.registry, dev: true}) - } - - let pkgIds: string[] = dependencies - .map((pkgName: string) => getPkgShortId(shr.dependencies[pkgName], pkgName)) - - copyDependencySubTree(packages, pkgIds, shr, [], { - registry: shr.registry, - }) - const allDeps = R.reduce(R.union, [], [optionalDependencies, devDependencies, dependencies]) const specifiers: ResolvedDependencies = {} const shrDependencies: ResolvedDependencies = {} @@ -52,6 +33,25 @@ export default function prune (shr: Shrinkwrap, pkg: Package): Shrinkwrap { } }) + if (shrOptionalDependencies) { + let optionalPkgIds: string[] = R.keys(shrOptionalDependencies) + .map((pkgName: string) => getPkgShortId(shrOptionalDependencies[pkgName], pkgName)) + copyDependencySubTree(packages, optionalPkgIds, shr, [], {registry: shr.registry, optional: true}) + } + + if (shrDevDependencies) { + let devPkgIds: string[] = R.keys(shrDevDependencies) + .map((pkgName: string) => getPkgShortId(shrDevDependencies[pkgName], pkgName)) + copyDependencySubTree(packages, devPkgIds, shr, [], {registry: shr.registry, dev: true}) + } + + let pkgIds: string[] = dependencies + .map((pkgName: string) => getPkgShortId(shrDependencies[pkgName], pkgName)) + + copyDependencySubTree(packages, pkgIds, shr, [], { + registry: shr.registry, + }) + const result = { version: SHRINKWRAP_VERSION, specifiers, @@ -70,28 +70,6 @@ export default function prune (shr: Shrinkwrap, pkg: Package): Shrinkwrap { return result } -function copyDependencyTree ( - resolvedPackages: ResolvedPackages, - shr: Shrinkwrap, - opts: { - registry: string, - dependencies: string[], - dev?: boolean, - optional?: boolean, - } -) { - let pkgIds: string[] = opts.dependencies - .map((pkgName: string) => getPkgShortId(shr.dependencies[pkgName], pkgName)) - - copyDependencySubTree(resolvedPackages, pkgIds, shr, [], opts) - - if (shr.optionalDependencies) { - let optionalPkgIds: string[] = R.keys(shr.optionalDependencies) - .map((pkgName: string) => getPkgShortId(shr!.optionalDependencies![pkgName], pkgName)) - copyDependencySubTree(resolvedPackages, optionalPkgIds, shr, [], Object.assign({}, opts, {optional: true})) - } -} - function copyDependencySubTree ( resolvedPackages: ResolvedPackages, pkgIds: string[], diff --git a/test/prune.ts b/test/prune.ts index 3334192e72..f396952aae 100644 --- a/test/prune.ts +++ b/test/prune.ts @@ -398,3 +398,52 @@ test('dev dependency should not have dev = true if it is used not only as dev', t.end() }) + +test('remove dependencies that are not in the package', t => { + t.deepEqual(prune({ + version: 3, + registry: 'https://registry.npmjs.org', + dependencies: { + 'is-positive': '1.0.0' + }, + devDependencies: { + 'is-negative': '1.0.0' + }, + optionalDependencies: { + 'fsevents': '1.0.0' + }, + specifiers: { + 'is-positive': '^1.0.0', + 'is-negative': '^1.0.0', + 'fsevents': '^1.0.0', + }, + packages: { + '/is-positive/1.0.0': { + resolution: { + integrity: 'sha1-ChbBDewTLAqLCzb793Fo5VDvg/g=' + } + }, + '/is-negative/1.0.0': { + resolution: { + integrity: 'sha1-ChbBDewTLAqLCzb793Fo5VDvg/g=' + } + }, + '/fsevents/1.0.0': { + resolution: { + integrity: 'sha1-ChbBDewTLAqLCzb793Fo5VDvg/g=' + } + }, + } + }, { + name: 'foo', + version: '1.0.0', + }), { + version: 3, + registry: 'https://registry.npmjs.org', + dependencies: {}, + specifiers: {}, + packages: {} + }) + + t.end() +})