package files by folder with gulp

I want this:

|-- guides | |-- _guide.hbs | |-- guide.hbs | `-- index.hbs |-- index.hbs `-- noroute.hbs

turn into this:

|-- common.js `-- guides.js

As you can see guides folder squashed into guides.js, and . folder squashed into common.js

Below is my ugly solution. Inspired by this post

function getFolderMap(dir) {
    var fs = require('fs');
    var path = require('path');

    var result = {};
    fs.readdirSync(dir)
        .filter(function(file) {
            if( fs.statSync(path.join(dir, file)).isDirectory()) {
                result[file] = file;
            }
        });

    return result;
};

gulp.task('build-dev-templates3', function() {
    var mergeStream = require('merge-stream')();

    var templatePaths = getFolderMap(paths.src + '/templates');

    templatePaths['./'] = 'common';

    for (var src in templatePaths) {
        var dst = templatePaths[src];
        var stream = gulp.src([paths.src + '/templates/' + src + '**/*.hbs'])
            .pipe($.process())
            .pipe($.concat(dst + '.js'))
            .pipe(gulp.dest(paths.dest + '/templates'));

        mergeStream.add(stream);
    }
    return mergeStream;
});

What is the gulp way to achieve this? Please at least share some guideful tools.

Edit2

I need to get rid of getFolderMap function and solve this with pure streams. The closest i can get is:

var directoryFilter = $.filter(function (file) {
    return file.isDirectory();
});

gulp.src([paths.src + + '/templates/**'])
        .pipe(directoryFilter)
        .pipe(

        //here I have list of directories
        //I need a gulp plugin to get the contents
        // so i can process them.
        );

This issue is related https://github.com/gulpjs/gulp/issues/386.

Final Solution

This is my final solution based on spiralx's answer. https://gist.github.com/eguneys/2fdbe7ac83dfab04748a

Something like this is my first guess, I use the forEachModule function at work to execute a sub-task for every module and then combine the results - helps with some plugins that have issues with paths and includes (gulp-stylus IIRC):

var gulp   = require('gulp');
var plugins = require('gulp-load-plugins')();
var es   = require('event-stream');
var path = require('path');
var config = require('./build.config');

// ------------------------------------

/*
 * For each module execute subtaskFunc and get result stream, then
 * combine all of the streams and return that.
 *
 * @param [{Object}] modules       array of module objects
 * @param {Function} subtaskFunc   function(module) -> stream
 * @return {Object} a stream
 */
function forEachModule(modules, subtaskFunc) {
  var subtaskStreams = modules.map(subtaskFunc);
  return es.concat.apply(null, subtaskStreams);
}

// ------------------------------------

gulp.task('templates', function() {
  var dest = path.join(config.dest, 'templates');

  return forEachModule(config.modules, function(module) {
    var src = path.join(config.src, 'templates', module, '**/*.hbs');

    // Compile .hbs files, wrap in a CommonJS module, combine into `<module>.js` and write to dest.
    return gulp.src(src)
      .pipe(plugins.handlebars().on('error', plugins.util.log))
      .pipe(plugins.defineModule('plain'))
      .pipe(plugins.declare({
        namespace: 'app.templates.' + module
      }))
      .pipe(plugins.concat(module + '.js'))
      .pipe(gulp.dest(dest));
  })
    // Combine all module template files into one?
    .pipe(plugins.concat('templates.js'))
    .pipe(gulp.dest(config.dest));
});

Edit:

This code is almost identical to what was there, but looks for directories under 'src/app' for modules instead of pre-defining the list, and doesn't generate any configuration outside of the gulp task function itself.

The reason it's like this to begin with was issues using gulp-stylus on a stream such as src/app/**/*.styl when a) using @include or anything referring to relative paths, or b) passing options to either Stylus itself, or a plugin such as Nib.

var modules = fs.readdirSync('src/app').filter(function(name) {
  return fs.statSync('src/app/' + name).isDirectory()
});

// ------------------------------------

gulp.task('styles', function() {
  var streams = modules.map(function(name) {
    return gulp.src('src/app/' + name + '/**/*.styl')
      .pipe(plugins.stylus({
        use: [
          require('nib')(),
          require('bootstrap3-stylus')()
        ],
        paths: [
          'src/common'
        ]
      }))
      .pipe(plugins.concat(name + '.css'))
      .pipe(gulp.dest('dist/css'))
      .pipe(plugins.minifyCss())
      .pipe(plugins.rename({
        suffix: '.min'
      }))
      .pipe(gulp.dest('dist/css'));
  });

  return plugins.mergeStream(streams)
    .pipe(plugins.concat('app.css'))
    .pipe(gulp.dest('dist/css'));
});