'use strict'; var through = require('through2'); var log = require('fancy-log'); var exec = require('child_process').exec; var escape = require('any-shell-escape'); var path = require('path'); // want to get the current git hash instead? // git.revParse({args:'--short HEAD'}) module.exports = function(message, opt) { if (!opt) opt = {}; if (!message) { if (opt.args.indexOf('--amend') === -1 && opt.disableMessageRequirement !== true) { throw new Error('gulp-git: Commit message is required git.commit("commit message") or --amend arg must be given'); } } if (!opt.cwd) opt.cwd = process.cwd(); if (!opt.maxBuffer) opt.maxBuffer = 200 * 1024; // Default buffer value for child_process.exec if (!opt.args) opt.args = ' '; var files = []; var paths = []; var write = function(file, enc, cb) { files.push(file); paths.push(path.relative(opt.cwd, file.path).replace('\\', '/') || '.'); cb(); }; var messageEntry = function(entry) { return '-m "' + entry + '" '; }; var flush = function(cb) { var writeStdin = false; var cmd = 'git commit '; // Allow delayed execution to determine the message if (typeof message === 'function') { message = message(); } if (message && opt.args.indexOf('--amend') === -1) { // Check if the message is multiline if (message && message instanceof Array) { if (opt.multiline) { writeStdin = true; message = message.join('\n'); } else { var messageExpanded = ''; // repeat -m as needed for (var i = 0; i < message.length; i++) { messageExpanded += messageEntry(message[i]); } cmd += messageExpanded + opt.args; } if (!opt.disableAppendPaths) { cmd += ' ' + escape(paths); } } else { if (~message.indexOf('\n')) { writeStdin = true; } else { cmd += '-m "' + message + '" ' + opt.args; } if (!opt.disableAppendPaths) { cmd += ' ' + escape(paths); } } } else if (opt.disableMessageRequirement === true) { cmd += opt.args; } else { // When amending, just add the file automatically and do not include the message not the file. // Also, add all the files and avoid lauching the editor (even if --no-editor was added) cmd += '-a ' + opt.args + (opt.args.indexOf('--no-edit') === -1 ? ' --no-edit' : ''); } var self = this; // If `message` was an array and `opt.multiline` was true // or was a string containing newlines, we append '-F -' if (writeStdin) { cmd += ' -F -'; } if (!opt.disableAppendPaths) { cmd += ' .'; } var execChildProcess = exec(cmd, opt, function(err, stdout, stderr) { if (err && (String(stdout).indexOf('no changes added to commit') === 0)) return cb(err); if (!opt.quiet) log(stdout, stderr); files.forEach(self.push.bind(self)); self.emit('end'); return cb(); }); if (writeStdin) { execChildProcess.stdin.write(message); execChildProcess.stdin.end(); } // If the user wants, we'll emit data events during exec // they can listen to them with .on('data',function(data){ }); // in their task if (opt.emitData) { execChildProcess.stdout.on('data', function(data) { self.emit('data', data); }); execChildProcess.stderr.on('data', function(data) { self.emit('data', data); }); } }; return through.obj(write, flush); };