Skip to content

Commit

Permalink
Use package root document
Browse files Browse the repository at this point in the history
  • Loading branch information
alexanderGugel committed Aug 12, 2016
1 parent 73fd37c commit 3544041
Show file tree
Hide file tree
Showing 6 changed files with 167 additions and 201 deletions.
85 changes: 8 additions & 77 deletions src/install.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {_catch} from 'rxjs/operator/catch'
import {mergeMap} from 'rxjs/operator/mergeMap'
import {retry} from 'rxjs/operator/retry'
import {skip} from 'rxjs/operator/skip'
import {satisfies} from 'semver'
import needle from 'needle'
import assert from 'assert'
import npa from 'npm-package-arg'
Expand All @@ -22,6 +21,7 @@ import memoize from 'lodash.memoize'
import * as cache from './cache'
import * as config from './config'
import * as registry from './registry'
import * as local from './local'
import * as git from './git'
import * as util from './util'
import * as progress from './progress'
Expand Down Expand Up @@ -55,60 +55,6 @@ export const DEPENDENCY_FIELDS = [
'optionalDependencies'
]

/**
* error class used for representing an error that occurs due to a lifecycle
* script that exits with a non-zero status code.
*/
export class LocalConflictError extends Error {
/**
* create instance.
* @param {String} name - name of the dependency.
* @param {String} version - local version.
* @param {String} expected - expected version.
*/
constructor (name, version, expected) {
super(`Local version ${name}@${version} does not match required version @${expected}`)
this.name = 'LocalConflictError'
}
}

/**
* resolve a dependency's `package.json` file from the local file system.
* @param {String} nodeModules - `node_modules` base directory.
* @param {String} parentTarget - relative parent's node_modules path.
* @param {String} name - name of the dependency.
* @param {String} version - version of the dependency.
* @param {Boolean} isExplicit - whether the install command asks for an explicit install.
* @return {Observable} - observable sequence of `package.json` objects.
*/
export function resolveLocal (nodeModules, parentTarget, name, version, isExplicit) {
const linkname = path.join(nodeModules, parentTarget, 'node_modules', name)
const mockFetch = () => EmptyObservable.create()
log(`resolving ${linkname} from node_modules`)

// support `file:` with symlinks
if (version.substr(0, 5) === 'file:') {
log(`resolved ${name}@${version} as local symlink`)
const isScoped = name.charAt(0) === '@'
const src = path.join(parentTarget, isScoped ? '..' : '', version.substr(5))
const dst = path.join('node_modules', parentTarget, 'node_modules', name)
return util.forceSymlink(src, dst)::_finally(progress.complete)
}

return util.readlink(linkname)::mergeMap((rel) => {
const target = path.basename(path.dirname(rel))
const filename = path.join(linkname, 'package.json')
log(`reading package.json from ${filename}`)

return util.readFileJSON(filename)::map((pkgJson) => {
if (isExplicit && !satisfies(pkgJson.version, version)) {
throw new LocalConflictError(name, pkgJson.version, version)
}
return {parentTarget, pkgJson, target, name, fetch: mockFetch}
})
})
}

/**
* resolve a dependency's `package.json` file from a remote registry.
* @param {String} nodeModules - `node_modules` base directory.
Expand All @@ -127,7 +73,10 @@ export function resolveRemote (nodeModules, parentTarget, name, version) {
case 'range':
case 'version':
case 'tag':
return resolveFromNpm(nodeModules, parentTarget, parsedSpec)
return registry.resolve(nodeModules, parentTarget, name, version, {
...config.httpOptions,
registry: config.registry
})
case 'remote':
return resolveFromTarball(nodeModules, parentTarget, parsedSpec)
case 'hosted':
Expand All @@ -139,24 +88,6 @@ export function resolveRemote (nodeModules, parentTarget, name, version) {
}
}

/**
* resolve a dependency's `package.json` file from the npm registry.
* @param {String} nodeModules - `node_modules` base directory.
* @param {String} parentTarget - relative parent's node_modules path.
* @param {Object} parsedSpec - parsed package name and specifier.
* @return {Observable} - observable sequence of `package.json` objects.
*/
export function resolveFromNpm (nodeModules, parentTarget, parsedSpec) {
const {raw, name, type, spec} = parsedSpec
log(`resolving ${raw} from npm`)
const options = {...config.httpOptions, retries: config.retries}
return registry.match(name, spec, options)::map((pkgJson) => {
const target = pkgJson.dist.shasum
log(`resolved ${raw} to tarball shasum ${target} from npm`)
return {parentTarget, pkgJson, target, name, type, fetch}
})
}

