Skip to content

Instantly share code, notes, and snippets.

@bengsfort
Created March 24, 2015 17:00
Show Gist options
  • Save bengsfort/1cd50f5d5297d2621e0b to your computer and use it in GitHub Desktop.
Save bengsfort/1cd50f5d5297d2621e0b to your computer and use it in GitHub Desktop.
Directory filtering to omit dotfiles
// Using Array#filter to create array without any dotfiles
var fs = require('fs');
var handlebars = require('handlebars');
module.exports = function(){
var appsArray = fs.readdirSync('apps').filter(function(dir) {
// return true if `dir` does not start with a `.`
// to avoid dotfiles causing ENOTDIR (not a directory) errors
return !dir.match(/^\.[\w -]/);
});
var apps = {};
for( var i = 0; i < appsArray.length; i++ ){
var appName = appsArray[i];
var app = {};
app.name = appName;
app.path = 'apps/' + app.name;
app.componentsPath = app.path + "/components"
app.main = app.path + '/app.js';
app.config = findConfig( app.path );
app.filesToWatch = [
app.path + '/**/*.js',
app.path + '/**/*.hbs',
// exclude templates.js from triggering a rebuild
// b/c this file is created on build
'!' + app.path + '/main/templates.js',
'!' + app.path + '/components/**/templates.js',
'!' + app.path + '/components/components.js'
];
// Get all components in current app folder
var componentsArr = fs.readdirSync( app.componentsPath );
var compoentsJSIndex = componentsArr.indexOf( "components.js" );
// make sure we are not including the components.js file in out list
if( compoentsJSIndex != -1 ){
componentsArr.splice( compoentsJSIndex , 1 );
}
app.components = [];
for( var j = 0; j < componentsArr.length; j++ ){
var component = {};
component.name = componentsArr[j];
component.path = "apps/" + app.name + "/components/" + component.name;
component.config = findConfig( component.path );
app.components.push( component );
}
var source = "module.exports = { \n" +
"{{#each components}} \n" +
" '{{name}}': { \n" +
" app : require('./{{name}}/main'), \n" +
" config : { \n" +
" present : false, \n" +
" options : {} \n" +
" } \n" +
" }, \n" +
"{{/each}} \n" +
"}";
var template = handlebars.compile(source);
app.componentsString = template(app);
apps[ app.name ] = app;
}
return apps;
};
function findConfig ( configFolderPath ){
var confiFolder = fs.readdirSync( configFolderPath );
var indexOfConfig = confiFolder.indexOf("config.json");
var config = { hasConfig : false , path : null };
if( indexOfConfig != -1 ){
config.hasConfig = true;
config.path = "./" + configFolderPath + "/config.json";
}
return config;
}
// Using a simple if statement
var fs = require('fs');
var handlebars = require('handlebars');
module.exports = function(){
var appsArray = fs.readdirSync('apps');
var apps = {};
for( var i = 0; i < appsArray.length; i++ ){
var appName = appsArray[i];
// continue if current iteration is not a dotfile
if (!appName.match(/^\.[\w -]/)) {
var app = {};
app.name = appName;
app.path = 'apps/' + app.name;
app.componentsPath = app.path + "/components"
app.main = app.path + '/app.js';
app.config = findConfig( app.path );
app.filesToWatch = [
app.path + '/**/*.js',
app.path + '/**/*.hbs',
// exclude templates.js from triggering a rebuild
// b/c this file is created on build
'!' + app.path + '/main/templates.js',
'!' + app.path + '/components/**/templates.js',
'!' + app.path + '/components/components.js'
];
// Get all components in current app folder
var componentsArr = fs.readdirSync( app.componentsPath );
var compoentsJSIndex = componentsArr.indexOf( "components.js" );
// make sure we are not including the components.js file in out list
if( compoentsJSIndex != -1 ){
componentsArr.splice( compoentsJSIndex , 1 );
}
app.components = [];
for( var j = 0; j < componentsArr.length; j++ ){
var component = {};
component.name = componentsArr[j];
component.path = "apps/" + app.name + "/components/" + component.name;
component.config = findConfig( component.path );
app.components.push( component );
}
var source = "module.exports = { \n" +
"{{#each components}} \n" +
" '{{name}}': { \n" +
" app : require('./{{name}}/main'), \n" +
" config : { \n" +
" present : false, \n" +
" options : {} \n" +
" } \n" +
" }, \n" +
"{{/each}} \n" +
"}";
var template = handlebars.compile(source);
app.componentsString = template(app);
apps[ app.name ] = app;
}
}
return apps;
};
function findConfig ( configFolderPath ){
var confiFolder = fs.readdirSync( configFolderPath );
var indexOfConfig = confiFolder.indexOf("config.json");
var config = { hasConfig : false , path : null };
if( indexOfConfig != -1 ){
config.hasConfig = true;
config.path = "./" + configFolderPath + "/config.json";
}
return config;
}
@benwestrate
Copy link

Does one run faster than the other?

@bengsfort
Copy link
Author

At first performance seemed marginal with the if statement slightly quicker, but after adding 16 items to the apps directory (12 dotfiles, which is truly an "edge case" that will probably never happen and 4 actual directories with apps in them) it appears the filter may actually be slightly faster under load somehow.

Test case 16 items, 12 being dotfiles and 4 directories with code inside
Each variation run 8 times

Filter

  • Average: 4.76s
  • Total time: 38.07s
  • Quickest time: 4.29s
  • Slowest time: 7.16s

If

  • Average: 5.01s
  • Total time: 40.09
  • Quickest time: 4.28s
  • Slowest time: 7.49s

The dotfiles take longer to filter through (5 regex steps vs 3) so I figured I'd add a ton of them to see if I could really stress it out without adding a ton of code that may take a variable amount of time to install.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment