Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

install: add support for package aliases #3

Merged
merged 2 commits into from
Feb 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 19 additions & 5 deletions lib/install.js
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ Installer.prototype.normalizeCurrentTree = function (cb) {
if (this.currentTree.error) {
for (let child of this.currentTree.children) {
if (!child.fakeChild && isExtraneous(child)) {
this.currentTree.package.dependencies[child.package.name] = computeVersionSpec(this.currentTree, child)
this.currentTree.package.dependencies[moduleName(child)] = computeVersionSpec(this.currentTree, child)
}
}
}
Expand Down Expand Up @@ -825,7 +825,11 @@ Installer.prototype.printInstalledForHuman = function (diffs, auditResult) {
var report = ''
if (this.args.length && (added || updated)) {
report += this.args.map((p) => {
return `+ ${p.name}@${p.version}`
return `+ ${p.name}@${p.version}${
!p._requested.name || p._requested.name === p.name
? ''
: ` (as ${p._requested.name})`
}`
}).join('\n') + '\n'
}
var actions = []
Expand Down Expand Up @@ -922,10 +926,14 @@ Installer.prototype.printInstalledForJSON = function (diffs, auditResult) {
function recordAction (action) {
var mutation = action[0]
var child = action[1]
const isAlias = child.package && child.package._requested && child.package._requested.type === 'alias'
const name = isAlias
? child.package._requested.name
: child.package && child.package.name
var result = {
action: mutation,
name: moduleName(child),
version: child.package && child.package.version,
name,
version: child.package && `${isAlias ? `npm:${child.package.name}@` : ''}${child.package.version}`,
path: child.path
}
if (mutation === 'move') {
Expand All @@ -947,10 +955,16 @@ Installer.prototype.printInstalledForParseable = function (diffs) {
} else if (mutation === 'update') {
var previousVersion = child.oldPkg.package && child.oldPkg.package.version
}
const isAlias = child.package._requested && child.package._requested.type === 'alias'
const version = child.package && isAlias
? `npm:${child.package.name}@${child.package.version}`
: child.package
? child.package.version
: ''
output(
mutation + '\t' +
moduleName(child) + '\t' +
(child.package ? child.package.version : '') + '\t' +
version + '\t' +
(child.path ? path.relative(self.where, child.path) : '') + '\t' +
(previousVersion || '') + '\t' +
(previousPath || ''))
Expand Down
3 changes: 2 additions & 1 deletion lib/install/action/extract.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const figgyPudding = require('figgy-pudding')
const stat = BB.promisify(require('graceful-fs').stat)
const gentlyRm = BB.promisify(require('../../utils/gently-rm.js'))
const mkdirp = BB.promisify(require('mkdirp'))
const moduleName = require('../../utils/module-name.js')
const moduleStagingPath = require('../module-staging-path.js')
const move = require('../../utils/move.js')
const npa = require('npm-package-arg')
Expand Down Expand Up @@ -113,7 +114,7 @@ function readBundled (pkg, staging, extractTo) {
}

function stageBundledModule (bundler, child, staging, parentPath) {
const stageFrom = path.join(parentPath, 'node_modules', child.package.name)
const stageFrom = path.join(parentPath, 'node_modules', moduleName(child))
const stageTo = moduleStagingPath(staging, child)

return BB.map(child.children, (child) => {
Expand Down
3 changes: 2 additions & 1 deletion lib/install/action/global-install.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ var path = require('path')
var npm = require('../../npm.js')
var Installer = require('../../install.js').Installer
var packageId = require('../../utils/package-id.js')
var moduleName = require('../../utils/module-name.js')

module.exports = function (staging, pkg, log, next) {
log.silly('global-install', packageId(pkg))
var globalRoot = path.resolve(npm.globalDir, '..')
npm.config.set('global', true)
var install = new Installer(globalRoot, false, [pkg.package.name + '@' + pkg.package._requested.fetchSpec])
var install = new Installer(globalRoot, false, [moduleName(pkg) + '@' + pkg.package._requested.rawSpec])
install.link = false
install.run(function () {
npm.config.set('global', false)
Expand Down
3 changes: 2 additions & 1 deletion lib/install/action/global-link.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
'use strict'
var moduleName = require('../../utils/module-name.js')
var npm = require('../../npm.js')
var packageId = require('../../utils/package-id.js')

module.exports = function (staging, pkg, log, next) {
log.silly('global-link', packageId(pkg))
npm.link(pkg.package.name, next)
npm.link(moduleName(pkg), next)
}
3 changes: 2 additions & 1 deletion lib/install/and-add-parent-to-errors.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
'use strict'
var moduleName = require('../utils/module-name.js')
var validate = require('aproba')

module.exports = function (parent, cb) {
validate('F', [cb])
return function (er) {
if (!er) return cb.apply(null, arguments)
if (er instanceof Error && parent && parent.package && parent.package.name) {
er.parent = parent.package.name
er.parent = moduleName(parent)
}
cb(er)
}
Expand Down
23 changes: 17 additions & 6 deletions lib/install/deps.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ function doesChildVersionMatch (child, requested, requestor) {
}
}

if (requested.type === 'alias') {
return doesChildVersionMatch(child, requested.subSpec, requestor)
}

if (!registryTypes[requested.type]) {
var childReq = child.package._requested
if (childReq) {
Expand All @@ -81,7 +85,7 @@ function doesChildVersionMatch (child, requested, requestor) {
// You'll see this scenario happen with at least tags and git dependencies.
// Some buggy clients will write spaces into the module name part of a _from.
if (child.package._from) {
var fromReq = npa.resolve(moduleName(child), child.package._from.replace(new RegExp('^\\s*' + moduleName(child) + '\\s*@'), ''))
var fromReq = npa(child.package._from)
if (fromReq.rawSpec === requested.rawSpec) return true
if (fromReq.type === requested.type && fromReq.saveSpec && fromReq.saveSpec === requested.saveSpec) return true
}
Expand Down Expand Up @@ -298,11 +302,13 @@ function computeVersionSpec (tree, child) {
var requested
var childReq = child.package._requested
if (child.isLink) {
requested = npa.resolve(child.package.name, 'file:' + child.realpath, getTop(tree).path)
requested = npa.resolve(moduleName(child), 'file:' + child.realpath, getTop(tree).path)
} else if (childReq && (isNotEmpty(childReq.saveSpec) || (isNotEmpty(childReq.rawSpec) && isNotEmpty(childReq.fetchSpec)))) {
requested = child.package._requested
} else if (child.package._from) {
requested = npa(child.package._from, tree.path)
} else if (child.name && child.name !== child.package.name) {
requested = npa.resolve(child.name, `npm:${child.package.name}@${child.package.version})`)
} else {
requested = npa.resolve(child.package.name, child.package.version)
}
Expand All @@ -314,6 +320,9 @@ function computeVersionSpec (tree, child) {
!npm.config.get('save-exact')) {
rangeDescriptor = npm.config.get('save-prefix')
}
if (requested.type === 'alias') {
rangeDescriptor = `npm:${requested.subSpec.name}@${rangeDescriptor}`
}
return rangeDescriptor + version
} else if (requested.type === 'directory' || requested.type === 'file') {
return 'file:' + unixFormatPath(path.relative(getTop(tree).path, requested.fetchSpec))
Expand All @@ -333,7 +342,7 @@ exports.removeDeps = function (args, tree, saveToDependencies, next) {
for (let pkg of args) {
var pkgName = moduleName(pkg)
var toRemove = tree.children.filter(moduleNameMatches(pkgName))
var pkgToRemove = toRemove[0] || createChild({package: {name: pkgName}})
var pkgToRemove = toRemove[0] || createChild({name: pkgName})
var saveType = getSaveType(tree, pkg) || 'dependencies'
if (tree.isTop && saveToDependencies) {
pkgToRemove.save = saveType
Expand Down Expand Up @@ -661,11 +670,13 @@ function resolveWithNewModule (pkg, tree, log, next) {
addBundled(pkg, (bundleErr) => {
var parent = earliestInstallable(tree, tree, pkg, log) || tree
var isLink = pkg._requested.type === 'directory'
var name = pkg._requested.name || pkg.name
var child = createChild({
name,
package: pkg,
parent: parent,
path: path.join(parent.isLink ? parent.realpath : parent.path, 'node_modules', pkg.name),
realpath: isLink ? pkg._requested.fetchSpec : path.join(parent.realpath, 'node_modules', pkg.name),
path: path.join(parent.isLink ? parent.realpath : parent.path, 'node_modules', name),
realpath: isLink ? pkg._requested.fetchSpec : path.join(parent.realpath, 'node_modules', name),
children: pkg._bundled || [],
isLink: isLink,
isInLink: parent.isLink,
Expand Down Expand Up @@ -768,7 +779,7 @@ var earliestInstallable = exports.earliestInstallable = function (requiredBy, tr
validate('OOOO', arguments)

function undeletedModuleMatches (child) {
return !child.removed && moduleName(child) === pkg.name
return !child.removed && moduleName(child) === ((pkg._requested && pkg._requested.name) || pkg.name)
}
const undeletedMatches = tree.children.filter(undeletedModuleMatches)
if (undeletedMatches.length) {
Expand Down
3 changes: 2 additions & 1 deletion lib/install/is-only-optional.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
module.exports = isOptional

const isOptDep = require('./is-opt-dep.js')
const moduleName = require('../utils/module-name.js')

function isOptional (node, seen) {
if (!seen) seen = new Set()
Expand All @@ -15,6 +16,6 @@ function isOptional (node, seen) {
const swOptional = node.fromShrinkwrap && node.package._optional
return node.requiredBy.every(function (req) {
if (req.fakeChild && swOptional) return true
return isOptDep(req, node.package.name) || isOptional(req, seen)
return isOptDep(req, moduleName(node)) || isOptional(req, seen)
})
}
12 changes: 9 additions & 3 deletions lib/ls.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ var readPackageTree = require('read-package-tree')
var archy = require('archy')
var semver = require('semver')
var color = require('ansicolors')
var moduleName = require('./utils/module-name.js')
var npa = require('npm-package-arg')
var sortedObject = require('sorted-object')
var npm = require('./npm.js')
Expand Down Expand Up @@ -59,7 +60,9 @@ var lsFromTree = ls.fromTree = function (dir, physicalTree, args, silent, cb) {
args = []
} else {
args = args.map(function (a) {
if (typeof a === 'object') {
if (typeof a === 'object' && a.package._requested.type === 'alias') {
return [moduleName(a), `npm:${a.package.name}@${a.package.version}`, a]
} else if (typeof a === 'object') {
return [a.package.name, a.package.version, a]
} else {
var p = npa(a)
Expand Down Expand Up @@ -392,8 +395,11 @@ function makeArchy_ (data, long, dir, depth, parent, d) {
}

var out = {}
// the top level is a bit special.
out.label = data._id || ''
if (data._requested && data._requested.type === 'alias') {
out.label = `${d}@npm:${data._id}`
} else {
out.label = data._id || ''
}
if (data._found === 'explicit' && data._id) {
if (npm.color) {
out.label = color.bgBlack(color.yellow(out.label.trim())) + ' '
Expand Down
92 changes: 54 additions & 38 deletions lib/outdated.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,30 +20,30 @@ outdated.usage = 'npm outdated [[<@scope>/]<pkg> ...]'

outdated.completion = require('./utils/completion/installed-deep.js')

var os = require('os')
var url = require('url')
var path = require('path')
var readPackageTree = require('read-package-tree')
var asyncMap = require('slide').asyncMap
var color = require('ansicolors')
var styles = require('ansistyles')
var table = require('text-table')
var semver = require('semver')
var npa = require('libnpm/parse-arg')
var pickManifest = require('npm-pick-manifest')
var fetchPackageMetadata = require('./fetch-package-metadata.js')
var mutateIntoLogicalTree = require('./install/mutate-into-logical-tree.js')
var npm = require('./npm.js')
const os = require('os')
const url = require('url')
const path = require('path')
const readPackageTree = require('read-package-tree')
const asyncMap = require('slide').asyncMap
const color = require('ansicolors')
const styles = require('ansistyles')
const table = require('text-table')
const semver = require('semver')
const npa = require('libnpm/parse-arg')
const pickManifest = require('npm-pick-manifest')
const fetchPackageMetadata = require('./fetch-package-metadata.js')
const mutateIntoLogicalTree = require('./install/mutate-into-logical-tree.js')
const npm = require('./npm.js')
const npmConfig = require('./config/figgy-config.js')
const figgyPudding = require('figgy-pudding')
const packument = require('libnpm/packument')
var long = npm.config.get('long')
var isExtraneous = require('./install/is-extraneous.js')
var computeMetadata = require('./install/deps.js').computeMetadata
var computeVersionSpec = require('./install/deps.js').computeVersionSpec
var moduleName = require('./utils/module-name.js')
var output = require('./utils/output.js')
var ansiTrim = require('./utils/ansi-trim')
const long = npm.config.get('long')
const isExtraneous = require('./install/is-extraneous.js')
const computeMetadata = require('./install/deps.js').computeMetadata
const computeVersionSpec = require('./install/deps.js').computeVersionSpec
const moduleName = require('./utils/module-name.js')
const output = require('./utils/output.js')
const ansiTrim = require('./utils/ansi-trim')

const OutdatedConfig = figgyPudding({
also: {},
Expand Down Expand Up @@ -215,8 +215,8 @@ function makeJSON (list, opts) {

function outdated_ (args, path, tree, parentHas, depth, opts, cb) {
if (!tree.package) tree.package = {}
if (path && tree.package.name) path += ' > ' + tree.package.name
if (!path && tree.package.name) path = tree.package.name
if (path && moduleName(tree)) path += ' > ' + tree.package.name
if (!path && moduleName(tree)) path = tree.package.name
if (depth > opts.depth) {
return cb(null, [])
}
Expand Down Expand Up @@ -298,10 +298,10 @@ function outdated_ (args, path, tree, parentHas, depth, opts, cb) {

var has = Object.create(parentHas)
tree.children.forEach(function (child) {
if (child.package.name && child.package.private) {
if (moduleName(child) && child.package.private) {
deps = deps.filter(function (dep) { return dep !== child })
}
has[child.package.name] = {
has[moduleName(child)] = {
version: child.isLink ? 'linked' : child.package.version,
from: child.isLink ? 'file:' + child.path : child.package._from
}
Expand Down Expand Up @@ -349,13 +349,6 @@ function shouldUpdate (args, tree, dep, has, req, depth, pkgpath, opts, cb, type
cb)
}

function doIt (wanted, latest) {
if (!long) {
return cb(null, [[tree, dep, curr && curr.version, wanted, latest, req, null, pkgpath]])
}
cb(null, [[tree, dep, curr && curr.version, wanted, latest, req, type, pkgpath]])
}

if (args.length && args.indexOf(dep) === -1) return skip()

if (tree.isLink && req == null) return skip()
Expand All @@ -374,11 +367,22 @@ function shouldUpdate (args, tree, dep, has, req, depth, pkgpath, opts, cb, type
} else if (parsed.type === 'file') {
return updateLocalDeps()
} else {
return packument(dep, opts.concat({
return packument(parsed, opts.concat({
'prefer-online': true
})).nodeify(updateDeps)
}

function doIt (wanted, latest) {
let c = curr && curr.version
if (parsed.type === 'alias') {
c = `npm:${parsed.subSpec.name}@${c}`
}
if (!long) {
return cb(null, [[tree, dep, c, wanted, latest, req, null, pkgpath]])
}
cb(null, [[tree, dep, c, wanted, latest, req, type, pkgpath]])
}

function updateLocalDeps (latestRegistryVersion) {
fetchPackageMetadata('file:' + parsed.fetchSpec, '.', (er, localDependency) => {
if (er) return cb()
Expand All @@ -405,6 +409,9 @@ function shouldUpdate (args, tree, dep, has, req, depth, pkgpath, opts, cb, type
function updateDeps (er, d) {
if (er) return cb(er)

if (parsed.type === 'alias') {
req = parsed.subSpec.rawSpec
}
try {
var l = pickManifest(d, 'latest')
var m = pickManifest(d, req)
Expand All @@ -421,11 +428,20 @@ function shouldUpdate (args, tree, dep, has, req, depth, pkgpath, opts, cb, type
var dFromUrl = m._from && url.parse(m._from).protocol
var cFromUrl = curr && curr.from && url.parse(curr.from).protocol

if (!curr ||
(dFromUrl && cFromUrl && m._from !== curr.from) ||
m.version !== curr.version ||
m.version !== l.version) {
doIt(m.version, l.version)
if (
!curr ||
(dFromUrl && cFromUrl && m._from !== curr.from) ||
m.version !== curr.version ||
m.version !== l.version
) {
if (parsed.type === 'alias') {
doIt(
`npm:${parsed.subSpec.name}@${m.version}`,
`npm:${parsed.subSpec.name}@${l.version}`
)
} else {
doIt(m.version, l.version)
}
} else {
skip()
}
Expand Down
Loading