_ = require 'underscore'
Seq = require 'seq'
-
+glob = require 'glob'
/**
- * Asynchronously reads each filepath supplied, returning a map
- * from filepath to contents.
+ * Asynchronously reads the text for each filepath produced by the
+ * globs supplied, returning a map from filepath to contents.
*
- * @param {Array<String>} files List of paths to read.
+ * @param {String|Array<String>} patterns List of file-paths and/or glob-patterns to read.
* @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 = (files, cb) ->
+readFilesAsync = exports.readFilesAsync = (patterns, cb) ->
+ patterns = [patterns] if typeof patterns is 'string'
+ files = []
data = {}
- Seq files
+ Seq patterns
+ .parMap (pat) -> glob pat, {+nocase, +nosort}, this
+ .flatten()
.parMap (f) ->
- # console.log "fs.readFile '#CWD/data/#f'"
+ files.push f
fs.readFile f, 'utf8', this
.parEach (text, i) ->
f = files[i]
data[f] = text
@ok()
- .seq ->
- # Success!
- cb null, data
+ .seq -> cb null, data
.catch (err) ->
- console.error '[readFilesAsync] catch!'
- console.error err
- console.error that if err.stack
+ console.error err.file, err
cb err
+/**
+ * Asynchronously reads text and parses JSON for each filepath produced by the
+ * globs supplied, returning a map from filepath to contents.
+ *
+ * @param {String|Array<String>} patterns List of filepaths and/or glob-patterns to read.
+ * @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) ->
+ data = {}
+ Seq()
+ .seq -> readFilesAsync patterns, this
+ .seq (data) ->
+ @ok _.map data, (text, f) -> [f, text]
+ .flatten false # flatten one level
+ .parMap ([f, text]) ->
+ try
+ data[f] = JSON.parse text
+ @ok()
+ catch err
+ err.file = f
+ console.error f, err
+ cb err
+ .seq -> cb null, data
+ .catch (err) ->
+ console.error err.file, err
+ cb err
+
+logErrorsAnd = exports.logErrorsAnd = (cb) ->
+ (err, ...args) ->
+ global.args = arguments
+ if err
+ console.error err
+ else
+ cb ...args if cb
+
+## Test Code
+if require.main is module
+ files = exports
+ u = require 'kraken/util/underscore'
+
+ paths = <[ package.* deploy.sh ]>
+ files.readFilesAsync paths, (err, data) ->
+ if err then console.error err
+ else console.log '\n\n', global.data = u.map data, (txt, f) -> "#f: #{txt.length}"
+
+ # u = require 'kraken/util/underscore'; files = require 'kraken/server/files'
+ # files.readJSONFilesAsync 'data/**/*.json', files.logErrorsAnd()
-# _ = require 'underscore'
-# files = require 'kraken/server/files'
-# files.readFilesAsync <[ package.co package.json deploy.sh ]>, (err, data) ->
-# if err
-# console.error err
-# else
-# console.log _.map data, (txt, f) -> "#f: #{txt.length}"
fs = require 'fs'
path = require 'path'
-findit = require 'findit'
+glob = require 'glob'
{existsSync:exists} = path
{exec, spawn} = require 'child_process'
{mkdirp, mkdirpAsync} = require './mkdirp'
-_ = require 'underscore'
-_.str = require 'underscore.string'
-_.mixin _.str.exports()
Seq = require 'seq'
yaml = require 'js-yaml'
Resource = require 'express-resource'
compiler = require 'connect-compiler-extras'
+_ = require '../util/underscore'
op = require '../util/op'
+files = require './files'
YAML_EXT_PAT = /\.ya?ml$/i
app.get '/datasources/all', (req, res, next) ->
data = {}
- files = []
- Seq(findit.sync 'data/datasources')
- # .seq fs.readdir, 'data/datasources', Seq
- # .flatten()
- .filter -> /\.(json|ya?ml)$/.test it
- .seq ->
- files := @stack.slice()
- # console.log 'files:', files
- @ok files
- .flatten()
- .parMap (f) ->
- # console.log "fs.readFile '#CWD/data/#f'"
- fs.readFile f, 'utf8', this
- .parMap (text, i) ->
- f = files[i]
+ Seq
+ .seq glob, 'data/datasources/**/*.@(yaml|json)', {+nocase, +nosort}, Seq
+ .seq (paths) -> files.readFilesAsync paths, this
+ .seq (txts) -> @ok _.items txts
+ .flatten false
+ .parMap ([f, text]) ->
# console.log "parsing file[#i]: '#f' -> text[#{text.length}]..."
k = f.replace YAML_EXT_PAT, '.json'
v = data[k] = {}
res.send { error:String(err), partial_data:data }
+
# temporarily hardcoded until funciton to get JSON out of
# files in a directory is finished. Also need to fix
# controller method action mapping.