├── .editorconfig ├── .gitattributes ├── .gitignore ├── .travis.yml ├── LICENSE ├── appveyor.yml ├── cli.js ├── index.js ├── lib ├── darwin.js ├── helpers.js └── win32.js ├── media ├── osx-usage.gif └── windows-usage.gif ├── package.json ├── readme.md └── test ├── darwin.js ├── general.js └── win32.js /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | node_modules 3 | typings 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | os: osx 2 | sudo: false 3 | language: cpp 4 | env: 5 | matrix: 6 | - TRAVIS_NODE_VERSION="4" 7 | - TRAVIS_NODE_VERSION="node" 8 | 9 | install: 10 | - rm -rf ~/.nvm && git clone https://github.com/creationix/nvm.git ~/.nvm && (cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`) && source ~/.nvm/nvm.sh && nvm install $TRAVIS_NODE_VERSION 11 | - PATH="`npm bin`:`npm bin -g`:$PATH" 12 | # Install dependencies and build 13 | - npm install 14 | 15 | script: 16 | # Output useful info for debugging 17 | - node --version 18 | - npm --version 19 | # Run tests 20 | - npm test 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Dave Jeffery 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | environment: 2 | matrix: 3 | - nodejs_version: "6" 4 | - nodejs_version: "7" 5 | 6 | install: 7 | - ps: Install-Product node $env:nodejs_version 8 | - npm install --force 9 | 10 | test_script: 11 | - node --version 12 | - npm --version 13 | - npm test 14 | 15 | build: off 16 | -------------------------------------------------------------------------------- /cli.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 'use strict'; 3 | 4 | const meow = require('meow'); 5 | const john = require('./'); 6 | const platform = process.platform.toLowerCase(); 7 | const supportedPlatforms = require('./package').os; 8 | 9 | (function () { 10 | if (supportedPlatforms.indexOf(platform) === -1) { 11 | return console.error(new Error(`${platform} unsupported, supported platforms: ${supportedPlatforms}`)); 12 | } 13 | const platformLib = require(`./lib/${platform}`); 14 | 15 | const cli = meow( 16 | platformLib.cliHelpText(), 17 | typeof platformLib.cliOptions === 'function' ? platformLib.cliOptions() : {} 18 | ); 19 | 20 | john(process.cwd(), cli.flags).then( 21 | deps => { 22 | platformLib.cliLog(deps, 'dependencies'); 23 | console.log(); 24 | platformLib.cliLog(deps, 'devDependencies'); 25 | } 26 | ); 27 | })(); 28 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const helpers = require('./lib/helpers'); 5 | const readPkgUp = require('read-pkg-up'); 6 | const platform = process.platform.toLowerCase(); 7 | const supportedPlatforms = require('./package').os; 8 | 9 | const defaultOpts = { 10 | clear: false, 11 | // OSX options 12 | dependencyColor: 'blue', 13 | devDependencyColor: 'yellow', 14 | // Windows options 15 | dependencyHidden: false, 16 | devDependencyHidden: false 17 | }; 18 | 19 | module.exports = (projectPath, opts) => { 20 | let modulesPath; 21 | const findRootPackage = () => 22 | readPkgUp({cwd: projectPath}).then(pkg => { 23 | if (!pkg.pkg) { 24 | return Promise.reject(new Error(`couldn't find package.json in ${projectPath}`)); 25 | } 26 | projectPath = path.dirname(pkg.path); 27 | modulesPath = path.join(projectPath, 'node_modules'); 28 | return pkg.pkg; 29 | }); 30 | 31 | return (function main() { 32 | if (supportedPlatforms.indexOf(platform) === -1) { 33 | return Promise.reject(new Error(`${platform} unsupported, supported platforms: ${supportedPlatforms}`)); 34 | } 35 | 36 | const platformLib = require(`./lib/${platform}`); 37 | 38 | if (typeof projectPath !== 'string') { 39 | return Promise.reject(new TypeError('projectPath path should be a string')); 40 | } 41 | 42 | opts = Object.assign({}, defaultOpts, opts || {}); 43 | 44 | if (typeof platformLib.handleOptions === 'function') { 45 | opts = platformLib.handleOptions(opts); 46 | } 47 | 48 | if (typeof platformLib.performPreAction !== 'function') { 49 | platformLib.performPreAction = () => Promise.resolve(); 50 | } 51 | 52 | return findRootPackage() 53 | .then(rootPackage => 54 | platformLib.performPreAction(projectPath, opts) 55 | .then(() => 56 | Promise.all([ 57 | helpers.getDeps(modulesPath, rootPackage.dependencies), 58 | helpers.getDeps(modulesPath, rootPackage.devDependencies) 59 | ]).then(deps => 60 | Promise.all([ 61 | platformLib.performAction('dependencies', deps[0], opts), 62 | platformLib.performAction('devDependencies', deps[1], opts) 63 | ]) 64 | ).then(affectedDeps => ({ 65 | dependencies: affectedDeps[0], 66 | devDependencies: affectedDeps[1] 67 | })) 68 | ) 69 | ); 70 | })(); 71 | }; 72 | -------------------------------------------------------------------------------- /lib/darwin.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const tag = require('finder-tag'); 4 | const chalk = require('chalk'); 5 | 6 | /** 7 | * Set colors to `clear` if the clear option is Set 8 | * @param {Object} opts 9 | * @return {Object} opts 10 | */ 11 | const handleOptions = opts => { 12 | if (opts.clear) { 13 | opts.dependencyColor = opts.devDependencyColor = 'clear'; 14 | } 15 | return opts; 16 | }; 17 | 18 | /** 19 | * Tag dependency folders with colors 20 | * @param {String} depType 'dependencies' or 'devDependencies' 21 | * @param {Array.} deps 22 | * @param {Object} opts 23 | * @return {Promise.>} 24 | */ 25 | const performAction = (depType, deps, opts) => { 26 | // tag dependency directories with corresponding color 27 | const depTypeSingular = `${depType.slice(0, -3)}y`; 28 | const color = opts[`${depTypeSingular}Color`]; 29 | 30 | return Promise.all(deps.map(dep => 31 | tag(dep.path, color) 32 | .then(data => { 33 | data.module = dep.module; 34 | return data; 35 | }) 36 | )); 37 | }; 38 | 39 | /** 40 | * CLI output to the user 41 | * @param {Array.} deps 42 | * @param {String} depType 'dependencies' or 'devDependencies' 43 | */ 44 | const cliLog = (deps, depType) => { 45 | const terminalColor = color => chalk[color] ? chalk[color](color) : color; 46 | 47 | deps = deps[depType]; 48 | if (!deps.length) { 49 | return console.log(`No ${depType} found.`); 50 | } 51 | const color = deps[0].tag; 52 | 53 | const logRemove = `Removed tags from ${depType}:`; 54 | const logNormal = `Tagged ${deps.length} ${depType} as ${terminalColor(color)}:`; 55 | console.log(color === 'clear' ? logRemove : logNormal); 56 | 57 | deps.forEach(dep => console.log(` - ${dep.module}`)); 58 | }; 59 | 60 | /** 61 | * Output the CLI helper text for OS X 62 | */ 63 | const cliHelpText = () => 64 | [ 65 | 'Usage', 66 | ' $ john', 67 | '', 68 | 'Options', 69 | ' --clear Clear all tags. [Default: false]', 70 | ' --deps Color for dependencies. [Default: blue]', 71 | ' --dev-deps Color for devDependencies. [Default: yellow]', 72 | '', 73 | 'Examples', 74 | ' $ john', 75 | ' Tagged 4 dependencies as blue', 76 | ' Tagged 2 devDependencies as yellow', 77 | '', 78 | ' $ john --clear', 79 | ' Removed 4 tags from dependencies', 80 | ' Removed 2 tags from devDependencies', 81 | '', 82 | ' $ john --deps=purple --dev-deps=gray', 83 | ' Tagged 4 dependencies as purple', 84 | ' Tagged 2 devDependencies as gray' 85 | ]; 86 | 87 | /** 88 | * Defines the OS X CLI options 89 | */ 90 | const cliOptions = () => 91 | ({ 92 | alias: { 93 | dep: 'dependencyColor', 94 | devDep: 'devDependencyColor', 95 | deps: 'dependencyColor', 96 | devDeps: 'devDependencyColor' 97 | } 98 | }); 99 | 100 | module.exports = { 101 | handleOptions, 102 | performAction, 103 | cliHelpText, 104 | cliOptions, 105 | cliLog 106 | }; 107 | -------------------------------------------------------------------------------- /lib/helpers.js: -------------------------------------------------------------------------------- 1 | const pify = require('pify'); 2 | const path = require('path'); 3 | const stat = pify(require('fs').stat); 4 | 5 | /** 6 | * Convert object to array (or pass-through is already array) 7 | * @param {Array|Object} arr 8 | * @return {Array} arr 9 | */ 10 | const toArray = arr => 11 | Array.isArray(arr) ? arr : Object.keys(arr || {}); 12 | 13 | /** 14 | * get path and module name for each dependency 15 | * @param {String} modulePath path to `node_modules` 16 | * @param {Array|Object} deps 17 | * @return {Array} deps 18 | */ 19 | const getDepPaths = (modulePath, deps) => 20 | toArray(deps).map(dep => ({ 21 | path: path.join(modulePath, dep), 22 | module: dep 23 | })); 24 | 25 | /** 26 | * check if `dep.path` exists and is directory otherwise return false 27 | * @param {Array} deps 28 | * @return {Promise.>} 29 | */ 30 | const checkDeps = deps => 31 | deps.map(dep => 32 | stat(dep.path) 33 | // Check if dep.path is directory 34 | .then(stats => stats.isDirectory() && dep) 35 | // Catch handles dependencies that are not installed 36 | .catch(() => false) 37 | ); 38 | 39 | /** 40 | * remove dependencies that are falsy 41 | * @param {Promise.>} deps 42 | * @return {Promise.>} 43 | */ 44 | const filterDeps = deps => 45 | // Filter out `deps` with value `false` 46 | Promise.all(deps).then(resolvedDeps => resolvedDeps.filter(dep => Boolean(dep))); 47 | 48 | /** 49 | * get dependency paths and filter out invalid paths 50 | * @param {String} module Path path to `node_modules` dir 51 | * @param {Array|Object} deps 52 | * @return {Promise.>} 53 | */ 54 | const getDeps = (modulePath, deps) => 55 | filterDeps(checkDeps(getDepPaths(modulePath, deps))); 56 | 57 | module.exports = { 58 | filterDeps, 59 | getDeps, 60 | getDepPaths 61 | }; 62 | -------------------------------------------------------------------------------- /lib/win32.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const pify = require('pify'); 4 | const fs = require('fs'); 5 | const path = require('path'); 6 | const helpers = require('./helpers'); 7 | const readdir = pify(fs.readdir); 8 | const writeFile = pify(fs.writeFile); 9 | const fswin = require('fswin'); 10 | 11 | /** 12 | * Modify options object as needed for Windows 13 | * @param opts Object 14 | * @returns Object 15 | */ 16 | const handleOptions = opts => { 17 | // Convert any CLI params to boolean 18 | Object.keys(opts).forEach(key => { 19 | const val = opts[key]; 20 | if (typeof val === 'string') { 21 | opts[key] = opts[key] === 'true'; 22 | } 23 | }); 24 | 25 | if (opts.clear) { 26 | opts.dependencyHidden = opts.devDependencyHidden = false; 27 | } 28 | return opts; 29 | }; 30 | 31 | /** 32 | * Sets the value of the `hidden` attribute on dependency paths 33 | * @param deps Object 34 | * @param hidden Boolean 35 | * @returns {Promise} 36 | */ 37 | const setHiddenAttr = (deps, hidden) => 38 | Promise.all( 39 | deps.map(dep => 40 | fswin.setAttributesSync(dep.path, {IS_HIDDEN: hidden}) ? 41 | Promise.resolve(Object.assign(dep, {hidden})) : 42 | Promise.reject(new Error(`Failed to modify dir attr: ${dep.path}`)) 43 | ) 44 | ); 45 | 46 | /** 47 | * This hides all the dependencies first and writes the info file 48 | * @param projectPath String 49 | * @param opts Object 50 | * @returns {Promise} 51 | */ 52 | const performPreAction = (projectPath, opts) => { 53 | const modules = path.join(projectPath, 'node_modules'); 54 | const hidden = typeof opts.clear === 'boolean' ? !opts.clear : true; 55 | 56 | const writeTextFile = writeFile( 57 | path.join(modules, 'modules_hidden.txt'), 58 | 'You\'ve hidden modules with `john` - https://github.com/davej/john', 59 | {flags: 'w'} 60 | ); 61 | 62 | return writeTextFile 63 | .then(() => readdir(modules)) 64 | .then(files => helpers.getDeps(modules, files)) 65 | .then(deps => setHiddenAttr(deps, hidden)); 66 | }; 67 | 68 | /** 69 | * Determine whether to hide or show the passed in type of dependencies 70 | * @param depType String 71 | * @param deps Object 72 | * @param opts Object 73 | * @returns {Promise} 74 | */ 75 | const performAction = (depType, deps, opts) => { 76 | const depTypeSingular = `${depType.slice(0, -3)}y`; 77 | const hidden = opts[`${depTypeSingular}Hidden`]; 78 | 79 | return setHiddenAttr(deps, hidden); 80 | }; 81 | 82 | /** 83 | * CLI output to the user 84 | * @param deps Object 85 | * @param depType String 86 | */ 87 | const cliLog = (deps, depType) => { 88 | deps = deps[depType]; 89 | if (deps.length) { 90 | const hidden = deps[0].hidden; 91 | const logShow = `Unhid ${depType}:`; 92 | const logHide = `Hid ${deps.length} ${depType}:`; 93 | console.log(hidden ? logHide : logShow); 94 | 95 | deps.forEach(dep => console.log(` - ${dep.module}`)); 96 | } else { 97 | console.log(`No ${depType} found.`); 98 | } 99 | }; 100 | 101 | /** 102 | * Output the helper text for using john in Windows 103 | */ 104 | const cliHelpText = () => 105 | [ 106 | 'Usage', 107 | ' > john', 108 | '', 109 | 'Options', 110 | ' --clear Clear all hidden dependencies. [Default: false]', 111 | ' --deps Hide dependencies. [Default: false]', 112 | ' --dev-deps Hide devDependencies. [Default: false]', 113 | '', 114 | 'Examples', 115 | ' $ john', 116 | ' Hid 4 dependencies', 117 | '', 118 | ' $ john --clear', 119 | ' Unhid 4 dependencies' 120 | ]; 121 | 122 | /** 123 | * Defines the Windows options for john 124 | */ 125 | const cliOptions = () => 126 | ({ 127 | alias: { 128 | dep: 'dependencyHidden', 129 | devDep: 'devDependencyHidden', 130 | deps: 'dependencyHidden', 131 | devDeps: 'devDependencyHidden' 132 | } 133 | }); 134 | 135 | module.exports = { 136 | handleOptions, 137 | performPreAction, 138 | performAction, 139 | cliHelpText, 140 | cliOptions, 141 | cliLog 142 | }; 143 | -------------------------------------------------------------------------------- /media/osx-usage.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davej/john/a8a20ef6fa7888da50ba5b585be4af7faf8351bb/media/osx-usage.gif -------------------------------------------------------------------------------- /media/windows-usage.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davej/john/a8a20ef6fa7888da50ba5b585be4af7faf8351bb/media/windows-usage.gif -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "john", 3 | "version": "1.1.0", 4 | "description": "Make npm3's flat dependencies easier to find and sort", 5 | "license": "MIT", 6 | "os": [ 7 | "darwin", 8 | "win32" 9 | ], 10 | "repository": "davej/john", 11 | "author": { 12 | "name": "DaveJ", 13 | "email": "dave@davejeffery.com", 14 | "url": "twitter.com/DaveJ" 15 | }, 16 | "contributors": [ 17 | { 18 | "name": "Enzo Martin", 19 | "email": "enzo.r.martin@gmail.com" 20 | } 21 | ], 22 | "bin": "cli.js", 23 | "engines": { 24 | "node": ">=4" 25 | }, 26 | "scripts": { 27 | "test": "xo && ava" 28 | }, 29 | "files": [ 30 | "lib", 31 | "index.js", 32 | "cli.js" 33 | ], 34 | "keywords": [ 35 | "cli-app", 36 | "cli", 37 | "npm", 38 | "npm3", 39 | "node_modules", 40 | "flatdeps", 41 | "osx", 42 | "tag", 43 | "tags", 44 | "color", 45 | "colour", 46 | "finder", 47 | "windows", 48 | "explorer", 49 | "mavericks", 50 | "yosemite", 51 | "mac" 52 | ], 53 | "dependencies": { 54 | "chalk": "^1.1.1", 55 | "meow": "^3.6.0", 56 | "pify": "^2.3.0", 57 | "read-pkg-up": "^1.0.1" 58 | }, 59 | "optionalDependencies": { 60 | "finder-tag": "^1.0.2", 61 | "fswin": "^2.15.1031" 62 | }, 63 | "devDependencies": { 64 | "ava": "^0.11.0", 65 | "xo": "^0.12.1" 66 | }, 67 | "xo": { 68 | "space": 2, 69 | "rules": { 70 | "linebreak-style": 0 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # john 2 | 3 | > Make npm's flat dependencies easier to find and sort 4 | 5 | [![npm version](https://img.shields.io/npm/v/john.svg)](https://www.npmjs.com/package/john) [![Build status: OS X](https://img.shields.io/travis/davej/john/master.svg?label=OS%20X)](https://travis-ci.org/davej/john) [![Build status: Windows](https://img.shields.io/appveyor/ci/davej/john/master.svg?label=windows)](https://ci.appveyor.com/project/davej/john/branch/master) 6 | 7 | `npm3+` has flat dependency trees, this is a good thing for many reasons. 8 | Unfortunately, this means your `node_modules` folder might contain hundreds (or thousands?) 9 | of modules and that makes it difficult to quickly debug/hack on issues with top-level dependencies. 10 | 11 | #### On OS X 12 | Puts color tags on your top-level dependencies and devDependencies, 13 | making top-level dependencies easier to find and sort in Finder. 14 | 15 | If you often use the terminal instead of finder then you can also do `ls -l | grep @` to list the folders with tags. 16 | 17 |

