*/
-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'
/**
* globs supplied, returning a map from filepath to contents.
*
* @param {String|Array<String>} 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
* globs supplied, returning a map from filepath to contents.
*
* @param {String|Array<String>} 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
console.error err.file, err
cb err
+
+
logErrorsAnd = exports.logErrorsAnd = (cb) ->
(err, ...args) ->
global.args = arguments
else
cb ...args if cb
+
## Test Code
if require.main is module
files = exports
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()