fix(shrinkwrap): don't save absolute path shrinkwrap.yaml

Relative path to the current working directory is saved
in the `shrinkwrap.yaml`.

Close #744
This commit is contained in:
zkochan
2017-05-13 00:07:36 +03:00
committed by Zoltan Kochan
parent 177ad66842
commit c4e2540dd2
9 changed files with 63 additions and 26 deletions

View File

@@ -224,6 +224,8 @@ async function installInContext (
nodeModules: nodeModulesPath,
update: opts.update,
keypath: [],
referencedFrom: opts.prefix,
prefix: opts.prefix,
}
const nonLinkedPkgs = await pFilter(packagesToInstall, (spec: PackageSpec) => !spec.name || safeIsInnerLink(nodeModulesPath, spec.name))
const pkgs: InstalledPackage[] = await installMultiple(

View File

@@ -0,0 +1,8 @@
import path = require('path')
import normalize = require('normalize-path')
export default function pkgIdToFilename (pkgId: string) {
if (pkgId.indexOf('file:') !== 0) return pkgId
return `local/${encodeURIComponent(normalize(path.resolve(pkgId.slice(5))))}`
}

View File

@@ -9,6 +9,7 @@ import resolve, {
PackageMeta,
} from '../resolve'
import mkdirp = require('mkdirp-promise')
import pkgIdToFilename from '../fs/pkgIdToFilename'
import readPkg from '../fs/readPkg'
import exists = require('path-exists')
import memoize, {MemoizedFunc} from '../memoize'
@@ -33,7 +34,7 @@ export type FetchedPackage = {
export default async function fetch (
spec: PackageSpec,
options: {
root: string,
prefix: string,
storePath: string,
localRegistry: string,
registry: string,
@@ -54,7 +55,7 @@ export default async function fetch (
if (!resolution || options.update) {
const resolveResult = await resolve(spec, {
loggedPkg: options.loggedPkg,
root: options.root,
prefix: options.prefix,
got: options.got,
localRegistry: options.localRegistry,
registry: options.registry,
@@ -75,7 +76,7 @@ export default async function fetch (
logStatus({status: 'resolved', pkgId: id, pkg: options.loggedPkg})
const target = path.join(options.storePath, id)
const target = path.join(options.storePath, pkgIdToFilename(id))
const fetchingFiles = options.fetchingLocker(id, () => fetchToStore({
target,
@@ -97,7 +98,7 @@ export default async function fetch (
resolution,
path: target,
srcPath: resolution.type == 'directory'
? resolution.root
? path.join(options.prefix, resolution.root)
: undefined,
abort: async () => {
try {

View File

@@ -44,7 +44,8 @@ export default async function installMultiple (
specs: PackageSpec[],
options: {
force: boolean,
root: string,
prefix: string,
referencedFrom: string,
storePath: string,
localRegistry: string,
registry: string,
@@ -125,7 +126,8 @@ async function install (
ctx: InstallContext,
options: {
force: boolean,
root: string,
prefix: string,
referencedFrom: string,
storePath: string,
localRegistry: string,
registry: string,
@@ -170,7 +172,7 @@ async function install (
update: options.update,
fetchingLocker: ctx.fetchingLocker,
registry,
root: options.root,
prefix: options.prefix,
storePath: options.storePath,
localRegistry: options.localRegistry,
metaCache: options.metaCache,
@@ -202,7 +204,7 @@ async function install (
fetchedPkg.id,
ctx,
Object.assign({}, options, {
root: fetchedPkg.srcPath,
referencedFrom: fetchedPkg.srcPath,
isInstallable,
})
)
@@ -304,7 +306,8 @@ async function installDependencies (
ctx: InstallContext,
opts: {
force: boolean,
root: string,
prefix: string,
referencedFrom: string,
storePath: string,
localRegistry: string,
registry: string,
@@ -331,7 +334,7 @@ async function installDependencies (
const deps = depsToSpecs(
filterDeps(Object.assign({}, pkg.optionalDependencies, pkg.dependencies)),
{
where: opts.root,
where: opts.referencedFrom,
devDependencies: pkg.devDependencies || {},
optionalDependencies: pkg.optionalDependencies || {},
}

View File

@@ -12,6 +12,7 @@ import linkBins from './linkBins'
import {Package, Dependencies} from '../types'
import resolvePeers, {DependencyTreeNode, DependencyTreeNodeMap} from './resolvePeers'
import logStatus from '../logging/logInstallStatus'
import pkgIdToFilename from '../fs/pkgIdToFilename'
export type LinkedPackage = {
id: string,
@@ -49,7 +50,7 @@ export default async function (
peerDependencies: installedPkg.pkg.peerDependencies || {},
hasBundledDependencies: !!(installedPkg.pkg.bundledDependencies || installedPkg.pkg.bundleDependencies),
fetchingFiles: installedPkg.fetchingFiles,
localLocation: path.join(opts.baseNodeModules, `.${installedPkg.id}`),
localLocation: path.join(opts.baseNodeModules, `.${pkgIdToFilename(installedPkg.id)}`),
path: installedPkg.path,
dependencies: installedPkg.dependencies,
}

View File

@@ -92,7 +92,7 @@ export type ResolveOptions = {
localRegistry: string,
registry: string,
metaCache: Map<string, PackageMeta>,
root: string,
prefix: string,
offline: boolean,
}

View File

@@ -1,5 +1,4 @@
import {resolve} from 'path'
import * as path from 'path'
import path = require('path')
import readPkg from '../fs/readPkg'
import {
PackageSpec,
@@ -9,19 +8,21 @@ import {
ResolveResult,
} from '.'
import fs = require('mz/fs')
import normalize = require('normalize-path')
/**
* Resolves a package hosted on the local filesystem
*/
export default async function resolveLocal (spec: PackageSpec, opts: ResolveOptions): Promise<ResolveResult> {
const dependencyPath = resolve(opts.root, spec.fetchSpec)
const dependencyPath = normalize(path.relative(opts.prefix, spec.fetchSpec))
const id = `file:${dependencyPath}`
if (spec.type === 'file') {
const resolution: TarballResolution = {
tarball: `file:${dependencyPath}`,
tarball: id,
}
return {
id: createLocalPkgId(dependencyPath),
id,
resolution,
}
}
@@ -32,11 +33,7 @@ export default async function resolveLocal (spec: PackageSpec, opts: ResolveOpti
root: dependencyPath,
}
return {
id: createLocalPkgId(dependencyPath),
id,
resolution,
}
}
function createLocalPkgId (dependencyPath: string): string {
return 'local/' + encodeURIComponent(dependencyPath)
}

View File

@@ -2,6 +2,9 @@ import tape = require('tape')
import promisifyTape from 'tape-promise'
import normalizePath = require('normalize-path')
import readPkg = require('read-pkg')
import ncpCB = require('ncp')
import thenify = require('thenify')
import path = require('path')
import {install, installPkgs} from '../../src'
import {
prepare,
@@ -10,9 +13,10 @@ import {
local,
} from '../utils'
const ncp = thenify(ncpCB.ncp)
const test = promisifyTape(tape)
test('scoped modules from a directory', async function (t) {
test('scoped modules from a directory', async function (t: tape.Test) {
const project = prepare(t)
await installPkgs([local('local-scoped-pkg')], testDefaults())
@@ -21,13 +25,33 @@ test('scoped modules from a directory', async function (t) {
t.equal(m(), '@scope/local-scoped-pkg', 'localScopedPkg() is available')
})
test('local file', async function (t) {
test('local file', async function (t: tape.Test) {
const project = prepare(t)
await installPkgs([local('local-pkg')], testDefaults())
await ncp(pathToLocalPkg('local-pkg'), path.resolve('..', 'local-pkg'))
await installPkgs(['file:../local-pkg'], testDefaults())
const m = project.requireModule('local-pkg')
t.ok(m, 'localPkg() is available')
const shr = await project.loadShrinkwrap()
t.deepEqual(shr, {
dependencies: {
[`local-pkg@file:..${path.sep}local-pkg`]: 'file:../local-pkg',
},
packages: {
'file:../local-pkg': {
resolution: {
root: '../local-pkg',
type: 'directory',
},
},
},
registry: 'http://localhost:4873/',
version: 2,
})
})
test('package with a broken symlink', async function (t) {
@@ -39,7 +63,7 @@ test('package with a broken symlink', async function (t) {
t.ok(m, 'has-broken-symlink is available')
})
test('nested local dependency of a local dependency', async function (t) {
test('nested local dependency of a local dependency', async function (t: tape.Test) {
const project = prepare(t)
await installPkgs([local('pkg-with-local-dep')], testDefaults())

View File

@@ -52,6 +52,7 @@
"src/fs/getPkgDirs.ts",
"src/fs/gracefulify.ts",
"src/fs/modulesController.ts",
"src/fs/pkgIdToFilename.ts",
"src/fs/readPkg.ts",
"src/fs/safeReadPkg.ts",
"src/fs/shrinkwrap.ts",