18 | 19 | #### On Windows 20 | Hides away non top-level dependencies and devDependencies, leaving you with just the modules that are important to you. 21 | 22 |

23 | 24 | > *Note: This project is currently OS X & Windows only, but if you have ideas on how something similar could be implemented on Linux or other platforms then create an issue.* 25 | 26 | ## Table of Contents 27 | 28 | * [CLI](#cli) 29 | * [OS X](#os-x) 30 | * [Windows](#windows) 31 | * [Using Programmatically](#using-programmatically) 32 | * [API](#api) 33 | * [See available colors](#available-colors-os-x-only) 34 | * [Why is this called John?](#why-is-this-called-john) 35 | * [Contributors](#contributors) 36 | * [License](#license) 37 | 38 | ## CLI 39 | 40 | ``` 41 | $ npm install --global john 42 | ``` 43 | 44 | #### OS X 45 | 46 | ``` 47 | $ john --help 48 | 49 | Make npm3's flat dependencies easier to find and sort 50 | 51 | Usage 52 | $ john 53 | 54 | Options 55 | --clear Clear all tags. [Default: false] 56 | --deps Color for dependencies. [Default: blue] 57 | --dev-deps Color for devDependencies. [Default: yellow] 58 | 59 | Available Colors: 60 | gray, green, purple, blue, yellow, red, orange, clear. 61 | 62 | Examples 63 | $ john 64 | Tagged 4 dependencies as blue 65 | Tagged 2 devDependencies as yellow 66 | 67 | $ john --clear 68 | Removed 4 tags from dependencies 69 | Removed 2 tags from devDependencies 70 | 71 | $ john --deps=purple --dev-deps=gray 72 | Tagged 4 dependencies as purple 73 | Tagged 2 devDependencies as gray 74 | ``` 75 | 76 | #### Windows 77 | 78 | ``` 79 | > john --help 80 | 81 | Make npm3's flat dependencies easier to find and sort 82 | 83 | Usage 84 | > john 85 | 86 | Options 87 | --clear Clear all hidden dependencies. [Default: false] 88 | --deps Hide dependencies. [Default: false] 89 | --dev-deps Hide devDependencies. [Default: false] 90 | 91 | Examples 92 | $ john 93 | Hid 4 dependencies 94 | 95 | $ john --clear 96 | Unhid 4 dependencies 97 | ``` 98 | 99 | ## Using Programmatically 100 | 101 | ### Install 102 | 103 | ``` 104 | $ npm install --save john 105 | ``` 106 | 107 | ### Usage 108 | 109 | ```js 110 | const john = require('john'); 111 | 112 | john('/path/to/project').then( 113 | (result) => console.log(result) 114 | // { 115 | // dependencies: [ 116 | // { 117 | // code: 0, 118 | // command: 'xattr …', 119 | // path: '/path/to/project/node_modules/finder-tag', 120 | // tag: 'blue', 121 | // module: 'finder-tag' 122 | // }, 123 | // {…}, 124 | // {…} 125 | // ], 126 | // devDependencies: [ 127 | // {…}, 128 | // {…} 129 | // ] 130 | // } 131 | ) 132 | ``` 133 | 134 | ## API 135 | 136 | ### john(projectPath, [options]) 137 | 138 | #### projectPath 139 | 140 | Type: `string` 141 | 142 | The path to your project's directory (that contains `package.json`). 143 | 144 | #### options 145 | 146 | ##### clear 147 | 148 | Type: `boolean` 149 | Default: `false` 150 | 151 | Clear all tags / show all dependencies. 152 | 153 | 154 | ##### dependencyColor *(OS X only)* 155 | 156 | Type: `string` 157 | Default: `blue` 158 | 159 | Color tag to use for dependencies. [See available colors](#available-colors-os-x-only). 160 | 161 | 162 | ##### devDependencyColor *(OS X only)* 163 | 164 | Type: `string` 165 | Default: `yellow` 166 | 167 | Color tag to use for devDependencies. [See available colors](#available-colors-os-x-only). 168 | 169 | 170 | ##### dependencyHidden *(Windows only)* 171 | 172 | Type: `boolean` 173 | Default: `false` 174 | 175 | Set to `true` to hide dependencies 176 | 177 | 178 | ##### devDependencyHidden *(Windows only)* 179 | 180 | Type: `boolean` 181 | Default: `false` 182 | 183 | Set to `true` to hide dev dependencies 184 | 185 | --- 186 | 187 | #### Available Colors *(OS X only)*: 188 | 189 | * gray 190 | * green 191 | * purple 192 | * blue 193 | * yellow 194 | * red 195 | * orange 196 | * clear (This will remove all tags) 197 | 198 | ## Why is this called John? 199 | 200 | Asking the important questions! 'John' like 'Johnny' like 'Johnny Depp' like 'Dep[p]endency'. Pfft, mainly because it was short, simple and not already taken. 201 | 202 | ## Contributors 203 | 204 | Special thanks to **[@EnzoMartin](https://github.com/EnzoMartin)** for doing the Windows work. 205 | 206 | 207 | ## License 208 | 209 | MIT © [DaveJ](https://twitter.com/DaveJ) 210 | -------------------------------------------------------------------------------- /test/darwin.js: -------------------------------------------------------------------------------- 1 | import test from 'ava'; 2 | import fn from '../'; 3 | import path from 'path'; 4 | const rootDir = path.resolve(__dirname, '../'); 5 | 6 | if (process.platform === 'darwin') { 7 | test('simple', t => 8 | fn(rootDir).then(tagged => { 9 | t.ok(tagged.dependencies); 10 | t.ok(tagged.devDependencies); 11 | t.is(tagged.dependencies[0].code, 0); 12 | t.ok(tagged.dependencies[0].command.length > 10); 13 | t.ok(tagged.dependencies[0].path.includes(rootDir)); 14 | t.is(tagged.dependencies[0].tag, 'blue'); 15 | t.is(tagged.devDependencies[0].tag, 'yellow'); 16 | }) 17 | ); 18 | 19 | test('launched from within node_modules dir', t => 20 | fn(path.join(rootDir, 'node_modules')).then(tagged => { 21 | t.ok(tagged.dependencies); 22 | t.ok(tagged.devDependencies); 23 | t.is(tagged.dependencies[0].code, 0); 24 | t.ok(tagged.dependencies[0].command.length > 10); 25 | t.ok(tagged.dependencies[0].path.includes(rootDir)); 26 | t.is(tagged.dependencies[0].tag, 'blue'); 27 | t.is(tagged.devDependencies[0].tag, 'yellow'); 28 | }) 29 | ); 30 | 31 | test('different colors', t => 32 | fn(rootDir, { 33 | dependencyColor: 'green', 34 | devDependencyColor: 'purple' 35 | }).then(tagged => { 36 | t.ok(tagged.dependencies); 37 | t.ok(tagged.devDependencies); 38 | t.is(tagged.dependencies[0].tag, 'green'); 39 | t.is(tagged.devDependencies[0].tag, 'purple'); 40 | }) 41 | ); 42 | 43 | test.after('clear tags', t => 44 | fn(rootDir, {clear: true}).then(tagged => { 45 | t.ok(tagged.dependencies); 46 | t.ok(tagged.devDependencies); 47 | t.is(tagged.dependencies[0].tag, 'clear'); 48 | t.is(tagged.devDependencies[0].tag, 'clear'); 49 | }) 50 | ); 51 | } else { 52 | test('skip darwin tests', t => 53 | t.pass() 54 | ); 55 | } 56 | -------------------------------------------------------------------------------- /test/general.js: -------------------------------------------------------------------------------- 1 | import test from 'ava'; 2 | import fn from '../'; 3 | 4 | test('invalid path', t => 5 | fn('/foo/bar').then(t.fail, err => t.ok(err.message.includes('couldn\'t find package.json'))) 6 | ); 7 | 8 | test('non-node path', t => 9 | fn('/tmp').then(t.fail, err => t.ok(err.message.includes('couldn\'t find package.json'))) 10 | ); 11 | -------------------------------------------------------------------------------- /test/win32.js: -------------------------------------------------------------------------------- 1 | import test from 'ava'; 2 | import fn from '../'; 3 | import path from 'path'; 4 | const rootDir = path.resolve(__dirname, '../'); 5 | 6 | if (process.platform === 'win32') { 7 | test('simple run with defaults', t => 8 | fn(rootDir).then(files => { 9 | t.ok(files.dependencies); 10 | t.ok(files.devDependencies); 11 | t.ok(files.dependencies[0].path.includes(rootDir)); 12 | t.is(files.dependencies[0].hidden, false); 13 | t.is(files.devDependencies[0].hidden, false); 14 | }) 15 | ); 16 | 17 | test('launched from within node_modules dir', t => 18 | fn(path.join(rootDir, 'node_modules')).then(files => { 19 | t.ok(files.dependencies); 20 | t.ok(files.devDependencies); 21 | t.ok(files.dependencies[0].path.includes(rootDir)); 22 | t.is(files.dependencies[0].hidden, false); 23 | t.is(files.devDependencies[0].hidden, false); 24 | }) 25 | ); 26 | 27 | test('hide dependencies', t => 28 | fn(rootDir, { 29 | dependencyHidden: true, 30 | devDependencyHidden: false 31 | }).then(files => { 32 | t.ok(files.dependencies); 33 | t.ok(files.devDependencies); 34 | t.is(files.dependencies[0].hidden, true); 35 | t.is(files.devDependencies[0].hidden, false); 36 | }) 37 | ); 38 | 39 | test('hide devDependencies', t => 40 | fn(rootDir, { 41 | dependencyHidden: false, 42 | devDependencyHidden: true 43 | }).then(files => { 44 | t.ok(files.dependencies); 45 | t.ok(files.devDependencies); 46 | t.is(files.dependencies[0].hidden, false); 47 | t.is(files.devDependencies[0].hidden, true); 48 | }) 49 | ); 50 | 51 | test.after('clear and show all', t => 52 | fn(rootDir, {clear: true}).then(files => { 53 | t.ok(files.dependencies); 54 | t.ok(files.devDependencies); 55 | t.is(files.dependencies[0].hidden, false); 56 | t.is(files.devDependencies[0].hidden, false); 57 | }) 58 | ); 59 | } else { 60 | test('skip win32 tests', t => 61 | t.pass() 62 | ); 63 | } 64 | --------------------------------------------------------------------------------