From d7e99369e9df15dc6e5fd461ac0ee407f21938fa Mon Sep 17 00:00:00 2001 From: David Schoonover Date: Thu, 12 Jul 2012 12:09:36 -0700 Subject: [PATCH] Adds YAML support to readJSONFilesAsync --- src/server/files.co | 40 ++++++++++++++++++++++++++++++---------- 1 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/server/files.co b/src/server/files.co index bb815a3..b07f73e 100644 --- a/src/server/files.co +++ b/src/server/files.co @@ -3,12 +3,14 @@ */ -fs = require 'fs' -path = require 'path' +fs = require 'fs' +path = require 'path' +exists = fs.existsSync or path.existsSync _ = require 'underscore' Seq = require 'seq' glob = require 'glob' +yaml = require 'js-yaml' /** @@ -16,13 +18,17 @@ glob = require 'glob' * globs supplied, returning a map from filepath to contents. * * @param {String|Array} patterns List of file-paths and/or glob-patterns to read. + * @param {Object} [opts={}] Options: + * @param {Boolean} [opts.verbose=false] Be chatty about errors. * @param {Function} cb Callback taking `(error, data)` where `data` is a map * from filepath to contents. As always, `error` will be null on success. * @returns {Seq} The Seq object representing the async operation chain. (You * can usually ignore this.) */ -readFilesAsync = exports.readFilesAsync = (patterns, cb) -> +readFilesAsync = exports.readFilesAsync = (patterns, opts, cb) -> patterns = [patterns] if typeof patterns is 'string' + [cb, opts] = [opts, {}] if typeof opts is 'function' + opts = {-verbose, ...opts or {}} files = [] data = {} Seq patterns @@ -45,21 +51,35 @@ readFilesAsync = exports.readFilesAsync = (patterns, cb) -> * globs supplied, returning a map from filepath to contents. * * @param {String|Array} patterns List of filepaths and/or glob-patterns to read. + * @param {Object} [opts={}] Options: + * @param {Boolean} [opts.verbose=false] Be chatty about errors. + * @param {Boolean} [opts.yaml=false] Also search for and include YAML files. + * @param {Boolean} [opts.appendExt=true] Treat the patterns as directories, and append + * the appropriate file extension glob-patterns. * @param {Function} cb Callback taking `(error, data)` where `data` is a map * from filepath to contents. As always, `error` will be null on success. * @returns {Seq} The Seq object representing the async operation chain. (You * can usually ignore this.) */ -readJSONFilesAsync = exports.readJSONFilesAsync = (patterns, cb) -> +readJSONFilesAsync = exports.readJSONFilesAsync = (patterns, opts, cb) -> + patterns = [patterns] if typeof patterns is 'string' + [cb, opts] = [opts, {}] if typeof opts is 'function' + opts = {-yaml, +appendExt, -verbose, ...opts or {}} data = {} + + if opts.appendExt + ext = if opts.yaml then '@(yaml|json)' else 'json' + patterns .= map -> path.join it, "*.#ext" + Seq() - .seq -> readFilesAsync patterns, this + .seq readFilesAsync, patterns, {opts.verbose}, Seq .seq (data) -> @ok _.map data, (text, f) -> [f, text] .flatten false # flatten one level .parMap ([f, text]) -> + parser = if /\.yaml$/i.test f then yaml.load else JSON.parse try - data[f] = JSON.parse text + data[f] = parser text @ok() catch err err.file = f @@ -70,6 +90,8 @@ readJSONFilesAsync = exports.readJSONFilesAsync = (patterns, cb) -> console.error err.file, err cb err + + logErrorsAnd = exports.logErrorsAnd = (cb) -> (err, ...args) -> global.args = arguments @@ -78,6 +100,7 @@ logErrorsAnd = exports.logErrorsAnd = (cb) -> else cb ...args if cb + ## Test Code if require.main is module files = exports @@ -89,8 +112,5 @@ if require.main is module else console.log '\n\n', global.data = u.map data, (txt, f) -> "#f: #{txt.length}" # u = require 'limn/util/underscore'; files = require 'limn/server/files' - # files.readJSONFilesAsync 'data/**/*.json', files.logErrorsAnd() - - - + # files.readJSONFilesAsync 'data/**', {+yaml}, files.logErrorsAnd() -- 1.7.0.4