diff options
Diffstat (limited to 'node_modules/ncp')
20 files changed, 674 insertions, 0 deletions
diff --git a/node_modules/ncp/.npmignore b/node_modules/ncp/.npmignore new file mode 100644 index 0000000..3e6a4d7 --- /dev/null +++ b/node_modules/ncp/.npmignore @@ -0,0 +1,4 @@ +node_modules +.*.sw[op] +.DS_Store +test/*fixtures/out diff --git a/node_modules/ncp/.travis.yml b/node_modules/ncp/.travis.yml new file mode 100644 index 0000000..a6e2198 --- /dev/null +++ b/node_modules/ncp/.travis.yml @@ -0,0 +1,6 @@ +language: node_js + +node_js: + - 0.8 + - "0.10" + - "0.11" diff --git a/node_modules/ncp/LICENSE.md b/node_modules/ncp/LICENSE.md new file mode 100644 index 0000000..e2b9b41 --- /dev/null +++ b/node_modules/ncp/LICENSE.md @@ -0,0 +1,21 @@ +# MIT License + +###Copyright (C) 2011 by Charlie McConnell + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/ncp/README.md b/node_modules/ncp/README.md new file mode 100644 index 0000000..9480032 --- /dev/null +++ b/node_modules/ncp/README.md @@ -0,0 +1,63 @@ +# ncp - Asynchronous recursive file & directory copying + +[![Build Status](https://secure.travis-ci.org/AvianFlu/ncp.png)](http://travis-ci.org/AvianFlu/ncp) + +Think `cp -r`, but pure node, and asynchronous. `ncp` can be used both as a CLI tool and programmatically. + +## Command Line usage + +Usage is simple: `ncp [source] [dest] [--limit=concurrency limit] +[--filter=filter] --stopOnErr` + +The 'filter' is a Regular Expression - matched files will be copied. + +The 'concurrency limit' is an integer that represents how many pending file system requests `ncp` has at a time. + +'stoponerr' is a boolean flag that will tell `ncp` to stop immediately if any +errors arise, rather than attempting to continue while logging errors. The default behavior is to complete as many copies as possible, logging errors along the way. + +If there are no errors, `ncp` will output `done.` when complete. If there are errors, the error messages will be logged to `stdout` and to `./ncp-debug.log`, and the copy operation will attempt to continue. + +## Programmatic usage + +Programmatic usage of `ncp` is just as simple. The only argument to the completion callback is a possible error. + +```javascript +var ncp = require('ncp').ncp; + +ncp.limit = 16; + +ncp(source, destination, function (err) { + if (err) { + return console.error(err); + } + console.log('done!'); +}); +``` + +You can also call ncp like `ncp(source, destination, options, callback)`. +`options` should be a dictionary. Currently, such options are available: + + * `options.filter` - a `RegExp` instance, against which each file name is + tested to determine whether to copy it or not, or a function taking single + parameter: copied file name, returning `true` or `false`, determining + whether to copy file or not. + + * `options.transform` - a function: `function (read, write) { read.pipe(write) }` + used to apply streaming transforms while copying. + + * `options.clobber` - boolean=true. if set to false, `ncp` will not overwrite + destination files that already exist. + + * `options.dereference` - boolean=false. If set to true, `ncp` will follow symbolic + links. For example, a symlink in the source tree pointing to a regular file + will become a regular file in the destination tree. Broken symlinks will result in + errors. + + * `options.stopOnErr` - boolean=false. If set to true, `ncp` will behave like `cp -r`, + and stop on the first error it encounters. By default, `ncp` continues copying, logging all + errors and returning an array. + + * `options.errs` - stream. If `options.stopOnErr` is `false`, a stream can be provided, and errors will be written to this stream. + +Please open an issue if any bugs arise. As always, I accept (working) pull requests, and refunds are available at `/dev/null`. diff --git a/node_modules/ncp/bin/ncp b/node_modules/ncp/bin/ncp new file mode 100644 index 0000000..388eaba --- /dev/null +++ b/node_modules/ncp/bin/ncp @@ -0,0 +1,48 @@ +#!/usr/bin/env node + + + + +var ncp = require('../lib/ncp'), + args = process.argv.slice(2), + source, dest; + +if (args.length < 2) { + console.error('Usage: ncp [source] [destination] [--filter=filter] [--limit=concurrency limit]'); + process.exit(1); +} + +// parse arguments the hard way +function startsWith(str, prefix) { + return str.substr(0, prefix.length) == prefix; +} + +var options = {}; +args.forEach(function (arg) { + if (startsWith(arg, "--limit=")) { + options.limit = parseInt(arg.split('=', 2)[1], 10); + } + if (startsWith(arg, "--filter=")) { + options.filter = new RegExp(arg.split('=', 2)[1]); + } + if (startsWith(arg, "--stoponerr")) { + options.stopOnErr = true; + } +}); + +ncp.ncp(args[0], args[1], options, function (err) { + if (Array.isArray(err)) { + console.error('There were errors during the copy.'); + err.forEach(function (err) { + console.error(err.stack || err.message); + }); + process.exit(1); + } + else if (err) { + console.error('An error has occurred.'); + console.error(err.stack || err.message); + process.exit(1); + } +}); + + diff --git a/node_modules/ncp/lib/ncp.js b/node_modules/ncp/lib/ncp.js new file mode 100644 index 0000000..bc25a05 --- /dev/null +++ b/node_modules/ncp/lib/ncp.js @@ -0,0 +1,266 @@ +var fs = require('fs'), + path = require('path'), + util = require('util'); + +const modern = /^v0\.1\d\.\d+/.test(process.version); + +module.exports = ncp; +ncp.ncp = ncp; + +function ncp (source, dest, options, callback) { + var cback = callback; + + if (!callback) { + cback = options; + options = {}; + } + + var basePath = process.cwd(), + currentPath = path.resolve(basePath, source), + targetPath = path.resolve(basePath, dest), + filter = options.filter, + rename = options.rename, + transform = options.transform, + clobber = options.clobber !== false, + modified = options.modified, + dereference = options.dereference, + errs = null, + eventName = modern ? 'finish' : 'close', + defer = modern ? setImmediate : process.nextTick, + started = 0, + finished = 0, + running = 0, + limit = options.limit || ncp.limit || 16; + + limit = (limit < 1) ? 1 : (limit > 512) ? 512 : limit; + + startCopy(currentPath); + + function startCopy(source) { + started++; + if (filter) { + if (filter instanceof RegExp) { + if (!filter.test(source)) { + return cb(true); + } + } + else if (typeof filter === 'function') { + if (!filter(source)) { + return cb(true); + } + } + } + return getStats(source); + } + + function getStats(source) { + var stat = dereference ? fs.stat : fs.lstat; + if (running >= limit) { + return defer(function () { + getStats(source); + }); + } + running++; + stat(source, function (err, stats) { + var item = {}; + if (err) { + return onError(err); + } + + // We need to get the mode from the stats object and preserve it. + item.name = source; + item.mode = stats.mode; + item.mtime = stats.mtime; //modified time + item.atime = stats.atime; //access time + + if (stats.isDirectory()) { + return onDir(item); + } + else if (stats.isFile()) { + return onFile(item); + } + else if (stats.isSymbolicLink()) { + // Symlinks don't really need to know about the mode. + return onLink(source); + } + }); + } + + function onFile(file) { + var target = file.name.replace(currentPath, targetPath); + if(rename) { + target = rename(target); + } + isWritable(target, function (writable) { + if (writable) { + return copyFile(file, target); + } + if(clobber) { + rmFile(target, function () { + copyFile(file, target); + }); + } + if (modified) { + var stat = dereference ? fs.stat : fs.lstat; + stat(target, function(err, stats) { + //if souce modified time greater to target modified time copy file + if (file.mtime.getTime()>stats.mtime.getTime()) + copyFile(file, target); + else return cb(); + }); + } + else { + return cb(); + } + }); + } + + function copyFile(file, target) { + var readStream = fs.createReadStream(file.name), + writeStream = fs.createWriteStream(target, { mode: file.mode }); + + readStream.on('error', onError); + writeStream.on('error', onError); + + if(transform) { + transform(readStream, writeStream, file); + } else { + writeStream.on('open', function() { + readStream.pipe(writeStream); + }); + } + writeStream.once(eventName, function() { + if (modified) { + //target file modified date sync. + fs.utimesSync(target, file.atime, file.mtime); + cb(); + } + else cb(); + }); + } + + function rmFile(file, done) { + fs.unlink(file, function (err) { + if (err) { + return onError(err); + } + return done(); + }); + } + + function onDir(dir) { + var target = dir.name.replace(currentPath, targetPath); + isWritable(target, function (writable) { + if (writable) { + return mkDir(dir, target); + } + copyDir(dir.name); + }); + } + + function mkDir(dir, target) { + fs.mkdir(target, dir.mode, function (err) { + if (err) { + return onError(err); + } + copyDir(dir.name); + }); + } + + function copyDir(dir) { + fs.readdir(dir, function (err, items) { + if (err) { + return onError(err); + } + items.forEach(function (item) { + startCopy(dir + '/' + item); + }); + return cb(); + }); + } + + function onLink(link) { + var target = link.replace(currentPath, targetPath); + fs.readlink(link, function (err, resolvedPath) { + if (err) { + return onError(err); + } + checkLink(resolvedPath, target); + }); + } + + function checkLink(resolvedPath, target) { + if (dereference) { + resolvedPath = path.resolve(basePath, resolvedPath); + } + isWritable(target, function (writable) { + if (writable) { + return makeLink(resolvedPath, target); + } + fs.readlink(target, function (err, targetDest) { + if (err) { + return onError(err); + } + if (dereference) { + targetDest = path.resolve(basePath, targetDest); + } + if (targetDest === resolvedPath) { + return cb(); + } + return rmFile(target, function () { + makeLink(resolvedPath, target); + }); + }); + }); + } + + function makeLink(linkPath, target) { + fs.symlink(linkPath, target, function (err) { + if (err) { + return onError(err); + } + return cb(); + }); + } + + function isWritable(path, done) { + fs.lstat(path, function (err) { + if (err) { + if (err.code === 'ENOENT') return done(true); + return done(false); + } + return done(false); + }); + } + + function onError(err) { + if (options.stopOnError) { + return cback(err); + } + else if (!errs && options.errs) { + errs = fs.createWriteStream(options.errs); + } + else if (!errs) { + errs = []; + } + if (typeof errs.write === 'undefined') { + errs.push(err); + } + else { + errs.write(err.stack + '\n\n'); + } + return cb(); + } + + function cb(skipped) { + if (!skipped) running--; + finished++; + if ((started === finished) && (running === 0)) { + if (cback !== undefined ) { + return errs ? cback(errs) : cback(null); + } + } + } +} + + diff --git a/node_modules/ncp/package.json b/node_modules/ncp/package.json new file mode 100644 index 0000000..af48e69 --- /dev/null +++ b/node_modules/ncp/package.json @@ -0,0 +1,62 @@ +{ + "_from": "ncp@1.0.x", + "_id": "ncp@1.0.1", + "_inBundle": false, + "_integrity": "sha1-0VNn5cuHQyuhF9K/gP30Wuz7QkY=", + "_location": "/ncp", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "ncp@1.0.x", + "name": "ncp", + "escapedName": "ncp", + "rawSpec": "1.0.x", + "saveSpec": null, + "fetchSpec": "1.0.x" + }, + "_requiredBy": [ + "/utile" + ], + "_resolved": "https://registry.npmjs.org/ncp/-/ncp-1.0.1.tgz", + "_shasum": "d15367e5cb87432ba117d2bf80fdf45aecfb4246", + "_spec": "ncp@1.0.x", + "_where": "/data/dev/Projets/Bingoloto Remote/node_modules/utile", + "author": { + "name": "AvianFlu", + "email": "charlie@charlieistheman.com" + }, + "bin": { + "ncp": "bin/ncp" + }, + "bugs": { + "url": "https://github.com/AvianFlu/ncp/issues" + }, + "bundleDependencies": false, + "deprecated": false, + "description": "Asynchronous recursive file copy utility.", + "devDependencies": { + "mocha": "1.15.x", + "read-dir-files": "0.0.x", + "rimraf": "1.0.x" + }, + "engine": { + "node": ">=0.8" + }, + "homepage": "https://github.com/AvianFlu/ncp#readme", + "keywords": [ + "cli", + "copy" + ], + "license": "MIT", + "main": "./lib/ncp.js", + "name": "ncp", + "repository": { + "type": "git", + "url": "git+https://github.com/AvianFlu/ncp.git" + }, + "scripts": { + "test": "mocha -R spec" + }, + "version": "1.0.1" +} diff --git a/node_modules/ncp/test/modified-files/out/a b/node_modules/ncp/test/modified-files/out/a new file mode 100644 index 0000000..29f446a --- /dev/null +++ b/node_modules/ncp/test/modified-files/out/a @@ -0,0 +1 @@ +test3
\ No newline at end of file diff --git a/node_modules/ncp/test/modified-files/src/a b/node_modules/ncp/test/modified-files/src/a new file mode 100644 index 0000000..29f446a --- /dev/null +++ b/node_modules/ncp/test/modified-files/src/a @@ -0,0 +1 @@ +test3
\ No newline at end of file diff --git a/node_modules/ncp/test/ncp.js b/node_modules/ncp/test/ncp.js new file mode 100644 index 0000000..bc6df22 --- /dev/null +++ b/node_modules/ncp/test/ncp.js @@ -0,0 +1,197 @@ + + +var assert = require('assert'), + fs = require('fs'), + path = require('path'), + rimraf = require('rimraf'), + readDirFiles = require('read-dir-files'), + util = require('util'), + ncp = require('../').ncp; + + + +describe('ncp', function () { + describe('regular files and directories', function () { + var fixtures = path.join(__dirname, 'regular-fixtures'), + src = path.join(fixtures, 'src'), + out = path.join(fixtures, 'out'); + + before(function (cb) { + rimraf(out, function() { + ncp(src, out, cb); + }); + }); + + describe('when copying a directory of files', function () { + it('files are copied correctly', function (cb) { + readDirFiles(src, 'utf8', function (srcErr, srcFiles) { + readDirFiles(out, 'utf8', function (outErr, outFiles) { + assert.ifError(srcErr); + assert.deepEqual(srcFiles, outFiles); + cb(); + }); + }); + }); + }); + + describe('when copying files using filter', function () { + before(function (cb) { + var filter = function(name) { + return name.substr(name.length - 1) != 'a'; + }; + rimraf(out, function () { + ncp(src, out, {filter: filter}, cb); + }); + }); + + it('files are copied correctly', function (cb) { + readDirFiles(src, 'utf8', function (srcErr, srcFiles) { + function filter(files) { + for (var fileName in files) { + var curFile = files[fileName]; + if (curFile instanceof Object) + return filter(curFile); + if (fileName.substr(fileName.length - 1) == 'a') + delete files[fileName]; + } + } + filter(srcFiles); + readDirFiles(out, 'utf8', function (outErr, outFiles) { + assert.ifError(outErr); + assert.deepEqual(srcFiles, outFiles); + cb(); + }); + }); + }); + }); + + describe('when using clobber=false', function () { + it('the copy is completed successfully', function (cb) { + ncp(src, out, function() { + ncp(src, out, {clobber: false}, function(err) { + assert.ifError(err); + cb(); + }); + }); + }); + }); + + describe('when using transform', function () { + it('file descriptors are passed correctly', function (cb) { + ncp(src, out, { + transform: function(read,write,file) { + assert.notEqual(file.name, undefined); + assert.strictEqual(typeof file.mode,'number'); + read.pipe(write); + } + }, cb); + }); + }); + + describe('when using rename', function() { + it('output files are correctly redirected', function(cb) { + ncp(src, out, { + rename: function(target) { + if(path.basename(target) == 'a') return path.resolve(path.dirname(target), 'z'); + return target; + } + }, function(err) { + if(err) return cb(err); + + readDirFiles(src, 'utf8', function (srcErr, srcFiles) { + readDirFiles(out, 'utf8', function (outErr, outFiles) { + assert.ifError(srcErr); + assert.deepEqual(srcFiles.a, outFiles.z); + cb(); + }); + }); + }); + }); + }); + }); + + describe('symlink handling', function () { + var fixtures = path.join(__dirname, 'symlink-fixtures'), + src = path.join(fixtures, 'src'), + out = path.join(fixtures, 'out'); + + beforeEach(function (cb) { + rimraf(out, cb); + }); + + it('copies symlinks by default', function (cb) { + ncp(src, out, function (err) { + if (err) return cb(err); + assert.equal(fs.readlinkSync(path.join(out, 'file-symlink')), 'foo'); + assert.equal(fs.readlinkSync(path.join(out, 'dir-symlink')), 'dir'); + cb(); + }) + }); + + it('copies file contents when dereference=true', function (cb) { + ncp(src, out, { dereference: true }, function (err) { + var fileSymlinkPath = path.join(out, 'file-symlink'); + assert.ok(fs.lstatSync(fileSymlinkPath).isFile()); + assert.equal(fs.readFileSync(fileSymlinkPath), 'foo contents'); + + var dirSymlinkPath = path.join(out, 'dir-symlink'); + assert.ok(fs.lstatSync(dirSymlinkPath).isDirectory()); + assert.deepEqual(fs.readdirSync(dirSymlinkPath), ['bar']); + + cb(); + }); + }); + }); + + describe('broken symlink handling', function () { + var fixtures = path.join(__dirname, 'broken-symlink-fixtures'), + src = path.join(fixtures, 'src'), + out = path.join(fixtures, 'out'); + + beforeEach(function (cb) { + rimraf(out, cb); + }); + + it('copies broken symlinks by default', function (cb) { + ncp(src, out, function (err) { + if (err) return cb(err); + assert.equal(fs.readlinkSync(path.join(out, 'broken-symlink')), 'does-not-exist'); + cb(); + }) + }); + + it('returns an error when dereference=true', function (cb) { + ncp(src, out, {dereference: true}, function (err) { + assert.equal(err.length, 1); + assert.equal(err[0].code, 'ENOENT'); + cb(); + }); + }); + }); + + describe('modified files copies', function () { + var fixtures = path.join(__dirname, 'modified-files'), + src = path.join(fixtures, 'src'), + out = path.join(fixtures, 'out'); + + it('if file not exists copy file to target', function(cb) { + rimraf(out, function() { + ncp(src, out, {modified: true, clobber: false}, function (err) { + assert.equal(fs.existsSync(out), true); + cb(); + }); + }); + }); + + it('change source file mtime and copy', function(cb) { + fs.utimesSync(src+"/a", new Date().getTime()/1000, new Date('2015-01-01 00:00:00').getTime()/1000); + ncp(src, out, {modified: true, clobber: false}, function (err) { + fs.stat(out+"/a", function(err, stats) { + assert.equal(stats.mtime.getTime(), new Date('2015-01-01 00:00:00').getTime()); + cb(); + }); + }); + }); + + }); +});
\ No newline at end of file diff --git a/node_modules/ncp/test/regular-fixtures/src/a b/node_modules/ncp/test/regular-fixtures/src/a new file mode 100644 index 0000000..802992c --- /dev/null +++ b/node_modules/ncp/test/regular-fixtures/src/a @@ -0,0 +1 @@ +Hello world diff --git a/node_modules/ncp/test/regular-fixtures/src/b b/node_modules/ncp/test/regular-fixtures/src/b new file mode 100644 index 0000000..9f6bb18 --- /dev/null +++ b/node_modules/ncp/test/regular-fixtures/src/b @@ -0,0 +1 @@ +Hello ncp diff --git a/node_modules/ncp/test/regular-fixtures/src/c b/node_modules/ncp/test/regular-fixtures/src/c new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/node_modules/ncp/test/regular-fixtures/src/c diff --git a/node_modules/ncp/test/regular-fixtures/src/d b/node_modules/ncp/test/regular-fixtures/src/d new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/node_modules/ncp/test/regular-fixtures/src/d diff --git a/node_modules/ncp/test/regular-fixtures/src/e b/node_modules/ncp/test/regular-fixtures/src/e new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/node_modules/ncp/test/regular-fixtures/src/e diff --git a/node_modules/ncp/test/regular-fixtures/src/f b/node_modules/ncp/test/regular-fixtures/src/f new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/node_modules/ncp/test/regular-fixtures/src/f diff --git a/node_modules/ncp/test/regular-fixtures/src/sub/a b/node_modules/ncp/test/regular-fixtures/src/sub/a new file mode 100644 index 0000000..cf291b5 --- /dev/null +++ b/node_modules/ncp/test/regular-fixtures/src/sub/a @@ -0,0 +1 @@ +Hello nodejitsu diff --git a/node_modules/ncp/test/regular-fixtures/src/sub/b b/node_modules/ncp/test/regular-fixtures/src/sub/b new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/node_modules/ncp/test/regular-fixtures/src/sub/b diff --git a/node_modules/ncp/test/symlink-fixtures/src/dir/bar b/node_modules/ncp/test/symlink-fixtures/src/dir/bar new file mode 100644 index 0000000..fd06f5f --- /dev/null +++ b/node_modules/ncp/test/symlink-fixtures/src/dir/bar @@ -0,0 +1 @@ +bar contents
\ No newline at end of file diff --git a/node_modules/ncp/test/symlink-fixtures/src/foo b/node_modules/ncp/test/symlink-fixtures/src/foo new file mode 100644 index 0000000..35fc060 --- /dev/null +++ b/node_modules/ncp/test/symlink-fixtures/src/foo @@ -0,0 +1 @@ +foo contents
\ No newline at end of file |