common.js
  1  'use strict';
  2  
  3  const walker = require('walker');
  4  const anymatch = require('anymatch');
  5  const micromatch = require('micromatch');
  6  const path = require('path');
  7  const platform = require('os').platform();
  8  
  9  /**
 10   * Constants
 11   */
 12  
 13  exports.DEFAULT_DELAY = 100;
 14  exports.CHANGE_EVENT = 'change';
 15  exports.DELETE_EVENT = 'delete';
 16  exports.ADD_EVENT = 'add';
 17  exports.ALL_EVENT = 'all';
 18  
 19  /**
 20   * Assigns options to the watcher.
 21   *
 22   * @param {NodeWatcher|PollWatcher|WatchmanWatcher} watcher
 23   * @param {?object} opts
 24   * @return {boolean}
 25   * @public
 26   */
 27  
 28  exports.assignOptions = function(watcher, opts) {
 29    opts = opts || {};
 30    watcher.globs = opts.glob || [];
 31    watcher.dot = opts.dot || false;
 32    watcher.ignored = opts.ignored || false;
 33  
 34    if (!Array.isArray(watcher.globs)) {
 35      watcher.globs = [watcher.globs];
 36    }
 37    watcher.hasIgnore =
 38      Boolean(opts.ignored) && !(Array.isArray(opts) && opts.length > 0);
 39    watcher.doIgnore = opts.ignored ? anymatch(opts.ignored) : () => false;
 40  
 41    if (opts.watchman && opts.watchmanPath) {
 42      watcher.watchmanPath = opts.watchmanPath;
 43    }
 44  
 45    return opts;
 46  };
 47  
 48  /**
 49   * Checks a file relative path against the globs array.
 50   *
 51   * @param {array} globs
 52   * @param {string} relativePath
 53   * @return {boolean}
 54   * @public
 55   */
 56  
 57  exports.isFileIncluded = function(globs, dot, doIgnore, relativePath) {
 58    if (doIgnore(relativePath)) {
 59      return false;
 60    }
 61    return globs.length
 62      ? micromatch.some(relativePath, globs, { dot: dot })
 63      : dot || micromatch.some(relativePath, '**/*');
 64  };
 65  
 66  /**
 67   * Traverse a directory recursively calling `callback` on every directory.
 68   *
 69   * @param {string} dir
 70   * @param {function} dirCallback
 71   * @param {function} fileCallback
 72   * @param {function} endCallback
 73   * @param {*} ignored
 74   * @public
 75   */
 76  
 77  exports.recReaddir = function(
 78    dir,
 79    dirCallback,
 80    fileCallback,
 81    endCallback,
 82    errorCallback,
 83    ignored
 84  ) {
 85    walker(dir)
 86      .filterDir(currentDir => !anymatch(ignored, currentDir))
 87      .on('dir', normalizeProxy(dirCallback))
 88      .on('file', normalizeProxy(fileCallback))
 89      .on('error', errorCallback)
 90      .on('end', () => {
 91        if (platform === 'win32') {
 92          setTimeout(endCallback, 1000);
 93        } else {
 94          endCallback();
 95        }
 96      });
 97  };
 98  
 99  /**
100   * Returns a callback that when called will normalize a path and call the
101   * original callback
102   *
103   * @param {function} callback
104   * @return {function}
105   * @private
106   */
107  
108  function normalizeProxy(callback) {
109    return (filepath, stats) => callback(path.normalize(filepath), stats);
110  }