pax_global_header00006660000000000000000000000064137554542370014531gustar00rootroot0000000000000052 comment=ab1cf1f5df914716173867d6e479a6fd4d6364cc fs2-0.3.9/000077500000000000000000000000001375545423700122345ustar00rootroot00000000000000fs2-0.3.9/.editorconfig000066400000000000000000000004401375545423700147070ustar00rootroot00000000000000# EditorConfig is awesome: http://EditorConfig.org # top-most EditorConfig file root = true [*] charset = utf-8 end_of_line = lf insert_final_newline = true indent_style = tab trim_trailing_whitespace = true [*.md] indent_size = 2 indent_style = space trim_trailing_whitespace = false fs2-0.3.9/.gitignore000066400000000000000000000000571375545423700142260ustar00rootroot00000000000000/node_modules npm-debug.log /package-lock.json fs2-0.3.9/.npmignore000066400000000000000000000000541375545423700142320ustar00rootroot00000000000000/.editorconfig /CHANGELOG.md /CHANGES /test fs2-0.3.9/CHANGELOG.md000066400000000000000000000153711375545423700140540ustar00rootroot00000000000000# Changelog All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. ### [0.3.9](https://github.com/medikoo/fs2/compare/v0.3.8...v0.3.9) (2020-11-19) ### Features - rmdirSync util ([3c50c17](https://github.com/medikoo/fs2/commit/3c50c17198bd77e52c2889e3ce05161d790250a8)) ### [0.3.8](https://github.com/medikoo/fs2/compare/v0.3.7...v0.3.8) (2020-04-27) ### Bug Fixes - Fix `mode` normalization in `fs.access` ([00f2a52](https://github.com/medikoo/fs2/commit/00f2a52b139576b5b5adcec7c3c01bb84b905076)) ### [0.3.7](https://github.com/medikoo/fs2/compare/v0.3.6...v0.3.7) (2019-11-07) ### Features - 'silent' option for mkdir ([e3fe863](https://github.com/medikoo/fs2/commit/e3fe863)) ### [0.3.6](https://github.com/medikoo/fs2/compare/v0.3.5...v0.3.6) (2019-09-26) ### Bug Fixes - Ensure to not leave open file descriptors when write crashes ([cf8ef7e](https://github.com/medikoo/fs2/commit/cf8ef7e)) ### Features - Expose debug stats in descriptors handler ([cdcac3f](https://github.com/medikoo/fs2/commit/cdcac3f)) ### [0.3.5](https://github.com/medikoo/fs2/compare/v0.3.4...v0.3.5) (2019-07-10) ### Features - 'append' mode for chmod ([afa7aaa](https://github.com/medikoo/fs2/commit/afa7aaa)) ## [0.3.4](https://github.com/medikoo/fs2/compare/v0.3.3...v0.3.4) (2019-02-04) ### Features - 'force' option for copy ([85a3560](https://github.com/medikoo/fs2/commit/85a3560)) ## [0.3.3](https://github.com/medikoo/fs2/compare/v0.3.2...v0.3.3) (2019-02-04) ### Features - 'access' util ([d85f934](https://github.com/medikoo/fs2/commit/d85f934)) - hasAccess util ([8c53ea9](https://github.com/medikoo/fs2/commit/8c53ea9)) ## [0.3.2](https://github.com/medikoo/fs2/compare/v0.3.1...v0.3.2) (2019-02-04) ### Bug Fixes - readdir 'loose' option handling with depth: Infinity ([f2c19ac](https://github.com/medikoo/fs2/commit/f2c19ac)) ## [0.3.1](https://github.com/medikoo/fs2/compare/v0.3.0...v0.3.1) (2019-01-31) ### Features - **readdir:** loose option ([7b2a5e7](https://github.com/medikoo/fs2/commit/7b2a5e7)) # [0.3.0](https://github.com/medikoo/fs2/compare/v0.2.21...v0.3.0) (2019-01-07) ### Bug Fixes - Ensure git ignore resolution works as expected ([c5d68fb](https://github.com/medikoo/fs2/commit/c5d68fb)) ### BREAKING CHANGES - Due to switch to 'ignore' not supporting Node below v6, drop support for old verions of Node.js. ## [0.2.21](https://github.com/medikoo/fs2/compare/v0.2.20...v0.2.21) (2018-11-15) ### Bug Fixes - 'loose' option handling on windows ([3788ebf](https://github.com/medikoo/fs2/commit/3788ebf)) ## [0.2.20](https://github.com/medikoo/fs2/compare/v0.2.19...v0.2.20) (2018-11-07) ### Bug Fixes - **copyDir:** symlink copying ([c0e4a6f](https://github.com/medikoo/fs2/commit/c0e4a6f)) ## [0.2.19](https://github.com/medikoo/fs2/compare/v0.2.18...v0.2.19) (2018-10-31) ### Bug Fixes - **symlink:** for symlink we should not fully resolve link path ([ae17653](https://github.com/medikoo/fs2/commit/ae17653)) ## [0.2.18](https://github.com/medikoo/fs2/compare/v0.2.17...v0.2.18) (2018-10-31) ### Bug Fixes - remove problematic stream.destroy() ([ceb67b9](https://github.com/medikoo/fs2/commit/ceb67b9)) - **copy:** validate destination existence ([7662c1e](https://github.com/medikoo/fs2/commit/7662c1e)) - **copyDir:** fix duplicate file copying ([41ff83b](https://github.com/medikoo/fs2/commit/41ff83b)) ## [0.2.17](https://github.com/medikoo/fs2/compare/v0.2.16...v0.2.17) (2018-10-31) ### Bug Fixes - **copyDir:** throw if destination path exists ([812fdfb](https://github.com/medikoo/fs2/commit/812fdfb)) ## [0.2.16](https://github.com/medikoo/fs2/compare/v0.2.15...v0.2.16) (2018-10-31) ### Features - copyDir util ([2f45d62](https://github.com/medikoo/fs2/commit/2f45d62)) ## [0.2.15](https://github.com/medikoo/fs2/compare/v0.2.14...v0.2.15) (2018-10-25) ### Bug Fixes - **readlink:** improve loose option handling ([b54f193](https://github.com/medikoo/fs2/commit/b54f193)) - improve arguments handling ([c32f340](https://github.com/medikoo/fs2/commit/c32f340)) - **lstat:** fix loose option handling ([889b829](https://github.com/medikoo/fs2/commit/889b829)) ### Features - isDirectory util ([835b4a9](https://github.com/medikoo/fs2/commit/835b4a9)) ## [0.2.14](https://github.com/medikoo/fs2/compare/v0.2.13...v0.2.14) (2018-10-24) ### Bug Fixes - **readlink:** fix support for loose option on existing non-symlinks ([3c52970](https://github.com/medikoo/fs2/commit/3c52970)) ## [0.2.13](https://github.com/medikoo/fs2/compare/v0.2.12...v0.2.13) (2018-10-24) ### Bug Fixes - require path ([6aa87f7](https://github.com/medikoo/fs2/commit/6aa87f7)) ## [0.2.12](https://github.com/medikoo/fs2/compare/v0.2.11...v0.2.12) (2018-10-24) ### Features - readlink util ([c5c63c7](https://github.com/medikoo/fs2/commit/c5c63c7)) ## [0.2.11](https://github.com/medikoo/fs2/compare/v0.2.10...v0.2.11) (2018-10-23) ### Features - introduce realpath ([727e7b8](https://github.com/medikoo/fs2/commit/727e7b8)) ## [0.2.10](https://github.com/medikoo/fs2/compare/v0.2.9...v0.2.10) (2018-09-14) ### Bug Fixes - support for very old versions of Node.js ([73bc389](https://github.com/medikoo/fs2/commit/73bc389)) ### Features - rm util, removes either file or directory ([6733df6](https://github.com/medikoo/fs2/commit/6733df6)) ## [0.2.9](https://github.com/medikoo/fs2/compare/v0.2.8...v0.2.9) (2018-09-13) ### Features - support "loose" option in stat and lstat ([76306c4](https://github.com/medikoo/fs2/commit/76306c4)) ## [0.2.8](https://github.com/medikoo/fs2/compare/v0.2.7...v0.2.8) (2018-09-07) ### Features - support `intermediate` option in symlink ([5846d47](https://github.com/medikoo/fs2/commit/5846d47)) ## [0.2.7](https://github.com/medikoo/fs2/compare/v0.2.6...v0.2.7) (2017-09-05) ### Bug Fixes - bring back node v0.12 support ([370fa80](https://github.com/medikoo/fs2/commit/370fa80)) ## [0.2.6](https://github.com/medikoo/fs2/compare/v0.2.5...v0.2.6) (2017-06-19) ## [0.2.5](https://github.com/medikoo/fs2/compare/v0.2.4...v0.2.5) (2017-06-16) ### Features - "loose" option for fs.copy ([885cba7](https://github.com/medikoo/fs2/commit/885cba7)) - resolve successful copy with `true` ([72d4961](https://github.com/medikoo/fs2/commit/72d4961)) ## Old Changelog See `CHANGES` fs2-0.3.9/CHANGES000066400000000000000000000037631375545423700132400ustar00rootroot00000000000000For new changelog see CHANGELOG.md v0.2.4 -- 2017.03.15 * Fix race condition issues in readdir and mkdir * Fix desciptor limiter for Node.js at v1.2 and greater * In descriptor limiter aside of EMFILE errors handle also ENFILE errors * Support cross device rename v0.2.3 -- 2015.09.14 * Fix error handling in rmdir v0.2.2 -- 2015.09.10 * Add `appendFile` * Implement `intermediate` option support for `copy` * Implement `dirFilter` option support for `readdir` * Implement `intermediate` option support for `rename` * Assure that on files copy mode is preserved * Fix writeFile so override of mode is supported * Improve and generalise descriptors handler logic * Fix spelling of LICENSE * Configure lint scripts v0.2.1 -- 2014.04.27 * Update package.json to use latest 'tad' engine (fixes tests evaluation in v0.8) v0.2.0 -- 2014.04.27 * Move out main modules out of lib folder * 'loose' option for rmdir * 'loose' option for unlink * 'intermediate' option for writeFile * Fix race condition issues in readdir * Fix `unwatch` call in watchAlt * Add fs.rename * Add fs.symlink * Update internals to use latest versions of dependencies * Remove Makefile, it's cross environment package * Update documentation v0.1.5 -- 2013.04.10 * Improve stream and error handling in `copy` * Promise version of fs.stat v0.1.4 -- 2013.02.08 * Fix error handling in copy * Improve copy by allowing to pass options to underlying fs.createWriteStream v0.1.3 -- 2013.02.08 * Fix callback support in readdir * Improved error handling in findRoot * Added missing Licence (MIT) v0.1.2 -- 2013.01.16 * Promise version of rmdir with recursive and force options * Promise versions of lstat, chmod, lchmod, unlink * Fix global and relative rules matching in isIgnored * Use primitive memoization for isIgnored map v0.1.1 -- 2012.10.04 * Fixed few race condition cases * Better lock logic in _watch * Fix readdir test for Windows * Better error message in readFile v0.1.0 -- 2012.10.04 Initial version (derived from next package) fs2-0.3.9/LICENSE000066400000000000000000000014051375545423700132410ustar00rootroot00000000000000ISC License Copyright (c) 2012-2020, Mariusz Nowak, @medikoo, medikoo.com Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. fs2-0.3.9/README.md000066400000000000000000000256371375545423700135300ustar00rootroot00000000000000# fs2 ## Functions that complement and extend [fs](http://nodejs.org/api/all.html#all_file_system) package _Originally derived from [node-ext](https://github.com/medikoo/node-ext) package._ ## Installation $ npm install fs2 ## API ### access(path[, mode[, cb]]) _(fs2/access)_ Same as [fs.access](https://nodejs.org/api/fs.html#fs_fs_access_path_mode_callback). Returns promise. ### chmod(path, mode[, cb]) _(fs2/chmod)_ Same as [fs.chmod](http://nodejs.org/api/all.html#all_fs_lchmod_path_mode_callback). Returns promise. Not available on Windows. Extra options: - **append** - If set to true, then given mode is appended to file ### copy(src, dest[, options[, cb]]) _(fs2/copy)_ Copy file, returns promise but accepts as well regular callback. Eventual options are passed to underlying [fs.createWriteStream](http://nodejs.org/api/all.html#all_fs_createwritestream_path_options) Extra options: - **force** - Overwrite destination if exists - **loose** - Do not error if source file doesn't exits, abort and resolve with `null` instead. ### copyDir(src, dest[, options[, cb]]) _(fs2/copy-dir)_ Copy directory recursively, returns promise but accepts as well regular callback. Supported options: - **loose** - Do not error if file doesn't exits or is inaccessible, return _false_ instead. ### descriptorsHandler() _(fs2/descriptors-handler)_ Initializes _EMFILE_ errors prevention. **To be used only in main modules. Never require it in generic module that may be required in others** How it works? If limit of descriptors is reached it holds the calls to native functions and releases them when taken descriptors are freed. Internally it provides same solution as [fs-graceful](https://github.com/isaacs/node-graceful-fs) module with following differences: 1. Focuses only on file descriptors limit problem 2. Gives access to taken/available descriptors count and allows setting of limit by external module. Thanks to that we can also cover descriptors opened by fs.watch module ([watch](#watchpath) is bound to that module) 3. Covers readdir calls (which also happen to throw _EMFILE_ errors) 4. More bulletproof (I assume) error handling logic ### hasAccess(path[, options[, cb]]) _(fs2/has-access)_ Conditional version of [`access`](#accesspath-mode-cb-fs2access). Returns promise. Supported options: - **mode** - Passed as `mode` argument to [`access`](#accesspath-mode-cb-fs2access) - **loose** - Do not error if file doesn't exits, resolve with `null` instead. ### isDirectory(path[, cb]) _(fs2/is-directory)_ Whether path points to a directory Resolves with `true` if provided path points to a directory, `false` if provided path points to a non-directory file, `null` if there's no file at path. Returns promise. ### isIgnored(mode, path[, options[, cb]]) _(fs2/is-ignored)_ Whether file is ignored up to predefined rules. Returns promise but regular callback is also supported. Rules are decided by _mode_ argument. Currently only `git` mode is supported, in that case rules are searched in _.gitignore_ files (Rules have effect only if placed in valid _git_ repositories). Other modes can be easily configured by extending `_ignoreModes` module (See _lib/fs/\_ignore-modes_ directory to see how it's done). Supported options: - **globalRules** `string|array` - additional global rules. They will be matched as if placed in filesystem root directory, it means that any rules found in existing ignore files may override them. - **watch** `bool` - whether to watch for changes. If ignore state would change, returned promise would emit `change` event with new value (_true_/_false_) ### isSymlink(path[, options[, cb]]) _(fs2/is-symlink)_ Whether path points to a symlimk Resolves with `true` if provided path points to symlink, `false` if provided path points to a non-symlink file, `null` if there's no file at path. Returns promise. Additionally resultion can be fine tuned for specific needs with below options: Supported options: - **linkPath** `string` - Expected linkPath to which symlink should point. If provided and symlink points elsewhere `false` is returned. - **recursive** `bool` - whether check for matching `linkPath` should be applied to final path (so if symlink points to other symlink we check against the final path, and not linked symlink path) ### lchmod(path, mode[, cb]) _(fs2/lchmod)_ Same as [fs.lchmod](http://nodejs.org/api/all.html#all_fs_lchmod_path_mode_callback). Returns promise. Only available on Mac OS X. ### lstat(path[, cb]) _(fs2/lstat)_ Same as [fs.lstat](http://nodejs.org/api/all.html#all_fs_lstat_path_callback). Returns promise. ### mkdir(path[, options|mode[, cb]]) _(fs2/mkdir)_ Extended version of native _mkdir_. Returns promise Supported options: - **mode** - Reflects _mode_ in [native version](http://nodejs.org/api/all.html#all_fs_mkdir_path_mode_callback) - **intermediate** - Whether to create directories recursively (if parent is not created), reflects `mkir -p`, internal implementation inspired by [Substack's node-mkdirp](https://github.com/substack/node-mkdirp/) - **silent** - Do not throw error if directory already exists ### readFile(path[, options][, cb]) _(fs2/read-file)_ Extended version of native [fs.readFile](http://nodejs.org/api/all.html#all_fs_readfile_filename_encoding_callback). Returns promise Supported options: - **loose** - Do not error if file doesn't exits or is inaccessible, return _null_ instead. - **watch** - Whether to watch file for changes. Changes are emited via _change_ event on returned promise. If file was removed and _loose_ option is off, _end_ event is emitted and watcher is closed ### readdir(path[, options[, cb]]) _(fs2/readdir)_ Extended version of native [fs.readdir](http://nodejs.org/api/all.html#all_fs_readdir_path_callback). Returns promise Suported options: - **loose** `boolean`- Resolve with `null` (instead of error) if directory doesn't exist - **depth** `number`- Level of recurse into subdirectories. Defaults to _0_ which resembles behavior of native version. If you want to recurse without any nest limitation just provide _Infinity_ - **type** `object`- Which type of files should be returned. By default all files are returned. [Stats methods](http://nodejs.org/api/all.html#all_class_fs_stats) shows how many different types can be returned. To narrow it down provide a hash. e.g. `{ file: true, symbolicLink: true }`. - **pattern** `regexp`- Filter returned files by specific pattern. Pattern should be regular expression that would be matched against full path. - **watch** `bool` - Watch directory for changes. Changes are emitted on returned promise with `change` events. _event_ object states which files were added (`event.added`) and which were removed (`event.removed`), **_Starting from next release (v0.4) this functionality will most likely be provided as valid Node.js [stream](http://nodejs.org/api/all.html#all_stream)_** - **stream** `bool` - Whether to provide data continuously. Currently it's not provided as a [stream](http://nodejs.org/api/all.html#all_stream) per se (it would be starting from next release, v0.4), data is emited as `change` events on returned promise object, structure of _event_ objects described under _watch_ option - **ignoreRules** `string|array` - Whether to obey ignore rules found in ignore files. See _[fs.isIgnored](#isignoredmode-path-options-cb)_ for more information - **globalRules** `string|array` - Global rules that complement ignoreRules. See _[fs.isIgnored](#isignoredmode-path-options-cb)_ for more information. - **dirFilter** `function|regexp` - Filter out directories into which we should not recurse to. Can be provided as function which having directory name should return boolaen (`true` if we should recurse into directory), or as regex which if matches means that directory should be recurse into. Neverthless `depth` setting is supported unconditionally ### readlink(path[, options[, cb]]) _(fs2/readlink)_ Same as [fs.readlink](http://nodejs.org/api/all.html#fs_fs_readlink_path_options_callback). Returns promise. Supports `loose: true` option, which when passed, resolves with `null` (instead of exception) if file at path is not a symlink or it doesn't exist. ### realpath(path[, options[, cb]]) _(fs2/realpath)_ Same as [fs.realpath](http://nodejs.org/api/all.html#fs_fs_realpath_path_options_callback). Returns promise. Supports `loose: true` option, which when passed, resolves with `null` (instead of exception) if path doesn't exist ### rename(oldPath, newPath[, cb]) _(fs2/rename)_ Same as [fs.rename](http://nodejs.org/api/all.html#all_fs_rename_oldpath_newpath_callback). Returns promise. ### rmdir(path[, options[, cb]]) _(fs2/rmdir)_ Extended version of native _rmdir_. Returns promise Supported options: - **recursive** - Attempt to remove directory with subdirectories recursively. - **force** - Attempt to remove other files within directory as well. ### rmdirSync(path[, options]) _(fs2/rmdir-sync)_ Extended version of native _rmdirSynnc_. Supported options: - **recursive** - Attempt to remove directory with all its content recursively. ### stat(path[, cb]) _(fs2/stat)_ Same as [fs.stat](http://nodejs.org/api/all.html#all_fs_stat_path_callback). Returns promise. ### symlink(srcPath, dstPath[, type[, cb]]) _(fs2/symlink)_ Same as [fs.symlink](http://nodejs.org/api/all.html#all_fs_symlink_srcpath_dstpath_type_callback). Returns promise. ### typeByStats(stats) _(fs2/type-by-stats)_ Returns type of file according to provided [stats](http://nodejs.org/api/all.html#all_class_fs_stats) object. ### unlink(path[, cb]) _(fs2/unlink)_ Same as [fs.unlink](http://nodejs.org/api/all.html#all_fs_unlink_path_callback). Returns promise. ### watchPath(path) _(fs2/watch-path)_ Watch specific path for changes. It's about observing specific file path (not directory content). `change` events are emitted with event object where `event.type` says wether file was created, modified or removed. ### watch(path) _(fs2/watch)_ Watch file for changes. [fs.watch](http://nodejs.org/api/all.html#all_fs_watch_filename_options_listener) wrapper that works same way on every platform, always configured in _persistent: false_ mode. It's aware of open file descriptors limitations, if _EMFILE_ error is approach, switch to alternative mode that pings file stats (see [fs.watchFile](http://nodejs.org/api/all.html#all_fs_watchfile_filename_options_listener)) is made. ### writeFile(filename, data[, options|encoding[, callback]]) _(fs2/write-file)_ Same as native [fs.writeFile](http://nodejs.org/api/all.html#all_fs_writefile_filename_data_encoding_callback) but safe for simultaneous calls of write to same file (in such case current write will be abandonded, and new would be started). Supported options: - **encoding** - Reflects _encoding_ in [native version](http://nodejs.org/api/all.html#all_fs_writefile_filename_data_options_callback) - **intermediate** - In case directory doesn't exist, whether to create full directory path ## Tests [![Build Status](https://travis-ci.org/medikoo/fs2.png?branch=master)](https://travis-ci.org/medikoo/fs2) $ npm test fs2-0.3.9/access.js000066400000000000000000000016361375545423700140410ustar00rootroot00000000000000"use strict"; var isCallable = require("es5-ext/object/is-callable") , isValue = require("es5-ext/object/is-value") , deferred = require("deferred") , resolve = require("path").resolve , fs = require("fs"); var original = fs.access, defaultMode = (fs.constants || fs).R_OK; var access = function (path, mode) { var def = deferred(); original(path, mode, function (err, stats) { if (err) { def.reject(err); } else { def.resolve(stats); } }); return def.promise; }; access.returnsPromise = true; module.exports = function (path/*[, mode[, callback]]*/) { var mode, cb; path = resolve(String(path)); mode = arguments[1]; cb = arguments[2]; if (!isValue(cb) && isCallable(mode)) { cb = mode; mode = defaultMode; } else if (isValue(mode)) { mode = Number(mode); } return access(path, mode).cb(cb); }; module.exports.returnsPromise = true; module.exports.access = access; fs2-0.3.9/append-file.js000066400000000000000000000030121375545423700147520ustar00rootroot00000000000000"use strict"; var isCallable = require("es5-ext/object/is-callable") , isValue = require("es5-ext/object/is-value") , isString = require("es5-ext/string/is-string") , deferred = require("deferred") , pathUtils = require("path") , original = require("fs").appendFile , mkdir = require("./mkdir").mkdir , dirname = pathUtils.dirname , resolve = pathUtils.resolve; var _appendFile = function (path, data, options, pResolve, reject) { original(path, data, options, function (err) { var dir; if (!isValue(err)) { pResolve(null); return; } if (!options.intermediate) { reject(err); return; } if (err.code !== "ENOENT") { reject(err); return; } dir = dirname(path); if (dir === path) { reject(err); return; } mkdir(dir, { intermediate: true }).cb(function () { _appendFile(path, data, options, pResolve, reject); }, reject); }); }; var appendFile = function (path, data, options) { var def = deferred(); _appendFile(path, data, options, def.resolve, def.reject); return def.promise; }; appendFile.returnsPromise = true; module.exports = exports = function (path, data/*, options*/) { var cb, options; path = resolve(String(path)); options = arguments[2]; cb = arguments[3]; if (!isValue(cb) && isCallable(options)) { cb = options; options = {}; } else { options = isString(options) ? { encoding: options } : Object(options); } return appendFile(path, data, options).cb(cb); }; exports.returnsPromise = true; exports.appendFile = appendFile; fs2-0.3.9/chmod.js000066400000000000000000000024361375545423700136710ustar00rootroot00000000000000"use strict"; if (process.platform === "win32") { module.exports = null; return; } var isValue = require("type/value/is") , isObject = require("type/object/is") , isPlainFunction = require("type/plain-function/is") , deferred = require("deferred") , resolve = require("path").resolve , original = require("fs").chmod , lstat = require("./lstat").lstat; var bareChmod = function (path, mode) { var def = deferred(); original(path, mode, function (err, stats) { if (err) def.reject(err); else def.resolve(stats); }); return def.promise; }; var chmod = function (path, mode, options) { if (!options.append) return bareChmod(path, mode); return lstat(path).then(function (stats) { var targetMode = stats.mode | mode; if (targetMode === stats.mode) return stats; return bareChmod(path, targetMode); }); }; chmod.returnsPromise = true; module.exports = exports = function (path, mode/*, options, callback*/) { var options = arguments[2], callback = arguments[3]; if (!isValue(callback) && isPlainFunction(options)) { callback = options; options = {}; } else if (!isObject(options)) { options = {}; } return chmod(resolve(String(path)), mode, options).cb(callback); }; exports.returnsPromise = true; exports.chmod = chmod; fs2-0.3.9/copy-dir.js000066400000000000000000000045551375545423700143310ustar00rootroot00000000000000"use strict"; var isCallable = require("es5-ext/object/is-callable") , isValue = require("es5-ext/object/is-value") , startsWith = require("es5-ext/string/#/starts-with") , deferred = require("deferred") , path = require("path") , lstat = require("./lstat") , mkdir = require("./mkdir") , readdir = require("./readdir") , readlink = require("./readlink") , symlink = require("./symlink") , copyFile = require("./copy").copy; var dirname = path.dirname, relative = path.relative, resolve = path.resolve, sep = path.sep; var copyDir = function (source, dest, options, sourceTop, destTop) { return readdir(source, { type: { directory: true, file: true, symbolicLink: true }, depth: Infinity })( function (files) { return deferred.map(files, function (relativePath) { var filename = resolve(source, relativePath); return lstat(filename)(function (stats) { if (stats.isDirectory()) { return mkdir(resolve(dest, relativePath), { intermediate: true }); } if (stats.isFile()) { return copyFile(filename, resolve(dest, relativePath), { intermediate: true }); } if (!stats.isSymbolicLink()) return null; return readlink(filename)(function (linkPath) { linkPath = resolve(dirname(filename), linkPath); var linkDirname = dirname(linkPath); if ( linkDirname === sourceTop || startsWith.call(linkDirname, sourceTop + sep) ) { linkPath = resolve(destTop, linkPath.slice(sourceTop.length + 1)); } return symlink( relative(dirname(resolve(dest, relativePath)), linkPath), resolve(dest, relativePath), { intermediate: true } ); }); }); }); }, function (error) { if (options.loose && error.code === "ENOENT") return false; throw error; } )(true); }; copyDir.returnsPromise = true; module.exports = exports = function (source, dest/*, options, cb*/) { var options = Object(arguments[2]), cb = arguments[3]; if (!isValue(cb) && isCallable(options)) { cb = options; options = {}; } source = resolve(String(source)); dest = resolve(String(dest)); return lstat(dest, { loose: true })(function (stats) { if (stats) throw new Error("Destination path exists"); return copyDir(source, dest, options, source, dest); }).cb(cb); }; exports.copyDir = copyDir; exports.returnsPromise = true; fs2-0.3.9/copy.js000066400000000000000000000062751375545423700135560ustar00rootroot00000000000000/* eslint max-lines: off */ // Copy file // Credit: Isaac Schlueter // http://groups.google.com/group/nodejs/msg/ef4de0b516f7d5b8 "use strict"; var isCallable = require("es5-ext/object/is-callable") , isValue = require("es5-ext/object/is-value") , normalizeOptions = require("es5-ext/object/normalize-options") , d = require("d") , deferred = require("deferred") , fs = require("fs") , path = require("path") , mkdir = require("./mkdir") , rm = require("./rm") , unlink = require("./unlink"); var objHasOwnProperty = Object.prototype.hasOwnProperty , defineProperty = Object.defineProperty , dirname = path.dirname , resolve = path.resolve , createReadStream = fs.createReadStream , createWriteStream = fs.createWriteStream , stat = fs.stat; var fixOptions = function (options) { if (options.hasOwnProperty) return options; return defineProperty(options, "hasOwnProperty", d(objHasOwnProperty)); }; var copyFileWithMode = function (def, source, dest, options) { var read, write; var isReadDisposed = false; try { read = createReadStream(source); } catch (e) { return def.reject(e); } read.on("error", function (e) { if (isReadDisposed) return; if (options.loose && e.code === "ENOENT") def.resolve(unlink(dest, { loose: true })(false)); else def.reject(e); }); try { write = createWriteStream(dest, fixOptions(options)); } catch (e1) { read.destroy(); return def.reject(e1); } write.on("error", function (e) { isReadDisposed = true; read.destroy(); if (e.code === "ENOENT" && options.intermediate) { mkdir(dirname(resolve(dest)), { intermediate: true }).done(function () { options = normalizeOptions(options); delete options.intermediate; return copyFileWithMode(def, source, dest, options); }, def.reject); return; } def.reject(e); }); read.pipe(write); write.on("close", def.resolve.bind(def, true)); return def.promise; }; var copyFile = function (source, dest, options) { var def = deferred(); if (options.mode) { copyFileWithMode(def, source, dest, options); return def.promise; } stat(source, function (e, stats) { if (e) { if (options.loose && e.code === "ENOENT") { def.resolve(false); return; } def.reject(e); return; } options = normalizeOptions(options); options.mode = stats.mode; stat(dest, function (error) { if (!error) { if (options.force) { rm(dest, { recursive: true, force: true, loose: true }).then(function () { return copyFileWithMode(def, source, dest, options); }); } else { def.reject(new Error("Destinaton '" + dest + "' exists")); } } else if (error.code === "ENOENT") { copyFileWithMode(def, source, dest, options); } else { def.reject(error); } }); }); return def.promise; }; copyFile.returnsPromise = true; module.exports = exports = function (source, dest/*, options, cb*/) { var options = Object(arguments[2]), cb = arguments[3]; if (!isValue(cb) && isCallable(options)) { cb = options; options = {}; } return copyFile(String(source), String(dest), options).cb(cb); }; exports.copy = copyFile; exports.returnsPromise = true; fs2-0.3.9/descriptors-handler.js000066400000000000000000000071771375545423700165620ustar00rootroot00000000000000/* eslint max-lines: off */ "use strict"; var last = require("es5-ext/array/#/last") , defineLength = require("es5-ext/function/_define-length") , callable = require("es5-ext/object/valid-callable") , d = require("d") , memoize = require("memoizee") , fs = require("fs"); var max = Math.max , slice = Array.prototype.slice , limit = Infinity , count = 0 , queue = [] , debugStats = { fd: 0, unknown: 0 }; var release = function () { var data, fnCb; // eslint-disable-next-line no-unmodified-loop-condition while (count < limit && (data = queue.shift())) { try { data.fn.apply(data.context, data.args); } catch (e) { fnCb = last.call(data.args); if (typeof fnCb === "function") fnCb(e); } } }; var wrap = function (asyncFn, type) { var self; debugStats[type] = 0; callable(asyncFn); return (self = defineLength(function () { var openCount, args = arguments, context, cb = last.call(args); if (!exports.initialized || typeof cb !== "function") return asyncFn.apply(this, arguments); if (count >= limit) { queue.push({ fn: self, context: this, args: arguments }); return null; } openCount = count++; context = this; args = slice.call(args, 0, -1); args.push(function (err, resultIgnored) { --debugStats[type]; --count; if (err && (err.code === "EMFILE" || err.code === "ENFILE")) { if (limit > openCount) limit = openCount; queue.push({ fn: self, context: context, args: args }); release(); return; } release(); if (typeof cb === "function") cb.apply(this, arguments); }); ++debugStats[type]; return asyncFn.apply(this, args); }, asyncFn.length)); }; module.exports = exports = memoize(function () { var open = fs.open, openSync = fs.openSync, close = fs.close, closeSync = fs.closeSync; if (exports.initialized) return; fs.open = function (path, flags, mode, fnCb) { var openCount, args; if (count >= limit) { queue.push({ fn: fs.open, context: this, args: arguments }); return; } openCount = count++; args = arguments; fnCb = last.call(args); ++debugStats.fd; open(path, flags, mode, function (err, fd) { if (err) { --debugStats.fd; --count; if (err.code === "EMFILE" || err.code === "ENFILE") { if (limit > openCount) limit = openCount; queue.push({ fn: fs.open, context: this, args: args }); release(); return; } release(); } if (typeof fnCb === "function") fnCb(err, fd); }); }; fs.openSync = function (pathIgnored, flagsIgnored, modeIgnored) { var result = openSync.apply(this, arguments); ++debugStats.fd; ++count; return result; }; fs.close = function (fd, fnCb) { close(fd, function (err) { if (!err) { --debugStats.fd; --count; release(); } if (typeof fnCb === "function") fnCb(err); }); }; fs.closeSync = function (fd) { var result; result = closeSync(fd); --debugStats.fd; --count; release(); return result; }; fs.readdir = wrap(fs.readdir, "readdir"); // Needed for Node >=1.2 because of commit e65308053c fs.readFile = wrap(fs.readFile, "readFile"); Object.defineProperty(exports, "initialized", d("e", true)); }); Object.defineProperties(exports, { initialized: d("ce", false), limit: d.gs( function () { return limit; }, function (nLimit) { if (limit >= nLimit) limit = max(nLimit, 5); } ), available: d.gs(function () { return max(limit - count, 0); }), taken: d.gs(function () { return count; }), open: d(function () { ++debugStats.unknown; ++count; }), close: d(function () { --debugStats.unknown; --count; if (release) release(); }), wrap: d(wrap), debugStats: d(debugStats) }); fs2-0.3.9/has-access.js000066400000000000000000000013461375545423700146100ustar00rootroot00000000000000"use strict"; var isCallable = require("es5-ext/object/is-callable") , isValue = require("es5-ext/object/is-value") , resolve = require("path").resolve , access = require("./access"); module.exports = function (path/*[, options[, callback]]*/) { path = resolve(String(path)); var options = arguments[1], cb = arguments[2]; if (!isValue(cb) && isCallable(options)) { cb = options; options = {}; } options = Object(options); return access(path, options.mode) .then( function () { return true; }, function (error) { if (options.loose && (error.code === "ENOENT" || error.code === "ENOTDIR")) { return null; } if (error.code === "EACCES") return false; throw error; } ) .cb(cb); }; fs2-0.3.9/index.js000066400000000000000000000016061375545423700137040ustar00rootroot00000000000000"use strict"; module.exports = { appendFile: require("./append-file"), chmod: require("./chmod"), copy: require("./copy"), copyDir: require("./copy-dir"), descriptorsHandler: require("./descriptors-handler"), isDirectory: require("./is-directory"), isIgnored: require("./is-ignored"), isSymlink: require("./is-symlink"), lchmod: require("./lchmod"), lstat: require("./lstat"), mkdir: require("./mkdir"), readFile: require("./read-file"), readdir: require("./readdir"), readlink: require("./readlink"), realpath: require("./realpath"), rename: require("./rename"), rm: require("./rm"), rmdir: require("./rmdir"), rmdirSync: require("./rmdir-sync"), stat: require("./stat"), symlink: require("./symlink"), typeByStats: require("./type-by-stats"), unlink: require("./unlink"), watch: require("./watch"), watchPath: require("./watch-path"), writeFile: require("./write-file") }; fs2-0.3.9/is-directory.js000066400000000000000000000004261375545423700152110ustar00rootroot00000000000000"use strict"; var lstat = require("./lstat").lstat; module.exports = function (path/*, callback*/) { return lstat(path, { loose: true })(function (stats) { if (stats) return stats.isDirectory(); return null; }).cb(arguments[1]); }; module.exports.returnsPromise = true; fs2-0.3.9/is-ignored.js000066400000000000000000000172211375545423700146350ustar00rootroot00000000000000/* eslint max-statements: off, max-lines: off */ "use strict"; var invoke = require("es5-ext/function/invoke") , noop = require("es5-ext/function/noop") , isCallable = require("es5-ext/object/is-callable") , isValue = require("es5-ext/object/is-value") , forEach = require("es5-ext/object/for-each") , memoize = require("memoizee") , deferred = require("deferred") , ignore = require("ignore") , pathUtils = require("path") , modes = require("./lib/ignore-modes") , getMap = require("./lib/get-conf-file-map") , memoizeWatcher = require("./lib/memoize-watcher") , findRoot = require("./lib/find-root"); var isArray = Array.isArray , push = Array.prototype.push , call = Function.prototype.call , trim = call.bind(String.prototype.trim) , dirname = pathUtils.dirname , resolve = pathUtils.resolve , sep = pathUtils.sep , ConfMap = getMap.ConfMap , applyRules , applyGlobalRules , compile , IsIgnored , isIgnored , buildMap , prepareRules , parseSrc , eolRe = /(?:\r\n|[\n\r\u2028\u2029])/; prepareRules = function (data) { return data.map(trim).filter(Boolean).reverse(); }; parseSrc = function (src) { return prepareRules(String(src).split(eolRe)); }; compile = function (maps, result) { var data = (result.data = {}), paths = (result.paths = []); // Merge rules found in ignorefiles maps.forEach(function (map) { forEach(map.map, function (rules, path) { if (!rules.length) return; if (!data[path]) { paths.push(path); data[path] = []; } data[path].push(rules); }); }); result.paths.sort(); return result; }; applyRules = function (rules, rootPath, path) { if (!rootPath.endsWith(sep)) rootPath += sep; if (!path.startsWith(rootPath)) return { value: false, target: path }; rules = rules.slice().reverse().filter(function (rule) { return !rule.startsWith("#"); }); var ig = ignore().add(rules); var testPath = path.slice(rootPath.length); var result = ig.ignores(testPath); if (!result) { var excludeRules = rules.filter(function (rule) { return rule.startsWith("!"); }); if (excludeRules.length) { var ig2 = ignore().add(excludeRules.map(function (rule) { return rule.slice(1); })); if (!ig2.ignores(testPath)) result = null; } else { result = null; } } return { value: result, target: path }; }; applyGlobalRules = function (path, rules) { var value; // Check global rules value = applyRules(rules, path.slice(0, path.indexOf(sep) + 1), path); return Boolean(value.value); }; buildMap = function (lDirname, lGetMap, watch) { var promise, data = {}, maps; lGetMap = lGetMap.map(function (getSubMap, index) { var map = getSubMap(lDirname); if (watch) { map.on("change", function (targetMap) { if (maps) { maps[index] = targetMap; compile(maps, data); promise.emit("change", data); } }); } return map; }); if (lGetMap.length > 1) { promise = deferred.map(lGetMap)(function (result) { maps = result; return compile(maps, data); }); } else { promise = lGetMap[0](function (map) { maps = [map]; return compile(maps, data); }); } if (watch) { promise.close = function () { lGetMap.forEach(invoke("close")); }; } return promise; }; IsIgnored = function (path, watch) { this.path = path; this.dirname = dirname(path); this.watch = watch; }; IsIgnored.prototype = { init: function (mapPromise) { this.mapPromise = mapPromise; this.promise = mapPromise( function (data) { this.data = data; return this.calculate(); }.bind(this) ); if (this.watch) { mapPromise.on( "change", function () { var value = this.calculate(); if (value !== this.promise.value) { this.promise.value = value; this.promise.emit("change", value, this.path); } }.bind(this) ); this.promise.close = this.close.bind(this); } return this.promise; }, close: function () { this.mapPromise.close(); }, calculate: function () { var current, result = false; if (!this.data.paths) return false; // Apply rules current = this.path; this.data.paths.some(function (rulesPath, index) { if (rulesPath.length > this.dirname.length) return true; if (index) { var dirIgnored = this.data.paths.slice(0, index).some(function (preRulesPath) { return this.data.data[preRulesPath].some(function (rules) { return applyRules(rules, preRulesPath, rulesPath).value; }, this); }, this); if (dirIgnored) return false; } this.data.data[rulesPath].forEach(function (rules) { var data = applyRules(rules, rulesPath, current); if (data.value === false && current !== pathUtils) { data = applyRules(rules, rulesPath, this.path); } if (data.target !== current || isValue(data.value)) { result = data.value; } current = data.target; }, this); return false; }, this); return Boolean(result); } }; isIgnored = function (mode, path, options) { var watch, globalRules, lIsIgnored, getMapFns, lDirname, promise; if (isValue(options.globalRules)) { globalRules = isArray(options.globalRules) ? options.globalRules : String(options.globalRules).split(eolRe); } if (mode) { getMapFns = []; if (!globalRules) globalRules = []; if (!isArray(mode)) { if (!modes[mode]) throw new Error("Unknown mode '" + mode + "'"); mode = [mode]; } mode.forEach(function (name) { var lMode = modes[name]; if (!lMode) throw new Error("Unknown mode '" + name + "'"); getMapFns.push(function (pathIgnored) { return getMap(lDirname, lMode, watch, parseSrc); }); if (lMode.globalRules) push.apply(globalRules, lMode.globalRules); }); } watch = options.watch; if (globalRules) { globalRules = prepareRules(globalRules); if (applyGlobalRules(path, globalRules)) { promise = deferred(true); if (watch) promise.close = noop; return promise; } } if (!mode) { promise = deferred(false); if (watch) promise.close = noop; return promise; } lIsIgnored = new IsIgnored(path, watch); lDirname = lIsIgnored.dirname; return lIsIgnored.init(buildMap(lDirname, getMapFns, watch)); }; isIgnored.returnsPromise = true; module.exports = exports = function (mode, path) { var options, cb; path = resolve(String(path)); options = Object(arguments[2]); cb = arguments[3]; if (!cb) { if (isCallable(options)) { cb = options; options = {}; } } return isIgnored(mode, path, options).cb(cb); }; exports.returnsPromise = true; exports.isIgnored = isIgnored; exports.IsIgnored = IsIgnored; exports.applyGlobalRules = applyGlobalRules; exports.getIsIgnored = function (modeNames, globalRules, watch) { var memo, mapGetters = [], build; if (!globalRules) globalRules = []; memo = watch ? memoizeWatcher : memoize; modeNames.forEach(function (name) { var mode = modes[name], isRoot, readRules; if (!mode) throw new Error("Unknown mode '" + name + "'"); isRoot = memo(mode[watch ? "isRootWatcher" : "isRoot"], { primitive: true }); readRules = memo(getMap[watch ? "readRulesWatcher" : "readRules"], { primitive: true }); mapGetters.push(function (path) { var map; map = new ConfMap(path, watch); map.filename = mode.filename; map.readRules = readRules; map.parse = parseSrc; return map.init(findRoot(isRoot, path, { watch: watch })); }); if (mode.globalRules) push.apply(globalRules, mode.globalRules); }); build = memo(function (lDirname) { return buildMap(lDirname, mapGetters, watch); }, { primitive: true }); return { isIgnored: function (path) { var lIsIgnored; lIsIgnored = new IsIgnored(path, watch); return lIsIgnored.init(build(lIsIgnored.dirname)); }, globalRules: globalRules.length ? prepareRules(globalRules) : null }; }; fs2-0.3.9/is-symlink.js000066400000000000000000000024231375545423700146720ustar00rootroot00000000000000"use strict"; var isCallable = require("es5-ext/object/is-callable") , isValue = require("es5-ext/object/is-value") , dirname = require("path").dirname , resolve = require("path").resolve , readlink = require("./readlink").readlink , realpath = require("./realpath").realpath; module.exports = function (path/*[, options[, callback]]*/) { path = resolve(String(path)); var options = arguments[1], cb = arguments[2]; if (!isValue(cb) && isCallable(options)) { cb = options; options = {}; } else { options = Object(options); } var expectedLinkPath = options.linkPath ? resolve(String(options.linkPath)) : null; return readlink(path, {})( function (linkPath) { if (!linkPath) return null; if (!expectedLinkPath) return true; if (!options.recursive) return resolve(dirname(path), linkPath) === expectedLinkPath; return realpath(path, { loose: true })(function (finalLinkPath) { if (!finalLinkPath) return false; return finalLinkPath === expectedLinkPath; }); }, function (error) { if (error.code === "ENOENT") return null; if (error.code === "EINVAL") return false; if (error.code === "ENOTDIR") return null; if (error.code === "UNKNOWN") return null; throw error; } ).cb(cb); }; module.exports.returnsPromise = true; fs2-0.3.9/lchmod.js000066400000000000000000000011251375545423700140370ustar00rootroot00000000000000"use strict"; var deferred = require("deferred") , resolve = require("path").resolve , original = require("fs").lchmod , lchmod; lchmod = function (path, mode) { var def = deferred(); original(path, mode, function (err, stats) { if (err) def.reject(err); else def.resolve(stats); }); return def.promise; }; lchmod.returnsPromise = true; if (original) { module.exports = exports = function (path, mode/*, callback*/) { return lchmod(resolve(String(path)), mode).cb(arguments[2]); }; exports.returnsPromise = true; exports.lchmod = lchmod; } else { module.exports = null; } fs2-0.3.9/lib/000077500000000000000000000000001375545423700130025ustar00rootroot00000000000000fs2-0.3.9/lib/buffer-from.js000066400000000000000000000003611375545423700155520ustar00rootroot00000000000000// Maintain support for very old versions of Node.js "use strict"; module.exports = Buffer.from ? Buffer.from : function (data, encoding) { // eslint-disable-next-line no-buffer-constructor return new Buffer(data, encoding); }; fs2-0.3.9/lib/find-root.js000066400000000000000000000050731375545423700152460ustar00rootroot00000000000000"use strict"; var invoke = require("es5-ext/function/invoke") , assign = require("es5-ext/object/assign") , isValue = require("es5-ext/object/is-value") , forEach = require("es5-ext/object/for-each") , deferred = require("deferred") , dirname = require("path").dirname; // eslint-disable-next-line no-empty-function var FindRoot = function () {}; FindRoot.prototype = { known: false, close: function () { if (this.promises) { forEach(this.promises, invoke("close")); this.known = true; delete this.promises; } if (!this.promise.resolved) { this.reject(new Error("Find root action cancelled")); } }, onvalue: function (value) { if (this.known) { return; } if (value) { this.known = true; if (this.watch && this.promise.resolved) { this.promise.value = this.path; this.promise.emit("change", this.path); } else { this.resolve(this.path); } } else { this.down(); } }, next: function () { var isRoot; isRoot = this.isRoot(this.path); if (this.watch) { this.promises[this.path] = isRoot; isRoot.on("change", this.onevent); } isRoot.done(this.onvalue); }, down: function () { var dir = dirname(this.path); if (dir === this.path) { this.known = true; this.path = ""; if (this.watch && this.promise.resolved) { this.promise.value = null; this.promise.emit("change", null); } else { this.resolve(null); } return; } this.path = dir; this.next(); }, onevent: function (value, path) { var dir; if (value) { if (!isValue(path)) throw new TypeError("Path must be provided"); this.path = path; dir = dirname(path); while (this.promises[dir]) { this.promises[dir].close(); delete this.promises[dir]; dir = dirname(dir); } this.known = true; // Race condition may occur, double check if (this.promise.value !== this.path) { this.promise.value = this.path; this.promise.emit("change", this.path); } } else { if (!this.known || path !== this.path) { return; } this.known = false; this.down(); } } }; module.exports = function (isRoot, path/*, options*/) { var findRoot, options; options = arguments[2]; findRoot = new FindRoot(); findRoot.isRoot = isRoot; findRoot.path = path; findRoot.onvalue = findRoot.onvalue.bind(findRoot); findRoot.onevent = findRoot.onevent.bind(findRoot); assign(findRoot, deferred()); findRoot.watch = options && options.watch; if (findRoot.watch) { findRoot.promises = {}; findRoot.promise.close = findRoot.close.bind(findRoot); } findRoot.next(); return findRoot.promise; }; fs2-0.3.9/lib/get-conf-file-map.js000066400000000000000000000125561375545423700165430ustar00rootroot00000000000000// Function that provides map of rules found in ignorefiles for given ignorefile // type. Additinally it invokes event on changes in map which are results of // changes in ignorefiles. "use strict"; var invoke = require("es5-ext/function/invoke") , assign = require("es5-ext/object/assign") , isValue = require("es5-ext/object/is-value") , forEach = require("es5-ext/object/for-each") , isCopy = require("es5-ext/object/is-copy-deep") , endsWith = require("es5-ext/string/#/ends-with") , deferred = require("deferred") , pathUtils = require("path") , findRoot = require("./find-root") , readFile = require("../read-file").readFile , dirname = pathUtils.dirname , sep = pathUtils.sep , ConfMap , readRules , readRulesWatcher , paths , getMap , lockId = 0; paths = function (rootPath, path2) { var starter, data; starter = [rootPath]; if (rootPath === path2) { return starter; } if (endsWith.call(rootPath, sep)) { data = path2.slice(rootPath.length).split(sep); starter.push((rootPath += data.shift())); } else { data = path2.slice(rootPath.length + 1).split(sep); } return starter.concat(data.map(function (path) { return (rootPath += sep + path); })); }; readRules = function (path) { return this.readFile(path + sep + this.filename)( function (src) { return isValue(src) ? this.parse(src, path) : src; }.bind(this) ); }; readRulesWatcher = function (path) { var watcher, promise, current; watcher = this.readFile(path + sep + this.filename); promise = watcher( function (src) { return (current = isValue(src) ? this.parse(src, path) : src); }.bind(this) ); watcher.on( "change", function (data) { data = isValue(data) ? this.parse(data, path) : data; if (data === current) return; if ( isValue(current) && isValue(data) && typeof current === "object" && isCopy(current, data) ) { return; } current = promise.value = data; promise.emit("change", current, path); }.bind(this) ); promise.close = watcher.close; return promise; }; ConfMap = function (path, watch) { this.path = path; this.watch = watch; this.data = { root: null, map: {} }; assign(this, deferred()); if (this.watch) { this.onRulesChange = this.onRulesChange.bind(this); this.rulePromises = {}; this.promise.close = this.close.bind(this); } }; ConfMap.prototype = { init: function (lFindRoot) { this.findRoot = lFindRoot; if (this.watch) { lFindRoot.on("change", this.updateRoot.bind(this)); } lFindRoot.done( function (rootPath) { if (rootPath) { this.data.root = rootPath; this.addPaths(rootPath, this.path).done( function () { this.resolve(this.data); }.bind(this), this.resolve ); } else { this.resolve(this.data); } }.bind(this), this.resolve ); return this.promise; }, close: function () { if (this.rulePromises) { this.findRoot.close(); forEach(this.rulePromises, invoke("close")); delete this.rulePromises; } }, parse: String, readFile: function (path) { return readFile(path, { loose: true, watch: this.watch }); }, onRulesChange: function (rules, path) { if (isValue(rules)) { this.data.map[path] = rules; } else { delete this.data.map[path]; } this.promise.emit("change", this.data); }, addPaths: function (rootPath, path) { return deferred.map( paths(rootPath, path), function (lPath) { var rules = this.readRules(lPath); if (this.watch) { this.rulePromises[lPath] = rules; rules.on("change", this.onRulesChange); } return rules.aside( function (lRules) { if (isValue(lRules)) { this[lPath] = lRules; } }.bind(this.data.map) )( null, function (err) { // Watcher might have been closed in a meantime, if it was we ignore // this error as we're not interested in that value anymore return this.rulePromises[lPath] ? err : null; }.bind(this) ); }, this ); }, removePaths: function (rootPath, path) { paths(rootPath, path).forEach(function (lPath) { var promise = this.rulePromises[lPath]; delete this.rulePromises[lPath]; delete this.data.map[lPath]; promise.close(); }, this); }, updateRoot: function (rootPath) { var lock = ++lockId; if (!rootPath) { this.removePaths(this.data.root, this.path); this.data.root = null; this.promise.emit("change", this.data); } else if (!this.data.root) { this.data.root = rootPath; this.addPaths(rootPath, this.path).done( function () { if (lock === lockId) { this.promise.emit("change", this.data); } }.bind(this) ); } else if (this.data.root < rootPath) { this.removePaths(this.data.root, dirname(rootPath)); this.data.root = rootPath; this.promise.emit("change", this.data); } else { this.addPaths(rootPath, dirname(this.data.root)).done( function () { if (lock === lockId) { this.promise.emit("change", this.data); } }.bind(this) ); this.data.root = rootPath; } } }; getMap = module.exports = function (path, mode, watch, parse) { var map = new ConfMap(path, watch); map.filename = mode.filename; map.readRules = watch ? readRulesWatcher : readRules; if (parse) { map.parse = parse; } return map.init(findRoot(watch ? mode.isRootWatcher : mode.isRoot, path, { watch: watch })); }; getMap.ConfMap = ConfMap; getMap.readRules = readRules; getMap.readRulesWatcher = readRulesWatcher; fs2-0.3.9/lib/ignore-modes/000077500000000000000000000000001375545423700153725ustar00rootroot00000000000000fs2-0.3.9/lib/ignore-modes/git.js000066400000000000000000000020361375545423700165140ustar00rootroot00000000000000"use strict"; var deferred = require("deferred") , resolve = require("path").resolve , lstat = require("fs").lstat , WatchPath = require("../../watch-path").WatchPath , isRoot; exports.filename = ".gitignore"; exports.globalRules = [".git"]; exports.isRoot = isRoot = function (path) { var def, gPath; gPath = resolve(path, ".git"); def = deferred(); lstat(gPath, function (err, stats) { def.resolve(err ? false : stats.isDirectory()); }); def.promise.gitPath = gPath; def.promise.path = path; return def.promise; }; exports.isRoot.returnsPromise = true; exports.isRootWatcher = function (path) { var promise, watcher; promise = isRoot(path); watcher = new WatchPath(promise.gitPath); watcher.on("change", function (event) { if (event.type === "create") { promise.value = true; } else if (event.type === "remove") { promise.value = false; } else { return; } promise.emit("change", promise.value, path); }); promise.close = watcher.close; return promise; }; exports.isRootWatcher.returnsPromise = true; fs2-0.3.9/lib/ignore-modes/index.js000066400000000000000000000000731375545423700170370ustar00rootroot00000000000000"use strict"; module.exports = { git: require("./git") }; fs2-0.3.9/lib/memoize-watcher.js000066400000000000000000000020141375545423700164350ustar00rootroot00000000000000"use strict"; var noop = require("es5-ext/function/noop") , assign = require("es5-ext/object/assign") , memoize = require("memoizee") , ee = require("event-emitter") , eePipe = require("event-emitter/pipe") , deferred = require("deferred") , isPromise = deferred.isPromise; module.exports = function (fn/*, options*/) { var factory, memoized; if (fn.__memoized__) return fn; memoized = memoize(fn, assign(Object(arguments[1]), { refCounter: true })); factory = function () { var watcher, emitter, pipe, args, def; args = arguments; watcher = memoized.apply(this, arguments); if (isPromise(watcher)) { def = deferred(); emitter = def.promise; def.resolve(watcher); } else { emitter = ee(); } pipe = eePipe(watcher, emitter); emitter.close = function () { emitter.close = noop; pipe.close(); if (memoized.deleteRef.apply(this, args)) watcher.close(); }; return emitter; }; factory.clear = memoized.delete; factory.__memoized__ = true; return factory; }; fs2-0.3.9/lib/watch-alt.js000066400000000000000000000051101375545423700152210ustar00rootroot00000000000000"use strict"; var promisify = require("deferred").promisify , ee = require("event-emitter") , fs = require("fs") , typeByStats = require("../type-by-stats") , lstatSync = fs.lstatSync , readdir = promisify(fs.readdir) , watchFile = fs.watchFile , unwatchFile = fs.unwatchFile , other , directory , opts = { persistent: false, interval: 1500 }; other = function (path, emitter, stats) { var end, close, type, listener; end = function (err) { if (emitter) { emitter.emit("end", err); close(); } }; close = function () { unwatchFile(path, listener); emitter = null; }; emitter.end = end; emitter.close = close; type = typeByStats(stats); watchFile( path, opts, (listener = function (nstats) { var nType, err; if (!emitter) return; if (!nstats.ctime.getTime() && !nstats.mode) { // It means that file doesn't exist enymore err = new Error("File doesn't exist"); err.code = "ENOENT"; end(err); return; } nType = typeByStats(nstats); if (type !== nType) { err = new Error("File type have changed"); err.code = "DIFFTYPE"; end(err); return; } if ( stats.ctime.valueOf() !== nstats.ctime.valueOf() || (stats.mtime.valueOf() !== nstats.mtime.valueOf() || stats.size !== nstats.size) ) { emitter.emit("change"); } stats = nstats; }) ); }; directory = function (path, emitter) { var end, close, data, compare, listener; end = function (err) { if (emitter) { emitter.emit("end", err); close(); } }; close = function () { if (emitter) { if (listener) unwatchFile(path, listener); emitter = null; } }; compare = function (file, index) { return data[index] === file; }; emitter.end = end; emitter.close = close; readdir(path).done(function (files) { data = files.sort(); watchFile( path, opts, (listener = function (stats) { var err; if (!emitter) return; if (!stats.ctime.getTime() && !stats.mode) { // It means that dir doesn't exist enymore err = new Error("Directory doesn't exist"); err.code = "ENOENT"; end(err); return; } readdir(path).done(function (nuFiles) { if (!emitter) return; if (nuFiles.length !== data.length || !nuFiles.sort().every(compare)) { data = nuFiles; emitter.emit("change"); } }, end); }) ); }, end); }; module.exports = function (path, emitter) { var stats = lstatSync(path); if (!emitter) emitter = ee(); if (stats.isDirectory()) directory(path, emitter); else other(path, emitter, stats); return emitter; }; fs2-0.3.9/lib/watch.js000066400000000000000000000041371375545423700144530ustar00rootroot00000000000000"use strict"; var promisify = require("deferred").promisify , ee = require("event-emitter") , fs = require("fs") , typeByStats = require("../type-by-stats"); var nextTick = process.nextTick , lstat = promisify(fs.lstat) , watch = fs.watch , opts = { persistent: false }; module.exports = function (path, emitter) { var stats, fileType, listener, watcher, lock, end, clearLock, close; end = function (err) { if (emitter) { emitter.emit("end", err); close(); } }; close = function () { if (emitter) { watcher.close(); emitter = null; } }; clearLock = function () { lock = null; }; listener = function (type) { if (lock) return; if (lock === false) { lock = type === "rename"; return; } lock = type === "rename"; // We do timeout, as there are cases that reinitializing watcher right away // doesn't work as file is not accessible. It gives us false positive that // file is removed (and that is not reported by dir watcher on parent dir) setTimeout(function () { var nwatcher; nextTick(clearLock); watcher.close(); try { nwatcher = watch(path, opts, listener); } catch (e) { end(e); return; } watcher = nwatcher; watcher.on("error", end); if (stats && (lock || stats.isFile())) { lstat(path).done(function (nstats) { var newFileType, err; if (!emitter) return; newFileType = typeByStats(nstats); if (fileType !== newFileType) { err = new Error("File type have changed"); err.code = "DIFFTYPE"; end(err); return; } if ( stats.isDirectory() || (stats.ctime.valueOf() !== nstats.ctime.valueOf() || (stats.mtime.valueOf() !== nstats.mtime.valueOf() || stats.size !== nstats.size)) ) { emitter.emit("change"); } stats = nstats; }, end); } }, 10); }; watcher = watch(path, opts, listener); watcher.on("error", end); if (!emitter) emitter = ee(); emitter.end = end; emitter.close = close; lstat(path)(function (nstats) { stats = nstats; fileType = typeByStats(stats); }, end); return emitter; }; fs2-0.3.9/lstat.js000066400000000000000000000017001375545423700137170ustar00rootroot00000000000000"use strict"; var isCallable = require("es5-ext/object/is-callable") , isValue = require("es5-ext/object/is-value") , deferred = require("deferred") , resolve = require("path").resolve , original = require("fs").lstat; var lstat = function (path, options) { var def = deferred(); original(path, function (err, stats) { if (err) { if (options.loose && (err.code === "ENOENT" || err.code === "ENOTDIR")) { def.resolve(null); } else { def.reject(err); } } else { def.resolve(stats); } }); return def.promise; }; lstat.returnsPromise = true; module.exports = function (path/*, callback*/) { var options, cb; path = resolve(String(path)); options = arguments[1]; cb = arguments[2]; if (!isValue(cb) && isCallable(options)) { cb = options; options = {}; } else { options = Object(options); } return lstat(path, options).cb(cb); }; module.exports.returnsPromise = true; module.exports.lstat = lstat; fs2-0.3.9/mkdir.js000066400000000000000000000035441375545423700137060ustar00rootroot00000000000000// Internal logic inspired by substack's node-mkdirp: // https://github.com/substack/node-mkdirp/ "use strict"; var isNumber = require("es5-ext/number/is-number") , isCallable = require("es5-ext/object/is-callable") , isValue = require("es5-ext/object/is-value") , deferred = require("deferred") , fs = require("fs") , pathUtils = require("path"); var stat = fs.stat, original = fs.mkdir, dirname = pathUtils.dirname, resolve = pathUtils.resolve; var _mkdir, mkdir; _mkdir = function (path, options, pResolve, reject) { original(path, options.mode, function (err) { var dir; if (!isValue(err)) { pResolve(null); return; } if (err.code === "EEXIST" && options.silent) { pResolve(null); return; } if (!options.intermediate) { reject(err); return; } if (err.code === "ENOENT") { dir = dirname(path); if (dir === path) { reject(err); return; } _mkdir(dir, options, function () { _mkdir(path, options, pResolve, reject); }, reject); } else { stat(path, function (statErr, stats) { if (statErr) { if (statErr.code !== "ENOENT") { reject(err); return; } _mkdir(path, options, pResolve, reject); return; } if (stats.isDirectory()) pResolve(null); else reject(err); }); } }); }; mkdir = function (path, options) { var def = deferred(); _mkdir(path, options, def.resolve, def.reject); return def.promise; }; mkdir.returnsPromise = true; module.exports = exports = function (path/*, mode|options, cb*/) { var options, cb; path = resolve(String(path)); options = arguments[1]; cb = arguments[2]; if (!isValue(cb) && isCallable(options)) { cb = options; options = {}; } else { options = isNumber(options) ? { mode: options } : Object(options); } return mkdir(path, options).cb(cb); }; exports.returnsPromise = true; exports.mkdir = mkdir; fs2-0.3.9/package.json000066400000000000000000000034131375545423700145230ustar00rootroot00000000000000{ "name": "fs2", "version": "0.3.9", "description": "fs (file system package) extensions", "author": "Mariusz Nowak (http://www.medikoo.com/)", "keywords": [ "addons", "extensions", "extras", "fs", "filesystem", "mkdir", "readdir", "files", "dirs", "directories", "git" ], "repository": { "type": "git", "url": "git://github.com/medikoo/fs2.git" }, "dependencies": { "d": "^1.0.1", "deferred": "^0.7.11", "es5-ext": "^0.10.53", "event-emitter": "^0.3.5", "ignore": "^5.1.8", "memoizee": "^0.4.14", "type": "^2.1.0" }, "devDependencies": { "eslint": "^7.13.0", "eslint-config-medikoo": "^3.1.0", "git-list-updated": "^1.2.1", "husky": "^4.3.0", "lint-staged": "^10.5.1", "prettier-elastic": "^2.1.2", "tad": "^3.0.1" }, "husky": { "hooks": { "pre-commit": "lint-staged" } }, "lint-staged": { "*.js": [ "eslint" ], "*.{css,html,js,json,md,yaml,yml}": [ "prettier -c" ] }, "eslintConfig": { "extends": "medikoo/node/6", "root": true, "overrides": [ { "files": [ "chmod.js" ], "rules": { "no-bitwise": "off" } } ] }, "prettier": { "printWidth": 100, "tabWidth": 4, "overrides": [ { "files": [ "*.md" ], "options": { "tabWidth": 2 } } ] }, "scripts": { "lint": "eslint --ignore-path=.gitignore .", "lint-updated": "pipe-git-updated --ext=js -- eslint --ignore-pattern '!*'", "prettier-check-updated": "pipe-git-updated --ext=css --ext=html --ext=js --ext=json --ext=md --ext=yaml --ext=yml -- prettier -c", "prettify": "prettier --write --ignore-path .gitignore '**/*.{css,html,js,json,md,yaml,yml}'", "test": "node ./node_modules/tad/bin/tad" }, "engines": { "node": ">=6" }, "license": "ISC" } fs2-0.3.9/read-file.js000066400000000000000000000046151375545423700144300ustar00rootroot00000000000000"use strict"; var isCallable = require("es5-ext/object/is-callable") , isValue = require("es5-ext/object/is-value") , isString = require("es5-ext/string/is-string") , deferred = require("deferred") , original = require("fs").readFile , resolve = require("path").resolve , watch = require("./watch").watch , WatchPath = require("./watch-path").WatchPath , readFile; readFile = function (filename, options) { var def, current, promise, watcher, resolveCb, onchange, loose; def = deferred(); loose = options.loose; original( filename, options.encoding, (resolveCb = function (err, data) { if (def.resolved) return; if (err) { if (watcher && !loose) watcher.close(); if (loose) def.resolve(null); else def.reject(err); return; } if (options.watch) current = String(data); def.resolve(data); }) ); promise = def.promise; if (options.watch) { onchange = function () { original(filename, options.encoding, function (err, data) { var dataStr; if (!def.resolved) { resolveCb(err, data); return; } if (!watcher) return; if (err) { watcher.close(); promise.emit("end"); return; } dataStr = String(data); if (dataStr !== current) { current = dataStr; promise.emit("change", data); } }); }; if (loose) { current = null; watcher = new WatchPath(filename); watcher.on("change", function (event) { if (event.type === "remove") { if (isValue(current)) promise.emit("change", (current = null)); } else { onchange(); } }); } else { try { watcher = watch(filename); } catch (e) { return def.reject(e); } watcher.on("change", onchange); watcher.on("end", function () { watcher = null; promise.emit("end"); }); } promise.close = function () { watcher.close(); if (!def.resolved) { def.reject(new Error("Operation aborted: " + filename)); } }; } return promise; }; readFile.returnsPromise = true; module.exports = exports = function (filename) { var options, cb; filename = resolve(String(filename)); options = arguments[1]; cb = arguments[2]; if (!isValue(cb) && isCallable(options)) { cb = options; options = {}; } else { options = isString(options) ? { encoding: options } : Object(options); } return readFile(filename, options).cb(cb); }; exports.returnsPromise = true; exports.readFile = readFile; fs2-0.3.9/readdir.js000066400000000000000000000421071375545423700142100ustar00rootroot00000000000000/* eslint max-statements: off, max-lines: off */ "use strict"; var invoke = require("es5-ext/function/invoke") , noop = require("es5-ext/function/noop") , curry = require("es5-ext/function/#/curry") , contains = curry.call(require("es5-ext/array/#/contains")) , diff = require("es5-ext/array/#/diff") , remove = require("es5-ext/array/#/remove") , assign = require("es5-ext/object/assign") , forEach = require("es5-ext/object/for-each") , isCallable = require("es5-ext/object/is-callable") , isCopy = require("es5-ext/object/is-copy") , isValue = require("es5-ext/object/is-value") , toPosInt = require("es5-ext/number/to-pos-integer") , startsWith = require("es5-ext/string/#/starts-with") , deferred = require("deferred") , fs = require("fs") , pathUtils = require("path") , typeByStats = require("./type-by-stats") , watchPath = require("./watch") , isIgnored = require("./is-ignored"); var isArray = Array.isArray , push = Array.prototype.push , promisify = deferred.promisify , resolve = pathUtils.resolve , sep = pathUtils.sep , original = fs.readdir , lstat = fs.lstat , pLstat = promisify(lstat) , getIsIgnored = isIgnored.getIsIgnored , applyGlobalRules = isIgnored.applyGlobalRules , Readdir , readdir , enoentSurpass , eolRe = /(?:\r\n|[\n\r\u2028\u2029])/ , passErrCodes = ["ENOENT", "DIFFTYPE"]; passErrCodes.contains = contains; enoentSurpass = function (err) { return passErrCodes.contains(err.code) ? [] : err; }; // eslint-disable-next-line no-empty-function Readdir = function () {}; Readdir.prototype = { init: function () { var data, result, promise, stream; stream = this.stream; data = this.read(this.path, this.depth); if (!this.depth) { promise = data.files; if (this.stream) { promise.aside(function (files) { if (!files) return; promise.emit("change", { data: files, added: files, removed: [] }); }); } return promise; } this.readers = {}; result = []; assign(this, deferred()); promise = this.promise; data.files.done(null, this.reject); if (this.watch) { data.files.on( "end", function () { delete this.readers; if (!promise.resolved) { this.reject(new Error("Directory was removed")); return; } promise.emit("end", result); }.bind(this) ); promise.close = this.close.bind(this); } (function self(nuData, rootPath, depth) { var getPath, files; this.readers[rootPath] = { files: nuData.files }; if (nuData.dirs && nuData.dirs !== nuData.files) { this.readers[rootPath].dirs = nuData.dirs; } if (rootPath) { getPath = function (path) { return rootPath + path; }; files = nuData.files.aside(function (newFiles) { if (newFiles.length) { newFiles = newFiles.map(getPath); push.apply(result, newFiles); if (promise.resolved || stream) { promise.emit("change", { data: result, removed: [], added: newFiles }); } } return newFiles; }); } else { files = nuData.files.aside(function (newFiles) { if (newFiles && newFiles.length) { push.apply(result, newFiles); if (promise.resolved || stream) { promise.emit("change", { data: result, removed: [], added: newFiles }); } } return newFiles; }); } if (this.watch) { if (rootPath) { nuData.files.on( "end", (nuData.files.onend = function (newFiles) { delete this.readers[rootPath]; if (newFiles.length) { newFiles = newFiles.map(getPath); remove.apply(result, newFiles); if (promise.resolved || stream) { promise.emit("change", { data: result, removed: newFiles, added: [] }); } } }.bind(this)) ); } nuData.files.on("change", function (nextData) { var removed, added; removed = rootPath ? nextData.removed.map(getPath) : nextData.removed; added = rootPath ? nextData.added.map(getPath) : nextData.added; remove.apply(result, removed); push.apply(result, added); if (promise.resolved || stream) { promise.emit("change", { data: result, removed: removed, added: added }); } }); } if (nuData.dirs) { if (this.watch) { nuData.dirs.on( "change", function (nextData) { deferred .map( nextData.added, function (dir) { return self.call( this, this.read(this.path + sep + rootPath + dir, depth - 1), rootPath + dir + sep, depth - 1 ); }, this ) .done(); nextData.removed.forEach( function (dir) { var path = rootPath + dir + sep, reader = this.readers[path]; if (reader) { reader.files.close(); if (reader.dirs) reader.dirs.close(); reader.files.onend(reader.files.value); forEach(this.readers, function (newReader, key) { if (startsWith.call(key, path)) { newReader.files.close(); if (newReader.dirs) newReader.dirs.close(); newReader.files.onend(newReader.files.value); } }); } }.bind(this) ); }.bind(this) ); } return deferred( files(null, enoentSurpass), nuData .dirs(null, enoentSurpass) .map(function (dir) { return self.call( this, this.read(this.path + sep + rootPath + dir, depth - 1), rootPath + dir + sep, depth - 1 ); }, this) ); } return files; } .call(this, data, "", this.depth) .done(this.resolve.bind(this, result), this.reject)); return this.promise; }, close: function () { if (this.readers) { forEach(this.readers, function (data) { data.files.close(); if (data.dirs) data.dirs.close(); }); delete this.readers; } }, read: function (path, getDirs) { var dirPaths, paths, data; paths = this.readdir(path); if (this.type || getDirs) { data = this.filterByType(paths, getDirs); paths = data.files; dirPaths = data.dirs; } else if (this.pattern || this.globalRules) { paths = this.filterByPattern(paths); } if (this.isIgnored) { if (dirPaths && dirPaths !== paths) { dirPaths = this.filterIgnored(dirPaths); paths = this.filterIgnored(paths); } else { paths = this.filterIgnored(paths); if (dirPaths) dirPaths = paths; } } return { files: paths, dirs: dirPaths }; }, filterByType: function (paths, getDirs) { var result = {} , test , rootPath = paths.root , files , dirs , resolveCb , defFiles , defDirs , close , resolved , failed; if (this.type || this.pattern || this.globalRules) { files = []; defFiles = deferred(); result.files = defFiles.promise; result.files.root = rootPath; } else { result.files = paths; } if (getDirs) { if (this.type && isCopy(this.type, { directory: true }) && !this.pattern) { dirs = files; result.dirs = result.files; getDirs = false; } else { dirs = []; defDirs = deferred(); result.dirs = defDirs.promise; result.dirs.root = rootPath; } } resolveCb = function (e) { if (defFiles) { if (e) defFiles.reject(e); else defFiles.resolve(files); } if (defDirs) { if (e) defDirs.reject(e); else defDirs.resolve(dirs); } failed = Boolean(e); resolved = true; }; paths.done( function (newPaths) { if (!newPaths) { files = null; resolveCb(); return; } var waiting = newPaths.length; if (!waiting) { resolveCb(); return; } newPaths.forEach(function (path) { var fullPath = rootPath + sep + path; if ( (!getDirs && this.pattern && !this.pattern.test(fullPath)) || (this.globalRules && applyGlobalRules(fullPath, this.globalRules)) ) { if (!--waiting) resolveCb(); return; } lstat( fullPath, function (err, stat) { var type; if (resolved) return; if (!err) { try { type = typeByStats(stat); } catch (e) { resolveCb(e); return; } if ( files && (!this.type || this.type[type]) && (!this.pattern || !getDirs || this.pattern.test(fullPath)) ) { files.push(path); } if (getDirs && type === "directory") { if (!this.dirFilter || this.dirFilter(fullPath)) { dirs.push(path); } } } else if (err.code !== "ENOENT") { resolveCb(err); return; } if (!--waiting) resolveCb(); }.bind(this) ); }, this); }.bind(this), resolveCb ); if (this.watch) { test = function (path, newFiles, newDirs) { var fullPath = rootPath + sep + path, promise; if ( (!getDirs && this.pattern && !this.pattern.test(fullPath)) || (this.globalRules && applyGlobalRules(fullPath, this.globalRules)) ) { return null; } promise = pLstat(fullPath).aside( function (stat) { var type = typeByStats(stat); if ( newFiles && (!this.type || this.type[type]) && (!this.pattern || !getDirs || this.pattern.test(fullPath)) ) { newFiles.push(path); } if (newDirs && type === "directory") newDirs.push(path); }.bind(this) ); return promise.catch(function (err) { if (err.code !== "ENOENT") throw err; }); }.bind(this); paths.on("change", function (data) { var removed, nFiles, nDirs; if (data.added.length) { nFiles = files && []; nDirs = getDirs && []; } deferred .map(data.added, function (path) { return test(path, nFiles, nDirs); }) .done(function () { if (files) { removed = data.removed.filter(contains, files); if (removed.length || (nFiles && nFiles.length)) { remove.apply(files, removed); if (nFiles) push.apply(files, nFiles); result.files.emit("change", { data: files, removed: removed, added: nFiles || [] }); } } if (getDirs) { removed = data.removed.filter(contains, dirs); if (removed.length || (nDirs && nDirs.length)) { remove.apply(dirs, removed); if (nDirs) push.apply(dirs, nDirs); result.dirs.emit("change", { data: dirs, removed: removed, added: nDirs || [] }); } } }); }); paths.on("end", function (data, err) { if (!resolved) { if (defFiles) defFiles.reject(err); if (defDirs) defDirs.reject(err); return; } if (!failed) { if (files) result.files.emit("end", files, err); if (getDirs) result.dirs.emit("end", dirs, err); } }); close = function () { if (defFiles && !defFiles.resolved) { defFiles.reject(new Error("Readdir operation cancelled")); } if (defDirs && !defDirs.resolved) { defDirs.reject(new Error("Readdir operation cancelled")); } if (paths.close) paths.close(); }; if (defFiles) { result.files.close = close; if (defDirs) result.dirs.close = noop; } else { result.dirs.close = close; } } return result; }, filterByPattern: function (paths) { var promise , result , rootPath = paths.root , pattern = this.pattern , rules = this.globalRules , filter; filter = function (path) { var fullPath = rootPath + sep + path; return ( (!pattern || pattern.test(fullPath)) && (!rules || !applyGlobalRules(fullPath, rules)) ); }; promise = paths(function (data) { return (result = data.filter(filter)); }); promise.root = rootPath; if (this.watch) { paths.on("change", function (data) { var removed, added; removed = data.removed.filter(contains, result); added = data.added.filter(filter); if (removed.length || added.length) { remove.apply(result, removed); push.apply(result, added); promise.emit("change", { data: result, removed: removed, added: added }); } }); paths.on("end", function (data, err) { promise.emit("end", result, err); }); promise.close = function () { paths.close(); }; } return promise; }, filterIgnored: function (paths) { var promise, result, test, rootPath = paths.root, promises, def = deferred(); promise = def.promise; test = function (path, cb) { var status = this.isIgnored(rootPath + sep + path); if (this.watch) { promises[path] = status; status.on("change", function (value) { if (value) { remove.call(result, path); promise.emit("change", { data: result, removed: [path], added: [] }); } else { result.push(path); promise.emit("change", { data: result, removed: [], added: [path] }); } }); } status.aside(cb); }.bind(this); if (this.watch) { promises = {}; paths.on("change", function (data) { var removed, added = [], waiting = data.added.length, onEnd; data.removed.forEach(function (path) { promises[path].close(); delete promises[path]; }); removed = data.removed.filter(contains, result); onEnd = function () { if (removed.length || added.length) { remove.apply(result, removed); push.apply(result, added); promise.emit("change", { data: result, removed: removed, added: added }); } }; if (!waiting) { onEnd(); return; } data.added.forEach(function (path) { test(path, function (lIsIgnored) { if (!lIsIgnored) added.push(path); if (!--waiting) onEnd(); }); }); }); paths.on("end", function (data, err) { if (!promises) return; forEach(promises, invoke("close")); promises = null; if (!def.resolved) { def.reject(err); return; } promise.emit("end", result, err); }); promise.close = function () { if (promises) { if (!def.resolved) def.reject(new Error("Operation aborted")); forEach(promises, invoke("close")); promises = null; paths.close(); } }; } paths.done( function (newPaths) { if (!newPaths) { def.resolve(newPaths); return; } var waiting = newPaths.length; result = []; if (!waiting) { def.resolve(result); return; } newPaths.forEach(function (path) { test(path, function (lIsIgnored) { if (!lIsIgnored) result.push(path); if (!--waiting) def.resolve(result); }); }); }, function (e) { def.reject(e); } ); promise.root = rootPath; return promise; }, readdir: function (path) { var def, promise, watcher, files; def = deferred(); promise = def.promise; promise.root = path; if (this.watch) { try { watcher = watchPath(path); } catch (e) { return def.reject(e); } watcher.on("end", function (err) { if (!def.resolved) def.reject(err); else if (files) promise.emit("end", files, err); }); watcher.on("change", function () { original(path, function (err, data) { var removed, added; if (err) { promise.emit("end", files, err); return; } removed = diff.call(files, data); added = diff.call(data, files); if (removed.length || added.length) { remove.apply(files, removed); push.apply(files, added); promise.emit("change", { data: files, removed: removed, added: added }); } }); }); promise.close = function () { watcher.close(); if (!def.resolved) def.reject(new Error("Readdir action cancelled")); }; } original( path, function (err, data) { if (err) { if (this.loose && this.path === path && err.code === "ENOENT") { def.resolve(null); } else { def.reject(err); } return; } def.resolve((files = data)); }.bind(this) ); return promise; } }; readdir = function (path, options) { var lReaddir, globalRules; lReaddir = new Readdir(); lReaddir.path = path; lReaddir.depth = isNaN(options.depth) ? 0 : toPosInt(options.depth); lReaddir.type = isValue(options.type) ? Object(options.type) : null; lReaddir.loose = Boolean(options.loose); lReaddir.pattern = isValue(options.pattern) ? new RegExp(options.pattern) : null; if (isValue(options.dirFilter)) { if (typeof options.dirFilter === "function") lReaddir.dirFilter = options.dirFilter; else lReaddir.dirFilter = RegExp.prototype.test.bind(new RegExp(options.dirFilter)); } lReaddir.watch = options.watch; lReaddir.stream = Boolean(options.stream); if (options.globalRules) { globalRules = isArray(options.globalRules) ? options.globalRules : String(options.globalRules).split(eolRe); } if (options.ignoreRules) { assign( lReaddir, getIsIgnored( isArray(options.ignoreRules) ? options.ignoreRules : [options.ignoreRules], globalRules, options.watch ) ); } else { lReaddir.globalRules = globalRules; } return lReaddir.init(); }; readdir.returnsPromise = true; module.exports = exports = function (path) { var options, cb; path = resolve(String(path)); options = Object(arguments[1]); cb = arguments[2]; if (!isValue(cb) && isCallable(options)) { cb = options; options = {}; } return readdir(path, options).cb(cb); }; exports.returnsPromise = true; exports.readdir = readdir; fs2-0.3.9/readlink.js000066400000000000000000000020771375545423700143710ustar00rootroot00000000000000"use strict"; var isCallable = require("es5-ext/object/is-callable") , isValue = require("es5-ext/object/is-value") , deferred = require("deferred") , resolve = require("path").resolve , original = require("fs").readlink; var readlink = function (path, options) { var def = deferred(); original(path, options, function (err, stats) { if (err) { if ( options.loose && (err.code === "ENOENT" || err.code === "EINVAL" || err.code === "ENOTDIR" || err.code === "UNKNOWN") ) { def.resolve(null); } else { def.reject(err); } } else { def.resolve(stats); } }); return def.promise; }; readlink.returnsPromise = true; module.exports = function (path/*[, options[, callback]]*/) { var options, cb; path = resolve(String(path)); options = arguments[1]; cb = arguments[2]; if (!isValue(cb) && isCallable(options)) { cb = Object(options); options = {}; } else { options = Object(options); } return readlink(path, options).cb(cb); }; module.exports.returnsPromise = true; module.exports.readlink = readlink; fs2-0.3.9/realpath.js000066400000000000000000000016541375545423700144000ustar00rootroot00000000000000"use strict"; var isCallable = require("es5-ext/object/is-callable") , isValue = require("es5-ext/object/is-value") , deferred = require("deferred") , resolve = require("path").resolve , original = require("fs").realpath; var realpath = function (path, options) { var def = deferred(); original(path, options, function (err, stats) { if (err) { if (options.loose && err.code === "ENOENT") def.resolve(null); else def.reject(err); } else { def.resolve(stats); } }); return def.promise; }; realpath.returnsPromise = true; module.exports = function (path/*, callback*/) { var options, cb; path = resolve(String(path)); options = arguments[1]; cb = arguments[2]; if (!isValue(cb) && isCallable(options)) { cb = options; options = {}; } else { options = Object(options); } return realpath(path, options).cb(cb); }; module.exports.returnsPromise = true; module.exports.realpath = realpath; fs2-0.3.9/rename.js000066400000000000000000000026171375545423700140470ustar00rootroot00000000000000"use strict"; var isCallable = require("es5-ext/object/is-callable") , isValue = require("es5-ext/object/is-value") , deferred = require("deferred") , path = require("path") , original = require("fs").rename , mkdir = require("./mkdir") , copy = require("./copy") , unlink = require("./unlink") , dirname = path.dirname , resolve = path.resolve; var crossDeviceRename = function (oldPath, newPath) { return copy(oldPath, newPath)(function () { return unlink(oldPath); }); }; var rename = function (oldPath, newPath) { var def = deferred(); original(oldPath, newPath, function (err) { if (err) { if (err.code === "EXDEV") { def.resolve(crossDeviceRename(oldPath, newPath)); return; } def.reject(err); } else { def.resolve(); } }); return def.promise; }; rename.returnsPromise = true; module.exports = exports = function (oldPath, newPath/*, options, cb*/) { var options = Object(arguments[2]), cb = arguments[3]; if (!isValue(cb) && isCallable(options)) { cb = options; options = {}; } oldPath = resolve(String(oldPath)); newPath = resolve(String(newPath)); if (options.intermediate) { return mkdir(dirname(newPath), { intermediate: true })(function () { return rename(oldPath, newPath); }).cb(cb); } return rename(oldPath, resolve(String(newPath))).cb(cb); }; exports.returnsPromise = true; exports.rename = rename; fs2-0.3.9/rm.js000066400000000000000000000016031375545423700132100ustar00rootroot00000000000000"use strict"; var isCallable = require("es5-ext/object/is-callable") , isValue = require("es5-ext/object/is-value") , resolve = require("path").resolve , lstat = require("./lstat") , rmdir = require("./rmdir") , unlink = require("./unlink"); var rm = function (path, options) { return lstat(path, options)(function (stats) { if (!stats) return null; // loose option if (stats.isDirectory()) return rmdir(path, options); return unlink(path, options); }); }; rm.returnsPromise = true; module.exports = function (path/*[, options[, callback]]*/) { var options, cb; path = resolve(String(path)); options = arguments[1]; cb = arguments[2]; if (!isValue(cb) && isCallable(options)) { cb = options; options = {}; } else { options = Object(options); } return rm(path, options).cb(cb); }; module.exports.returnsPromise = true; module.exports.rm = rm; fs2-0.3.9/rmdir-sync.js000066400000000000000000000026761375545423700146740ustar00rootroot00000000000000"use strict"; const fs = require("fs") , path = require("path") , ensureString = require("type/string/ensure") , isObject = require("type/object/is") , toShortString = require("type/lib/to-short-string"); const removeDir = dirname => { let errors; for (let filename of fs.readdirSync(dirname)) { filename = path.resolve(dirname, filename); try { const stats = fs.statSync(filename); if (stats.isDirectory()) removeDir(filename); else fs.unlinkSync(filename); } catch (error) { if (!errors) errors = []; if (error.errors) errors.push(...error.errors); else errors.push(Object.assign(error, { _filename: filename })); } } if (errors) throw Object.assign(new Error("Could not remove dir"), { errors }); else fs.rmdirSync(dirname); }; module.exports = (dirnameInput, options = {}) => { const dirname = path.resolve(ensureString(dirnameInput)); if (!isObject(options)) options = {}; if (!options.recursive) { fs.rmdirSync(dirname); return; } try { removeDir(dirname); } catch (error) { if (!error.errors) throw error; let errorMessage = `Could not remove ${ toShortString(dirnameInput) } due to:\n- ${ error.errors.slice(0, 5).map(({ code, _filename }) => `${ code } on ${ _filename }`) }`; if (error.errors.length > 5) { errorMessage += `\nand ${ error.errors.length - 5 } other errors`; } throw Object.assign(new Error(errorMessage), { errors: error.errors }); } }; fs2-0.3.9/rmdir.js000066400000000000000000000060521375545423700137120ustar00rootroot00000000000000"use strict"; var partial = require("es5-ext/function/#/partial") , isCallable = require("es5-ext/object/is-callable") , isValue = require("es5-ext/object/is-value") , deferred = require("deferred") , fs = require("fs") , pathUtils = require("path") , chmod = require("./chmod") , lstat = require("./lstat") , readdir = require("./readdir") , unlink = require("./unlink"); var original = fs.rmdir , resolve = pathUtils.resolve , sep = pathUtils.sep , rmdir , rmcontent , empty = {}; rmcontent = function (path, options) { return readdir(path)( function self(files, repeated) { return deferred.map(files, function (name) { var filename = path + sep + name, aborted; return lstat(filename)( function (stats) { var err; if (aborted || options.aborted) return null; if (stats.isDirectory()) { return rmcontent(filename, options)(null, function (err2) { options.aborted = true; throw err2; }); } if (options.force) { return unlink(filename)(null, function (err2) { if (err2.code === "ENOENT") return; aborted = true; throw err2; }); } err = new Error("ENOTEMPTY rmdir '" + path + "'"); err.errno = 53; err.code = "ENOTEMPTY"; err.path = path; options.aborted = true; throw err; }, function (err) { if (err.code === "ENOENT") return; options.aborted = true; throw err; } ); })(null, function (err) { if (!options.aborted && !repeated && err.code === "EACCES" && chmod) { return chmod(path, 146)(partial.call(self, files, true)); } throw err; }); }, function (err) { if (err.code === "ENOENT") return; throw err; } )( function () { if (options.aborted) return null; return rmdir(path, empty)(null, function (err) { if (options.aborted) return null; if (err.code === "ENOTEMPTY") { // Race condition (new files were added to the directory in a meantime) return rmcontent(path, options); } if (err.code === "ENOENT") return null; throw err; }); }, function (err) { if (err.code === "ENOENT") return; throw err; } ); }; rmdir = function (path, options) { var def = deferred(); original(path, function (err) { if (err) { if (err.code === "ENOTEMPTY") { if (options.recursive) { def.resolve(rmcontent(path, { force: options.force })); return; } } else if (err.code === "ENOENT") { if (options.loose) { def.resolve(null); return; } } def.reject(err); return; } def.resolve(null); }); return def.promise; }; rmdir.returnsPromise = true; module.exports = exports = function (path/*, options, callback*/) { var options, cb; path = resolve(String(path)); options = arguments[1]; cb = arguments[2]; if (!isValue(cb) && isCallable(options)) { cb = options; options = {}; } else { options = Object(options); } return rmdir(path, options).cb(cb); }; exports.returnsPromise = true; exports.rmdir = rmdir; fs2-0.3.9/stat.js000066400000000000000000000016131375545423700135460ustar00rootroot00000000000000"use strict"; var isCallable = require("es5-ext/object/is-callable") , isValue = require("es5-ext/object/is-value") , deferred = require("deferred") , resolve = require("path").resolve , original = require("fs").stat; var stat = function (path, options) { var def = deferred(); original(path, function (err, stats) { if (err) { if (options.loose && err.code === "ENOENT") def.resolve(null); else def.reject(err); } else { def.resolve(stats); } }); return def.promise; }; stat.returnsPromise = true; module.exports = function (path/*, callback*/) { var options, cb; path = resolve(String(path)); options = arguments[1]; cb = arguments[2]; if (!isValue(cb) && isCallable(options)) { cb = options; options = {}; } else { options = Object(options); } return stat(path, options).cb(cb); }; module.exports.returnsPromise = true; module.exports.stat = stat; fs2-0.3.9/symlink.js000066400000000000000000000023261375545423700142630ustar00rootroot00000000000000"use strict"; var isCallable = require("es5-ext/object/is-callable") , isValue = require("es5-ext/object/is-value") , isString = require("es5-ext/string/is-string") , deferred = require("deferred") , path = require("path") , original = require("fs").symlink , mkdir = require("./mkdir"); var dirname = path.dirname, resolve = path.resolve, symlink; symlink = function (src, dest, options) { var def = deferred(); original(src, dest, options.type, function (err) { if (err) { def.reject(err); return; } def.resolve(); }); return def.promise; }; symlink.returnsPromise = true; module.exports = exports = function (src, dest /* [, options[, callback]]*/) { var options, cb; src = String(src); dest = resolve(String(dest)); options = arguments[2]; cb = arguments[3]; if (!isValue(cb) && isCallable(options)) { cb = options; options = {}; } else { options = isString(options) ? { type: options } : Object(options); } if (options.intermediate) { return mkdir(dirname(dest), { intermediate: true })(function () { return symlink(src, dest, options); }).cb(cb); } return symlink(src, dest, options).cb(cb); }; exports.returnsPromise = true; exports.symlink = symlink; fs2-0.3.9/test/000077500000000000000000000000001375545423700132135ustar00rootroot00000000000000fs2-0.3.9/test/__playground/000077500000000000000000000000001375545423700156755ustar00rootroot00000000000000fs2-0.3.9/test/__playground/chmod/000077500000000000000000000000001375545423700167675ustar00rootroot00000000000000fs2-0.3.9/test/__playground/chmod/test000066400000000000000000000000001375545423700176570ustar00rootroot00000000000000fs2-0.3.9/test/__playground/copy-dir/000077500000000000000000000000001375545423700174235ustar00rootroot00000000000000fs2-0.3.9/test/__playground/copy-dir/some-dir/000077500000000000000000000000001375545423700211425ustar00rootroot00000000000000fs2-0.3.9/test/__playground/copy-dir/some-dir/sample1.js000066400000000000000000000000441375545423700230400ustar00rootroot00000000000000"use strict"; module.exports = {}; fs2-0.3.9/test/__playground/copy-dir/some-dir/sample3.js000066400000000000000000000000441375545423700230420ustar00rootroot00000000000000"use strict"; module.exports = {}; fs2-0.3.9/test/__playground/copy-dir/some-dir/some-dir2/000077500000000000000000000000001375545423700227435ustar00rootroot00000000000000fs2-0.3.9/test/__playground/copy-dir/some-dir/some-dir2/sample1.js000066400000000000000000000000441375545423700246410ustar00rootroot00000000000000"use strict"; module.exports = {}; fs2-0.3.9/test/__playground/copy/000077500000000000000000000000001375545423700166475ustar00rootroot00000000000000fs2-0.3.9/test/__playground/copy/sample.js000066400000000000000000000000441375545423700204640ustar00rootroot00000000000000"use strict"; module.exports = {}; fs2-0.3.9/test/__playground/is-ignored/000077500000000000000000000000001375545423700177355ustar00rootroot00000000000000fs2-0.3.9/test/__playground/is-ignored/x000066400000000000000000000000001375545423700201150ustar00rootroot00000000000000fs2-0.3.9/test/__playground/is-symlink/000077500000000000000000000000001375545423700177745ustar00rootroot00000000000000fs2-0.3.9/test/__playground/is-symlink/from000066400000000000000000000000001375545423700206500ustar00rootroot00000000000000fs2-0.3.9/test/__playground/lchmod/000077500000000000000000000000001375545423700171435ustar00rootroot00000000000000fs2-0.3.9/test/__playground/lchmod/test000066400000000000000000000000001375545423700200330ustar00rootroot00000000000000fs2-0.3.9/test/__playground/lib/000077500000000000000000000000001375545423700164435ustar00rootroot00000000000000fs2-0.3.9/test/__playground/lib/find-root/000077500000000000000000000000001375545423700203445ustar00rootroot00000000000000fs2-0.3.9/test/__playground/lib/find-root/x000066400000000000000000000000001375545423700205240ustar00rootroot00000000000000fs2-0.3.9/test/__playground/lib/get-conf-file-map/000077500000000000000000000000001375545423700216355ustar00rootroot00000000000000fs2-0.3.9/test/__playground/lib/get-conf-file-map/x000066400000000000000000000000001375545423700220150ustar00rootroot00000000000000fs2-0.3.9/test/__playground/lib/ignore-modes/000077500000000000000000000000001375545423700210335ustar00rootroot00000000000000fs2-0.3.9/test/__playground/lib/ignore-modes/git/000077500000000000000000000000001375545423700216165ustar00rootroot00000000000000fs2-0.3.9/test/__playground/lib/ignore-modes/git/x000066400000000000000000000000001375545423700217760ustar00rootroot00000000000000fs2-0.3.9/test/__playground/lib/watch-alt/000077500000000000000000000000001375545423700203275ustar00rootroot00000000000000fs2-0.3.9/test/__playground/lib/watch-alt/x000066400000000000000000000000001375545423700205070ustar00rootroot00000000000000fs2-0.3.9/test/__playground/lib/watch/000077500000000000000000000000001375545423700175515ustar00rootroot00000000000000fs2-0.3.9/test/__playground/lib/watch/x000066400000000000000000000000001375545423700177310ustar00rootroot00000000000000fs2-0.3.9/test/__playground/mkdir/000077500000000000000000000000001375545423700170035ustar00rootroot00000000000000fs2-0.3.9/test/__playground/mkdir/one/000077500000000000000000000000001375545423700175645ustar00rootroot00000000000000fs2-0.3.9/test/__playground/mkdir/one/x000066400000000000000000000000001375545423700177440ustar00rootroot00000000000000fs2-0.3.9/test/__playground/read-file/000077500000000000000000000000001375545423700175255ustar00rootroot00000000000000fs2-0.3.9/test/__playground/read-file/test000066400000000000000000000000071375545423700204240ustar00rootroot00000000000000raz dwafs2-0.3.9/test/__playground/readdir/000077500000000000000000000000001375545423700173075ustar00rootroot00000000000000fs2-0.3.9/test/__playground/readdir/done/000077500000000000000000000000001375545423700202345ustar00rootroot00000000000000fs2-0.3.9/test/__playground/readdir/done/done/000077500000000000000000000000001375545423700211615ustar00rootroot00000000000000fs2-0.3.9/test/__playground/readdir/done/done/dthree/000077500000000000000000000000001375545423700224345ustar00rootroot00000000000000fs2-0.3.9/test/__playground/readdir/done/done/dthree/dthree/000077500000000000000000000000001375545423700237075ustar00rootroot00000000000000fs2-0.3.9/test/__playground/readdir/done/done/dthree/dthree/foo000066400000000000000000000000021375545423700244050ustar00rootroot00000000000000x fs2-0.3.9/test/__playground/readdir/done/done/dthree/dtwo/000077500000000000000000000000001375545423700234115ustar00rootroot00000000000000fs2-0.3.9/test/__playground/readdir/done/done/dthree/dtwo/foo000066400000000000000000000000021375545423700241070ustar00rootroot00000000000000x fs2-0.3.9/test/__playground/readdir/done/done/dthree/one000066400000000000000000000000011375545423700231270ustar00rootroot00000000000000xfs2-0.3.9/test/__playground/readdir/done/done/dthree/three000066400000000000000000000000021375545423700234560ustar00rootroot00000000000000x fs2-0.3.9/test/__playground/readdir/done/done/dthree/two000066400000000000000000000000021375545423700231600ustar00rootroot00000000000000x fs2-0.3.9/test/__playground/readdir/done/done/dtwo/000077500000000000000000000000001375545423700221365ustar00rootroot00000000000000fs2-0.3.9/test/__playground/readdir/done/done/dtwo/dtwo/000077500000000000000000000000001375545423700231135ustar00rootroot00000000000000fs2-0.3.9/test/__playground/readdir/done/done/dtwo/dtwo/foo000066400000000000000000000000021375545423700236110ustar00rootroot00000000000000x fs2-0.3.9/test/__playground/readdir/done/done/dtwo/one000066400000000000000000000000011375545423700226310ustar00rootroot00000000000000xfs2-0.3.9/test/__playground/readdir/done/done/dtwo/three000066400000000000000000000000021375545423700231600ustar00rootroot00000000000000x fs2-0.3.9/test/__playground/readdir/done/done/dtwo/two000066400000000000000000000000021375545423700226620ustar00rootroot00000000000000x fs2-0.3.9/test/__playground/readdir/done/done/one000066400000000000000000000000011375545423700216540ustar00rootroot00000000000000xfs2-0.3.9/test/__playground/readdir/done/done/three000066400000000000000000000000021375545423700222030ustar00rootroot00000000000000x fs2-0.3.9/test/__playground/readdir/done/done/two000066400000000000000000000000021375545423700217050ustar00rootroot00000000000000x fs2-0.3.9/test/__playground/readdir/done/dtwo/000077500000000000000000000000001375545423700212115ustar00rootroot00000000000000fs2-0.3.9/test/__playground/readdir/done/dtwo/foo000066400000000000000000000000031375545423700217100ustar00rootroot00000000000000x fs2-0.3.9/test/__playground/readdir/done/one000066400000000000000000000000011375545423700207270ustar00rootroot00000000000000xfs2-0.3.9/test/__playground/readdir/done/three000066400000000000000000000000021375545423700212560ustar00rootroot00000000000000x fs2-0.3.9/test/__playground/readdir/done/two000066400000000000000000000000021375545423700207600ustar00rootroot00000000000000x fs2-0.3.9/test/__playground/readdir/dthree/000077500000000000000000000000001375545423700205625ustar00rootroot00000000000000fs2-0.3.9/test/__playground/readdir/dthree/dthree/000077500000000000000000000000001375545423700220355ustar00rootroot00000000000000fs2-0.3.9/test/__playground/readdir/dthree/dthree/done/000077500000000000000000000000001375545423700227625ustar00rootroot00000000000000fs2-0.3.9/test/__playground/readdir/dthree/dthree/done/dthree/000077500000000000000000000000001375545423700242355ustar00rootroot00000000000000fs2-0.3.9/test/__playground/readdir/dthree/dthree/done/dthree/foo000066400000000000000000000000021375545423700247330ustar00rootroot00000000000000x fs2-0.3.9/test/__playground/readdir/dthree/dthree/done/one000066400000000000000000000000011375545423700234550ustar00rootroot00000000000000xfs2-0.3.9/test/__playground/readdir/dthree/dthree/done/three000066400000000000000000000000021375545423700240040ustar00rootroot00000000000000x fs2-0.3.9/test/__playground/readdir/dthree/dthree/done/two000066400000000000000000000000021375545423700235060ustar00rootroot00000000000000x fs2-0.3.9/test/__playground/readdir/dthree/dthree/one000066400000000000000000000000011375545423700225300ustar00rootroot00000000000000xfs2-0.3.9/test/__playground/readdir/dthree/dthree/three000066400000000000000000000000021375545423700230570ustar00rootroot00000000000000x fs2-0.3.9/test/__playground/readdir/dthree/dthree/two000066400000000000000000000000021375545423700225610ustar00rootroot00000000000000x fs2-0.3.9/test/__playground/readdir/dthree/dtwo/000077500000000000000000000000001375545423700215375ustar00rootroot00000000000000fs2-0.3.9/test/__playground/readdir/dthree/dtwo/foo000066400000000000000000000000021375545423700222350ustar00rootroot00000000000000x fs2-0.3.9/test/__playground/readdir/dthree/one000066400000000000000000000000011375545423700212550ustar00rootroot00000000000000xfs2-0.3.9/test/__playground/readdir/dthree/three000066400000000000000000000000021375545423700216040ustar00rootroot00000000000000x fs2-0.3.9/test/__playground/readdir/dthree/two000066400000000000000000000000021375545423700213060ustar00rootroot00000000000000x fs2-0.3.9/test/__playground/readdir/dtwo/000077500000000000000000000000001375545423700202645ustar00rootroot00000000000000fs2-0.3.9/test/__playground/readdir/dtwo/one000066400000000000000000000000011375545423700207570ustar00rootroot00000000000000xfs2-0.3.9/test/__playground/readdir/dtwo/three000066400000000000000000000000021375545423700213060ustar00rootroot00000000000000x fs2-0.3.9/test/__playground/readdir/dtwo/two000066400000000000000000000000021375545423700210100ustar00rootroot00000000000000x fs2-0.3.9/test/__playground/readdir/one000066400000000000000000000000011375545423700200020ustar00rootroot00000000000000xfs2-0.3.9/test/__playground/readdir/three000066400000000000000000000000021375545423700203310ustar00rootroot00000000000000x fs2-0.3.9/test/__playground/readdir/two000066400000000000000000000000021375545423700200330ustar00rootroot00000000000000x fs2-0.3.9/test/__playground/readlink/000077500000000000000000000000001375545423700174665ustar00rootroot00000000000000fs2-0.3.9/test/__playground/readlink/from000066400000000000000000000000001375545423700203420ustar00rootroot00000000000000fs2-0.3.9/test/__playground/readlink/non-symlink000066400000000000000000000000001375545423700216550ustar00rootroot00000000000000fs2-0.3.9/test/__playground/rename/000077500000000000000000000000001375545423700171445ustar00rootroot00000000000000fs2-0.3.9/test/__playground/rename/.gitignore000066400000000000000000000000171375545423700211320ustar00rootroot00000000000000* !/.gitignore fs2-0.3.9/test/__playground/symlink/000077500000000000000000000000001375545423700173635ustar00rootroot00000000000000fs2-0.3.9/test/__playground/symlink/from000066400000000000000000000000001375545423700202370ustar00rootroot00000000000000fs2-0.3.9/test/__playground/watch-path/000077500000000000000000000000001375545423700177355ustar00rootroot00000000000000fs2-0.3.9/test/__playground/watch-path/test000066400000000000000000000000001375545423700206250ustar00rootroot00000000000000fs2-0.3.9/test/__playground/watch/000077500000000000000000000000001375545423700170035ustar00rootroot00000000000000fs2-0.3.9/test/__playground/watch/x000066400000000000000000000000001375545423700171630ustar00rootroot00000000000000fs2-0.3.9/test/access.js000066400000000000000000000004721375545423700150150ustar00rootroot00000000000000"use strict"; var fs = require("fs"); var execMode = (fs.constants || fs).X_OK; module.exports = function (t, a, d) { t(__filename)(function (result) { a(result, undefined, "Success"); return t(__filename, execMode)(a.never, function (err) { a(err.code, "EACCES", "Error"); }); }, a.never).done(d, d); }; fs2-0.3.9/test/append-file.js000066400000000000000000000024231375545423700157360ustar00rootroot00000000000000"use strict"; var fs = require("fs") , resolve = require("path").resolve , rmdir = require("../rmdir") , readFile = fs.readFile , unlink = fs.unlink , pgPath = resolve(__dirname, "./__playground") , testFilePath = resolve(pgPath, "append-file-test") , intermediateDirPath = resolve(pgPath, "_append-file") , intermediatePath = resolve(intermediateDirPath, "intermediate/test"); module.exports = { Append: function (t, a, d) { t(testFilePath, "raz", function (err) { a(err, null, "#1"); t(testFilePath, "dwa", function (err2) { a(err2, null, "#2"); t(testFilePath, "trzy", function (err3) { a(err3, null, "#3"); readFile(testFilePath, function (err4, content) { a(String(content), "razdwatrzy", "Result"); unlink(testFilePath, d); }); }); }); }); }, Intermediate: function (t, a, d) { t(intermediatePath, "elo", { intermediate: true }, function (err) { if (err) { d(err); return; } fs.readFile(intermediatePath, function (err2, content) { if (err2) { d(err2); return; } a(String(content), "elo", "Content"); rmdir(intermediateDirPath, { recursive: true, force: true }, d); }); }); } }; fs2-0.3.9/test/chmod.js000066400000000000000000000010201375545423700146340ustar00rootroot00000000000000"use strict"; var lstat = require("../lstat") , testFile = require("path").resolve(__dirname, "__playground/chmod/test"); module.exports = function (t, a, d) { if (process.platform === "win32") { a(t, null); d(); return; } lstat(testFile)(function (stats) { var org = stats.mode; return t(testFile, 511)(function () { return lstat(testFile)(function (stats2) { // eslint-disable-next-line no-bitwise a(stats2.mode & 511, 511); return t(testFile, org); }); }); }, a.never).done(d, d); }; fs2-0.3.9/test/copy-dir.js000066400000000000000000000023531375545423700153020ustar00rootroot00000000000000"use strict"; var deferred = require("deferred") , path = require("path") , readdir = require("../readdir") , readlink = require("../readlink") , symlink = require("../symlink") , rm = require("../rm"); var relative = path.relative , resolve = path.resolve , pg = path.resolve(__dirname, "./__playground/copy-dir"); module.exports = function (t, a, d) { var src = resolve(pg, "some-dir") , srcFile1 = resolve(src, "sample1") , srcSymlink1 = resolve(src, "symlink1") , srcSymlink2 = resolve(src, "symlink2") , dst = resolve(pg, "dir-copy"); symlink(srcFile1, srcSymlink1)(function () { return symlink(__dirname, srcSymlink2); })( function () { return t(src, dst); } )(function () { return deferred(readdir(src, { depth: Infinity }), readdir(dst, { depth: Infinity })); }) .spread(function (srcFiles, dstFiles) { a.deep(srcFiles, dstFiles); return readlink(resolve(dst, "symlink1")); })(function (symLinkPath) { a(symLinkPath, relative(dst, resolve(dst, "sample1"))); return readlink(resolve(dst, "symlink2")); })(function (symLinkPath) { a(symLinkPath, relative(dst, __dirname)); return rm(dst, { recursive: true, force: true })(rm(srcSymlink1))(rm(srcSymlink2)); }) .done(d, d); }; fs2-0.3.9/test/copy.js000066400000000000000000000036241375545423700145300ustar00rootroot00000000000000"use strict"; var path = require("path") , fs = require("fs") , pg = path.resolve(__dirname, "./__playground/copy"); module.exports = { "Success": function (t, a, d) { var src = pg + "/sample.js", dst = pg + "/sample.copy.js"; t(src, dst, function (err) { if (err) { d(err); return; } fs.readFile(src, "utf8", function (err2, srcContent) { if (err2) { d(err2); return; } fs.readFile(dst, "utf8", function (err3, dstContent) { if (err3) { d(err3); return; } a(dstContent, srcContent, "Content"); fs.stat(src, function (err4, srcStats) { if (err4) { d(err4); return; } fs.stat(dst, function (err5, dstStats) { if (err5) { d(err5); return; } a(dstStats.mode, srcStats.mode); fs.unlink(dst, d); }); }); }); }); }); }, "Deep": function (t, a, d) { var src = pg + "/sample.js", dst = pg + "/deep/path/sample.copy.js"; return t(src, dst, { intermediate: true }).done(function () { fs.readFile(src, "utf8", function (err, srcContent) { if (err) { d(err); return; } fs.readFile(dst, "utf8", function (err2, dstContent) { if (err2) { d(err2); return; } a(dstContent, srcContent, "Content"); fs.unlink(dst, d); }); }); }, d); }, "Wrong path": function (t, a, d) { t(pg + "/sample.js", pg + "/:;\\//wrong-filename").done(a.never, function (e) { a(e.code, "ENOENT", "Path error"); d(); }); }, "Loose": function (t, a, d) { t(pg + "/:;\\//wrong-filename", pg + "/sample-test.js", { loose: true }).done(function ( result ) { a(result, false); d(); }, d); }, "Loose with mode": function (t, a, d) { t(pg + "/:;\\//wrong-filename", pg + "/sample-test2.js", { loose: true, mode: 33188 }).done( function (result) { a(result, false); d(); }, d ); } }; fs2-0.3.9/test/descriptors-handler.js000066400000000000000000000010071375545423700175230ustar00rootroot00000000000000"use strict"; var fs = require("fs"); module.exports = function (t, a, d) { var done = 0; t(); fs.closeSync(fs.openSync(__filename, "r")); fs.open(__filename, "r", function (err, fd) { if (err) { d(err); return; } a(typeof fd, "number", "Open"); fs.close(fd, function (err2) { if (err2 || done++) { d(err2); } }); }); fs.readdir(__dirname, function (err, result) { if (err) { d(err); return; } a(Array.isArray(result), true, "Readdir"); if (done++) { d(); } }); }; fs2-0.3.9/test/has-access.js000066400000000000000000000007611375545423700155670ustar00rootroot00000000000000"use strict"; var resolve = require("path").resolve , fs = require("fs"); var execMode = (fs.constants || fs).X_OK; module.exports = function (t, a, d) { t(__filename) .then(function (result) { a(result, true, "Success"); return t(__filename, { mode: execMode }); }, a.never) .then(function (result) { a(result, false, "No access"); return t(resolve(__filename, "n-a"), { loose: true }); }) .then(function (result) { a(result, null, "Loose"); }) .done(d, d); }; fs2-0.3.9/test/is-directory.js000066400000000000000000000005771375545423700161770ustar00rootroot00000000000000"use strict"; var resolve = require("path").resolve; module.exports = function (t, a, d) { t(__filename)(function (result) { a(result, false, "Existing non directory"); return t(__dirname); })(function (result) { a(result, true, "Existing directory"); return t(resolve(__filename, "foo")); })(function (result) { a(result, null, "Existing directory"); }).done(d, d); }; fs2-0.3.9/test/is-ignored.js000066400000000000000000000156471375545423700156260ustar00rootroot00000000000000"use strict"; var fs = require("fs") , resolve = require("path").resolve , noop = require("es5-ext/function/noop") , deferred = require("deferred") , delay = deferred.delay , promisify = deferred.promisify , mkdir = promisify(fs.mkdir) , writeFile = promisify(fs.writeFile) , unlink = promisify(fs.unlink) , rmdir = promisify(fs.rmdir) , modes = require("../lib/ignore-modes") , pgPath = resolve(__dirname, "./__playground/is-ignored"); module.exports = function (t, a, d) { var invoked = null , testIsRoot , DELAY = 100 , gitRoot = resolve(pgPath, ".git") , rootFile = resolve(pgPath, ".gitignore") , onePath = resolve(pgPath, "one") , oneFile = resolve(onePath, ".gitignore") , twoPath = resolve(onePath, "two") , twoFile = resolve(twoPath, ".gitignore") , twoOtherFile = resolve(twoPath, ".ignore") , twoFooPath = resolve(twoPath, "foo") , watcher; modes.test = { filename: ".ignore", isRoot: (testIsRoot = function (path) { var promise = deferred(path === onePath); promise.close = noop; return promise; }), isRootWatcher: testIsRoot }; // Make .git dir deferred(mkdir(gitRoot), mkdir(onePath)(function () { return mkdir(twoPath); }))( delay(function () { t("git", resolve(gitRoot, "foo/bar"))(function (value) { a(value, true, "Ignore gitrepo file"); }).done(); watcher = t("git", twoFooPath, { watch: true }); watcher.on("change", function (arg) { a(invoked, null, "Invoked once"); invoked = arg; }); watcher.done(); return t("git", twoFooPath); }, DELAY) )( delay(function (value) { a(value, false, "#1"); // Write root .gitignore with "foo" return writeFile(rootFile, "foo"); }, DELAY) )( delay(function () { a(invoked, true, "#2 event"); invoked = null; return t("git", twoFooPath); }, DELAY) )(function (value) { a(value, true, "#2"); // Write root/one .gitignore with "/two/foo" return writeFile(oneFile, "/two/foo"); })( delay(function () { a(invoked, null, "#3 event"); return t("git", twoFooPath); }, DELAY) )(function (value) { a(value, true, "#3"); // Write root/one/two .gitignore with "!foo" return writeFile(twoFile, "!foo"); })( delay(function () { a(invoked, false, "#4 event"); invoked = null; return t("git", twoFooPath); }, DELAY) )(function (value) { a(value, false, "#4"); // Remove root .gitignore // Remove root/one .gitignore return deferred(unlink(rootFile), unlink(oneFile)); })( delay(function () { a(invoked, null, "#5 event"); return t("git", twoFooPath); }, DELAY) )(function (value) { a(value, false, "#5"); // Remove root/one/two .gitignore return unlink(twoFile); })( delay(function () { a(invoked, null, "#6 event"); invoked = null; return t("git", twoFooPath); }, DELAY) )(function (value) { a(value, false, "#6"); // Write root/one .gitignore with "/two/foo\n!/two/foo" return writeFile(oneFile, "/two/foo\n!/two/foo"); })( delay(function () { a(invoked, null, "#7 event"); invoked = null; return t("git", twoFooPath); }, DELAY) )(function (value) { a(value, false, "#7"); // Write root .gitignore with "two" return writeFile(rootFile, "two"); })( delay(function () { a(invoked, null, "#8 event"); return t("git", twoFooPath); }, DELAY) )(function (value) { a(value, false, "#8"); // Remove root .gitignore return unlink(rootFile); })( delay(function () { a(invoked, null, "#9 event"); return t("git", twoFooPath); }, DELAY) )(function (value) { a(value, false, "#9"); // Write root .gitignore with "/one" return writeFile(rootFile, "/one"); })( delay(function () { a(invoked, true, "#10 event"); invoked = null; return t("git", twoFooPath); }, DELAY) )(function (value) { a(value, true, "#10"); watcher.close(); // Write root .gitignore with "one\n!one/two/foo" // Remove root/one .gitignore return deferred(writeFile(rootFile, "one\n!one/two/foo"), unlink(oneFile)); })( delay(function () { a(invoked, null, "#11 event"); invoked = null; return t("git", twoFooPath); }, DELAY) )(function (value) { a(value, true, "#11"); // Remove root .gitignore return unlink(rootFile); })( delay(function () { invoked = null; watcher = t(["git", "test"], twoFooPath, { watch: true }); watcher.on("change", function (arg) { a(invoked, null, "Invoked once"); invoked = arg; }); watcher.done(); return t("git", twoFooPath); }, DELAY) )(function (value) { a(value, false, "Both #1"); // Write root .gitignore with "foo" return writeFile(rootFile, "foo"); })( delay(function () { a(invoked, true, "Both #2"); invoked = null; return t(["git", "test"], twoFooPath); }, DELAY * 2) )(function (value) { a(value, true, "Both #2"); return writeFile(twoOtherFile, "!foo"); })( delay(function () { a(invoked, false, "Both #3"); invoked = null; return t(["git", "test"], twoFooPath); }, DELAY) )(function (value) { a(value, false, "Both #3"); return writeFile(rootFile, "one\n"); })( delay(function () { a(invoked, true, "Both #4"); invoked = null; return t(["git", "test"], twoFooPath); }, DELAY) )(function (value) { a(value, true, "Both #4"); return unlink(rootFile); })( delay(function () { a(invoked, false, "Both #5"); invoked = null; return t(["git", "test"], twoFooPath); }, DELAY) )(function (value) { a(value, false, "Both #5"); return writeFile(twoOtherFile, "foo"); })( delay(function () { a(invoked, true, "Both #6"); invoked = null; return t(["git", "test"], twoFooPath); }, DELAY) )(function (value) { a(value, true, "Both #6"); return writeFile(twoFile, "!foo"); })( delay(function () { a(invoked, null, "Both #7"); invoked = null; return t(["git", "test"], twoFooPath); }, DELAY) )(function (value) { a(value, true, "Both #7"); return writeFile(twoOtherFile, "!foo"); })( delay(function () { a(invoked, false, "Both #8"); invoked = null; return t(["git", "test"], twoFooPath); }, DELAY) )(function (value) { a(value, false, "Both #8"); return writeFile(twoFile, "foo"); })( delay(function () { a(invoked, null, "Both #9"); invoked = null; return t(["git", "test"], twoFooPath); }, DELAY) )(function (value) { a(value, false, "Both #9"); watcher.close(); })(delay(function () { return deferred(unlink(twoFile), unlink(twoOtherFile)); }, DELAY))( delay(function () { t(null, twoFooPath, { globalRules: "foo" })(function (value) { a(value, true, "Global: Direct"); }); t(null, twoFooPath, { globalRules: ["one"] })(function (value) { a(value, true, "Global: Upper"); }); t(null, twoFooPath, { globalRules: ["bar"] })(function (value) { a(value, false, "Global: Not matching"); }); delete modes.test; return deferred( rmdir(gitRoot), rmdir(twoPath)(function () { return rmdir(onePath); }) )(false); }, DELAY) ).done(d, d); }; fs2-0.3.9/test/is-symlink.js000066400000000000000000000022171375545423700156520ustar00rootroot00000000000000"use strict"; var resolve = require("path").resolve , symlink = require("../symlink") , unlink = require("../unlink"); var rootPath = resolve(__dirname, "./__playground/is-symlink") , targetFile = resolve(rootPath, "from") , nonSymlink = resolve(rootPath, "non-symlink") , symlink1 = resolve(rootPath, "sym1") , symlink2 = resolve(rootPath, "sym2"); module.exports = function (t, a, d) { symlink( "from", symlink1 )(function () { return symlink("sym1", symlink2); })(function () { return t(symlink2); })( function (result) { a(result, true); return t(symlink2, { linkPath: targetFile }); } )(function (result) { a(result, false); return t(symlink2, { linkPath: symlink1 }); })(function (result) { a(result, true); return t(symlink2, { linkPath: targetFile, recursive: true }); })(function (result) { a(result, true); return t(targetFile); })(function (result) { a(result, false); return t(targetFile + "/foo"); })(function (result) { a(result, null); return unlink(symlink1)(unlink(symlink2)); })(function () { return t(nonSymlink, { loose: true }); })(function (result) { a(result, null); }).done(d, d); }; fs2-0.3.9/test/lchmod.js000066400000000000000000000010121375545423700150110ustar00rootroot00000000000000"use strict"; var lstat = require("../lstat") , testFile = require("path").resolve(__dirname, "__playground/lchmod/test"); module.exports = function (t, a, d) { if (!require("fs").lchmod) { a(t, null); d(); return; } lstat(testFile)(function (stats) { var org = stats.mode; return t(testFile, 511)(function () { return lstat(testFile)(function (stats2) { // eslint-disable-next-line no-bitwise a(stats2.mode & 511, 511); return t(testFile, org); }); }); }, a.never).done(d, d); }; fs2-0.3.9/test/lib/000077500000000000000000000000001375545423700137615ustar00rootroot00000000000000fs2-0.3.9/test/lib/buffer-from.js000066400000000000000000000001321375545423700165250ustar00rootroot00000000000000"use strict"; module.exports = function (t, a) { a(Buffer.isBuffer(t("data")), true); }; fs2-0.3.9/test/lib/find-root.js000066400000000000000000000047111375545423700162230ustar00rootroot00000000000000"use strict"; var fs = require("fs") , deferred = require("deferred") , resolve = require("path").resolve , promisify = deferred.promisify , delay = deferred.delay , mkdir = promisify(fs.mkdir) , rmdir = promisify(fs.rmdir) , gitMode = require("../../lib/ignore-modes/git") , rootPath = resolve(__dirname, "../__playground/lib/find-root"); module.exports = function (t, a, d) { var gitRoot = resolve(rootPath, ".git") , onePath = resolve(rootPath, "one") , gitOnePath = resolve(onePath, ".git") , twoPath = resolve(onePath, "two") , gitTwoPath = resolve(twoPath, ".git") , filePath = resolve(twoPath, "file.xxx"); var DELAY = 100, watcher, events = []; // Create /.git mkdir(gitRoot)(function () { // Create /one return mkdir(onePath); })(function () { // Create /one/.git return mkdir(gitOnePath); })(function () { watcher = t(gitMode.isRootWatcher, filePath, { watch: true }); watcher.on("change", function (path) { events.push(path); }); return watcher; })(function (path) { a(path, onePath, "#1"); })( delay(function () { a(String(events), "", "#1: Event"); events = []; // Create /one/two return mkdir(twoPath); }, DELAY) )( delay(function () { // Create /one/two/.git return mkdir(gitTwoPath); }, DELAY) )( delay(function () { a(String(events), twoPath, "#2: Event"); events = []; return t(gitMode.isRoot, filePath); }, DELAY) )(function (path) { a(path, twoPath, "#2"); // Remove /one/.git return rmdir(gitOnePath); })( delay(function () { // Remove /one/two/.git return rmdir(gitTwoPath); }, DELAY) )( delay(function () { a(String(events), rootPath, "#3: Event"); events = []; return t(gitMode.isRoot, filePath); }, DELAY) )(function (path) { a(path, rootPath, "#3"); // Create /one/two/.git return mkdir(gitTwoPath); })( delay(function () { a(String(events), twoPath, "#4: Event"); events = []; return t(gitMode.isRoot, filePath); }, DELAY) )(function (path) { a(path, twoPath, "#4"); // Remove /one/two/.git return rmdir(gitTwoPath); })(function () { // Remove /one/two return rmdir(twoPath); })(function () { // Remove /one return rmdir(onePath); })( delay(function () { a(String(events), rootPath, "#5: Event"); events = []; return t(gitMode.isRoot, filePath); }, DELAY) )(function (path) { a(path, rootPath, "#5"); watcher.close(); return rmdir(gitRoot); }).done(d, d); }; fs2-0.3.9/test/lib/get-conf-file-map.js000066400000000000000000000076571375545423700175300ustar00rootroot00000000000000"use strict"; var fs = require("fs") , resolve = require("path").resolve , omap = require("es5-ext/object/map") , deferred = require("deferred") , delay = deferred.delay , promisify = deferred.promisify , mkdir = promisify(fs.mkdir) , writeFile = promisify(fs.writeFile) , unlink = promisify(fs.unlink) , rmdir = promisify(fs.rmdir) , mode = require("../../lib/ignore-modes/git") , pgPath = resolve(__dirname, "../__playground/lib/get-conf-file-map"); module.exports = function (t, a, d) { var data , invoked = false , DELAY = 100 , gitRoot = resolve(pgPath, ".git") , rootFile = resolve(pgPath, ".gitignore") , onePath = resolve(pgPath, "one") , oneFile = resolve(onePath, ".gitignore") , twoPath = resolve(onePath, "two") , twoFile = resolve(twoPath, ".gitignore") , gitTwo = resolve(twoPath, ".git") , watcher; deferred(mkdir(gitRoot), mkdir(onePath)(function () { return mkdir(twoPath); }))( delay(function () { watcher = t(twoPath, mode, true); watcher.on("change", function (arg) { a(invoked, false, "Invoked once"); invoked = arg; }); return watcher; }, DELAY) )( delay(function (value) { var map = {}; data = value; a(data.root, pgPath, "#1 Root"); a.deep(omap(data.map, String), map, "#1 Data"); return writeFile(oneFile, "foo\n!bar"); }, DELAY) )( delay(function () { var map = {}; map[onePath] = "foo\n!bar"; a(invoked, data, "#2 invoked"); invoked = false; a(data.root, pgPath, "#2 Root"); a.deep(omap(data.map, String), map, "#2 Data"); return writeFile(twoFile, "!raz\ndwa\n"); }, DELAY) )( delay(function () { var map = {}; map[onePath] = "foo\n!bar"; map[twoPath] = "!raz\ndwa\n"; a(invoked, data, "#3 invoked"); invoked = false; a(data.root, pgPath, "#3 Root"); a.deep(omap(data.map, String), map, "#3 Data"); return t(twoPath, mode); }, DELAY) )(function (lData) { var map = {}; map[onePath] = "foo\n!bar"; map[twoPath] = "!raz\ndwa\n"; a(lData.root, pgPath, "#3 Root"); a.deep(omap(lData.map, String), map, "#3 Data"); return writeFile(rootFile, "one\n\ntwo\n!three\n"); })( delay(function () { var map = {}; map[pgPath] = "one\n\ntwo\n!three\n"; map[onePath] = "foo\n!bar"; map[twoPath] = "!raz\ndwa\n"; a(invoked, data, "#4 invoked"); invoked = false; a(data.root, pgPath, "#4 Root"); a.deep(omap(data.map, String), map, "#4 Data"); return mkdir(gitTwo); }, DELAY) )( delay(function () { var map = {}; map[twoPath] = "!raz\ndwa\n"; a(invoked, data, "#5 invoked"); invoked = false; a(data.root, twoPath, "#5 Root"); a.deep(omap(data.map, String), map, "#5 Data"); return rmdir(gitTwo); }, DELAY) )( delay(function () { var map = {}; map[pgPath] = "one\n\ntwo\n!three\n"; map[onePath] = "foo\n!bar"; map[twoPath] = "!raz\ndwa\n"; a(invoked, data, "#6 invoked"); invoked = false; a(data.root, pgPath, "#6 Root"); a.deep(omap(data.map, String), map, "#6 Data"); return unlink(twoFile); }, DELAY) )( delay(function () { var map = {}; map[pgPath] = "one\n\ntwo\n!three\n"; map[onePath] = "foo\n!bar"; a(invoked, data, "#7 invoked"); invoked = false; a(data.root, pgPath, "#7 Root"); a.deep(omap(data.map, String), map, "#7 Data"); return unlink(oneFile); }, DELAY) )( delay(function () { var map = {}; map[pgPath] = "one\n\ntwo\n!three\n"; a(invoked, data, "#8 invoked"); invoked = false; a(data.root, pgPath, "#8 Root"); a.deep(omap(data.map, String), map, "#8 Data"); return unlink(rootFile); }, DELAY) )( delay(function () { var map = {}; a(invoked, data, "#9 invoked"); invoked = false; a(data.root, pgPath, "#9 Root"); a.deep(omap(data.map, String), map, "#9 Data"); watcher.close(); return deferred( rmdir(gitRoot), rmdir(twoPath)(function () { return rmdir(onePath); }) )(false); }, DELAY) ).done(d, d); }; fs2-0.3.9/test/lib/ignore-modes/000077500000000000000000000000001375545423700163515ustar00rootroot00000000000000fs2-0.3.9/test/lib/ignore-modes/git.js000066400000000000000000000106311375545423700174730ustar00rootroot00000000000000"use strict"; var isValue = require("es5-ext/object/is-value") , fs = require("fs") , deferred = require("deferred") , resolve = require("path").resolve , promisify = deferred.promisify , delay = deferred.delay , mkdir = promisify(fs.mkdir) , rmdir = promisify(fs.rmdir) , isArray = Array.isArray , rootPath = resolve(__dirname, "../../__playground/lib/ignore-modes/git"); module.exports = function (t, a, d) { var gitRoot = resolve(rootPath, ".git") , onePath = resolve(rootPath, "one") , gitOnePath = resolve(onePath, ".git") , twoPath = resolve(onePath, "two") , gitTwoPath = resolve(twoPath, ".git") , rootEvents = [] , oneEvents = [] , twoEvents = [] , w1 , w2 , w3; a(typeof t.filename, "string", "Filename"); a(!isValue(t.globalRules) || isArray(t.globalRules), true, "Global rules"); // Create /.git mkdir(gitRoot)(function () { // Create /one return mkdir(onePath); })(function () { // Create /one/.git return mkdir(gitOnePath); })(function () { w1 = t.isRootWatcher(rootPath); w1.on("change", function (value) { rootEvents.push(value); }); w2 = t.isRootWatcher(onePath); w2.on("change", function (value) { oneEvents.push(value); }); w3 = t.isRootWatcher(twoPath); w3.on("change", function (value) { twoEvents.push(value); }); return deferred(w1, w2, w3); })( delay(function (data) { a.deep(data, [true, true, false], "#1"); a(String(rootEvents), "", "#1: Root Event"); a(String(oneEvents), "", "#1: One Event"); a(String(twoEvents), "", "#1: Two Event"); rootEvents = []; oneEvents = []; twoEvents = []; // Create /one/two return mkdir(twoPath); }, 20) )( delay(function () { // Create /one/two/.git return mkdir(gitTwoPath); }, 20) )( delay(function () { a(String(rootEvents), "", "#2: Root Event"); a(String(oneEvents), "", "#2: One Event"); a(String(twoEvents), "true", "#2: Two Event"); rootEvents = []; oneEvents = []; twoEvents = []; return deferred(t.isRoot(rootPath), t.isRoot(onePath), t.isRoot(twoPath)); }, 20) )(function (data) { a.deep(data, [true, true, true], "#2"); // Remove /one/.git return rmdir(gitOnePath); })( delay(function () { a(String(rootEvents), "", "#3: Root Event"); a(String(oneEvents), "false", "#3: One Event"); a(String(twoEvents), "", "#3: Two Event"); rootEvents = []; oneEvents = []; twoEvents = []; return deferred(t.isRoot(rootPath), t.isRoot(onePath), t.isRoot(twoPath)); }, 20) )(function (data) { a.deep(data, [true, false, true], "#3"); // Remove /one/two/.git return rmdir(gitTwoPath); })( delay(function () { a(String(rootEvents), "", "#4: Root Event"); a(String(oneEvents), "", "#4: One Event"); a(String(twoEvents), "false", "#4: Two Event"); rootEvents = []; oneEvents = []; twoEvents = []; return deferred(t.isRoot(rootPath), t.isRoot(onePath), t.isRoot(twoPath)); }, 20) )(function (data) { a.deep(data, [true, false, false], "#4"); // Create /one/two/.git return mkdir(gitTwoPath); })( delay(function () { a(String(rootEvents), "", "#5: Root Event"); a(String(oneEvents), "", "#5: One Event"); a(String(twoEvents), "true", "#5: Two Event"); rootEvents = []; oneEvents = []; twoEvents = []; return deferred(t.isRoot(rootPath), t.isRoot(onePath), t.isRoot(twoPath)); }, 20) )(function (data) { a.deep(data, [true, false, true], "#5"); // Remove /one/two/.git return rmdir(gitTwoPath); })( delay(function () { a(String(rootEvents), "", "#6: Root Event"); a(String(oneEvents), "", "#6: One Event"); a(String(twoEvents), "false", "#6: Two Event"); rootEvents = []; oneEvents = []; twoEvents = []; return deferred(t.isRoot(rootPath), t.isRoot(onePath), t.isRoot(twoPath)); }, 20) )(function (data) { a.deep(data, [true, false, false], "#6"); })(function () { // Remove /one/two return rmdir(twoPath); })(function () { // Remove /one return rmdir(onePath); })( delay(function () { a(String(rootEvents), "", "#7: Root Event"); a(String(oneEvents), "", "#7: One Event"); a(String(twoEvents), "", "#7: Two Event"); rootEvents = []; oneEvents = []; twoEvents = []; return deferred(t.isRoot(rootPath), t.isRoot(onePath), t.isRoot(twoPath)); }, 20) )(function (data) { a.deep(data, [true, false, false], "#7"); w1.close(); w2.close(); w3.close(); return rmdir(gitRoot); }).done(d, d); }; fs2-0.3.9/test/lib/ignore-modes/index.js000066400000000000000000000003031375545423700200120ustar00rootroot00000000000000"use strict"; var indexTest = require("tad/lib/utils/index-test") , dirPath = require("path").resolve(__dirname, "../../../lib/ignore-modes"); module.exports = indexTest(dirPath, ["tad"]); fs2-0.3.9/test/lib/memoize-watcher.js000066400000000000000000000013671375545423700174260ustar00rootroot00000000000000"use strict"; module.exports = function (t, a) { var fn, invoked, mfn, fnX, fnY, fnZ; fn = function (pathIgnored) { return { emit: function () { return true; }, close: function () { invoked = true; } }; }; invoked = false; mfn = t(fn); fnX = mfn("foo"); fnY = mfn("foo"); fnZ = mfn("bar"); a(invoked, false, "Pre calls"); fnZ.close(); a(invoked, true, "After single call"); invoked = false; fnZ.close(); a(invoked, false, "Second close call has no effect"); invoked = false; fnX.close(); a(invoked, false, "After one of two calls"); invoked = false; fnY.close(); a(invoked, true, "After two of two calls"); invoked = false; fnX.close(); a(invoked, false, "Second close call has no effect (two calls case)"); invoked = false; }; fs2-0.3.9/test/lib/watch-alt.js000066400000000000000000000064011375545423700162040ustar00rootroot00000000000000"use strict"; var fs = require("fs") , resolve = require("path").resolve , deferred = require("deferred") , bufferFrom = require("../../lib/buffer-from") , delay = deferred.delay , promisify = deferred.promisify , mkdir = promisify(fs.mkdir) , open = promisify(fs.open) , rename = promisify(fs.rename) , write = promisify(fs.write) , close = promisify(fs.close) , writeFile = promisify(fs.writeFile) , unlink = promisify(fs.unlink) , rmdir = promisify(fs.rmdir) , pgPath = resolve(__dirname, "../__playground/lib/watch-alt"); module.exports = function (t, a, d) { var ondirchange = 0 , onfilechange = 0 , ondirend = 0 , onfileend = 0 , DELAY = 200 , DELAYWAIT = 2000 , dirPath = resolve(pgPath, "tmpdir") , filePath = resolve(dirPath, "tmpfile"); a.throws(function () { t(filePath); }, "Not existing"); delay(function () { return mkdir(dirPath); }, DELAY)()( delay(function () { var dirWatch; dirWatch = t(dirPath); dirWatch.on("change", function () { ++ondirchange; }); dirWatch.on("end", function () { ++ondirend; }); }, DELAY) )(delay(function () { return writeFile(filePath, "raz"); }, DELAYWAIT))( delay(function () { var fileWatch; a(ondirchange, 1, "Dir change: File created"); a(ondirend, 0, "Dir end: File created"); ondirchange = ondirend = 0; fileWatch = t(filePath); fileWatch.on("change", function () { ++onfilechange; }); fileWatch.on("end", function () { ++onfileend; }); }, DELAYWAIT) )( delay(function () { return open(filePath, "a")(function (fd) { return write( fd, bufferFrom("dwatrzy"), 0, 3, null )(function () { return close(fd); }); }); }, DELAY) )( delay(function () { a(ondirchange, 0, "Dir change: File changed"); a(ondirend, 0, "Dir end: File changed"); a(onfilechange, 1, "File change: File created"); a(onfileend, 0, "File end: File created"); ondirchange = ondirend = onfilechange = onfileend = 0; return rename(filePath, filePath + "r"); }, DELAYWAIT) )( delay(function () { a(ondirchange, 1, "Dir change: File renamed"); a(ondirend, 0, "Dir end: File renamed"); a(onfilechange, 0, "File change: File renamed"); a(onfileend, 1, "File end: File renamed"); ondirchange = ondirend = onfilechange = onfileend = 0; return rename(filePath + "r", filePath); }, DELAYWAIT) )( delay(function () { a(ondirchange, 1, "Dir change: File renamed back"); a(ondirend, 0, "Dir end: File renamed back"); a(onfilechange, 0, "File change: File renamed back"); a(onfileend, 0, "File end: File renamed back"); ondirchange = ondirend = onfilechange = onfileend = 0; return unlink(filePath); }, DELAYWAIT) )( delay(function () { a(ondirchange, 1, "Dir change: File removed"); a(ondirend, 0, "Dir end: File removed"); a(onfilechange, 0, "File change: File removed"); a(onfileend, 0, "File end: File removed"); ondirchange = ondirend = onfilechange = onfileend = 0; return rmdir(dirPath); }, DELAYWAIT) )( delay(function () { a(ondirchange, 0, "Dir change: Dir removed"); a(ondirend, 1, "Dir end: Dir removed"); a(onfilechange, 0, "File change: Dir removed"); a(onfileend, 0, "File end: Dir removed"); }, DELAYWAIT) ).done(d, d); }; fs2-0.3.9/test/lib/watch.js000066400000000000000000000062631375545423700154340ustar00rootroot00000000000000"use strict"; var fs = require("fs") , resolve = require("path").resolve , deferred = require("deferred") , bufferFrom = require("../../lib/buffer-from") , delay = deferred.delay , promisify = deferred.promisify , mkdir = promisify(fs.mkdir) , open = promisify(fs.open) , rename = promisify(fs.rename) , write = promisify(fs.write) , close = promisify(fs.close) , writeFile = promisify(fs.writeFile) , unlink = promisify(fs.unlink) , rmdir = promisify(fs.rmdir) , pgPath = resolve(__dirname, "../__playground/lib/watch"); module.exports = function (t, a, d) { var ondirchange = 0 , onfilechange = 0 , ondirend = 0 , onfileend = 0 , DELAY = 200 , dirPath = resolve(pgPath, "tmpdir") , filePath = resolve(dirPath, "tmpfile"); a.throws(function () { t(filePath); }, "Not existing"); delay(function () { return mkdir(dirPath); }, DELAY)()( delay(function () { var emitter = t(dirPath); emitter.on("change", function () { ++ondirchange; }); emitter.on("end", function () { ++ondirend; }); }, DELAY) )(delay(function () { return writeFile(filePath, "raz"); }, DELAY))( delay(function () { var emitter; a(ondirchange, 1, "Dir change: File created"); a(ondirend, 0, "Dir end: File created"); ondirchange = ondirend = 0; emitter = t(filePath); emitter.on("change", function () { ++onfilechange; }); emitter.on("end", function () { ++onfileend; }); }, DELAY) )( delay(function () { return open(filePath, "a")(function (fd) { return write( fd, bufferFrom("dwatrzy"), 0, 3, null )(function () { return close(fd); }); }); }, DELAY) )( delay(function () { a(ondirchange, 0, "Dir change: File changed"); a(ondirend, 0, "Dir end: File changed"); a(onfilechange, 1, "File change: File created"); a(onfileend, 0, "File end: File created"); ondirchange = ondirend = onfilechange = onfileend = 0; return rename(filePath, filePath + "r"); }, DELAY) )( delay(function () { a(ondirchange, 1, "Dir change: File renamed"); a(ondirend, 0, "Dir end: File renamed"); a(onfilechange, 0, "File change: File renamed"); a(onfileend, 1, "File end: File renamed"); ondirchange = ondirend = onfilechange = onfileend = 0; return rename(filePath + "r", filePath); }, DELAY) )( delay(function () { a(ondirchange, 1, "Dir change: File renamed back"); a(ondirend, 0, "Dir end: File renamed back"); a(onfilechange, 0, "File change: File renamed back"); a(onfileend, 0, "File end: File renamed back"); ondirchange = ondirend = onfilechange = onfileend = 0; return unlink(filePath); }, DELAY) )( delay(function () { a(ondirchange, 1, "Dir change: File removed"); a(ondirend, 0, "Dir end: File removed"); a(onfilechange, 0, "File change: File removed"); a(onfileend, 0, "File end: File removed"); ondirchange = ondirend = onfilechange = onfileend = 0; return rmdir(dirPath); }, DELAY) )( delay(function () { a(ondirchange, 0, "Dir change: Dir removed"); a(ondirend, 1, "Dir end: Dir removed"); a(onfilechange, 0, "File change: Dir removed"); a(onfileend, 0, "File end: Dir removed"); }, DELAY) ).done(d, d); }; fs2-0.3.9/test/lstat.js000066400000000000000000000004541375545423700147030ustar00rootroot00000000000000"use strict"; var resolve = require("path").resolve; module.exports = function (t, a, d) { t(__filename)(function (stats) { a(stats.isFile(), true, "Success"); return t( resolve(__dirname, "n/a") )(a.never, function (err) { a(err.code, "ENOENT", "Error"); }); }, a.never).done(d, d); }; fs2-0.3.9/test/mkdir.js000066400000000000000000000024561375545423700146660ustar00rootroot00000000000000"use strict"; var promisify = require("deferred").promisify , fs = require("fs") , path = require("path") , dirname = path.dirname , resolve = path.resolve , lstat = promisify(fs.lstat) , rmdir = promisify(fs.rmdir) , rootPath = resolve(__dirname, "./__playground/mkdir") , regular = resolve(rootPath, "foo") , existing = resolve(rootPath, "one") , deep = resolve(rootPath, "foo", "bar"); module.exports = function (t) { return { Regular: { Success: function (a, d) { t(regular)(function () { return lstat(regular)(function (stats) { a(stats.isDirectory(), true); return rmdir(regular); }); }).done(d, d); }, Error: function (a, d) { t(deep)(a.never, function () { a.ok(true, ""); }).done(d, d); }, Existing: function (a, d) { t(existing)(a.never, function () { a.ok(true, ""); }).done(d, d); } }, Intermediate: { "": function (a, d) { t(deep, { intermediate: true })(function () { return lstat(deep)(function (stats) { a(stats.isDirectory(), true); return rmdir(deep)(function () { return rmdir(dirname(deep)); }); }); }).done(d, d); }, "Existing": function (a, d) { t(existing, { intermediate: true })(function () { a.ok(true, ""); }).done(d, d); } } }; }; fs2-0.3.9/test/read-file.js000066400000000000000000000113511375545423700154020ustar00rootroot00000000000000"use strict"; var deferred = require("deferred") , bufferFrom = require("../lib/buffer-from") , delay = deferred.delay , promisify = deferred.promisify , isBuffer = Buffer.isBuffer , fs = require("fs") , resolve = require("path").resolve , open = promisify(fs.open) , write = promisify(fs.write) , close = promisify(fs.close) , writeFile = promisify(fs.writeFile) , unlink = promisify(fs.unlink) , pgPath = resolve(__dirname, "./__playground/read-file"); module.exports = function (t) { var DELAY = 100; return { Regular: { "Doesn't exist": function (a, d) { t(resolve(pgPath, "fake"))(a.never, function (err) { a(err.code, "ENOENT"); }).done( d, d ); }, "Exists": function (a, d) { t(resolve(pgPath, "test"))(function (data) { a(isBuffer(data), true, "Buffer returned"); a(String(data), "raz\ndwa", "Content"); }, a.never).done(d, d); }, "Encoding": function (a, d) { t(resolve(pgPath, "test"), "utf8")(function (data) { a(data, "raz\ndwa"); }, a.never).done(d, d); }, "Loose": { "Doesn't exist": function (a, d) { t(resolve(pgPath, "fake"), { loose: true })(function (data) { a(data, null); }, a.never).done(d, d); }, "Exists": function (a, d) { t(resolve(pgPath, "test"), { loose: true })(function (data) { a(String(data), "raz\ndwa"); }, a.never).done(d, d); } } }, Watch: { Regular: { "Doesn't exist": function (a, d) { t(resolve(pgPath, "fake"), { watch: true })(a.never, function (err) { a(err.code, "ENOENT"); }).done(d, d); }, "Exists": function (a, d) { var path = resolve(pgPath, "watch-test"), invoked, ended, watcher; return writeFile(path, "one\ntwo")( delay(function () { invoked = false; ended = false; watcher = t(path, { watch: true }); watcher.on("change", function (data) { a(invoked, false, "Expected invoke"); invoked = data; }); watcher.on("end", function () { ended = true; }); return watcher; }, DELAY) )( delay(function (data) { a(isBuffer(data), true, "Buffer returned"); a(String(data), "one\ntwo", "Content"); return open(path, "a")(function (fd) { return write( fd, bufferFrom("\nthree\n"), 0, 7, null )(function () { return close(fd); }); }); }, DELAY) )( delay(function () { a(isBuffer(invoked), true, "Emitted buffer"); a(String(invoked), "one\ntwo\nthree\n", "Buffer data"); invoked = false; return open(path, "a")(function (fd) { return write( fd, bufferFrom(""), 0, 0, null )(function () { return close(fd); }); }); }, DELAY) )( delay(function () { a(invoked, false, "Update without change"); a(ended, false, "Not ended"); return unlink(path); }, DELAY) )(delay(function () { a(ended, true, "Watcher ended"); }, DELAY)).done(d, d); } }, Loose: function (a, d) { var path = resolve(pgPath, "watch-loose-test"), invoked, ended, watcher; invoked = false; ended = false; watcher = t(path, { watch: true, loose: true }); watcher.on("change", function (data) { a(invoked, false, "Expected invoke"); invoked = data; }); watcher.on("end", function () { ended = true; }); return watcher( delay(function (data) { a(data, null, "No file yet"); return writeFile(path, "foo\nbar"); }, DELAY) )( delay(function () { a(isBuffer(invoked), true, "Emitted buffer"); a(String(invoked), "foo\nbar", "Emitted Content"); invoked = false; return open(path, "a")(function (fd) { return write( fd, bufferFrom("\nfour\n"), 0, 6, null )(function () { return close(fd); }); }); }, DELAY) )( delay(function () { a(isBuffer(invoked), true, "Emitted buffer"); a(String(invoked), "foo\nbar\nfour\n", "Buffer data"); invoked = false; return open(path, "a")(function (fd) { return write( fd, bufferFrom(""), 0, 0, null )(function () { return close(fd); }); }); }, DELAY) )( delay(function () { a(invoked, false, "Update without change"); a(ended, false, "Not ended"); return unlink(path); }, DELAY) )( delay(function () { a(invoked, null, "Emitted null"); invoked = false; return writeFile(path, "foo\nagain"); }, DELAY) )( delay(function () { a(isBuffer(invoked), true, "Emitted buffer"); a(String(invoked), "foo\nagain", "Emitted Content"); watcher.close(); return unlink(path); }, DELAY) ).done(d, d); } } }; }; fs2-0.3.9/test/readdir.js000066400000000000000000000725551375545423700152010ustar00rootroot00000000000000/* eslint max-lines: off */ "use strict"; var push = Array.prototype.push , fs = require("fs") , pathUtils = require("path") , aFrom = require("es5-ext/array/from") , diff = require("es5-ext/array/#/diff") , startsWith = require("es5-ext/string/#/starts-with") , deferred = require("deferred") , delay = deferred.delay , promisify = deferred.promisify , mkdir = promisify(fs.mkdir) , writeFile = promisify(fs.writeFile) , unlink = promisify(fs.unlink) , rmdir = promisify(fs.rmdir) , basename = pathUtils.basename , resolve = pathUtils.resolve , sep = pathUtils.sep , pgPath = resolve(__dirname, "./__playground/readdir"); module.exports = function (t) { var pathsAll, paths2, paths0, files2, replaceSep, DELAY = 100; replaceSep = function (path) { return path.replace(/\//g, sep); }; pathsAll = [ "done", "done/done", "done/done/dthree", "done/done/dthree/dthree", "done/done/dthree/dthree/foo", "done/done/dthree/dtwo", "done/done/dthree/dtwo/foo", "done/done/dthree/one", "done/done/dthree/three", "done/done/dthree/two", "done/done/dtwo", "done/done/dtwo/dtwo", "done/done/dtwo/dtwo/foo", "done/done/dtwo/one", "done/done/dtwo/three", "done/done/dtwo/two", "done/done/one", "done/done/three", "done/done/two", "done/dtwo", "done/dtwo/foo", "done/one", "done/three", "done/two", "dthree", "dthree/dthree", "dthree/dthree/done", "dthree/dthree/done/dthree", "dthree/dthree/done/dthree/foo", "dthree/dthree/done/one", "dthree/dthree/done/three", "dthree/dthree/done/two", "dthree/dthree/one", "dthree/dthree/three", "dthree/dthree/two", "dthree/dtwo", "dthree/dtwo/foo", "dthree/one", "dthree/three", "dthree/two", "dtwo", "dtwo/one", "dtwo/three", "dtwo/two", "one", "three", "two" ].map(replaceSep); paths2 = pathsAll.filter(function (path) { return path.split(sep).length < 4; }); paths0 = pathsAll.filter(function (path) { return path.split(sep).length < 2; }); files2 = paths2.filter(function (path) { return basename(path)[0] !== "d"; }); return { "": { "0": function (a, d) { var reader = t(pgPath, { watch: true }) , testName = "foo" , testPath = resolve(pgPath, testName) , paths = paths0 , invoked = false; reader.on("change", function (data) { invoked = data; }); reader( delay(function (data) { a.deep(data.sort(), paths); return mkdir(testPath); }, DELAY * 2) )( delay(function () { a.deep(invoked.removed, [], "Created: removed"); a.deep(invoked.added, [testName], "Created: added"); invoked = false; reader(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Created: data"); }).done(); return t(pgPath); }, DELAY) )(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Not watched"); return rmdir(testPath); })( delay(function () { a.deep(invoked.removed, [testName], "Deleted: removed"); a.deep(invoked.added, [], "Deleted: added"); invoked = false; reader(function (data) { a.deep(data.sort(), paths, "Deleted: data"); }).done(); reader.close(); }, DELAY) ).done(d, d); }, "2": function (a, d) { var reader = t(pgPath, { depth: 2, watch: true }) , testName = replaceSep("dtwo/foo") , testPath = resolve(pgPath, testName) , paths = paths2 , invoked = false; reader.on("change", function (data) { invoked = data; }); reader(function (data) { a.deep(data.sort(), paths); })( delay(function () { return mkdir(testPath); }, DELAY) )( delay(function () { a.deep(invoked.removed, [], "Created: removed"); a.deep(invoked.added, [testName], "Created: added"); invoked = false; reader(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Created: data"); }).done(); return t(pgPath, { depth: 2 }); }, DELAY) )(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Not watched"); return rmdir(testPath); })( delay(function () { a.deep(invoked.removed, [testName], "Deleted: removed"); a.deep(invoked.added, [], "Deleted: added"); invoked = false; reader(function (data) { a.deep(data.sort(), paths, "Deleted: data"); }).done(); reader.close(); }, DELAY) ).done(d, d); }, "∞": function (a, d) { var reader = t(pgPath, { depth: Infinity, watch: true }) , testName = replaceSep("done/done/dthree/test") , testPath = resolve(pgPath, testName) , paths = pathsAll , invoked = false; reader.on("change", function (data) { invoked = data; }); reader(function (data) { a.deep(data.sort(), paths); })( delay(function () { return writeFile(testPath, "foo"); }, DELAY) )( delay(function () { a.deep(invoked.removed, [], "Created: removed"); a.deep(invoked.added, [testName], "Created: added"); invoked = false; reader(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Created: data"); }).done(); return t(pgPath, { depth: Infinity }); }, DELAY) )(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Not watched"); return unlink(testPath); })( delay(function () { a.deep(invoked.removed, [testName], "Deleted: removed"); a.deep(invoked.added, [], "Deleted: added"); invoked = false; reader(function (data) { a.deep(data.sort(), paths, "Deleted: data"); }).done(); reader.close(); }, DELAY) ).done(d, d); } }, "Loose": function (a, d) { var reader = t(resolve(pgPath, "not-existing"), { loose: true }); reader(function (data) { a(data, null); }).done(d, d); }, "Progress events": function (a, d) { var reader = t(pgPath, { depth: Infinity, stream: true }) , result = [] , lengths = [] , count = 0; reader.on("change", function (data) { ++count; lengths.push(data.added.length); a.deep(data.removed, [], "Removed #" + count); push.apply(result, data.added); a.deep(result.sort(), data.data.sort(), "Data #" + count); }); reader(function (data) { a.deep(lengths.sort(), [1, 1, 1, 1, 1, 1, 3, 4, 4, 4, 5, 5, 5, 5, 6], "Events"); a.deep(result.sort(), data.sort(), "Result"); }).done(d, d); }, "Type": function (a, d) { var reader = t(pgPath, { depth: 2, type: { file: true }, watch: true }) , testName = replaceSep("dtwo/test") , testPath = resolve(pgPath, testName) , paths = files2 , invoked = false; reader.on("change", function (data) { invoked = data; }); reader(function (data) { a.deep(data.sort(), paths); return mkdir(testPath); })( delay(function () { a(invoked, false, "Created other type: event"); invoked = false; reader(function (data) { a.deep(data.sort(), paths, "Created other type: data"); }).done(); return rmdir(testPath); }, DELAY) )( delay(function () { a(invoked, false, "Deleted other type: event"); invoked = false; reader(function (data) { a.deep(data.sort(), paths, "Deleted other type: data"); }).done(); return writeFile(testPath, "foo"); }, DELAY) )( delay(function () { a.deep(invoked.removed, [], "Created: removed"); a.deep(invoked.added, [testName], "Created: added"); invoked = false; reader(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Created: data"); }).done(); return t(pgPath, { depth: 2, type: { file: true } }); }, DELAY) )(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Not watched"); return unlink(testPath); })( delay(function () { a.deep(invoked.removed, [testName], "Deleted: removed"); a.deep(invoked.added, [], "Deleted: added"); invoked = false; reader(function (data) { a.deep(data.sort(), paths, "Deleted: data"); }).done(); reader.close(); }, DELAY) ).done(d, d); }, "Types": function (a, d) { var reader = t(pgPath, { depth: 2, type: { file: true, directory: true }, watch: true }) , testName = replaceSep("dtwo/foo") , testPath = resolve(pgPath, testName) , paths = paths2 , invoked = false; reader.on("change", function (data) { invoked = data; }); reader( delay(function (data) { a.deep(data.sort(), paths); return mkdir(testPath); }, DELAY) )( delay(function () { a.deep(invoked.removed, [], "Created: removed"); a.deep(invoked.added, [testName], "Created: added"); invoked = false; reader(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Created: data"); }).done(); return t(pgPath, { depth: 2, type: { file: true, directory: true } }); }, DELAY) )(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Not watched"); return rmdir(testPath); })( delay(function () { a.deep(invoked.removed, [testName], "Deleted: removed"); a.deep(invoked.added, [], "Deleted: added"); invoked = false; reader(function (data) { a.deep(data.sort(), paths, "Deleted: data"); }).done(); reader.close(); }, DELAY) ).done(d, d); }, "Pattern": function (a, d) { var pattern = /one$/ , reader = t(pgPath, { depth: 2, pattern: pattern, watch: true }) , otherName = replaceSep("dtwo/test") , otherPath = resolve(pgPath, otherName) , testName = replaceSep("dtwo/fooone") , testPath = resolve(pgPath, testName) , paths = paths2.filter(function (path) { return pattern.test(path); }) , invoked = false; reader.on("change", function (data) { invoked = data; }); reader(function (data) { a.deep(data.sort(), paths); return mkdir(otherPath); })( delay(function () { a(invoked, false, "Created other type: event"); invoked = false; reader(function (data) { a.deep(data.sort(), paths, "Created other type: data"); }).done(); return rmdir(otherPath); }, DELAY) )( delay(function () { a(invoked, false, "Deleted other type: event"); invoked = false; reader(function (data) { a.deep(data.sort(), paths, "Deleted other type: data"); }).done(); return mkdir(testPath); }, DELAY) )( delay(function () { a.deep(invoked.removed, [], "Created: removed"); a.deep(invoked.added, [testName], "Created: added"); invoked = false; reader(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Created: data"); }).done(); return t(pgPath, { depth: 2, pattern: pattern }); }, DELAY) )(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Not watched"); return rmdir(testPath); })( delay(function () { a.deep(invoked.removed, [testName], "Deleted: removed"); a.deep(invoked.added, [], "Deleted: added"); invoked = false; reader(function (data) { a.deep(data.sort(), paths, "Deleted: data"); }).done(); reader.close(); }, DELAY) ).done(d, d); }, "Global rules": function (a, d) { var rules = ["one"] , re = /(?:^|\/|\\)one(?:\/|\\|$)/ , reader = t(pgPath, { depth: 2, globalRules: rules, watch: true }) , otherName = replaceSep("dthree/dtwo/one") , otherPath = resolve(pgPath, otherName) , testName = replaceSep("dtwo/fooone") , testPath = resolve(pgPath, testName) , paths = paths2.filter(function (path) { return !re.test(path); }) , invoked = false; reader.on("change", function (data) { invoked = data; }); reader(function (data) { a.deep(data.sort(), paths); return mkdir(otherPath); })( delay(function () { a(invoked, false, "Created other type: event"); invoked = false; reader(function (data) { a.deep(data.sort(), paths, "Created other type: data"); }).done(); return rmdir(otherPath); }, DELAY) )( delay(function () { a(invoked, false, "Deleted other type: event"); invoked = false; reader(function (data) { a.deep(data.sort(), paths, "Deleted other type: data"); }).done(); return mkdir(testPath); }, DELAY) )( delay(function () { a.deep(invoked.removed, [], "Created: removed"); a.deep(invoked.added, [testName], "Created: added"); invoked = false; reader(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Created: data"); }).done(); return t(pgPath, { depth: 2, globalRules: rules }); }, DELAY) )(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Not watched"); return rmdir(testPath); })( delay(function () { a.deep(invoked.removed, [testName], "Deleted: removed"); a.deep(invoked.added, [], "Deleted: added"); invoked = false; reader(function (data) { a.deep(data.sort(), paths, "Deleted: data"); }).done(); reader.close(); }, DELAY) ).done(d, d); }, "Pattern & Type": function (a, d) { var pattern = /one$/ , reader = t(pgPath, { depth: 2, type: { file: true }, pattern: pattern, watch: true }) , testName = replaceSep("dtwo/fooone") , testPath = resolve(pgPath, testName) , paths = files2.filter(function (path) { return pattern.test(path); }) , invoked = false; reader.on("change", function (data) { invoked = data; }); reader( delay(function (data) { a.deep(data.sort(), paths); return mkdir(testPath); }, DELAY) )( delay(function () { a(invoked, false, "Created other type: event"); invoked = false; reader(function (data) { a.deep(data.sort(), paths, "Created other type: data"); }).done(); return rmdir(testPath); }, DELAY) )( delay(function () { a(invoked, false, "Deleted other type: event"); invoked = false; reader(function (data) { a.deep(data.sort(), paths, "Deleted other type: data"); }).done(); return writeFile(testPath, "foo"); }, DELAY) )( delay(function () { a.deep(invoked.removed, [], "Created: removed"); a.deep(invoked.added, [testName], "Created: added"); invoked = false; reader(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Created: data"); }).done(); return t(pgPath, { depth: 2, type: { file: true }, pattern: pattern }); }, DELAY) )(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Not watched"); return unlink(testPath); })( delay(function () { a.deep(invoked.removed, [testName], "Deleted: removed"); a.deep(invoked.added, [], "Deleted: added"); invoked = false; reader(function (data) { a.deep(data.sort(), paths, "Deleted: data"); }).done(); reader.close(); }, DELAY) ).done(d, d); }, "Ignored": function (a, d) { var gitPath = resolve(pgPath, ".git") , ignoreFile = resolve(pgPath, ".gitignore") , otherName = replaceSep("dtwo/test") , otherPath = resolve(pgPath, otherName) , testName = replaceSep("dthree/fooone") , testPath = resolve(pgPath, testName) , paths = paths2.filter(function (path) { return path.indexOf("dtwo") === -1; }) , reader , invoked = [] , mergeInvoked , npaths; mergeInvoked = function () { var result; if (!invoked.length) { return false; } result = { data: invoked[0].data, removed: [], added: [] }; invoked.forEach(function (data) { push.apply(result.added, data.added); push.apply(result.removed, data.removed); }); invoked = []; return result; }; paths.push(".gitignore"); paths.sort(); npaths = paths.filter(function (path) { return ( path !== "one" && path.indexOf(sep + "one") === -1 && !startsWith.call(path, "dthree" + sep + "dthree") ); }); deferred(mkdir(gitPath), writeFile(ignoreFile, "dtwo"))( delay(function () { reader = t(pgPath, { depth: 2, ignoreRules: "git", watch: true }); reader.on("change", function (data) { invoked.push(data); }); return reader; }, DELAY) )(function (data) { a.deep(data.sort(), paths); return mkdir(otherPath); })( delay(function () { var lInvoked = mergeInvoked(); a(lInvoked, false, "Created other type: event"); reader(function (data) { a.deep(data.sort(), paths, "Created other type: data"); }).done(); return rmdir(otherPath); }, DELAY) )( delay(function () { var lInvoked = mergeInvoked(); a(lInvoked, false, "Deleted other type: event"); reader(function (data) { a.deep(data.sort(), paths, "Deleted other type: data"); }).done(); return mkdir(testPath); }, DELAY) )( delay(function () { var lInvoked = mergeInvoked(); a.deep(lInvoked.removed, [], "Created: removed"); a.deep(lInvoked.added, [testName], "Created: added"); reader(function (data) { var npaths2 = aFrom(paths); npaths2.push(testName); a.deep(data.sort(), npaths2.sort(), "Created: data"); }).done(); return t(pgPath, { depth: 2, ignoreRules: "git" }); }, DELAY) )(function (data) { var npaths2 = aFrom(paths); npaths2.push(testName); a.deep(data.sort(), npaths2.sort(), "Not watched"); return rmdir(testPath); })( delay(function () { var lInvoked = mergeInvoked(); a.deep(lInvoked.removed, [testName], "Deleted: removed"); a.deep(lInvoked.added, [], "Deleted: added"); reader(function (data) { a.deep(data.sort(), paths, "Deleted: data"); }).done(); return writeFile(ignoreFile, "dtwo\none\n/dthree/dthree"); }, DELAY) )( delay(function () { var lInvoked = mergeInvoked(); a.deep( lInvoked && lInvoked.removed && lInvoked.removed.sort(), diff.call(paths, npaths).sort(), "Ignored: removed" ); a.deep(lInvoked.added, [], "Ignored: added"); reader(function (data) { a.deep(data.sort(), npaths, "Ignored: data"); }).done(); return writeFile(ignoreFile, "dtwo"); }, DELAY) )( delay(function () { var lInvoked = mergeInvoked(); a.deep(lInvoked.removed, [], "Ignored revert: removed"); a.deep( lInvoked && lInvoked.added && lInvoked.added.sort(), diff.call(paths, npaths).sort(), "Ignored revert: added" ); reader(function (data) { a.deep(data.sort(), paths, "Ignored revert: data"); }).done(); reader.close(); return deferred(rmdir(gitPath), unlink(ignoreFile))(false); }, DELAY) ).done(d, d); }, "Ignored & Type": function (a, d) { var gitPath = resolve(pgPath, ".git") , ignoreFile = resolve(pgPath, ".gitignore") , otherName = replaceSep("dtwo/test") , otherPath = resolve(pgPath, otherName) , testName = replaceSep("dthree/fooone") , testPath = resolve(pgPath, testName) , paths = files2.filter(function (path) { return path.indexOf("dtwo") === -1; }) , reader , invoked = [] , mergeInvoked; mergeInvoked = function () { var result; if (!invoked.length) { return false; } result = { data: invoked[0].data, removed: [], added: [] }; invoked.forEach(function (data) { push.apply(result.added, data.added); push.apply(result.removed, data.removed); }); invoked = []; return result; }; paths.push(".gitignore"); paths.sort(); deferred(mkdir(gitPath), writeFile(ignoreFile, "dtwo"))( delay(function () { reader = t(pgPath, { depth: 2, type: { file: true }, ignoreRules: "git", watch: true }); reader.on("change", function (data) { invoked.push(data); }); return reader; }, DELAY) )( delay(function (data) { a.deep(data.sort(), paths); return writeFile(otherPath, "foo"); }, DELAY) )( delay(function () { var lInvoked = mergeInvoked(); a(lInvoked, false, "Created other type: event"); reader(function (data) { a.deep(data.sort(), paths, "Created other type: data"); }).done(); return unlink(otherPath); }, DELAY) )( delay(function () { var lInvoked = mergeInvoked(); a(lInvoked, false, "Deleted other type: event"); reader(function (data) { a.deep(data.sort(), paths, "Deleted other type: data"); }).done(); return writeFile(testPath, "foo"); }, DELAY) )( delay(function () { var lInvoked = mergeInvoked(); a.deep(lInvoked.removed, [], "Created: removed"); a.deep(lInvoked.added, [testName], "Created: added"); reader(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Created: data"); }).done(); return t(pgPath, { depth: 2, type: { file: true }, ignoreRules: "git" }); }, DELAY) )(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Not watched"); return unlink(testPath); })( delay(function () { var lInvoked = mergeInvoked(); a.deep(lInvoked.removed, [testName], "Deleted: removed"); a.deep(lInvoked.added, [], "Deleted: added"); reader(function (data) { a.deep(data.sort(), paths, "Deleted: data"); }).done(); }, DELAY) )(delay(function () { return writeFile(ignoreFile, "dtwo\none"); }, DELAY))( delay(function () { var lInvoked , npaths = paths .filter(function (path) { return path !== "one" && path.indexOf(sep + "one") === -1; }) .sort(); lInvoked = mergeInvoked(); a.deep( lInvoked.removed && lInvoked.removed.sort(), diff.call(paths, npaths).sort(), "Ignored: removed" ); a.deep(lInvoked.added, [], "Ignored: added"); reader(function (data) { a.deep(data.sort(), npaths, "Ignored: data"); }).done(); reader.close(); return deferred(rmdir(gitPath), unlink(ignoreFile))(false); }, DELAY) ).done(d, d); }, "Ignored & Pattern": function (a, d) { var pattern = /done/ , gitPath = resolve(pgPath, ".git") , ignoreFile = resolve(pgPath, ".gitignore") , otherName = replaceSep("dtwo/test") , otherPath = resolve(pgPath, otherName) , testName = replaceSep("done/fooone") , testPath = resolve(pgPath, testName) , paths = paths2.filter(function (path) { return path.indexOf("dtwo") === -1 && pattern.test(path); }) , reader , invoked = [] , mergeInvoked; mergeInvoked = function () { var result; if (!invoked.length) { return false; } result = { data: invoked[0].data, removed: [], added: [] }; invoked.forEach(function (data) { push.apply(result.added, data.added); push.apply(result.removed, data.removed); }); invoked = []; return result; }; deferred(mkdir(gitPath), writeFile(ignoreFile, "dtwo"))( delay(function () { reader = t(pgPath, { depth: 2, pattern: pattern, ignoreRules: "git", watch: true }); reader.on("change", function (data) { invoked.push(data); }); return reader; }, DELAY) )( delay(function (data) { a.deep(data.sort(), paths); return mkdir(otherPath); }, DELAY) )( delay(function () { var lInvoked = mergeInvoked(); a(lInvoked, false, "Created other type: event"); reader(function (data) { a.deep(data.sort(), paths, "Created other type: data"); }).done(); return rmdir(otherPath); }, DELAY) )( delay(function () { var lInvoked = mergeInvoked(); a(lInvoked, false, "Deleted other type: event"); reader(function (data) { a.deep(data.sort(), paths, "Deleted other type: data"); }).done(); return mkdir(testPath); }, DELAY) )( delay(function () { var lInvoked = mergeInvoked(); a.deep(lInvoked.removed, [], "Created: removed"); a.deep(lInvoked.added, [testName], "Created: added"); reader(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Created: data"); }).done(); return t(pgPath, { depth: 2, pattern: pattern, ignoreRules: "git" }); }, DELAY) )(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Not watched"); return rmdir(testPath); })( delay(function () { var lInvoked = mergeInvoked(); a.deep(lInvoked.removed, [testName], "Deleted: removed"); a.deep(lInvoked.added, [], "Deleted: added"); reader(function (data) { a.deep(data.sort(), paths, "Deleted: data"); }).done(); }, DELAY) )(delay(function () { return writeFile(ignoreFile, "dtwo\none"); }, DELAY))( delay(function () { var lInvoked , npaths = paths .filter(function (path) { return path !== "one" && path.indexOf(sep + "one") === -1; }) .sort(); lInvoked = mergeInvoked(); a.deep( lInvoked && lInvoked.removed && lInvoked.removed.sort(), diff.call(paths, npaths).sort(), "Ignored: removed" ); a.deep(lInvoked.added, [], "Ignored: added"); reader(function (data) { a.deep(data.sort(), npaths, "Ignored: data"); }).done(); reader.close(); return deferred(rmdir(gitPath), unlink(ignoreFile))(false); }, DELAY) ).done(d, d); }, "Ignored & Pattern & Type": function (a, d) { var pattern = /done/ , gitPath = resolve(pgPath, ".git") , ignoreFile = resolve(pgPath, ".gitignore") , otherName = replaceSep("dtwo/test") , otherPath = resolve(pgPath, otherName) , testName = replaceSep("done/fooone") , testPath = resolve(pgPath, testName) , paths = files2.filter(function (path) { return path.indexOf("dtwo") === -1 && pattern.test(path); }) , reader , invoked = [] , mergeInvoked; mergeInvoked = function () { var result; if (!invoked.length) { return false; } result = { data: invoked[0].data, removed: [], added: [] }; invoked.forEach(function (data) { push.apply(result.added, data.added); push.apply(result.removed, data.removed); }); invoked = []; return result; }; deferred(mkdir(gitPath), writeFile(ignoreFile, "dtwo"))( delay(function () { reader = t(pgPath, { depth: 2, type: { file: true }, pattern: pattern, ignoreRules: "git", watch: true }); reader.on("change", function (data) { invoked.push(data); }); return reader; }, DELAY) )( delay(function (data) { a.deep(data.sort(), paths); return writeFile(otherPath, "foo"); }, DELAY) )( delay(function () { var lInvoked = mergeInvoked(); a(lInvoked, false, "Created other type: event"); reader(function (data) { a.deep(data.sort(), paths, "Created other type: data"); }).done(); return unlink(otherPath); }, DELAY) )( delay(function () { var lInvoked = mergeInvoked(); a(lInvoked, false, "Deleted other type: event"); reader(function (data) { a.deep(data.sort(), paths, "Deleted other type: data"); }).done(); return writeFile(testPath, "foo"); }, DELAY) )( delay(function () { var lInvoked = mergeInvoked(); a.deep(lInvoked.removed, [], "Created: removed"); a.deep(lInvoked.added, [testName], "Created: added"); reader(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Created: data"); }).done(); return t(pgPath, { depth: 2, type: { file: true }, pattern: pattern, ignoreRules: "git" }); }, DELAY) )(function (data) { var npaths = aFrom(paths); npaths.push(testName); a.deep(data.sort(), npaths.sort(), "Not watched"); return unlink(testPath); })( delay(function () { var lInvoked = mergeInvoked(); a.deep(lInvoked.removed, [testName], "Deleted: removed"); a.deep(lInvoked.added, [], "Deleted: added"); reader(function (data) { a.deep(data.sort(), paths, "Deleted: data"); }).done(); }, DELAY) )(delay(function () { return writeFile(ignoreFile, "dtwo\none"); }, DELAY))( delay(function () { var lInvoked , npaths = paths .filter(function (path) { return path !== "one" && path.indexOf(sep + "one") === -1; }) .sort(); lInvoked = mergeInvoked(); a.deep( lInvoked && lInvoked.removed && lInvoked.removed.sort(), diff.call(paths, npaths).sort(), "Ignored: removed" ); a.deep(lInvoked.added, [], "Ignored: added"); reader(function (data) { a.deep(data.sort(), npaths, "Ignored: data"); }).done(); reader.close(); return deferred(rmdir(gitPath), unlink(ignoreFile))(false); }, DELAY) ).done(d, d); }, "cb": function (a, d) { t(pgPath, function (err, result) { if (err) { d(err); return; } a.deep(result.sort(), ["done", "dthree", "dtwo", "one", "three", "two"]); d(); }); } }; }; fs2-0.3.9/test/readlink.js000066400000000000000000000013541375545423700153450ustar00rootroot00000000000000"use strict"; var resolve = require("path").resolve , symlink = require("../symlink") , unlink = require("../unlink"); var rootPath = resolve(__dirname, "./__playground/readlink") , targetFile = resolve(rootPath, "from") , nonSymlink = resolve(rootPath, "non-symlink") , symlink1 = resolve(rootPath, "sym1") , symlink2 = resolve(rootPath, "sym2"); module.exports = function (t, a, d) { symlink(targetFile, symlink1)(function () { return symlink(symlink1, symlink2); })(function () { return t(symlink2); })(function (resolvedTarget) { a(resolvedTarget, symlink1); return unlink(symlink1)(unlink(symlink2)); })(function () { return t(nonSymlink, { loose: true }); })(function (result) { a(result, null); }).done(d, d); }; fs2-0.3.9/test/realpath.js000066400000000000000000000004571375545423700153570ustar00rootroot00000000000000"use strict"; var resolve = require("path").resolve; module.exports = function (t, a, d) { t(__filename)(function (filename) { a(filename, __filename, "Success"); return t( resolve(__dirname, "n/a") )(a.never, function (err) { a(err.code, "ENOENT", "Error"); }); }, a.never).done(d, d); }; fs2-0.3.9/test/rename.js000066400000000000000000000021461375545423700150230ustar00rootroot00000000000000"use strict"; var deferred = require("deferred") , resolve = require("path").resolve , lstat = require("../lstat") , unlink = require("../unlink") , writeFile = require("../write-file") , rootPath = resolve(__dirname, "__playground/rename") , name1 = resolve(rootPath, "file1") , name2 = resolve(rootPath, "file2"); module.exports = function (t, a, d) { writeFile(name1, "fooraz")(function () { return lstat(name1)(function (stats1) { return t(name1, name2)(function () { return deferred( lstat(name1)(a.never, function () { a.ok(true, "No first file"); }), lstat(name2)(function (stats2) { // Do not compare eventual birthtime and ctime // as in some envs they may not reflect value of source file delete stats1.birthtime; delete stats1.birthtimeMs; delete stats2.birthtime; delete stats2.birthtimeMs; delete stats1.ctime; delete stats1.ctimeMs; delete stats2.ctime; delete stats2.ctimeMs; a.deep(stats1, stats2, "Same"); return unlink(name2); }) )(false); }); }); }).done(d, d); }; fs2-0.3.9/test/rm.js000066400000000000000000000016101375545423700141650ustar00rootroot00000000000000"use strict"; var lstat = require("../lstat") , mkdir = require("../mkdir") , writeFile = require("../write-file") , testFile = require("path").resolve(__dirname, "__playground/rm-file") , testDir = require("path").resolve(__dirname, "__playground/rm-dir"); module.exports = { File: function (t, a, d) { return writeFile(testFile, "foo")(function () { return lstat(testFile)(function () { return t(testFile)(function () { return lstat(testFile)(a.never, function (err) { a(err.code, "ENOENT"); return t(testFile + "bla", { loose: true }).catch(a.never); }); }); }); }).done(d, d); }, Directory: function (t, a, d) { mkdir(testDir)(function () { return lstat(testDir)(function () { return t(testDir)(function () { return lstat(testDir)(a.never, function (err) { a(err.code, "ENOENT"); }); }); }); }).done(d, d); } }; fs2-0.3.9/test/rmdir-sync.js000066400000000000000000000016331375545423700156430ustar00rootroot00000000000000"use strict"; const { resolve } = require("path") , lstat = require("../lstat") , mkdir = require("../mkdir") , writeFile = require("../write-file") , pg = resolve(__dirname, "__playground") , rootPath = resolve(pg, "rmdir-sync") , nested = resolve(rootPath, "one/two/three/dir") , nested2 = resolve(rootPath, "one/four/five/six"); module.exports = function (t, a) { return Promise.all([ mkdir(nested, { intermediate: true }), mkdir(nested2, { intermediate: true }) ]) .then(() => writeFile(resolve(nested, "../foo"), "bar")) .then(() => { try { t(rootPath); throw new Error("Unexpected"); } catch (error) { a(error.code, "ENOTEMPTY", "Default on not empty"); } t(rootPath, { recursive: true, force: true }); return lstat(rootPath).then(a.never, err => { a(err.code, "ENOENT", "Recursive and forced"); }); }); }; fs2-0.3.9/test/rmdir.js000066400000000000000000000030351375545423700146670ustar00rootroot00000000000000"use strict"; var resolve = require("path").resolve , lstat = require("../lstat") , mkdir = require("../mkdir") , writeFile = require("../write-file") , pg = resolve(__dirname, "__playground") , rootPath = resolve(pg, "rmdir") , nested = resolve(rootPath, "one/two/three/dir") , nested2 = resolve(rootPath, "one/four/five/six"); module.exports = function (t, a, d) { mkdir(nested, { intermediate: true })(mkdir(nested2, { intermediate: true }))(function () { return writeFile(resolve(nested, "../foo"), "bar"); })(function () { return t( rootPath )(a.never, function (err) { a(err.code, "ENOTEMPTY", "Default on not empty"); })(function () { return t(rootPath, { recursive: true })(a.never, function (err) { a(err.code, "ENOTEMPTY", "Recursive not empty"); }); })(function () { var path = resolve(rootPath, "one/four"); return t(path, { recursive: true })(function () { return lstat( path )(a.never, function (err) { a(err.code, "ENOENT", "Recursive on empty"); }); }); })(function () { return t(nested)(function () { return lstat(nested)(a.never, function (err) { a(err.code, "ENOENT", "Plain"); }); }); })(function () { return t(nested, { loose: true })(function (res) { a(res, null, "Loose option"); }, a.never); })(function () { return t(rootPath, { recursive: true, force: true })(function () { return lstat( rootPath )(a.never, function (err) { a(err.code, "ENOENT", "Recursive and forced"); }); }); }); }).done(d, d); }; fs2-0.3.9/test/stat.js000066400000000000000000000004541375545423700145270ustar00rootroot00000000000000"use strict"; var resolve = require("path").resolve; module.exports = function (t, a, d) { t(__filename)(function (stats) { a(stats.isFile(), true, "Success"); return t( resolve(__dirname, "n/a") )(a.never, function (err) { a(err.code, "ENOENT", "Error"); }); }, a.never).done(d, d); }; fs2-0.3.9/test/symlink.js000066400000000000000000000014411375545423700152370ustar00rootroot00000000000000"use strict"; var promisify = require("deferred").promisify , fs = require("fs") , path = require("path") , resolve = path.resolve , lstat = promisify(fs.lstat) , unlink = promisify(fs.unlink) , rootPath = resolve(__dirname, "./__playground/symlink") , base = resolve(rootPath, "from") , regular = resolve(rootPath, "foo") , deep = resolve(rootPath, "foo/bar"); module.exports = function (t) { return { Regular: { Success: function (a, d) { t(base, regular)(function () { return lstat(regular)(function (stats) { a(stats.isSymbolicLink(), true); return unlink(regular); }); }).done(d, d); }, Error: function (a, d) { t(base, deep)(a.never, function () { a.ok(true, ""); }).done(d, d); } } }; }; fs2-0.3.9/test/type-by-stats.js000066400000000000000000000005371375545423700163030ustar00rootroot00000000000000"use strict"; var lstat = require("fs").lstat; module.exports = function (t, a, d) { lstat(__filename, function (err, stat) { if (err) { d(err); return; } a(t(stat), "file", "File"); lstat(__dirname, function (err2, stat2) { if (err2) { d(err2); return; } a(t(stat2), "directory", "Directory"); d(); }); }); }; fs2-0.3.9/test/unlink.js000066400000000000000000000010041375545423700150440ustar00rootroot00000000000000"use strict"; var lstat = require("../lstat") , writeFile = require("../write-file") , testFile = require("path").resolve(__dirname, "__playground/unlink"); module.exports = function (t, a, d) { return writeFile(testFile, "foo")(function () { return lstat(testFile)(function () { return t(testFile)(function () { return lstat(testFile)(a.never, function (err) { a(err.code, "ENOENT"); return t(testFile + "bla", { loose: true }).catch(a.never); }); }); }); }).done(d, d); }; fs2-0.3.9/test/watch-path.js000066400000000000000000000071661375545423700156230ustar00rootroot00000000000000"use strict"; var fs = require("fs") , resolve = require("path").resolve , deferred = require("deferred") , bufferFrom = require("../lib/buffer-from") , delay = deferred.delay , promisify = deferred.promisify , mkdir = promisify(fs.mkdir) , open = promisify(fs.open) , rename = promisify(fs.rename) , write = promisify(fs.write) , close = promisify(fs.close) , writeFile = promisify(fs.writeFile) , unlink = promisify(fs.unlink) , rmdir = promisify(fs.rmdir) , pgPath = resolve(__dirname, "./__playground/watch-path"); module.exports = function (t, a, d) { var ondirchange = [] , onfilechange = [] , DELAY = 100 , dirPath = resolve(pgPath, "tmpdir") , filePath = resolve(dirPath, "tmpfile") , watch1 , watch2; watch1 = t(dirPath); watch1.on("change", function (e) { ondirchange.push(e.type); }); watch2 = t(filePath); watch2.on("change", function (e) { onfilechange.push(e.type); }); delay(function () { return mkdir(dirPath); }, DELAY)()( delay(function () { a(String(ondirchange), "create", "Dir: Dir created"); a(String(onfilechange), "", "File: Dir created"); ondirchange = []; onfilechange = []; return writeFile(filePath, "raz"); }, DELAY) )( delay(function () { a(String(ondirchange), "modify", "Dir: File created"); a(String(onfilechange), "create", "File: File created"); ondirchange = []; onfilechange = []; return open(filePath, "a")(function (fd) { return write( fd, bufferFrom("dwatrzy"), 0, 3, null )(function () { return close(fd); }); }); }, DELAY) )( delay(function () { a(String(ondirchange), "", "Dir: File changed"); a(String(onfilechange), "modify", "File: File changed"); ondirchange = []; onfilechange = []; return rename(filePath, filePath + "r"); }, DELAY) )( delay(function () { a(String(ondirchange), "modify", "Dir: File renamed"); a(String(onfilechange), "remove", "File: File renamed"); ondirchange = []; onfilechange = []; return rename(filePath + "r", filePath); }, DELAY) )( delay(function () { a(String(ondirchange), "modify", "Dir: File renamed back"); a(String(onfilechange), "create", "File: File renamed back"); ondirchange = []; onfilechange = []; return unlink(filePath); }, DELAY) )( delay(function () { a(String(ondirchange), "modify", "Dir: File removed"); a(String(onfilechange), "remove", "File: File removed"); ondirchange = []; onfilechange = []; return rmdir(dirPath); }, DELAY) )( delay(function () { a(String(ondirchange), "remove", "Dir: Dir removed"); a(String(onfilechange), "", "File: Dir removed"); ondirchange = []; onfilechange = []; return mkdir(dirPath); }, DELAY) )( delay(function () { a(String(ondirchange), "create", "Dir: Dir created #2"); a(String(onfilechange), "", "File: Dir created #2"); ondirchange = []; onfilechange = []; return writeFile(filePath, "raz"); }, DELAY) )( delay(function () { a(String(ondirchange), "modify", "Dir: File created #2"); a(String(onfilechange), "create", "File: File created #2"); ondirchange = []; onfilechange = []; return unlink(filePath); }, DELAY) )( delay(function () { a(String(ondirchange), "modify", "Dir: File removed #2"); a(String(onfilechange), "remove", "File: File removed #2"); ondirchange = []; onfilechange = []; return rmdir(dirPath); }, DELAY) )( delay(function () { a(String(ondirchange), "remove", "Dir: Dir removed #2"); a(String(onfilechange), "", "File: Dir removed #2"); watch1.close(); watch2.close(); }, DELAY) ).done(d, d); }; fs2-0.3.9/test/watch.js000066400000000000000000000063761375545423700146730ustar00rootroot00000000000000"use strict"; var fs = require("fs") , resolve = require("path").resolve , deferred = require("deferred") , bufferFrom = require("../lib/buffer-from") , delay = deferred.delay , promisify = deferred.promisify , mkdir = promisify(fs.mkdir) , open = promisify(fs.open) , rename = promisify(fs.rename) , write = promisify(fs.write) , close = promisify(fs.close) , writeFile = promisify(fs.writeFile) , unlink = promisify(fs.unlink) , rmdir = promisify(fs.rmdir) , pgPath = resolve(__dirname, "./__playground/watch"); module.exports = function (t, a, d) { var ondirchange = 0 , onfilechange = 0 , ondirend = 0 , onfileend = 0 , w1 , w2 , w3 , w4 , DELAY = 500 , dirPath = resolve(pgPath, "tmpdir") , filePath = resolve(dirPath, "tmpfile"); a.throws(function () { t(filePath); }, "Not existing"); delay(function () { return mkdir(dirPath); }, DELAY)()( delay(function () { w1 = t(dirPath); w1.on("change", function () { ++ondirchange; }); w2 = t(dirPath); w2.on("end", function () { ++ondirend; }); }, DELAY) )(delay(function () { return writeFile(filePath, "raz"); }, DELAY))( delay(function () { a(ondirchange, 1, "Dir change: File created"); a(ondirend, 0, "Dir end: File created"); ondirchange = ondirend = 0; w3 = t(filePath); w3.on("change", function () { ++onfilechange; }); w4 = t(filePath); w4.on("end", function () { ++onfileend; }); }, DELAY) )( delay(function () { return open(filePath, "a")(function (fd) { return write( fd, bufferFrom("dwatrzy"), 0, 3, null )(function () { return close(fd); }); }); }, DELAY) )( delay(function () { a(ondirchange, 0, "Dir change: File changed"); a(ondirend, 0, "Dir end: File changed"); a(onfilechange, 1, "File change: File created"); a(onfileend, 0, "File end: File created"); ondirchange = ondirend = onfilechange = onfileend = 0; return rename(filePath, filePath + "r"); }, DELAY) )( delay(function () { a(ondirchange, 1, "Dir change: File renamed"); a(ondirend, 0, "Dir end: File renamed"); a(onfilechange, 0, "File change: File renamed"); a(onfileend, 1, "File end: File renamed"); ondirchange = ondirend = onfilechange = onfileend = 0; return rename(filePath + "r", filePath); }, DELAY) )( delay(function () { a(ondirchange, 1, "Dir change: File renamed back"); a(ondirend, 0, "Dir end: File renamed back"); a(onfilechange, 0, "File change: File renamed back"); a(onfileend, 0, "File end: File renamed back"); ondirchange = ondirend = onfilechange = onfileend = 0; return unlink(filePath); }, DELAY) )( delay(function () { a(ondirchange, 1, "Dir change: File removed"); a(ondirend, 0, "Dir end: File removed"); a(onfilechange, 0, "File change: File removed"); a(onfileend, 0, "File end: File removed"); ondirchange = ondirend = onfilechange = onfileend = 0; return rmdir(dirPath); }, DELAY) )( delay(function () { a(ondirchange, 0, "Dir change: Dir removed"); a(ondirend, 1, "Dir end: Dir removed"); a(onfilechange, 0, "File change: Dir removed"); a(onfileend, 0, "File end: Dir removed"); w1.close(); w2.close(); w3.close(); w4.close(); }, DELAY) ).done(d, d); }; fs2-0.3.9/test/write-file.js000066400000000000000000000023721375545423700156240ustar00rootroot00000000000000"use strict"; var fs = require("fs") , resolve = require("path").resolve , rmdir = require("../rmdir") , readFile = fs.readFile , unlink = fs.unlink , pgPath = resolve(__dirname, "./__playground") , overwritePath = resolve(pgPath, "write-file-test") , intermediateDirPath = resolve(pgPath, "_write-file") , intermediatePath = resolve(intermediateDirPath, "intermediate/test"); module.exports = { Overwrite: function (t, a, d) { t(overwritePath, "raz", function (err) { a(err, null, "#1"); }); t(overwritePath, "dwa", function (err) { a(err, null, "#2"); }); t(overwritePath, "trzy", function (err) { a(err, null, "#3"); readFile(overwritePath, function (err2, content) { a(String(content), "trzy", "Last written"); unlink(overwritePath, d); }); }); }, Intermediate: function (t, a, d) { t(intermediatePath, "elo", { intermediate: true }, function (err) { if (err) { d(err); return; } fs.readFile(intermediatePath, function (err2, content) { if (err2) { d(err2); return; } a(String(content), "elo", "Content"); rmdir(intermediateDirPath, { recursive: true, force: true }, d); }); }); } }; fs2-0.3.9/type-by-stats.js000066400000000000000000000007341375545423700153230ustar00rootroot00000000000000"use strict"; module.exports = function (stat) { if (stat.isFile()) { return "file"; } if (stat.isDirectory()) { return "directory"; } if (stat.isSymbolicLink && stat.isSymbolicLink()) { return "symbolicLink"; } if (stat.isSocket()) { return "socket"; } if (stat.isBlockDevice()) { return "blockDevice"; } if (stat.isCharacterDevice()) { return "characterDevice"; } if (stat.isFIFO()) { return "FIFO"; } throw new Error("Cannot detect type"); }; fs2-0.3.9/unlink.js000066400000000000000000000016301375545423700140720ustar00rootroot00000000000000"use strict"; var isCallable = require("es5-ext/object/is-callable") , isValue = require("es5-ext/object/is-value") , deferred = require("deferred") , resolve = require("path").resolve , original = require("fs").unlink , unlink; unlink = function (path, options) { var def = deferred(); original(path, function (err) { if (err) { if (err.code === "ENOENT" && options.loose) def.resolve(); else def.reject(err); return; } def.resolve(); }); return def.promise; }; unlink.returnsPromise = true; module.exports = exports = function (path /* [, options[, callback]]*/) { var options, cb; path = resolve(String(path)); options = arguments[1]; cb = arguments[2]; if (!isValue(cb) && isCallable(options)) { cb = options; options = {}; } else { options = Object(options); } return unlink(path, options).cb(cb); }; exports.returnsPromise = true; exports.unlink = unlink; fs2-0.3.9/watch-path.js000066400000000000000000000040221375545423700146300ustar00rootroot00000000000000"use strict"; var ee = require("event-emitter") , pathUtils = require("path") , watch = require("./watch").watch; var basename = pathUtils.basename , dirname = pathUtils.dirname , join = pathUtils.join , resolve = pathUtils.resolve , Watcher; Watcher = function (path) { this.path = path; this.missing = []; this.onchange = this.onchange.bind(this); this.onremove = this.onremove.bind(this); this.up = this.up.bind(this); this.watch(); this.emitter = ee(); this.emitter.close = this.close.bind(this); return this.emitter; }; Watcher.prototype = { close: function () { this.watcher.close(); }, up: function () { var parent = dirname(this.path); if (parent === this.path) { return; } this.missing.unshift(basename(this.path)); this.path = parent; this.watch(); }, watch: function () { var watcher; try { watcher = watch(this.path); } catch (e) { this.up(); return; } this.onwatch(watcher); }, tryDown: function () { var watcher, npath; npath = join(this.path, this.missing[0]); try { watcher = watch(npath); } catch (e) { return false; } this.path = npath; this.missing.shift(); if (!this.missing.length) { this.onwatch(watcher); this.oncreate(); } else if (this.tryDown()) { watcher.close(); } else { this.onwatch(watcher); } return true; }, onwatch: function (watcher) { if (this.missing.length) { watcher.on( "change", function () { if (this.tryDown()) { watcher.close(); } }.bind(this) ); watcher.once("end", this.up); } else { watcher.on("change", this.onchange); watcher.once("end", this.onremove); } this.watcher = watcher; }, oncreate: function () { this.emitter.emit("change", { type: "create" }); }, onchange: function () { this.emitter.emit("change", { type: "modify" }); }, onremove: function () { this.emitter.emit("change", { type: "remove" }); this.up(); } }; module.exports = exports = function (path) { return new Watcher(resolve(String(path))); }; exports.WatchPath = Watcher; fs2-0.3.9/watch.js000066400000000000000000000075671375545423700137170ustar00rootroot00000000000000/* eslint max-statements: off */ "use strict"; var last = require("es5-ext/array/#/last") , remove = require("es5-ext/array/#/remove") , descHandler = require("./descriptors-handler") , resolve = require("path").resolve , watchReg = require("./lib/watch") , watchAlt = require("./lib/watch-alt") , memoizeWatcher = require("./lib/memoize-watcher") , max = Math.max , watch , compare , releaseDescs , switchToAlt , switchToReg , switchAltsToReg , onLstat , isAvail , watchers = { reg: [], alt: [] }; compare = function (watcherA, watcherB) { return watcherB.count - watcherA.count; }; isAvail = function () { return descHandler.available > 50; }; switchToAlt = function (watcher) { var closePrevious = watcher.emitter._close; remove.call(watchers.reg, watcher); try { watchAlt(watcher.path, watcher.emitter); } catch (err) { if (err.code === "ENOENT" || err.code === "DIFFTYPE") { watcher.emitter.end(err); return; } throw err; } closePrevious(); descHandler.close(); watcher.alt = true; onLstat(watcher); watchers.alt.push(watcher); watchers.alt.sort(compare); }; switchToReg = function (watcher) { var emitter = watcher.emitter, closePrevious = emitter._close; try { watchReg(watcher.path, watcher.emitter); } catch (err) { if (err.code === "EMFILE") { descHandler.limit = descHandler.taken; releaseDescs(); return; } if (err.code === "ENOENT" || err.code === "DIFFTYPE") { emitter.off("change", emitter._watchSwitchListener); delete emitter._watchSwitchListener; remove.call(watchers.alt, watcher); watcher.emitter.end(err); return; } throw err; } emitter.off("change", emitter._watchSwitchListener); delete emitter._watchSwitchListener; remove.call(watchers.alt, watcher); closePrevious(); descHandler.open(); watcher.alt = false; watchers.reg.push(watcher); watchers.reg.sort(compare); }; switchAltsToReg = function () { while (watchers.alt.length && isAvail()) { switchToReg(watchers.alt[0]); } }; releaseDescs = function () { var count = max(watchers.reg.length - (descHandler.taken - 50), 0); if (count) { watchers.reg.sort(compare).slice(-count).forEach(switchToAlt); } }; onLstat = function (watcher) { var emitter = watcher.emitter; emitter.on( "change", (emitter._watchSwitchListener = function () { var candidate; watchers.alt.sort(compare); if (watchers.alt[0] !== watcher) return; if (isAvail()) { switchAltsToReg(); } else if (watchers.reg.length) { candidate = last.call(watchers.reg.sort(compare)); if (candidate.count >= watcher.count) return; // Move last regular watcher to lstat watch switchToAlt(candidate); // Move current watcher to regular watch switchToReg(watcher); } }) ); }; watch = memoizeWatcher( function self(path) { var emitter, watcher; watcher = { path: path, count: 0 }; if (isAvail()) { try { emitter = watcher.emitter = watchReg(path); } catch (e) { if (e.code === "EMFILE") { descHandler.limit = descHandler.taken; releaseDescs(); return self(path); } throw e; } descHandler.open(); watchers.reg.push(watcher); } else { emitter = watcher.emitter = watchAlt(path); watcher.alt = true; watchers.alt.push(watcher); } emitter._close = emitter.close; emitter.close = function () { emitter._close(); remove.call(watchers[watcher.alt ? "alt" : "reg"], watcher); if (!watcher.alt) { descHandler.close(); // Switch if possible switchAltsToReg(); } }; emitter.on("end", function () { watch.clear(path); emitter.close(); }); emitter.on("change", function () { ++watcher.count; }); if (watcher.alt) { onLstat(watcher); } return emitter; }, { primitive: true } ); module.exports = exports = function (path) { return watch(resolve(String(path))); }; exports.watch = watch; fs2-0.3.9/write-file.js000066400000000000000000000062231375545423700146440ustar00rootroot00000000000000// Fs.writeFile that's safe for simultaneous calls for same file. // In such event write that is ongoing is exited and new one is initialized "use strict"; var isCallable = require("es5-ext/object/is-callable") , isValue = require("es5-ext/object/is-value") , isString = require("es5-ext/string/is-string") , deferred = require("deferred") , fs = require("fs") , pathUtils = require("path") , bufferFrom = require("./lib/buffer-from") , mkdir = require("./mkdir").mkdir; var dirname = pathUtils.dirname , resolve = pathUtils.resolve , next , writeAll , cache = {} , _writeFile , writeFile; next = function (path, err, content, encoding, flag, mode) { var data = cache[path]; if (err) { if (!cache[path].intermediate || err.code !== "ENOENT") { delete cache[path]; data.def.reject(err); return; } mkdir(dirname(path), { intermediate: true }).cb(function (err2) { delete cache[path].intermediate; if (err2) { next(path, err2); return; } _writeFile(path, content, encoding, flag, mode); }); return; } if (data.data) { data = data.data; delete cache[path].data; _writeFile(path, data.data, data.encoding, data.flag, data.mode); } else { delete cache[path]; data.def.resolve(); } }; writeAll = function (path, fd, buffer, offset, length) { fs.write(fd, buffer, offset, length, offset, function (writeErr, written) { if (writeErr) { fs.close(fd, function () { next(path, writeErr); }); } else if (written === length || cache[path].data) { fs.close(fd, function (err) { next(path, err); }); } else { writeAll(path, fd, buffer, offset + written, length - written); } }); }; _writeFile = function (path, data, encoding, flag, mode) { if (!encoding) { encoding = "utf8"; } fs.open(path, flag || "w", mode || 438, function (openErr, fd) { if (openErr) { next(path, openErr, data, encoding, flag, mode); return; } if (cache[path].data) { fs.close(fd, function (err) { next(path, err); }); } else { var buffer; if (Buffer.isBuffer(data)) { buffer = data; } else { buffer = bufferFrom(String(data), encoding); } writeAll(path, fd, buffer, 0, buffer.length); } }); }; writeFile = function (path, data, options) { var def, encoding = options.encoding || null; if (cache[path]) { if (!cache[path].intermediate && options.intermediate) { cache[path].intermediate = true; } cache[path].data = { data: data, encoding: encoding, flag: options.flag, mode: options.mode }; def = cache[path].def; } else { def = deferred(); cache[path] = { def: def, intermediate: options.intermediate }; _writeFile(path, data, encoding, options.flag, options.mode); } return def.promise; }; writeFile.returnsPromise = true; module.exports = exports = function (path, data) { var cb, options; path = resolve(String(path)); options = arguments[2]; cb = arguments[3]; if (!isValue(cb) && isCallable(options)) { cb = options; options = {}; } else { options = isString(options) ? { encoding: options } : Object(options); } return writeFile(path, data, options).cb(cb); }; exports.returnsPromise = true; exports.writeFile = writeFile;