diff --git a/models/workspace.js b/models/workspace.js index 1e9d699a..ae057767 100644 --- a/models/workspace.js +++ b/models/workspace.js @@ -35,6 +35,18 @@ Workspace.getAvailableTemplates = function(cb) { fs.readdir(TEMPLATE_DIR, cb); } +/** + * Recursively copy files. + * API consumers may override this function, e.g. to detect existing files + * and provide conflict resolution. + * @param {String} source + * @param {String} destination + * @param {function(Error=)} cb + */ +Workspace.copyRecursive = function(source, destination, cb) { + ncp(source, destination, cb); +}; + Workspace.addComponent = function(options, cb) { var template; var templateName = options.template || DEFAULT_TEMPLATE; @@ -126,7 +138,7 @@ Workspace.addComponent = function(options, cb) { steps.push(function(cb) { fs.exists(fileTemplatesDir, function(exists) { if(exists) { - ncp(fileTemplatesDir, dest, cb); + Workspace.copyRecursive(fileTemplatesDir, dest, cb); } else { cb(); } diff --git a/test/workspace.js b/test/workspace.js index a54d8f0a..92692359 100644 --- a/test/workspace.js +++ b/test/workspace.js @@ -29,6 +29,26 @@ describe('Workspace', function() { expectFileExists(getPath('rest/rest.js')); expectFileExists(getPath('rest/boot/authentication.js')); }); + + it('should provide a hook for custom of `cp -r`', function(done) { + var calls = []; + var ncp = Workspace.copyRecursive; + Workspace.copyRecursive = function(src, dest, cb) { + calls.push([src, dest]); + process.nextTick(cb); + }; + + Workspace.addComponent( + { + template: 'server' + }, + function(err) { + Workspace.copyRecursive = ncp; + if (err) return done(err); + expect(calls).to.be.not.empty; + done(); + }); + }); }); describe('Workspace.createFromTemplate(templateName, callback)', function() {