Implementing rsync or sftp in Node.js to synchronize files?

; Date: 2013-01-01 19:39

Tags: Synchronizing Files »»»» rsync »»»» AkashaCMS »»»» Command Line Tools

How do you accomplish synchronizing a directory tree of files to a server?  For example (akashacms.com) AkashaCMS, my newly developed tool for building static websites, it builds a directory structure containing all the files for the website.  The question I've been pondering for awhile is, what's the best way to get those files over to the web server?  I've been using scp -r, and have also played with using rsync, and just integrated rsync into the AkashaCMS scripts.  But, I'm not seeing a great solution-set available, especially because this needs to run on my girlfriend's computer, and she is a Windows user and therefore does not have rsync available, I need a solution.

Many of the Node modules for sftp are wrappers around Unix command line tools.  Uh, that raises the same problem as the rsync issue, which is that sftp doesn't exist on Windows.  Much as this makes you want to scream at Microsoft, this is the facts of the matter

One that isn't is (github.com) SSH2, a JavaScript implementation of the SSH protocol.  In theory one could implement the synchronization algorithm using that module, and glancing through the API the other day I see it's possible.  But, unfortunately, my first stab at using the module was to configure the sample scripts to attach to my server and do some commands, but it failed to log in.  Perhaps because the SSH implementation on my server is old?  Hopefully we can work out a resolution for the problem.

In the meantime I've done this:-

var user = config.deploy_rsync.user;
var host = config.deploy_rsync.host;
var dir  = config.deploy_rsync.dir;
var rsync = spawn('rsync',
    [ '--verbose', '--archive', '--delete', config.root_out+'/', user+'@'+host+':'+dir+'/' ],
    {env: process.env, stdio: 'inherit'});

This works well enough, and it does seem that there is an (www.rsync.net) rsync available for Windows.

However, the more I think about this - relying on wrapping a command line tool - it seems wrong.  Isn't it cleaner architecturally to implement the protocol in Node.js itself rather than have a dependency on an external tool?  There's more room for software-flake-outs when you're calling a command line tool from a program, right?