Added fs flag to sync to a 2nd local filesystem
This commit is contained in:
parent
2bf6162c00
commit
4e86f469e8
|
@ -1352,6 +1352,7 @@ size: 5 //default 750. File chunk size in Kb.
|
||||||
checksum: false //default 'false'. False will skip files if their size AND modified times are the same (regardless of content difference).
|
checksum: false //default 'false'. False will skip files if their size AND modified times are the same (regardless of content difference).
|
||||||
time: true //default 'false'. Preserves file modified time when syncing.
|
time: true //default 'false'. Preserves file modified time when syncing.
|
||||||
links: true //default 'false'. Copies symlinks as links instead of resolving.
|
links: true //default 'false'. Copies symlinks as links instead of resolving.
|
||||||
|
fs: new Filer.FileSystem() //takes an optional FS reference to sync the changes to. If absent syncs to/from the same FS.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
|
|
72
src/rsync.js
72
src/rsync.js
|
@ -6,6 +6,7 @@ define(function(require) {
|
||||||
var async = require('async');
|
var async = require('async');
|
||||||
var cache = {};
|
var cache = {};
|
||||||
var options;
|
var options;
|
||||||
|
var destFS;
|
||||||
|
|
||||||
//MD5 hashing for RSync
|
//MD5 hashing for RSync
|
||||||
//Used from Node.js Anchor module
|
//Used from Node.js Anchor module
|
||||||
|
@ -150,7 +151,7 @@ define(function(require) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function rsync (srcPath, destPath, opts, callback) {
|
function rsync (srcPath, destPath, opts, callback) {
|
||||||
var self = this;
|
var srcFS = this.fs;
|
||||||
if(typeof opts === 'function') {
|
if(typeof opts === 'function') {
|
||||||
callback = opts;
|
callback = opts;
|
||||||
options = {};
|
options = {};
|
||||||
|
@ -159,6 +160,7 @@ define(function(require) {
|
||||||
options.recursive = false;
|
options.recursive = false;
|
||||||
options.time = false;
|
options.time = false;
|
||||||
options.links = false;
|
options.links = false;
|
||||||
|
destFS = srcFS;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
options = opts || {};
|
options = opts || {};
|
||||||
|
@ -167,6 +169,7 @@ define(function(require) {
|
||||||
options.recursive = options.recursive || false;
|
options.recursive = options.recursive || false;
|
||||||
options.time = options.time || false;
|
options.time = options.time || false;
|
||||||
options.links = options.links || false;
|
options.links = options.links || false;
|
||||||
|
destFS = options.fs || srcFS;
|
||||||
callback = callback || function() {};
|
callback = callback || function() {};
|
||||||
}
|
}
|
||||||
if(srcPath === null || srcPath === '/' || srcPath === '') {
|
if(srcPath === null || srcPath === '/' || srcPath === '') {
|
||||||
|
@ -176,13 +179,13 @@ define(function(require) {
|
||||||
|
|
||||||
function getSrcList(path, callback) {
|
function getSrcList(path, callback) {
|
||||||
var result = [];
|
var result = [];
|
||||||
self.fs.lstat(path, function(err, stats) {
|
srcFS.lstat(path, function(err, stats) {
|
||||||
if(err) {
|
if(err) {
|
||||||
callback(err);
|
callback(err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(stats.isDirectory()) {
|
if(stats.isDirectory()) {
|
||||||
self.fs.readdir(path, function(err, entries) {
|
srcFS.readdir(path, function(err, entries) {
|
||||||
if(err) {
|
if(err) {
|
||||||
callback(err);
|
callback(err);
|
||||||
return;
|
return;
|
||||||
|
@ -190,7 +193,7 @@ define(function(require) {
|
||||||
|
|
||||||
function getSrcContents(_name, callback) {
|
function getSrcContents(_name, callback) {
|
||||||
var name = Path.join(path, _name);
|
var name = Path.join(path, _name);
|
||||||
self.fs.lstat(name, function(error, stats) {
|
srcFS.lstat(name, function(error, stats) {
|
||||||
|
|
||||||
if(error) {
|
if(error) {
|
||||||
callback(error);
|
callback(error);
|
||||||
|
@ -257,12 +260,12 @@ define(function(require) {
|
||||||
});
|
});
|
||||||
} else if(entry.type === 'FILE' || !options.links) {
|
} else if(entry.type === 'FILE' || !options.links) {
|
||||||
if(!options.checksum) {
|
if(!options.checksum) {
|
||||||
self.fs.stat(Path.join(destPath, entry.path), function(err, stat) {
|
destFS.stat(Path.join(destPath, entry.path), function(err, stat) {
|
||||||
if(!err && stat.mtime === entry.modified && stat.size === entry.size) {
|
if(!err && stat.mtime === entry.modified && stat.size === entry.size) {
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
checksum.call(self, Path.join(destPath, entry.path), function(err, checksums) {
|
checksum.call(destFS, Path.join(destPath, entry.path), function(err, checksums) {
|
||||||
if(err) {
|
if(err) {
|
||||||
callback(err);
|
callback(err);
|
||||||
return;
|
return;
|
||||||
|
@ -276,7 +279,7 @@ define(function(require) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
checksum.call(self, Path.join(destPath, entry.path), function(err, checksums) {
|
checksum.call(destFS, Path.join(destPath, entry.path), function(err, checksums) {
|
||||||
if(err) {
|
if(err) {
|
||||||
callback(err);
|
callback(err);
|
||||||
return;
|
return;
|
||||||
|
@ -290,7 +293,7 @@ define(function(require) {
|
||||||
}
|
}
|
||||||
else if(entry.type === 'SYMLINK'){
|
else if(entry.type === 'SYMLINK'){
|
||||||
if(!options.checksum) {
|
if(!options.checksum) {
|
||||||
self.fs.stat(Path.join(destPath, entry.path), function(err, stat){
|
destFS.stat(Path.join(destPath, entry.path), function(err, stat){
|
||||||
if(!err && stat.mtime === entry.modified && stat.size === entry.size) {
|
if(!err && stat.mtime === entry.modified && stat.size === entry.size) {
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
|
@ -317,7 +320,7 @@ define(function(require) {
|
||||||
callback(err);
|
callback(err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
self.mkdirp(destPath, function(err) {
|
destFS.Shell().mkdirp(destPath, function(err) {
|
||||||
getChecksums(destPath, result, function(err, result) {
|
getChecksums(destPath, result, function(err, result) {
|
||||||
if(err) {
|
if(err) {
|
||||||
callback(err);
|
callback(err);
|
||||||
|
@ -327,13 +330,15 @@ define(function(require) {
|
||||||
callback();
|
callback();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
diff.call(self, srcPath, result, function(err, diffs) {
|
diff.call(srcFS, srcPath, result, function(err, diffs) {
|
||||||
if(err) {
|
if(err) {
|
||||||
callback(err);
|
callback(err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sync.call(self, destPath, diffs, function(err) {
|
destFS.readdir('/', function(err, stuff){
|
||||||
callback(err);
|
sync(destPath, diffs, function(err) {
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -349,8 +354,8 @@ define(function(require) {
|
||||||
* MIT Licensed
|
* MIT Licensed
|
||||||
*/
|
*/
|
||||||
function checksum (path, callback) {
|
function checksum (path, callback) {
|
||||||
var self = this;
|
//var destFS = this;
|
||||||
self.fs.readFile(path, function (err, data) {
|
destFS.readFile(path, function (err, data) {
|
||||||
if (!err) {
|
if (!err) {
|
||||||
// cache file
|
// cache file
|
||||||
cache[path] = data;
|
cache[path] = data;
|
||||||
|
@ -394,17 +399,17 @@ define(function(require) {
|
||||||
* MIT Licensed
|
* MIT Licensed
|
||||||
*/
|
*/
|
||||||
function diff(path, checksums, callback) {
|
function diff(path, checksums, callback) {
|
||||||
var self = this;
|
var srcFS = this;
|
||||||
// roll through the file
|
// roll through the file
|
||||||
var diffs = [];
|
var diffs = [];
|
||||||
self.fs.lstat(path, function(err, stat) {
|
srcFS.lstat(path, function(err, stat) {
|
||||||
if(stat.isDirectory()) {
|
if(stat.isDirectory()) {
|
||||||
async.each(checksums, getDiff, function(err) {
|
async.each(checksums, getDiff, function(err) {
|
||||||
callback(err, diffs);
|
callback(err, diffs);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (stat.isFile() || !options.links) {
|
else if (stat.isFile() || !options.links) {
|
||||||
self.fs.readFile(path, function (err, data) {
|
srcFS.readFile(path, function (err, data) {
|
||||||
if (err) { return callback(err); }
|
if (err) { return callback(err); }
|
||||||
diffs.push({
|
diffs.push({
|
||||||
diff: roll(data, checksums[0].checksum, options.size),
|
diff: roll(data, checksums[0].checksum, options.size),
|
||||||
|
@ -415,12 +420,12 @@ define(function(require) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (stat.isSymbolicLink()) {
|
else if (stat.isSymbolicLink()) {
|
||||||
self.fs.readlink(path, function(err, linkContents) {
|
srcFS.readlink(path, function(err, linkContents) {
|
||||||
if(err) {
|
if(err) {
|
||||||
callback(err);
|
callback(err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
self.fs.lstat(path, function(err, stats){
|
srcFS.lstat(path, function(err, stats){
|
||||||
if(err) {
|
if(err) {
|
||||||
callback(err);
|
callback(err);
|
||||||
return;
|
return;
|
||||||
|
@ -438,7 +443,7 @@ define(function(require) {
|
||||||
|
|
||||||
function getDiff(entry, callback) {
|
function getDiff(entry, callback) {
|
||||||
if(entry.hasOwnProperty('contents')) {
|
if(entry.hasOwnProperty('contents')) {
|
||||||
diff.call(self, Path.join(path, entry.path), entry.contents, function(err, stuff) {
|
diff.call(srcFS, Path.join(path, entry.path), entry.contents, function(err, stuff) {
|
||||||
if(err) {
|
if(err) {
|
||||||
callback(err);
|
callback(err);
|
||||||
return;
|
return;
|
||||||
|
@ -469,7 +474,7 @@ define(function(require) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
self.fs.readFile(Path.join(path,entry.path), function (err, data) {
|
srcFS.readFile(Path.join(path,entry.path), function (err, data) {
|
||||||
if (err) { return callback(err); }
|
if (err) { return callback(err); }
|
||||||
diffs.push({
|
diffs.push({
|
||||||
diff: roll(data, entry.checksum, options.size),
|
diff: roll(data, entry.checksum, options.size),
|
||||||
|
@ -490,8 +495,6 @@ define(function(require) {
|
||||||
* MIT Licensed
|
* MIT Licensed
|
||||||
*/
|
*/
|
||||||
function sync(path, diff, callback) {
|
function sync(path, diff, callback) {
|
||||||
var self = this;
|
|
||||||
|
|
||||||
function syncEach(entry, callback) {
|
function syncEach(entry, callback) {
|
||||||
|
|
||||||
//get slice of raw file from block's index
|
//get slice of raw file from block's index
|
||||||
|
@ -500,9 +503,8 @@ define(function(require) {
|
||||||
var end = start + options.size > raw.length ? raw.length : start + options.size;
|
var end = start + options.size > raw.length ? raw.length : start + options.size;
|
||||||
return raw.subarray(start, end);
|
return raw.subarray(start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(entry.hasOwnProperty('contents')) {
|
if(entry.hasOwnProperty('contents')) {
|
||||||
sync.call(self, Path.join(path, entry.path), entry.contents, function(err) {
|
sync(Path.join(path, entry.path), entry.contents, function(err) {
|
||||||
if(err) {
|
if(err) {
|
||||||
callback(err);
|
callback(err);
|
||||||
return;
|
return;
|
||||||
|
@ -511,9 +513,8 @@ define(function(require) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (entry.hasOwnProperty('link')) {
|
else if (entry.hasOwnProperty('link')) {
|
||||||
|
|
||||||
var syncPath = Path.join(path,entry.path);
|
var syncPath = Path.join(path,entry.path);
|
||||||
self.fs.symlink(entry.link, syncPath, function(err){
|
destFS.symlink(entry.link, syncPath, function(err){
|
||||||
if(err) {
|
if(err) {
|
||||||
callback(err);
|
callback(err);
|
||||||
return;
|
return;
|
||||||
|
@ -541,13 +542,13 @@ define(function(require) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete cache[Path.join(path,entry.path)];
|
delete cache[Path.join(path,entry.path)];
|
||||||
self.fs.writeFile(Path.join(path,entry.path), buf, function(err) {
|
destFS.writeFile(Path.join(path,entry.path), buf, function(err) {
|
||||||
if(err) {
|
if(err) {
|
||||||
callback(err);
|
callback(err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(options.time) {
|
if(options.time) {
|
||||||
self.fs.utimes(Path.join(path,entry.path), entry.modified, entry.modified, function(err) {
|
destFS.utimes(Path.join(path,entry.path), entry.modified, entry.modified, function(err) {
|
||||||
if(err) {
|
if(err) {
|
||||||
callback(err);
|
callback(err);
|
||||||
return;
|
return;
|
||||||
|
@ -562,10 +563,15 @@ define(function(require) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
destFS.mkdir(path, function(err){
|
||||||
async.each(diff, syncEach, function(err) {
|
if(err && err.code != "EEXIST"){
|
||||||
callback(err);
|
callback(err);
|
||||||
});
|
return;
|
||||||
|
}
|
||||||
|
async.each(diff, syncEach, function(err) {
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function appendBuffer( buffer1, buffer2 ) {
|
function appendBuffer( buffer1, buffer2 ) {
|
||||||
|
|
Loading…
Reference in New Issue