UNPKG

savvy-js

Version:

Savvy - Style sheet documentation tool

181 lines (156 loc) 5.84 kB
/** * The fileReader finds files in given paths and reads them. * * @class fileReader * @namespace savvy */ (function () { 'use strict'; var Minimatch = require('minimatch').Minimatch, fs = require('fs'); /** * Get a flat list of files from a given folders, that match a specific patten. * * var fileReader = require('./fileReader'), * sassFiles = fileReader.getFiles('c:/workspace/sass', '*.scss', { matchBase: true }); * * This uses the Minimatch library, see more details on possible patterns at https://github.com/isaacs/minimatch. * * @method getFiles * @param {string | []} folders - a folder path or collection of folder paths. All files inside them will be * evaluated using Minimatch pattern. * @param {function} callback * @param {string} [pattern] - A pattern that matches the files you wish to get. * @param {object} [options] - Pattern matching options. See more details at https://github.com/isaacs/minimatch */ function getFiles (folders, callback, pattern, options) { var files = [], foldersProcessed, test; function processFiles(files){ return matchPattern(test, files); } function folderReadCallback(err, resultFiles){ if(err){ callback(err, null); } else{ files = files.concat(resultFiles); foldersProcessed = foldersProcessed - 1; if(!foldersProcessed){ callback(null, files); } } } if(!pattern){ pattern = '*.*'; } if(!options){ options = { matchBase: true }; } if (typeof folders === 'string') { folders = [folders]; } test = new Minimatch(pattern, options); foldersProcessed = folders.length; folders.forEach(function(folder){ readDirectoryRecursively(folder, processFiles, folderReadCallback); }); } /** * Test a file path or list of file paths against a minimatch pattern and return only paths that match the pattern. * * var Minimatch = require("minimatch").Minimatch, * pattern = new Minimatch('*.js', { matchBase: true }), * result; * * result = matchPattern(pattern, ['C:/myFile.js', 'CL/myOtherFile.css']); // Will return only the js file. * * @method matchPattern * @param {Minimatch} matchPatten - the pattern a file path must match. * @param {[] | string} files - file path or array of file path * @returns {[]} return all the given files that match the pattern */ function matchPattern(matchPatten, files){ var i; if(typeof files === 'string'){ files = [files]; } i = files.length; while(i){ i = i - 1; if(matchPatten.match(files[i]) === false){ files.splice(i, 1); } } return files; } /** * Read all files in a folder, recursively. Each file gets to be processed by a function to determine if it should * be included in the final file list result. * * @method readDirectoryRecursively * * @param {string} folderPath - the full path of the folder. * @param {function} processFiles - this function should accept a file paths array and return a file paths array. * * function processFiles(files){ return files; } * * You can manipulate the files array to remove unwanted file for example. * * @param {function} callback - once all files are collected, this callback will be invoked with (err, files), where * 'err' is an error object (or null if all went smoothly) and 'files' is a file paths array (or null, if something * went wrong); * * @private */ function readDirectoryRecursively(folderPath, processFiles, callback) { var results = [], pending; function handleFolder(folderPath) { readDirectoryRecursively(folderPath, processFiles, function recursionCallback(err, files) { files = processFiles(files); results = results.concat(files); pending = pending - 1; if (!pending) { callback(null, results); } }); } function handleSingleFile(filePath){ var files = processFiles(filePath); results = results.concat(files); pending = pending - 1; if (!pending){ callback(null, results); } } fs.readdir(folderPath, function(err, list) { if (err){ return callback(err); } pending = list.length; if (!pending) { return callback(null, results); } list.forEach(function(file) { file = folderPath + '/' + file; fs.stat(file, function(err, stat) { if (stat && stat.isDirectory()) { handleFolder(file); } else { handleSingleFile(file); } }); }); }); } function readFile(filePath, callback){ fs.readFile(filePath, 'utf8', callback); } module.exports = { getFiles : getFiles, matchPattern : matchPattern, readFile : readFile }; }());