"Fossies" - the Fresh Open Source Software Archive

Member "Atom/resources/app/apm/node_modules/npm/lib/install/diff-trees.js" (8 Mar 2017, 5130 Bytes) of archive /windows/misc/atom-windows.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Javascript source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 'use strict'
    2 var validate = require('aproba')
    3 var npa = require('npm-package-arg')
    4 var flattenTree = require('./flatten-tree.js')
    5 
    6 function nonRegistrySource (pkg) {
    7   validate('O', arguments)
    8   var requested = pkg._requested || (pkg._from && npa(pkg._from))
    9   if (!requested) return false
   10 
   11   if (requested.type === 'hosted') return true
   12   if (requested.type === 'local') return true
   13   return false
   14 }
   15 
   16 function pkgAreEquiv (aa, bb) {
   17   var aaSha = (aa.dist && aa.dist.shasum) || aa._shasum
   18   var bbSha = (bb.dist && bb.dist.shasum) || bb._shasum
   19   if (aaSha === bbSha) return true
   20   if (aaSha || bbSha) return false
   21   if (nonRegistrySource(aa) || nonRegistrySource(bb)) return false
   22   if (aa.version === bb.version) return true
   23   return false
   24 }
   25 
   26 function getNameAndVersion (pkg) {
   27   var versionspec = pkg._shasum
   28 
   29   if (!versionspec && nonRegistrySource(pkg)) {
   30     if (pkg._requested) {
   31       versionspec = pkg._requested.spec
   32     } else if (pkg._from) {
   33       versionspec = npa(pkg._from).spec
   34     }
   35   }
   36   if (!versionspec) {
   37     versionspec = pkg.version
   38   }
   39   return pkg.name + '@' + versionspec
   40 }
   41 
   42 function pushAll (aa, bb) {
   43   Array.prototype.push.apply(aa, bb)
   44 }
   45 
   46 module.exports = function (oldTree, newTree, differences, log, next) {
   47   validate('OOAOF', arguments)
   48   pushAll(differences, sortActions(diffTrees(oldTree, newTree)))
   49   log.finish()
   50   next()
   51 }
   52 
   53 function isLink (node) {
   54   return node && node.isLink
   55 }
   56 
   57 function requiredByAllLinked (node) {
   58   if (!node.requiredBy.length) return false
   59   return node.requiredBy.filter(isLink).length === node.requiredBy.length
   60 }
   61 
   62 function isNotTopOrExtraneous (node) {
   63   return !node.isTop && !node.userRequired && !node.existing
   64 }
   65 
   66 var sortActions = module.exports.sortActions = function (differences) {
   67   var actions = {}
   68   differences.forEach(function (action) {
   69     var child = action[1]
   70     actions[child.location] = action
   71   })
   72 
   73   var sorted = []
   74   var added = {}
   75 
   76   var sortedlocs = Object.keys(actions).sort(sortByLocation)
   77 
   78   // We're going to sort the actions taken on top level dependencies first, before
   79   // considering the order of transitive deps. Because we're building our list
   80   // from the bottom up, this means we will return a list with top level deps LAST.
   81   // This is important in terms of keeping installations as consistent as possible
   82   // as folks add new dependencies.
   83   var toplocs = sortedlocs.filter(function (location) {
   84     var mod = actions[location][1]
   85     if (!mod.requiredBy) return true
   86     // If this module is required by any non-top level module
   87     // or by any extraneous module, eg user requested or existing
   88     // then we don't want to give this priority sorting.
   89     return !mod.requiredBy.some(isNotTopOrExtraneous)
   90   })
   91 
   92   toplocs.concat(sortedlocs).forEach(function (location) {
   93     sortByDeps(actions[location])
   94   })
   95 
   96   function sortByLocation (aa, bb) {
   97     return bb.localeCompare(aa)
   98   }
   99   function sortModuleByLocation (aa, bb) {
  100     return sortByLocation(aa && aa.location, bb && bb.location)
  101   }
  102   function sortByDeps (action) {
  103     var mod = action[1]
  104     if (added[mod.location]) return
  105     added[mod.location] = action
  106     if (!mod.requiredBy) mod.requiredBy = []
  107     mod.requiredBy.sort(sortModuleByLocation).forEach(function (mod) {
  108       if (actions[mod.location]) sortByDeps(actions[mod.location])
  109     })
  110     sorted.unshift(action)
  111   }
  112 
  113   return sorted
  114 }
  115 
  116 function diffTrees (oldTree, newTree) {
  117   validate('OO', arguments)
  118   var differences = []
  119   var flatOldTree = flattenTree(oldTree)
  120   var flatNewTree = flattenTree(newTree)
  121   var toRemove = {}
  122   var toRemoveByNameAndVer = {}
  123   // find differences
  124   Object.keys(flatOldTree).forEach(function (flatname) {
  125     if (flatNewTree[flatname]) return
  126     var pkg = flatOldTree[flatname]
  127     toRemove[flatname] = pkg
  128     var namever = getNameAndVersion(pkg.package)
  129     if (!toRemoveByNameAndVer[namever]) toRemoveByNameAndVer[namever] = []
  130     toRemoveByNameAndVer[namever].push(flatname)
  131   })
  132   Object.keys(flatNewTree).forEach(function (path) {
  133     var pkg = flatNewTree[path]
  134     pkg.oldPkg = flatOldTree[path]
  135     pkg.isInLink = (pkg.oldPkg && isLink(pkg.oldPkg.parent)) ||
  136                    (pkg.parent && isLink(pkg.parent)) ||
  137                    requiredByAllLinked(pkg)
  138     if (pkg.oldPkg) {
  139       if (!pkg.userRequired && pkgAreEquiv(pkg.oldPkg.package, pkg.package)) return
  140       if (!pkg.isInLink && (isLink(pkg.oldPkg) || isLink(pkg))) {
  141         differences.push(['update-linked', pkg])
  142       } else {
  143         differences.push(['update', pkg])
  144       }
  145     } else {
  146       var vername = getNameAndVersion(pkg.package)
  147       if (toRemoveByNameAndVer[vername] && toRemoveByNameAndVer[vername].length && !pkg.fromBundle) {
  148         var flatname = toRemoveByNameAndVer[vername].shift()
  149         pkg.fromPath = toRemove[flatname].path
  150         differences.push(['move', pkg])
  151         delete toRemove[flatname]
  152       } else {
  153         differences.push(['add', pkg])
  154       }
  155     }
  156   })
  157   Object
  158     .keys(toRemove)
  159     .map(function (path) { return toRemove[path] })
  160     .forEach(function (pkg) {
  161       differences.push(['remove', pkg])
  162     })
  163   return differences
  164 }