var _ = require('underscore') , path = require('path'); var regexp = "(\n?)### begin grunt-svn-ignore(.|\n)*### end grunt-svn-ignore[^\n]*(\n?)"; module.exports = function(grunt) { grunt.registerMultiTask('svn-ignore', "Makes sure the specified source files are ignored in Subversion.", function(){ var done = this.async(); var tasks = _.chain(this.filesSrc) .groupBy(path.dirname) .map(function(files, dir) { return _.partial(updateSvnIgnore, dir, _.chain(files) .map(path.basename) .sortBy(_.identity) .value()); }) .value(); grunt.util.async.series(tasks,function(error, results){ done(error); }); }); grunt.registerMultiTask('svn-ignore-clean', "Clean generated ignore sections in Subversion.", function(){ var done = this.async(); var tasks = _.chain(this.filesSrc) .map(function(file) { return _.partial(clearSvnIgnore, file); }) .value(); grunt.util.async.series(tasks,function(error, results){ done(error); }); }); function updateSvnIgnore(dir,files,callback) { if ( !grunt.file.exists(dir) || !grunt.file.isDir(dir) ) { callback(null); return; } grunt.log.writeln("Updating svn:ignore for '"+dir+"'"); readSvnIgnore(dir, function(error, ignore) { if ( error ) { callback(error); return; } ignore = createIgnore(files, ignore); writeSvnIgnore(dir, ignore, function(error) { callback(error); }); }); } function clearSvnIgnore(dir,callback) { if ( !grunt.file.exists(dir) || !grunt.file.isDir(dir) ) { callback(null); return; } grunt.log.writeln("Cleaning svn:ignore for '"+dir+"'"); readSvnIgnore(dir, function(error, ignore) { if ( error ) { callback(error); return; } ignore = clearIgnore(ignore); if ( /^\s*$/.test(ignore) ) { deleteSvnIgnore(dir, function(error) { callback(error); }); } else { writeSvnIgnore(dir, ignore, function(error) { callback(error); }); } }); } function createIgnore(files, currentIgnore) { // build autoIgnore section var autoIgnore = "### begin grunt-svn-ignore managed ignores\n### edits will be overwritten when grunt svn-ignore is run"; _.each(files, function(file){ autoIgnore += "\n"+file; }); autoIgnore += "\n### end grunt-svn-ignore managed ignores"; // replace iff exists or append var re = new RegExp(regexp); var newIgnore = currentIgnore || ""; if ( re.test(newIgnore) ) { newIgnore = newIgnore.replace(re,"$1"+autoIgnore+"$2"); } else { newIgnore += "\n"+autoIgnore; } return newIgnore; } function clearIgnore(currentIgnore) { // replace iff exists or append var re = new RegExp(regexp); var newIgnore = currentIgnore || ""; newIgnore = newIgnore.replace(re,""); return newIgnore; } function readSvnIgnore(dir,callback) { return svnCommand('svn', ['propget', 'svn:ignore', dir], callback); } function writeSvnIgnore(dir,ignore,callback) { return svnCommand('svn', ['propset', 'svn:ignore', ignore, dir], callback); } function deleteSvnIgnore(dir,callback) { return svnCommand('svn', ['propdel', 'svn:ignore', dir], callback); } function svnCommand(cmd,args,callback) { grunt.util.spawn({ cmd: cmd, args: (args || []) }, function(error, result, code) { if ( error ) { callback(error); return; } callback(null,result.stdout); }); } };