/**
* resolve a dependency's `package.json` file from an url tarball.
* @param {String} nodeModules - `node_modules` base directory.
Expand Down Expand Up @@ -211,7 +142,7 @@ export function resolveFromHosted (nodeModules, parentTarget, parsedSpec) {
throw new Error(`Unknown hosted type: ${hosted.type} for ${name}`)
}

return registry.fetch(hosted.directUrl, options)
return registry.getJson(hosted.directUrl, options)
::map(({body}) => JSON.parse(body))
::map(pkgJson => {
pkgJson.dist = {tarball, shasum} // eslint-disable-line no-param-reassign
Expand Down Expand Up @@ -269,7 +200,7 @@ export function resolve (nodeModules, parentTarget, isExplicit) {
progress.report(`resolving ${name}@${version}`)
log(`resolving ${name}@${version}`)

return resolveLocal(nodeModules, parentTarget, name, version, isExplicit)
return local.resolve(nodeModules, parentTarget, name, version, isExplicit)
::_catch((error) => {
if (error.name !== 'LocalConflictError' && error.code !== 'ENOENT') {
throw error
Expand Down Expand Up @@ -406,7 +337,7 @@ function fixPermissions (target, bin) {
::mergeMap((filepath) => util.chmod(filepath, execMode))
}

function fetch (nodeModules) {
export function fetch (nodeModules) {
const {target, type, pkgJson: {name, bin, dist: {tarball, shasum}}} = this
const where = path.join(nodeModules, target, 'package')

Expand Down
46 changes: 46 additions & 0 deletions src/local.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import path from 'path'
import {EmptyObservable} from 'rxjs/observable/EmptyObservable'
import {_finally} from 'rxjs/operator/finally'
import {map} from 'rxjs/operator/map'
import {mergeMap} from 'rxjs/operator/mergeMap'
import {satisfies} from 'semver'
import {inherits} from 'util'

import * as util from './util'
import * as progress from './progress'

// thrown when the currently installed version does not satisfy the semantic
// version constraint.
inherits(LocalConflictError, Error)
function LocalConflictError (name, version, expected) {
Error.captureStackTrace(this, this.constructor)
this.name = 'LocalConflictError'
this.message = `Local version ${name}@${version} does not match required version @${expected}`
this.extra = {name, version, expected}
}

export const fetch = () => EmptyObservable.create()

export const resolve = (nodeModules, parentTarget, name, version, isExplicit) => {
const linkname = path.join(nodeModules, parentTarget, 'node_modules', name)

// support `file:` with symlinks
if (version.substr(0, 5) === 'file:') {
const isScoped = name.charAt(0) === '@'
const src = path.join(parentTarget, isScoped ? '..' : '', version.substr(5))
const dst = path.join('node_modules', parentTarget, 'node_modules', name)
return util.forceSymlink(src, dst)::_finally(progress.complete)
}

return util.readlink(linkname)::mergeMap((rel) => {
const target = path.basename(path.dirname(rel))
const filename = path.join(linkname, 'package.json')

return util.readFileJSON(filename)::map((pkgJson) => {
if (isExplicit && !satisfies(pkgJson.version, version)) {
throw new LocalConflictError(name, pkgJson.version, version)
}
return {parentTarget, pkgJson, target, name, fetch}
})
})
}
4 changes: 2 additions & 2 deletions src/ping.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import url from 'url'
import {registry} from './config'
import {httpGetJSON} from './util'
import {httpGet} from './util'

/**
* ping the pre-configured npm registry by hitting `/-/ping?write=true`.
* @return {Observable} - observable sequence of the returned JSON object.
*/
export function ping () {
const uri = url.resolve(registry, '-/ping?write=true')
return httpGetJSON(uri)
return httpGet(uri)
}
Loading

0 comments on commit 3544041

Please sign in to comment.