From 4b02b85f0a47cccec46eb22c2b961390dc28dea0 Mon Sep 17 00:00:00 2001 From: zkochan Date: Sat, 18 Mar 2017 14:50:08 +0200 Subject: [PATCH] feat: when resolution only a shasum, fold the property Close #664, PR #666 --- src/fs/shrinkwrap.ts | 5 +- src/install/fetch.ts | 4 -- src/install/installMultiple.ts | 88 ++++++++++++++++++++++++++-------- 3 files changed, 72 insertions(+), 25 deletions(-) diff --git a/src/fs/shrinkwrap.ts b/src/fs/shrinkwrap.ts index 3229eeb94d..426a5d70b8 100644 --- a/src/fs/shrinkwrap.ts +++ b/src/fs/shrinkwrap.ts @@ -36,8 +36,8 @@ export type ResolvedPackages = { [pkgId: string]: DependencyShrinkwrap, } -export type DependencyShrinkwrap = { - resolution: Resolution, +export type DependencyShrinkwrap = string | { + resolution: string | Resolution, dependencies?: ResolvedDependencies, } @@ -153,6 +153,7 @@ function copyDependencyTree (shr: Shrinkwrap, registry: string): ResolvedPackage } const depShr = shr.packages[pkgId] resolvedPackages[pkgId] = depShr + if (typeof depShr === 'string') continue const newDependencies = R.keys(depShr.dependencies) .map((pkgName: string) => getPkgShortId((depShr.dependencies && depShr.dependencies[pkgName]), pkgName)) .filter((newPkgId: string) => !resolvedPackages[newPkgId] && pkgIds.indexOf(newPkgId) === -1) diff --git a/src/install/fetch.ts b/src/install/fetch.ts index 63daffde98..43eae904e8 100644 --- a/src/install/fetch.ts +++ b/src/install/fetch.ts @@ -9,7 +9,6 @@ import resolve, { PackageMeta, } from '../resolve' import mkdirp = require('mkdirp-promise') -import getNpmTarballUrl from 'get-npm-tarball-url' import readPkg from '../fs/readPkg' import exists = require('path-exists') import memoize, {MemoizedFunc} from '../memoize' @@ -72,9 +71,6 @@ export default async function fetch ( if (resolveResult.package) { fetchingPkg = Promise.resolve(resolveResult.package) } - } else if (resolution.type === undefined && resolution.tarball === undefined) { - const parts = pkgId!.split('/') - resolution.tarball = getNpmTarballUrl(parts[1], parts[2], {registry: options.registry}) } const id = pkgId diff --git a/src/install/installMultiple.ts b/src/install/installMultiple.ts index a7b7f8754a..71b139fb79 100644 --- a/src/install/installMultiple.ts +++ b/src/install/installMultiple.ts @@ -2,6 +2,7 @@ import path = require('path') import logger from 'pnpm-logger' import pFilter = require('p-filter') import R = require('ramda') +import getNpmTarballUrl from 'get-npm-tarball-url' import fetch, {FetchedPackage} from './fetch' import {InstallContext, InstalledPackages} from '../api/install' import {Dependencies} from '../types' @@ -125,7 +126,10 @@ async function installMultiple ( try { const pkg = await install(spec, ctx, Object.assign({}, options, { pkgId, - dependencyShrinkwrap, + resolvedDependencies: dependencyShrinkwrap && dependencyShrinkwrap['dependencies'], + shrinkwrapResolution: pkgShortId && dependencyShrinkwrap + ? dependencyShrToResolution(pkgShortId, dependencyShrinkwrap, options.registry) + : undefined, })) if (options.keypath && options.keypath.indexOf(pkg.id) !== -1) { return null @@ -149,6 +153,36 @@ async function installMultiple ( return installedPkgs } +function dependencyShrToResolution ( + pkgShortId: string, + depShr: DependencyShrinkwrap, + registry: string +): Resolution { + if (typeof depShr === 'string') { + return { + shasum: depShr, + tarball: getTarball() + } + } + if (typeof depShr.resolution === 'string') { + return { + shasum: depShr.resolution, + tarball: getTarball(), + } + } + if (!depShr.resolution.type && !depShr.resolution.tarball) { + return Object.assign({}, depShr.resolution, { + tarball: getTarball() + }) + } + return depShr.resolution + + function getTarball () { + const parts = pkgShortId.split('/') + return getNpmTarballUrl(parts[1], parts[2], {registry}) + } +} + async function isInnerLink (modules: string, depName: string) { let linkTarget: string try { @@ -179,7 +213,8 @@ async function install ( got: Got, keypath: string[], pkgId?: string, - dependencyShrinkwrap?: DependencyShrinkwrap, + shrinkwrapResolution?: Resolution, + resolvedDependencies: ResolvedDependencies, optional: boolean, depth: number, engineStrict: boolean, @@ -206,7 +241,6 @@ async function install ( const fetchedPkg = await fetch(spec, Object.assign({}, options, { loggedPkg, update, - shrinkwrapResolution: options.dependencyShrinkwrap && options.dependencyShrinkwrap.resolution, fetchingLocker: ctx.fetchingLocker, registry, })) @@ -215,13 +249,6 @@ async function install ( return fetchedPkg } - const shortId = pkgShortId(fetchedPkg.id, ctx.shrinkwrap.registry) - ctx.shrinkwrap.packages[shortId] = ctx.shrinkwrap.packages[shortId] || {} - ctx.shrinkwrap.packages[shortId].resolution = Object.assign({}, fetchedPkg.resolution) - if (shortId.startsWith('/') && ctx.shrinkwrap.packages[shortId].resolution.type === undefined) { - delete ctx.shrinkwrap.packages[shortId].resolution['tarball'] - } - const pkg = await fetchedPkg.fetchingPkg if (!options.force) { @@ -268,16 +295,10 @@ async function install ( dependency, ctx, modules, - Object.assign({}, options, { - resolvedDependencies: options.dependencyShrinkwrap && options.dependencyShrinkwrap.dependencies - }) + options ) - if (dependencies.length) { - ctx.shrinkwrap.packages[shortId].dependencies = dependencies - .reduce((resolutions, dep) => Object.assign(resolutions, { - [dep.pkg.name]: pkgIdToRef(dep.id, dep.pkg.version, dep.resolution, ctx.shrinkwrap.registry) - }), {}) - } + const shortId = pkgShortId(fetchedPkg.id, ctx.shrinkwrap.registry) + ctx.shrinkwrap.packages[shortId] = toShrDependency(shortId, fetchedPkg.resolution, dependencies, ctx.shrinkwrap.registry) await linking @@ -301,6 +322,35 @@ async function install ( return dependency } +function toShrDependency ( + shortId: string, + resolution: Resolution, + deps: InstalledPackage[], + registry: string +): DependencyShrinkwrap { + const shrResolution = toShrResolution(shortId, resolution) + if (deps.length) { + return { + resolution: shrResolution, + dependencies: deps + .reduce((resolutions, dep) => Object.assign(resolutions, { + [dep.pkg.name]: pkgIdToRef(dep.id, dep.pkg.version, dep.resolution, registry) + }), {}) + } + } + if (typeof shrResolution === 'string') return shrResolution + return { + resolution: shrResolution + } +} + +function toShrResolution (shortId: string, resolution: Resolution): string | Resolution { + if (shortId.startsWith('/') && resolution.type === undefined && resolution.shasum) { + return resolution.shasum + } + return resolution +} + async function isSameFile (file1: string, file2: string) { const stats = await Promise.all([fs.stat(file1), fs.stat(file2)]) return stats[0].ino === stats[1].ino