code: function defineTaskGroups() {
    const gulpTasks = gulp.tree({ deep: false }).nodes
    const gulpMode = options.parallel ? gulp.parallel : gulp.series
    const groups = Object.keys(options.groups).map(key => [
      key.trim().replace(/[^a-z]+/gi, ''),
      options.groups[key]
    ])
  
    groups.forEach(group => {
      const [name, value] = group
      let children = []
  
      if (Array.isArray(value)) {
        children = value
      } else if (typeof value === 'function') {
        children = gulpTasks
          .filter(value)
          // Group tasks should not call themselves/other groups
          .filter(child => !groups.includes(child))
      } else {
        return
      }
  
      if (children.length === 0) {
        gulp.task(name, done => {
          handleError(new Error(`No tasks found in '${name}' group`))
          done()
        })
      } else {
        gulp.task(name, gulpMode.apply(null, children))
      }
    })
  }
docs: Register configured task groups; by default, 'build' and 'watch'
  We might end up calling this several times (especially if using
  the gulpTaskMaker.task method), but gulp seems to be okay with
  overwriting a task reference with a new one.