index.js
function Definition (factoryName, factory) {
  var configDefaults = {}
  var deps = []

  return {
    /**
     * Calls the factory for each arguments and returns
     * the list of tasks that just got created.
     *
     * @params {Object}
     * @returns {Array}
     */
    add: function add () {
      var configs = _(arguments).toArray().flatten(true).value()

      if (configs.length === 0) {
        // by adding an empty object
        // we'll create a task that has no alias
        // that's useful for Definition that are not
        // really tasks creators (e.g the help task)
        configs = [{}]
      }

      var addedTasks = _(configs)
        .map(function (config) {
          return _.assign({}, configDefaults, config)
        })
        .map(function (config) {
          var taskName = name(factoryName, config.alias)
          var deps = _(factory(config, options())).flatten(true).filter(_.identity).value()
          var fn = _.isFunction(_.last(deps)) ? deps.pop() : _.noop

          gulp.task(taskName, deps, fn)
          return taskName
        })
        .run()

      if (gulp.tasks[factoryName] == null || gulp.tasks[factoryName].$root) {
        gulp.task(factoryName, deps.concat(tasks(factoryName + ':')))
        gulp.tasks[factoryName].$root = true
      }

      return addedTasks
    },

    /**
     * Sets the factory's default config.
     *
     * @param {Object} config
     * @returns {{add: add, defaults: defaults, before: before}}
     */
    defaults: function defaults (config) {
      configDefaults = config
      return this
    },

    /**
     * Getter/setter that add tasks to run before any factory's task.
     *
     * @returns {*}
     */
    before: function before () {
      if (arguments.length) {
        deps = arguments[0]
        return this
      }

      return deps
    }
  }
}
function Definition (factoryName, factory) {
  var configDefaults = {}
  var deps = []

  return {
    /**
     * Calls the factory for each arguments and returns
     * the list of tasks that just got created.
     *
     * @params {Object}
     * @returns {Array}
     */
    add: function add () {
      var configs = _(arguments).toArray().flatten(true).value()

      if (configs.length === 0) {
        // by adding an empty object
        // we'll create a task that has no alias
        // that's useful for Definition that are not
        // really tasks creators (e.g the help task)
        configs = [{}]
      }

      var addedTasks = _(configs)
        .map(function (config) {
          return _.assign({}, configDefaults, config)
        })
        .map(function (config) {
          var taskName = name(factoryName, config.alias)
          var deps = _(factory(config, options())).flatten(true).filter(_.identity).value()
          var fn = _.isFunction(_.last(deps)) ? deps.pop() : _.noop

          gulp.task(taskName, deps, fn)
          return taskName
        })
        .run()

      if (gulp.tasks[factoryName] == null || gulp.tasks[factoryName].$root) {
        gulp.task(factoryName, deps.concat(tasks(factoryName + ':')))
        gulp.tasks[factoryName].$root = true
      }

      return addedTasks
    },

    /**
     * Sets the factory's default config.
     *
     * @param {Object} config
     * @returns {{add: add, defaults: defaults, before: before}}
     */
    defaults: function defaults (config) {
      configDefaults = config
      return this
    },

    /**
     * Getter/setter that add tasks to run before any factory's task.
     *
     * @returns {*}
     */
    before: function before () {
      if (arguments.length) {
        deps = arguments[0]
        return this
      }

      return deps
    }
  }
}
function Definition ( factoryName , factory ) { var configDefaults = { } var deps = [ ] return { /**
     * Calls the factory for each arguments and returns
     * the list of tasks that just got created.
     *
     * @params {Object}
     * @returns {Array}
     */ add : function add ( ) { var configs = _ ( arguments ) . toArray ( ) . flatten ( true ) . value ( ) if ( configs . length === 0 ) { // by adding an empty object // we'll create a task that has no alias // that's useful for Definition that are not // really tasks creators (e.g the help task) configs = [ { } ] } var addedTasks = _ ( configs ) . map ( function ( config ) { return _ . assign ( { } , configDefaults , config ) } ) . map ( function ( config ) { var taskName = name ( factoryName , config . alias ) var deps = _ ( factory ( config , options ( ) ) ) . flatten ( true ) . filter ( _ . identity ) . value ( ) var fn = _ . isFunction ( _ . last ( deps ) ) ? deps . pop ( ) : _ . noop gulp . task ( taskName , deps , fn ) return taskName } ) . run ( ) if ( gulp . tasks [ factoryName ] == null || gulp . tasks [ factoryName ] . $root ) { gulp . task ( factoryName , deps . concat ( tasks ( factoryName + ':' ) ) ) gulp . tasks [ factoryName ] . $root = true } return addedTasks } , /**
     * Sets the factory's default config.
     *
     * @param {Object} config
     * @returns {{add: add, defaults: defaults, before: before}}
     */ defaults : function defaults ( config ) { configDefaults = config return this } , /**
     * Getter/setter that add tasks to run before any factory's task.
     *
     * @returns {*}
     */ before : function before ( ) { if ( arguments . length ) { deps = arguments [ 0 ] return this } return deps } } }
Return a Definition object that's used to create
tasks from a given factory.

@param {String} factoryName
@param {Function} factory
@returns {{add: add, defaults: defaults}}
Return a Definition object that s used to create tasks from a given factory .