├── .gitignore ├── .jshintrc ├── .npmignore ├── .travis.yml ├── Gruntfile.js ├── LICENSE-MIT ├── README.md ├── lib └── matchdep.js ├── package.json └── test ├── fixtures ├── package.json ├── sample.json └── submodule.js └── matchdep_test.js /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules/ 2 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "loopfunc": true, 3 | "curly": true, 4 | "eqeqeq": true, 5 | "immed": true, 6 | "latedef": true, 7 | "newcap": true, 8 | "noarg": true, 9 | "sub": true, 10 | "undef": true, 11 | "unused": true, 12 | "boss": true, 13 | "eqnull": true, 14 | "node": true 15 | } 16 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | test 2 | Gruntfile.js -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: 4 | - "6" 5 | - "8" 6 | - "10" 7 | - "node" 8 | before_install: 9 | - npm install -g grunt-cli 10 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(grunt) { 4 | 5 | // Project configuration. 6 | grunt.initConfig({ 7 | jshint: { 8 | options: { 9 | jshintrc: '.jshintrc' 10 | }, 11 | all: ['Gruntfile.js', 'lib/**/*.js', 'test/**/*.js'] 12 | }, 13 | nodeunit: { 14 | files: ['test/**/*_test.js'], 15 | } 16 | }); 17 | 18 | // Load plugins. 19 | grunt.loadNpmTasks('grunt-contrib-jshint'); 20 | grunt.loadNpmTasks('grunt-contrib-nodeunit'); 21 | 22 | // Default task. 23 | grunt.registerTask('default', ['jshint', 'nodeunit']); 24 | }; 25 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Tyler Kellen 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # matchdep [![Build Status](https://secure.travis-ci.org/tkellen/js-matchdep.svg?branch=master)](http://travis-ci.org/tkellen/js-matchdep) 2 | > Use [micromatch] to filter npm module dependencies by name. 3 | 4 | [![NPM](https://nodei.co/npm/matchdep.png)](https://nodei.co/npm/matchdep/) 5 | 6 | ## Examples 7 | 8 | ```js 9 | var matchdep = require('matchdep'); 10 | 11 | // Filter dependencies (by autoloading nearest package.json) 12 | matchdep.filter('mini*'); 13 | 14 | // Filter devDependencies (with config string indicating file to be required) 15 | matchdep.filterDev('grunt-contrib-*', './package.json'); 16 | 17 | // Filter peerDependencies (with config string indicating file to be required) 18 | matchdep.filterPeer('foo-{bar,baz}', './some-other.json'); 19 | 20 | // Filter all dependencies (with explicit config provided) 21 | matchdep.filterAll('*', require('./yet-another.json')); 22 | 23 | // Filter all dependencies, exclude grunt (multiple matching patterns) 24 | matchdep.filterAll(['*','!grunt']); 25 | ``` 26 | 27 | ## Usage 28 | 29 | ```js 30 | filter(pattern, config) 31 | filterDev(pattern, config) 32 | filterPeer(pattern, config) 33 | filterAll(pattern, config) 34 | ``` 35 | 36 | ### pattern 37 | Type: `String|Array` 38 | Default: 'none' 39 | 40 | A [micromatch] compatible match pattern to filter dependencies. 41 | 42 | ### config 43 | Type: `String` or `Object` 44 | Default: Path to nearest package.json. 45 | 46 | If config is a string, matchdep will attempt to require it. If it is an object, it will be used directly. 47 | 48 | ## Release History 49 | 50 | * 2017-08-18 - v2.0.0 - Upgrade major versions of dependencies, Upgrade devDeps 51 | * 2016-02-09 - v1.0.1 - switch to [micromatch], remove [globule] 52 | * 2015-09-27 - v1.0.0 - throw when no package.json found, update dependencies, remove node 0.8 support 53 | * 2013-10-09 - v0.3.0 - support multiple pattern matches using [globule] 54 | * 2013-10-08 - v0.2.0 - refactor and support filtering peerDependencies 55 | * 2012-11-27 - v0.1.0 - initial release 56 | 57 | 58 | [globule]: https://github.com/cowboy/node-globule 59 | [micromatch]: https://github.com/jonschlinkert/micromatch 60 | -------------------------------------------------------------------------------- /lib/matchdep.js: -------------------------------------------------------------------------------- 1 | /* 2 | * matchdep 3 | * https://github.com/tkellen/node-matchdep 4 | * 5 | * Copyright (c) 2012 Tyler Kellen 6 | * Licensed under the MIT license. 7 | */ 8 | 9 | 'use strict'; 10 | 11 | var micromatch = require('micromatch'); 12 | var findup = require('findup-sync'); 13 | var resolve = require('resolve').sync; 14 | var stackTrace = require('stack-trace'); 15 | var path = require('path'); 16 | 17 | // export object 18 | var matchdep = module.exports = {}; 19 | 20 | // Ensure configuration has the correct properties. 21 | function loadConfig(config, props) { 22 | // The calling module's path. Unfortunately, because modules are cached, 23 | // module.parent is the FIRST calling module parent, not necessarily the 24 | // current one. 25 | var callerPath = path.dirname(stackTrace.get(loadConfig)[1].getFileName()); 26 | 27 | // If no config defined, resolve to nearest package.json to the calling lib. If not found, throw an error. 28 | if (config == null) { 29 | config = findup('package.json', {cwd: callerPath}); 30 | if (config == null) { 31 | throw new Error('No package.json found.'); 32 | } 33 | } 34 | // If filename was specified with no path parts, make the path absolute so 35 | // that resolve doesn't look in node_module directories for it. 36 | else if (typeof config === 'string' && !/[\\\/]/.test(config)) { 37 | config = path.join(callerPath, config); 38 | } 39 | 40 | // If package is a string, try to require it. 41 | if (typeof config === 'string') { 42 | config = require(resolve(config, {basedir: callerPath})); 43 | } 44 | 45 | // If config is not an object yet, something is amiss. 46 | if (typeof config !== 'object') { 47 | throw new Error('Invalid configuration specified.'); 48 | } 49 | 50 | // For all specified props, populate result object. 51 | var result = {}; 52 | props.forEach(function(prop) { 53 | result[prop] = config[prop] ? Object.keys(config[prop]) : []; 54 | }); 55 | return result; 56 | } 57 | 58 | // What config properties should each method search? 59 | var methods = { 60 | filter: ['dependencies'], 61 | filterDev: ['devDependencies'], 62 | filterPeer: ['peerDependencies'], 63 | filterAll: ['dependencies', 'devDependencies', 'peerDependencies'], 64 | }; 65 | 66 | // Dynamically generate methods. 67 | Object.keys(methods).forEach(function(method) { 68 | var props = methods[method]; 69 | matchdep[method] = function(pattern, config) { 70 | config = loadConfig(config, props); 71 | var search = props.reduce(function(result, prop) { 72 | return result.concat(config[prop]); 73 | }, []); 74 | return micromatch(search, pattern); 75 | }; 76 | }); 77 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "matchdep", 3 | "description": "Use micromatch to filter npm module dependencies by name.", 4 | "version": "2.0.0", 5 | "homepage": "https://github.com/tkellen/js-matchdep", 6 | "author": { 7 | "name": "Tyler Kellen", 8 | "url": "http://goingslowly.com/" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git://github.com/tkellen/js-matchdep.git" 13 | }, 14 | "bugs": { 15 | "url": "https://github.com/tkellen/js-matchdep/issues" 16 | }, 17 | "license": "MIT", 18 | "main": "lib/matchdep", 19 | "engines": { 20 | "node": ">= 0.10.0" 21 | }, 22 | "scripts": { 23 | "test": "grunt" 24 | }, 25 | "dependencies": { 26 | "findup-sync": "^2.0.0", 27 | "micromatch": "^3.0.4", 28 | "resolve": "^1.4.0", 29 | "stack-trace": "0.0.10" 30 | }, 31 | "devDependencies": { 32 | "grunt": "^1.0.1", 33 | "grunt-contrib-jshint": "^1.1.0", 34 | "grunt-contrib-nodeunit": "^1.0.0" 35 | }, 36 | "keywords": [ 37 | "package.json", 38 | "dependencies", 39 | "devDependencies", 40 | "peerDependencies" 41 | ] 42 | } 43 | -------------------------------------------------------------------------------- /test/fixtures/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "pkg-1": "~1.2.3", 4 | "pkg-2": "~1.2.3", 5 | "pkg-3": "~1.2.3" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/sample.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "dep-1": "~1.2.3", 4 | "dep-2": "~1.2.3", 5 | "dep-3": "~1.2.3" 6 | }, 7 | "devDependencies": { 8 | "dev-1": "~1.2.3", 9 | "dev-2": "~1.2.3", 10 | "dev-3": "~1.2.3" 11 | }, 12 | "peerDependencies": { 13 | "peer-1": "~1.2.3", 14 | "peer-2": "~1.2.3", 15 | "peer-3": "~1.2.3" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/fixtures/submodule.js: -------------------------------------------------------------------------------- 1 | var matchdep = require('../../lib/matchdep'); 2 | 3 | exports.defaultConfig = function() { 4 | return matchdep.filter('*'); 5 | }; 6 | 7 | exports.fileConfig = function() { 8 | return matchdep.filter('*', 'package.json'); 9 | }; 10 | 11 | exports.relativeConfig = function() { 12 | return matchdep.filter('*', './package.json'); 13 | }; 14 | 15 | exports.relativeConfig2 = function() { 16 | return matchdep.filter('*', '../../package.json'); 17 | }; 18 | 19 | exports.absoluteConfig = function() { 20 | return matchdep.filter('*', __dirname + '/package.json'); 21 | }; 22 | -------------------------------------------------------------------------------- /test/matchdep_test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var matchdep = require('../lib/matchdep'); 4 | 5 | exports['matchdep'] = { 6 | setUp: function(done) { 7 | this.fixture = __dirname + '/fixtures/sample.json'; 8 | done(); 9 | }, 10 | filter: function(test) { 11 | test.expect(1); 12 | test.equal(matchdep.filter('*', this.fixture).join(), 'dep-1,dep-2,dep-3', 'should find all dependencies matching "*"'); 13 | test.done(); 14 | }, 15 | filterDev: function(test) { 16 | test.expect(1); 17 | test.equal(matchdep.filterDev('*', this.fixture).join(), 'dev-1,dev-2,dev-3', 'should find all devDependencies matching "*"'); 18 | test.done(); 19 | }, 20 | filterPeer: function(test) { 21 | test.expect(1); 22 | test.equal(matchdep.filterPeer('*', this.fixture).join(), 'peer-1,peer-2,peer-3', 'should find all peerDependencies matching "*"'); 23 | test.done(); 24 | }, 25 | filterAll: function(test) { 26 | test.expect(1); 27 | test.equal(matchdep.filterAll('*', this.fixture).join(), 'dep-1,dep-2,dep-3,dev-1,dev-2,dev-3,peer-1,peer-2,peer-3', 'should find everything matching "*"'); 28 | test.done(); 29 | }, 30 | 'wildcard support': function(test) { 31 | test.expect(3); 32 | test.equal(matchdep.filterAll('*', this.fixture).join(), 'dep-1,dep-2,dep-3,dev-1,dev-2,dev-3,peer-1,peer-2,peer-3', 'should find everything matching "*"'); 33 | test.equal(matchdep.filterAll('*-{1,3}', this.fixture).join(), 'dep-1,dep-3,dev-1,dev-3,peer-1,peer-3', 'should find everything matching "*-{1,3}"'); 34 | test.equal(matchdep.filterAll('', this.fixture).join(), '', 'should find nothing, since "" matches nothing'); 35 | test.done(); 36 | }, 37 | 'multiple pattern support': function(test) { 38 | test.expect(1); 39 | test.equal(matchdep.filterAll(['*','!micromatch']).join(), 'findup-sync,resolve,stack-trace,grunt,grunt-contrib-jshint,grunt-contrib-nodeunit', 'should find everything except micromatch'); 40 | test.done(); 41 | }, 42 | 'default to package.json': function(test) { 43 | test.expect(1); 44 | test.equal(matchdep.filter('*').join(), 'findup-sync,micromatch,resolve,stack-trace', 'should find all dependencies and devDependencies matching "*"'); 45 | test.done(); 46 | }, 47 | 'path is relative to calling module, not cwd': function(test) { 48 | test.expect(5); 49 | var submodule = require('./fixtures/submodule'); 50 | test.equal(submodule.defaultConfig().join(), 'pkg-1,pkg-2,pkg-3', 'should find all deps in package.json next to submodule'); 51 | test.equal(submodule.fileConfig().join(), 'pkg-1,pkg-2,pkg-3', 'should find all deps in package.json next to submodule'); 52 | test.equal(submodule.relativeConfig().join(), 'pkg-1,pkg-2,pkg-3', 'should find all deps in package.json next to submodule'); 53 | test.equal(submodule.relativeConfig2().join(), 'findup-sync,micromatch,resolve,stack-trace', 'should find all deps in ../../package.json from submodule'); 54 | test.equal(submodule.absoluteConfig().join(), 'pkg-1,pkg-2,pkg-3', 'should find all deps in package.json next to submodule'); 55 | test.done(); 56 | }, 57 | }; 58 | --------------------------------------------------------------------------------