package/package.json000644 0000001653 3560116604 011553 0ustar00000000 000000 { "name": "hash-for-dep", "version": "1.5.1", "description": "generates a hash that represents a module and its depenencies uniqueness", "main": "index.js", "scripts": { "test": "mocha tests/**/*-test.js", "test:debug": "mocha debug tests/**/*-test.js" }, "repository": { "type": "git", "url": "git+https://github.com/stefanpenner/hash-for-dep.git" }, "author": "Stefan Penner ", "license": "ISC", "bugs": { "url": "https://github.com/stefanpenner/hash-for-dep/issues" }, "homepage": "https://github.com/stefanpenner/hash-for-dep#readme", "dependencies": { "broccoli-kitchen-sink-helpers": "^0.3.1", "heimdalljs": "^0.2.3", "heimdalljs-logger": "^0.1.7", "path-root": "^0.1.1", "resolve": "^1.10.0", "resolve-package-path": "^1.0.11" }, "devDependencies": { "chai": "^3.5.0", "mocha": "^2.2.4", "mocha-jshint": "^1.0.0" } } package/.jshintignore000644 0000000017 3560116604 011762 0ustar00000000 000000 /node_modules/*package/.jshintrc000644 0000001343 3560116604 011106 0ustar00000000 000000 { "predef": [ "console", "it", "describe", "beforeEach", "afterEach", "before", "after", "-Promise" ], "expr": true, "proto": true, "strict": true, "indent": 2, "camelcase": true, "node": true, "browser": false, "boss": true, "curly": true, "latedef": "nofunc", "debug": false, "devel": false, "eqeqeq": true, "evil": true, "forin": false, "immed": false, "laxbreak": false, "newcap": true, "noarg": true, "noempty": false, "quotmark": true, "nonew": false, "nomen": false, "onevar": false, "plusplus": false, "regexp": false, "undef": true, "unused": true, "sub": true, "trailing": true, "white": false, "eqnull": true, "esnext": true }package/.travis.yml000644 0000000332 3560116604 011367 0ustar00000000 000000 language: node_js sudo: false os: - linux node_js: - "0.10" - "0.12" - "4" - "5" - "6" - "8" - "10" - "11" before_install: - "npm config set spin false" - "npm install -g npm@^3" script: npm test package/appveyor.yml000644 0000001165 3560116604 011653 0ustar00000000 000000 # AppVeyor file # http://www.appveyor.com/docs/appveyor-yml # Build version format version: "{build}" # Fix line endings on Windows init: - git config --global core.autocrlf true - git config --global core.symlinks true # What combinations to test environment: matrix: - nodejs_version: "0.10" - nodejs_version: "0.12" - nodejs_version: "4" - nodejs_version: "5" - nodejs_version: "6" - nodejs_version: "8" - nodejs_version: "10" - nodejs_version: "11" install: - ps: Install-Product node $env:nodejs_version - npm install build: off test_script: - npm version - cmd: npm testpackage/index.js000644 0000005024 3560116604 010726 0ustar00000000 000000 'use strict'; var hashTree = require('./lib/hash-tree'); var heimdall = require('heimdalljs'); var CacheGroup = require('./lib/cache-group'); var cacheKey = require('./lib/cache-key'); var logger = require('heimdalljs-logger')('hash-for-dep:'); var ModuleEntry = require('./lib/module-entry'); /* * hash-for-dep by default operates by caching all its findings until the * current process exits. * * In some less common scenarios, it may be appropriate to skip this process * cache. To do so, hashForDep can be invoked with the fourth argument = true. * * ``` * hashForDep(name, dir, null, true); * ``` * * Doing so will not interfere with the existing process cache. Instead, * the current invocation of hashForDep is given its own unique cache. * This cache is used to prevent duplicate work within that invocation of * hashForDep, and is discarded once the invocation completes. */ /* * PROCESS_CACHE is the default cache used until the process exits. */ var PROCESS_CACHE = new CacheGroup(); function HashForDepSchema() { this.paths = 0; } /* @public * * @method hashForDep * @param {String} name name of the dependency module. * @param {String} dir (optional) root dir to run the hash resolving from * @param {String} _hashTreeOverride (optional) private, used internally for testing * @param {Boolean} _skipCache (optional) intended to bypass cache * @return {String} a hash representing the stats of this module and all its descendents */ module.exports = function hashForDep(name, dir, _hashTreeOverride, _skipCache) { var skipCache = (typeof _hashTreeOverride === 'function' || _skipCache === true); var caches = skipCache ? new CacheGroup() : PROCESS_CACHE; var hashTreeFn = (_hashTreeOverride || hashTree); var heimdallNodeOptions = { name: 'hashForDep(' + name + ')', hashForDep: true, dependencyName: name, rootDir: dir, skipCache: skipCache, cacheKey: cacheKey(name, dir) }; var h = heimdall.start(heimdallNodeOptions, HashForDepSchema); try { var moduleEntry = ModuleEntry.locate(caches, name, dir, hashTreeFn); return moduleEntry.getHash(h); } finally { h.stop(); } }; module.exports._resetCache = function() { PROCESS_CACHE = new CacheGroup(); }; // Expose the module entry cache for testing only Object.defineProperty(module.exports, '_cache', { get: function() { return PROCESS_CACHE.MODULE_ENTRY; } }); // Expose the process cache for testing only Object.defineProperty(module.exports, '_caches', { get: function() { return PROCESS_CACHE; } }); package/README.md000644 0000004363 3560116604 010545 0ustar00000000 000000 # hash-for-dep [![Build Status](https://travis-ci.org/stefanpenner/hash-for-dep.svg?branch=stuff)](https://travis-ci.org/stefanpenner/hash-for-dep) [![Build status](https://ci.appveyor.com/api/projects/status/wf2u3j6lc52hdd21?svg=true)](https://ci.appveyor.com/project/embercli/hash-for-dep) Generate a hash representing the stats of this module files and all its descendents files. ```js var hashForDep = require('hash-for-dep'); hashForDep('rsvp'); // if RSVP is a dependency of the current project, you will get a checksum for it hashForDep('rsvp', 'path/to/other/project'); // you will get a checksum for RSVP resolved relative to the provided root ``` ## What does Hash For Dep consider a dependency? HashForDep respects the [node resolution algorithim](https://nodejs.org/api/modules.html#modules_all_together). For example given: ``` foo/package.json foo/index.js foo/node_modules/a/ foo/node_modules/a/package.json foo/node_modules/a/index.js foo/node_modules/a/node_modules/b foo/node_modules/a/node_modules/b/package.json foo/node_modules/a/node_modules/b/index.js foo/node_modules/a/node_modules/f foo/node_modules/a/node_modules/f/index.js foo/node_modules/a/node_modules/f/package.json foo/node_modules/c foo/node_modules/c/index.js foo/node_modules/c/package.json foo/node_modules/d foo/node_modules/d/index.js foo/node_modules/d/package.js ``` where `foo/package.json` depends on `a` and `c` but not `d` and `foo/node_modules/a/package.json` depends on `b` not `f` HashForDep will consider: `a` `c` `b` as dependencies, and simply ignore `d` and `f`. When HashForDep considers a dependency, it will stat each of its files and those of its dependencies. ## Cache NOTE: By default, these hashes are cached for the life of the process. As this is the same strategy node uses for `require(x)` we can safely follow suit. That being said, some scenarios may exist where this is not wanted. So just like `require._cache` exists, we provide the following options: #### To evict the cache manually (maybe for testing) ```js require('hash-for-dep')._resetCache(); ``` #### To opt out of the cache on a per invocation basis ```js var hashForDep = require('hash-for-dep'); hashForDep(name, path, null, false /* this mysterious argument should be set to false */); ``` package/yarn.lock000644 0000040221 3560116604 011102 0ustar00000000 000000 # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. # yarn lockfile v1 assertion-error@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== dependencies: balanced-match "^1.0.0" concat-map "0.0.1" broccoli-kitchen-sink-helpers@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/broccoli-kitchen-sink-helpers/-/broccoli-kitchen-sink-helpers-0.3.1.tgz#77c7c18194b9664163ec4fcee2793444926e0c06" integrity sha1-d8fBgZS5ZkFj7E/O4nk0RJJuDAY= dependencies: glob "^5.0.10" mkdirp "^0.5.1" chai@^3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/chai/-/chai-3.5.0.tgz#4d02637b067fe958bdbfdd3a40ec56fef7373247" integrity sha1-TQJjewZ/6Vi9v906QOxW/vc3Mkc= dependencies: assertion-error "^1.0.1" deep-eql "^0.1.3" type-detect "^1.0.0" cli@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/cli/-/cli-1.0.1.tgz#22817534f24bfa4950c34d532d48ecbc621b8c14" integrity sha1-IoF1NPJL+klQw01TLUjsvGIbjBQ= dependencies: exit "0.1.2" glob "^7.1.1" commander@0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/commander/-/commander-0.6.1.tgz#fa68a14f6a945d54dbbe50d8cdb3320e9e3b1a06" integrity sha1-+mihT2qUXVTbvlDYzbMyDp47GgY= commander@2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.3.0.tgz#fd430e889832ec353b9acd1de217c11cb3eef873" integrity sha1-/UMOiJgy7DU7ms0d4hfBHLPu+HM= concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= console-browserify@1.1.x: version "1.1.0" resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" integrity sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA= dependencies: date-now "^0.1.4" core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= date-now@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs= debug@2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" integrity sha1-+HBX6ZWxofauaklgZkE3vFbwOdo= dependencies: ms "0.7.1" debug@^2.2.0: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: ms "2.0.0" deep-eql@^0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-0.1.3.tgz#ef558acab8de25206cd713906d74e56930eb69f2" integrity sha1-71WKyrjeJSBs1xOQbXTlaTDrafI= dependencies: type-detect "0.1.1" diff@1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/diff/-/diff-1.4.0.tgz#7f28d2eb9ee7b15a97efd89ce63dcfdaa3ccbabf" integrity sha1-fyjS657nsVqX79ic5j3P2qPMur8= dom-serializer@0: version "0.1.0" resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82" integrity sha1-BzxpdUbOB4DOI75KKOKT5AvDDII= dependencies: domelementtype "~1.1.1" entities "~1.1.1" domelementtype@1: version "1.3.1" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== domelementtype@~1.1.1: version "1.1.3" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b" integrity sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs= domhandler@2.3: version "2.3.0" resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.3.0.tgz#2de59a0822d5027fabff6f032c2b25a2a8abe738" integrity sha1-LeWaCCLVAn+r/28DLCsloqir5zg= dependencies: domelementtype "1" domutils@1.5: version "1.5.1" resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" integrity sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8= dependencies: dom-serializer "0" domelementtype "1" entities@1.0: version "1.0.0" resolved "https://registry.yarnpkg.com/entities/-/entities-1.0.0.tgz#b2987aa3821347fcde642b24fdfc9e4fb712bf26" integrity sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY= entities@~1.1.1: version "1.1.2" resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== escape-string-regexp@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz#4dbc2fe674e71949caf3fb2695ce7f2dc1d9a8d1" integrity sha1-Tbwv5nTnGUnK8/smlc5/LcHZqNE= exit@0.1.2, exit@0.1.x: version "0.1.2" resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= glob@3.2.11: version "3.2.11" resolved "https://registry.yarnpkg.com/glob/-/glob-3.2.11.tgz#4a973f635b9190f715d10987d5c00fd2815ebe3d" integrity sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0= dependencies: inherits "2" minimatch "0.3" glob@^5.0.10: version "5.0.15" resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" integrity sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E= dependencies: inflight "^1.0.4" inherits "2" minimatch "2 || 3" once "^1.3.0" path-is-absolute "^1.0.0" glob@^7.1.1: version "7.1.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" inherits "2" minimatch "^3.0.4" once "^1.3.0" path-is-absolute "^1.0.0" growl@1.9.2: version "1.9.2" resolved "https://registry.yarnpkg.com/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f" integrity sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8= heimdalljs-logger@^0.1.7: version "0.1.10" resolved "https://registry.yarnpkg.com/heimdalljs-logger/-/heimdalljs-logger-0.1.10.tgz#90cad58aabb1590a3c7e640ddc6a4cd3a43faaf7" integrity sha512-pO++cJbhIufVI/fmB/u2Yty3KJD0TqNPecehFae0/eps0hkZ3b4Zc/PezUMOpYuHFQbA7FxHZxa305EhmjLj4g== dependencies: debug "^2.2.0" heimdalljs "^0.2.6" heimdalljs@^0.2.3, heimdalljs@^0.2.6: version "0.2.6" resolved "https://registry.yarnpkg.com/heimdalljs/-/heimdalljs-0.2.6.tgz#b0eebabc412813aeb9542f9cc622cb58dbdcd9fe" integrity sha512-o9bd30+5vLBvBtzCPwwGqpry2+n0Hi6H1+qwt6y+0kwRHGGF8TFIhJPmnuM0xO97zaKrDZMwO/V56fAnn8m/tA== dependencies: rsvp "~3.2.1" htmlparser2@3.8.x: version "3.8.3" resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.8.3.tgz#996c28b191516a8be86501a7d79757e5c70c1068" integrity sha1-mWwosZFRaovoZQGn15dX5ccMEGg= dependencies: domelementtype "1" domhandler "2.3" domutils "1.5" entities "1.0" readable-stream "1.1" inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= dependencies: once "^1.3.0" wrappy "1" inherits@2, inherits@~2.0.1: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= isarray@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= jade@0.26.3: version "0.26.3" resolved "https://registry.yarnpkg.com/jade/-/jade-0.26.3.tgz#8f10d7977d8d79f2f6ff862a81b0513ccb25686c" integrity sha1-jxDXl32NefL2/4YqgbBRPMslaGw= dependencies: commander "0.6.1" mkdirp "0.3.0" jshint@^2.5: version "2.10.1" resolved "https://registry.yarnpkg.com/jshint/-/jshint-2.10.1.tgz#06bd4cea090c424405aa0987de741341ff17f6bc" integrity sha512-9GpPfKeffYBl7oBDX2lHPG16j0AM7D2bn3aLy9DaWTr6CWa0i/7UGhX8WLZ7V14QQnnr4hXbjauTLYg06F+HYw== dependencies: cli "~1.0.0" console-browserify "1.1.x" exit "0.1.x" htmlparser2 "3.8.x" lodash "~4.17.10" minimatch "~3.0.2" shelljs "0.3.x" strip-json-comments "1.0.x" lodash@~4.17.10: version "4.17.11" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== lru-cache@2: version "2.7.3" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952" integrity sha1-bUUk6LlV+V1PW1iFHOId1y+06VI= minimatch@0.3: version "0.3.0" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.3.0.tgz#275d8edaac4f1bb3326472089e7949c8394699dd" integrity sha1-J12O2qxPG7MyZHIInnlJyDlGmd0= dependencies: lru-cache "2" sigmund "~1.0.0" "minimatch@2 || 3", minimatch@^3.0.4, minimatch@~3.0.2: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== dependencies: brace-expansion "^1.1.7" minimist@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= mkdirp@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.0.tgz#1bbf5ab1ba827af23575143490426455f481fe1e" integrity sha1-G79asbqCevI1dRQ0kEJkVfSB/h4= mkdirp@0.5.1, mkdirp@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= dependencies: minimist "0.0.8" mocha-jshint@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/mocha-jshint/-/mocha-jshint-1.1.0.tgz#2258ebf753435df0a3bbc0529b43b88a782fb5bb" integrity sha1-Iljr91NDXfCju8BSm0O4ingvtbs= dependencies: jshint "^2.5" mocha@^2.2.4: version "2.5.3" resolved "https://registry.yarnpkg.com/mocha/-/mocha-2.5.3.tgz#161be5bdeb496771eb9b35745050b622b5aefc58" integrity sha1-FhvlvetJZ3HrmzV0UFC2IrWu/Fg= dependencies: commander "2.3.0" debug "2.2.0" diff "1.4.0" escape-string-regexp "1.0.2" glob "3.2.11" growl "1.9.2" jade "0.26.3" mkdirp "0.5.1" supports-color "1.2.0" to-iso-string "0.0.2" ms@0.7.1: version "0.7.1" resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" integrity sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg= ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= once@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= dependencies: wrappy "1" path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= path-parse@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== path-root-regex@^0.1.0: version "0.1.2" resolved "https://registry.yarnpkg.com/path-root-regex/-/path-root-regex-0.1.2.tgz#bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d" integrity sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0= path-root@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/path-root/-/path-root-0.1.1.tgz#9a4a6814cac1c0cd73360a95f32083c8ea4745b7" integrity sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc= dependencies: path-root-regex "^0.1.0" readable-stream@1.1: version "1.1.13" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.13.tgz#f6eef764f514c89e2b9e23146a75ba106756d23e" integrity sha1-9u73ZPUUyJ4rniMUanW6EGdW0j4= dependencies: core-util-is "~1.0.0" inherits "~2.0.1" isarray "0.0.1" string_decoder "~0.10.x" resolve-package-path@^1.0.11: version "1.0.11" resolved "https://registry.yarnpkg.com/resolve-package-path/-/resolve-package-path-1.0.11.tgz#c57263d99c4cc112ac05aa073231832aa202c722" integrity sha512-HfJBvKmHJGURW8cb4w3LTf1acpqxrTNU5bUxwxbAxXg6dPrDVwh/fVi3CgFw1PAsQmMaG3CtJISwXZjxfNUKng== dependencies: path-root "^0.1.1" resolve "^1.10.0" resolve@^1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.10.0.tgz#3bdaaeaf45cc07f375656dfd2e54ed0810b101ba" integrity sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg== dependencies: path-parse "^1.0.6" rsvp@~3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-3.2.1.tgz#07cb4a5df25add9e826ebc67dcc9fd89db27d84a" integrity sha1-B8tKXfJa3Z6Cbrxn3Mn9idsn2Eo= shelljs@0.3.x: version "0.3.0" resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.3.0.tgz#3596e6307a781544f591f37da618360f31db57b1" integrity sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E= sigmund@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" integrity sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA= string_decoder@~0.10.x: version "0.10.31" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= strip-json-comments@1.0.x: version "1.0.4" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-1.0.4.tgz#1e15fbcac97d3ee99bf2d73b4c656b082bbafb91" integrity sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E= supports-color@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-1.2.0.tgz#ff1ed1e61169d06b3cf2d588e188b18d8847e17e" integrity sha1-/x7R5hFp0Gs88tWI4YixjYhH4X4= to-iso-string@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/to-iso-string/-/to-iso-string-0.0.2.tgz#4dc19e664dfccbe25bd8db508b00c6da158255d1" integrity sha1-TcGeZk38y+Jb2NtQiwDG2hWCVdE= type-detect@0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-0.1.1.tgz#0ba5ec2a885640e470ea4e8505971900dac58822" integrity sha1-C6XsKohWQORw6k6FBZcZANrFiCI= type-detect@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-1.0.0.tgz#762217cc06db258ec48908a1298e8b95121e8ea2" integrity sha1-diIXzAbbJY7EiQihKY6LlRIejqI= wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= package/lib/cache-group.js000644 0000004740 3560116604 012566 0ustar00000000 000000 'use strict'; var Cache = require('./cache'); /* * CacheGroup is used to both speed up and ensure consistency of hashForDep. * * The CacheGroup contains three separate caches: * * - MODULE_ENTRY: the cache of realPathKey => ModuleEntry objects. * Each ModuleEntry contains information about a particular module * found during hash-for-dep processing. realPathKey is a hash * of the resolved real path to the module's package.json file. * * Having the real path means that when resolving dependencies, we can * take the resolved paths, hash them and check quickly for cache entries, * speeding creation of the cache. Because many modules may refer to * the same module as a dependency, this eliminates duplication and having * to reread package.json files. * * However, that also means we need a second cache to map from the original * name and dir passed to hashForDep to the final resolved path for the * module's package.json file. * * - PATH: the cache of nameDirKey => realPathKey. nameDirKey is a hash of the * combination of the name and starting directory passed to hashForDep. * realPathKey is a hash of the resulting real path to the relevant package.json file. * * - REAL_FILE_PATH: the cache of filePath => resolved realPath for relevant files. * When determining the location of a file, the file path may involve links. * This cache is keyed on the original file path, with a value of the real path. * This cache helps to speed up path resolution in both cases by minimizing * the use of costly 'fs.statSync' calls. * * - REAL_DIRECTORY_PATH: the cache of filePath => resolved realPath for relevant directories. * When determining the location of a file by going up the node_modules chain, * paths to intervening directories may contain links. Similar to REAL_FILE_PATH, * this cache is keyed on the original directory path, with a value of the real path. * This cache helps to speed up path resolution in both cases by minimizing * the use of costly 'fs.statSync' calls. * * Note: when discussing 'real paths' above, the paths are normalized by routines * like path.join() or path.resolve(). We do nothing beyond that (e.g., we do not attempt * to force the paths into POSIX style.) */ module.exports = function CacheGroup() { this.MODULE_ENTRY = new Cache(); this.PATH = new Cache(); this.REAL_FILE_PATH = new Cache(); this.REAL_DIRECTORY_PATH = new Cache(); Object.freeze(this); }; package/lib/cache-key.js000644 0000001032 3560116604 012211 0ustar00000000 000000 'use strict'; var crypto = require('crypto'); /* * Create a cache key for the given name and dir. This is used for all the * keys in the various caches within hash-for-dep. * * @param name is the 'require'-style name (i.e., could include a full path, * or be relative to dir) * @param dir optional directory to start resolution from when running * the node-resolution algorithm as 'require' does. */ module.exports = function cacheKey(name, dir) { return crypto.createHash('sha1').update(name + '\x00' + dir).digest('hex'); }; package/lib/cache.js000644 0000001533 3560116604 011431 0ustar00000000 000000 'use strict'; function makeCache() { // object with no prototype var cache = Object.create(null); // force the jit to immediately realize this object is a dictionary. This // should prevent the JIT from going wastefully one direction (fast mode) // then going another (dict mode) after cache['_cache'] = 1; delete cache['_cache']; return cache; } module.exports = Cache; function Cache() { this._store = makeCache(); } Cache.prototype.set = function(key, value) { return this._store[key] = value; }; Cache.prototype.get = function(key) { return this._store[key]; }; Cache.prototype.has = function(key) { return key in this._store; }; Cache.prototype.delete = function(key) { delete this._store[key]; }; Object.defineProperty(Cache.prototype, 'size', { get: function() { return Object.keys(this._store).length; } }); package/lib/deps-for.js000644 0000002504 3560116604 012104 0ustar00000000 000000 'use strict'; var pkg = require('./pkg'); /* @private * * Constructs a set of all dependencies recursively. * * @method depsFor * @param {String} name of package to assemble unique dependencies for * @param {String} dir (optional) path to begin resolving from * @param {Object} options (optional) * @param {Boolean} options.includeOptionalDeps (optional) should optionalDependencies be included * @return {Array} a unique set of all deps */ module.exports = function depsFor(name, dir, _options) { var options = _options ? _options : {}; var dependencies = []; var visited = Object.create(null); (function again(name, dir, _options) { var options = _options ? _options : {}; var thePackage = pkg(name, dir); if (thePackage === null) { return; } var key = thePackage.name + thePackage.version + thePackage.baseDir; if (visited[key]) { return; } visited[key] = true; dependencies.push(thePackage); var depsOfThePackage = []; if (options.includeOptionalDeps) { depsOfThePackage = Object.keys(thePackage.optionalDependencies || {}); } depsOfThePackage = depsOfThePackage.concat(Object.keys(thePackage.dependencies || {})); return depsOfThePackage.forEach(function(dep) { again(dep, thePackage.baseDir, options); }); }(name, dir, options)); return dependencies; }; package/lib/hash-tree.js000644 0000004325 3560116604 012250 0ustar00000000 000000 'use strict'; /* * Given a full path (no path-resolution is performed), find all the files underneath that * path (to the leaves of the directory tree), excluding any node_modules subdirectories. * Collect stat information about each file and join the information together in a string, * then return that string. */ var crypto = require('crypto'); var fs = require('fs'); var path = require('path'); function getFileInfos(fullPath, _visited) { var visited = Array.isArray(_visited) ? _visited : []; var realPath = fs.realpathSync(fullPath); if (visited.indexOf(realPath) >= 0) { return []; } else { visited.push(realPath); } var stat = fs.statSync(fullPath); if (stat.isFile()) { return [{ fullPath: fullPath, mtime: stat.mtime.getTime(), mode: stat.mode, size: stat.size }]; } else if (stat.isDirectory()) { // if it ends with node_modules do nothing return fs.readdirSync(realPath).sort().reduce(function(paths, entry) { if (entry.toLowerCase() === 'node_modules') { return paths; } var keys; try { keys = getFileInfos(path.join(realPath, entry), visited); } catch (err) { if (typeof err === "object" && err !== null && err.code !== 'ENOENT') { throw err; } keys = ['missing']; } return paths.concat(keys); }, []); } else { throw new Error('"' + fullPath + '": Unexpected file type'); } } function stringifyFileInfo(fileInfo) { return '|' + fileInfo.mtime + '|' + fileInfo.mode + '|' + fileInfo.size; } var hasWorkingFrom = false; // node 5.x has a incomplete `Buffer.from` if (typeof Buffer.from === 'function') { try { Buffer.from([]); hasWorkingFrom = true; } catch (e) { hasWorkingFrom = false; } } module.exports = function hashTree(fullPath) { var strings = getFileInfos(fullPath).sort().map(stringifyFileInfo).join(); // Once we drop Node < 6 support, we can simplify this code to Buffer.from var buf = (hasWorkingFrom ? Buffer.from(strings) : (new Buffer(strings, 'utf8'))); return crypto.createHash('md5').update(buf).digest('hex'); }; module.exports.stringifyFileInfo = stringifyFileInfo; module.exports.getFileInfos = getFileInfos; package/lib/module-entry.js000644 0000022426 3560116604 013016 0ustar00000000 000000 'use strict'; var resolvePackagePath = require('resolve-package-path'); var cacheKey = require('./cache-key'); var tryRequire = require('./try-require'); var crypto = require('crypto'); /* * Entries in 'MODULE_ENTRY' cache. The idea is to minimize the information needed for * each entry (don't store the entire package.json object), but keep * information around for all parts of computing a hash for the dependency * tree of the original module named by 'name' and 'dir' in hashForDep. * The ModuleEntry is created at the time the package.json file is * read in (so that's only done once), but some properties may not be initialized * until later (this then supports creating cycles in the dependencies list, * which is supported by Node). */ module.exports = ModuleEntry; function ModuleEntry(name, version, rootDir, sourceHash, isValid) { // The name of the module, from its package.json file. this.name = name; // The version of the module, from its package.json file. this.version = version; // The resolved real file path for the directory containing the package.json file. // The string has no trailing path separator(s), as path.resolve() removes them. this.rootDir = rootDir; // The computed hash for only the module's source files (under // the root dir, but specifically NOT any node_modules dependencies). // See locate() for initialization of this value. this._sourceHash = sourceHash; // The computed hash for the module's source files plus // the source hashes of the dependencies, recursively to the // leaves of the dependency tree. this._hash = null; // References to other ModuleEntry objects that correspond // to the dependencies listed in the package.json file. // See locate() for initialization of this value. this._dependencies = Object.create(null); this.isValid = isValid === false ? false : true; } ModuleEntry.prototype.addDependency = function(dependency, moduleEntry) { this._dependencies[dependency] = moduleEntry; }; /* * Starting from an initial ModuleEntry, traverse the entry's dependencies * ("almost" ModuleEntry objects) recursively to the leaves of the dependency * tree. Return an object containing all the ModuleEntry objects, * keyed by each entry's rootDir (real path to the module's root directory.) * NOTE: for speed, the initial caller of _gatherDependencies must pass * in a result object, so we aren't constantly checking that it is set. */ ModuleEntry.prototype._gatherDependencies = function(dependencies) { var moduleEntry = this; if (dependencies[moduleEntry.rootDir] !== undefined) { // we already hit this path during the dependencies somewhere earlier // in the dependency tree, so avoid cycling. return; } dependencies[moduleEntry.rootDir] = moduleEntry; Object.keys(moduleEntry._dependencies).forEach(function(dep) { moduleEntry._dependencies[dep]._gatherDependencies(dependencies); }); return dependencies; }; /* * Compute/return the 'hash' field for the given moduleEntry. * The hash actually consists only of the _sourceHash values of all the * dependencies (ModuleEntry objects) concatenated with '\x00' between * entries. The '_sourceHash' values are computed at the time the * ModuleEntry is created, so don't need to be done again. */ ModuleEntry.prototype.getHash = function(heimdallNode) { if (this._hash !== null) { return this._hash; } // We haven't computed the hash for this entry yet, though the // ModuleEntry entries are all present. It is possible that we // have the hash for some dependencies already. // Compute the full transitive dependency list. There are no duplicates, // because we check during _gatherDependencies before inserting in the result. // The keys of the returned object are the package.json baseDir values (the // moduleEntry.rootDir). The values are the moduleEntry objects. var dependencies = this._gatherDependencies(Object.create(null)); // For repeatability between runs, sort the dependencies list keys // (rootDir values) before assembling into a final hash value. var dependencyRootDirs = Object.keys(dependencies).sort(); if (heimdallNode) { heimdallNode.stats.paths += dependencyRootDirs.length; } var sourceHashes = dependencyRootDirs.map(function(rootDir) { return dependencies[rootDir]._sourceHash; }).join('\x00'); var hash = crypto.createHash('sha1').update(sourceHashes).digest('hex'); return (this._hash = hash); }; /* * This exists to maintain compatibbility with some unexpected old behavior. * Specifically invalid input, would still produce a hash. * * This is clearly not helpful, but to fix a regression we will restore this * behavior, but the next major version (2.x.x) we should remove support for * this, and instead error with a helpful error message */ ModuleEntry.buildInvalidModule = function(name, dir) { return new this(name, '0.0.0' , dir, crypto.createHash('sha1').update([name, dir].filter(Boolean).join('\x00')).digest('hex'), false); }; /* * Compute and return the ModuleEntry for a given name/dir pair. This is done * recursively so a whole tree can be computed all at once, independent of the * hashing functions. We also compute the '_sourceHash' value (i.e. the hash of * just the package source files, excluding the node_modules dependencies) at * the same time to make it easier to establish the 'hash' value (includes * dependency _sourceHash values) later. * Note this is a class function, not an instance function. */ ModuleEntry.locate = function(caches, name, dir, hashTreeFn) { var Constructor = this; var nameDirKey = cacheKey(name, dir); var realPathKey; // It's possible that for a given name/dir pair, there is no package. // Record a null entry in CACHES.PATH anyway so we don't need to // redo that search each time. if (caches.PATH.has(nameDirKey)) { realPathKey = caches.PATH.get(nameDirKey); if (realPathKey !== null) { return caches.MODULE_ENTRY.get(realPathKey); } else { return this.buildInvalidModule(name, dir); } } // There is no caches.PATH entry. Try to get a real package.json path. If there // isn't a real path, the name+dir reference is invalid, so note that in caches.PATH. // If there is a real path, check if it is already in the caches.MODULE_ENTRY. // If not, create it and insert it. var realPath = resolvePackagePath(name, dir, caches);; if (realPath === null) { return this.buildInvalidModule(name, dir); } // We have a path to a file that supposedly is package.json. We need to be sure // that either we already have a caches.MODULE_ENTRY entry (in which case we can // just create a caches.PATH entry to point to it) or that we can read the // package.json file, at which point we can create a caches.MODULE_ENTRY entry, // then finally the new caches.PATH ENTRY. // Generate the cache key for a given real file path. This key is then // used as the key for entries in the CacheGroup.MODULE_ENTRY cache // and values in the CacheGroup.PATH cache. realPathKey = cacheKey('hashed:' + realPath, ''); if (caches.MODULE_ENTRY.has(realPathKey)) { caches.PATH.set(nameDirKey, realPathKey); return caches.MODULE_ENTRY.get(realPathKey); } // Require the package. If we get a 'module-not-found' error it will return null // and we can insert an entry in the cache saying we couldn't find the package // in case it's requested later. Any other more serious error we specifically // don't try to catch here. var thePackage = tryRequire(realPath); // if the package was not found, do as above to create a caches.PATH entry // that refers to no path, so we don't waste time doing it again later. if (thePackage === null) { caches.PATH.set(nameDirKey, null); return thePackage; } // We have the package object and the relevant keys. // Compute the dir containing the package.json, var rootDir = realPath.slice(0, realPath.length - 13); // length('/package.json') === 13 // Create and insert the new ModuleEntry into the cache.MODULE_ENTRY // now so we know to stop when dealing with cycles. var moduleEntry = new Constructor(thePackage.name, thePackage.version, rootDir, hashTreeFn(rootDir)); caches.MODULE_ENTRY.set(realPathKey, moduleEntry); caches.PATH.set(nameDirKey, realPathKey); // compute the dependencies here so the ModuleEntry doesn't need to know // about caches or the hashTreeFn or the package and we don't need to // guard against accidental reinitialization of dependencies. if (thePackage.dependencies) { // Recursively locate the references to other moduleEntry objects for the module's // dependencies. Initially we just do the 'local' dependencies (i.e. the ones referenced // in the package.json's 'dependencies' field.) Later, moduleEntry._gatherDependencies // is called to compute the complete list including transitive dependencies, and that // is then used for the final moduleEntry._hash calculation. Object.keys(thePackage.dependencies).sort().forEach(function(dep) { var dependencyModuleEntry = Constructor.locate(caches, dep, rootDir, hashTreeFn); // there's not really a good reason to include a failed resolution // of a package in the dependencies list. if (dependencyModuleEntry !== null) { moduleEntry.addDependency(dep, dependencyModuleEntry); } }); } return moduleEntry; }; package/lib/pkg.js000644 0000001227 3560116604 011147 0ustar00000000 000000 'use strict'; var resolvePkg = require('./resolve-pkg.js'); /* @private * * given the name of a descendent module this module locates and returns its * package.json. In addition, it provides the baseDir. * * @method pkg * @param {String} name * @param {String} dir (optional) root directory to begin resolution */ module.exports = function pkg(name, dir) { if (name !== './') { name += '/'; } var packagePath = resolvePkg(name, dir); if (packagePath === null) { return null; } var thePackage = require(packagePath); thePackage.baseDir = packagePath.slice(0, packagePath.length - 12 /* index of `/package.json` */); return thePackage; }; package/lib/resolve-pkg.js000644 0000000761 3560116604 012626 0ustar00000000 000000 'use strict'; var resolve = require('resolve'); var resolvePackagePath = require('resolve-package-path'); var path = require('path'); /* @private * * @method resolvePkg * @param {String} name * @param {String} dir * @return {String} */ module.exports = function resolvePkg(name, dir) { if (name.charAt(0) === '/') { return name + '/package.json'; } if (name === './') { return path.resolve(name, 'package.json'); } return resolvePackagePath(name, dir || __dirname); }; package/lib/try-require.js000644 0000000765 3560116604 012664 0ustar00000000 000000 'use strict'; /* * attempt to require a given node_module. * If the module was found, return found value * If the module was NOT found, return null * If requiring the module crashes for an unexpected reason, throw the unexpected error */ module.exports = function tryRequire(moduleName) { try { return require(moduleName); } catch (err) { if (err !== null && typeof err === 'object' && err.code === 'MODULE_NOT_FOUND') { return null; } else { throw err; } } };