UNPKG

broccoli-funnel

Version:

Broccoli plugin that allows you to filter files selected from an input node down based on regular expressions.

376 lines (283 loc) 8.86 kB
# Broccoli Funnel [![Build Status](https://travis-ci.org/broccolijs/broccoli-funnel.svg?branch=master)](https://travis-ci.org/broccolijs/broccoli-funnel) [![Build status](https://ci.appveyor.com/api/projects/status/3y3wo7hipq6d0cbp/branch/master?svg=true)](https://ci.appveyor.com/project/embercli/broccoli-funnel/branch/master) Given an input node, the Broccoli Funnel plugin returns a new node with only a subset of the files from the input node. The files can be moved to different paths. You can use regular expressions to select which files to include or exclude. ## Documentation ### `funnel(inputNode, options)` `inputNode` *{Single node}* A Broccoli node (formerly: "tree"). A node in Broccoli can be either a string that references a directory in your project or a node object returned from running another Broccoli plugin. If your project has the following file structure: ```shell . ├── Brocfile.js └── src/ ├── css/ │   ├── reset.css │   └── todos.css ├── icons/ │   ├── check-mark.png │   └── logo.jpg └── javascript/ ├── app.js └── todo.js ``` You can select a subsection of the tree via Funnel: ```javascript const funnel = require('broccoli-funnel'); const cssFiles = funnel('src/css'); /* cssFiles contains the following files: ├── reset.css └── todos.css */ // export the node for Broccoli to begin processing module.exports = cssFiles; ``` #### Options `srcDir` *{String}* A string representing the portion of the input node to start the funneling from. This will be the base path for any `include`/`exclude` regexps. Default: `'.'`, the root path of the input node. If your project has the following file structure: ```shell . ├── Brocfile.js └── src/ ├── css/ │   ├── reset.css │   └── todos.css ├── icons/ │   ├── check-mark.png │   └── logo.jpg └── javascript/ ├── app.js └── todo.js ``` You can select a subsection of the node via Funnel: ```javascript const funnel = require('broccoli-funnel'); const merge = require('broccoli-merge-trees'); // root of our source files const projectFiles = 'src'; /* get a new node of only files in the 'src/css' directory cssFiles contains the following files: ├── reset.css └── todos.css */ const cssFiles = funnel(projectFiles, { srcDir: 'css' }); /* get a new node of only files in the 'src/icons' directory imageFiles contains the following files: ├── check-mark.png └── logo.jpg */ const imageFiles = funnel(projectFiles, { srcDir: 'icons' }); module.exports = merge([cssFiles, imageFiles]); ``` ---- `destDir` *{String}* A string representing the destination path that filtered files will be copied to. Default: `'.'`, the root path of input node. If your project has the following file structure: ```shell . ├── Brocfile.js └── src/ ├── css/ │   ├── reset.css │   └── todos.css ├── icons/ │   ├── check-mark.png │   └── logo.jpg └── javascript/ ├── app.js └── todo.js ``` You can select a subsection of the directory structure via Funnel and copy it to a new location: ```javascript const funnel = require('broccoli-funnel'); const cssFiles = funnel('src/css', { destDir: 'build' }); /* cssFiles contains the following files: build/ ├── reset.css └── todos.css */ module.exports = cssFiles; ``` ---- `allowEmpty` *{Boolean}* When using `srcDir`/`destDir` options only (aka no filtering via `include`/`exclude` options), if the `srcDir` were missing an error would be thrown. Setting `allowEmpty` to true, will prevent that error by creating an empty directory at the destination path. ---- `include` *{Array of GlobStrings|RegExps|Functions}* One or more matcher expression (regular expression, glob string, or function). Files within the node whose names match this expression will be copied (with the location inside their parent directories preserved) to the `destDir`. Default: `[]`. If your project has the following file structure ```shell . ├── Brocfile.js └── src/ ├── css/ │   ├── reset.css │   └── todos.css ├── icons/ │   ├── check-mark.png │   └── logo.jpg └── javascript/ ├── app.js └── todo.js ``` You can select files that match a glob expression and copy those subdirectories to a new location, preserving their location within parent directories: ```javascript const funnel = require('broccoli-funnel'); // finds all files that match /todo/ and moves them // the destDir const todoRelatedFiles = funnel('src', { include: ['**/todo*'] }); /* todoRelatedFiles contains the following files: . ├── css │   └── todos.css └── javascript └── todo.js */ module.exports = todoRelatedFiles; ``` ---- `exclude` *{Array of Glob Strings|Function}* One or more matcher expression (regular expression, glob string, or function). Files within the node whose names match this expression will _not_ be copied to the `destDir` if they otherwise would have been. *Note, in the case when a file matches both an include and exclude pattern, the exclude pattern wins* Default: `[]`. If your project has the following file structure: ```shell . ├── Brocfile.js └── src/ ├── css/ │   ├── reset.css │   └── todos.css ├── icons/ │   ├── check-mark.png │   └── logo.jpg └── javascript/ ├── app.js └── todo.js ``` You can select files that match a glob expression and exclude them from copying: ```javascript const funnel = require('broccoli-funnel'); // finds all files in 'src' EXCEPT `todo.js` in any directory // or sub-directory and adds them to a node. const nobodyLikesTodosAnyway = funnel('src', { exclude: ['**/todo.js'] }); /* nobodyLikesTodosAnyway contains the following files: . ├── css │   └── reset.css ├── icons │   ├── check-mark.png │   └── logo.jpg └── javascript └── app.js */ module.exports = nobodyLikesTodosAnyway; ``` ---- `files` *{Array of Strings}* One or more relative file paths. Files within the node whose relative paths match will be copied (with the location inside their parent directories preserved) to the `destDir`. Default: `[]`. If your project has the following file structure ```shell . ├── Brocfile.js └── src/ ├── css/ │   ├── reset.css │   └── todos.css ├── icons/ │   ├── check-mark.png │   └── logo.jpg └── javascript/ ├── app.js └── todo.js ``` You can select a specific list of files copy those subdirectories to a new location, preserving their location within parent directories: ```javascript const funnel = require('broccoli-funnel'); // finds these specific files and moves them to the destDir const someFiles = funnel('src', { files: ['css/reset.css', 'icons/check-mark.png'] }); /* someFiles contains the following files: . ├── css │   └── reset.css └── icons └── check-mark.png */ module.exports = someFiles; ``` ---- `getDestinationPath` *{Function}* This method will get called for each file, receiving the currently processing `relativePath` as its first argument. The value returned from `getDestinationPath` will be used as the destination for the new node. This is a very simple way to rename files or move them from one path to another (replacing the need for `broccoli-file-mover` for example). The return value of this method is cached for each input file. This means that `getDestinationPath` will only be called once per `relativePath`. In the following example, `getDestinationPath` is used to move `main.js` to `ember-metal.js`: ```javascript const node = funnel('packages/ember-metal/lib', { destDir: 'ember-metal', getDestinationPath: function(relativePath) { if (relativePath === 'lib/main.js') { return 'ember-metal.js'; } return relativePath; } }); ``` ## Extending Funnel If you desire to extend funnel follow the below snippet ```js const { Funnel } = require('broccoli-funnel'); class CustomFunnel extends Funnel { // cutstom implementation } ``` ## ZOMG!!! TESTS?!?!!? I know, right? Running the tests: ```javascript npm install npm test ``` ## License This project is distributed under the MIT license.