var FileStatusSummary = require('./FileStatusSummary'); module.exports = StatusSummary; /** * The StatusSummary is returned as a response to getting `git().status()` * * @constructor */ function StatusSummary () { this.not_added = []; this.conflicted = []; this.created = []; this.deleted = []; this.modified = []; this.renamed = []; this.files = []; this.staged = []; } /** * Number of commits ahead of the tracked branch * @type {number} */ StatusSummary.prototype.ahead = 0; /** * Number of commits behind the tracked branch * @type {number} */ StatusSummary.prototype.behind = 0; /** * Name of the current branch * @type {null} */ StatusSummary.prototype.current = null; /** * Name of the branch being tracked * @type {string} */ StatusSummary.prototype.tracking = null; /** * All files represented as an array of objects containing the `path` and status in `index` and * in the `working_dir`. * * @type {Array} */ StatusSummary.prototype.files = null; /** * Gets whether this StatusSummary represents a clean working branch. * * @return {boolean} */ StatusSummary.prototype.isClean = function () { return 0 === Object.keys(this).filter(function (name) { return Array.isArray(this[name]) && this[name].length; }, this).length; }; StatusSummary.parsers = { '##': function (line, status) { var aheadReg = /ahead (\d+)/; var behindReg = /behind (\d+)/; var currentReg = /^(.+?(?=(?:\.{3}|\s|$)))/; var trackingReg = /\.{3}(\S*)/; var regexResult; regexResult = aheadReg.exec(line); status.ahead = regexResult && +regexResult[1] || 0; regexResult = behindReg.exec(line); status.behind = regexResult && +regexResult[1] || 0; regexResult = currentReg.exec(line); status.current = regexResult && regexResult[1]; regexResult = trackingReg.exec(line); status.tracking = regexResult && regexResult[1]; }, '??': function (line, status) { status.not_added.push(line); }, A: function (line, status) { status.created.push(line); }, AM: function (line, status) { status.created.push(line); }, D: function (line, status) { status.deleted.push(line); }, M: function (line, status, indexState) { status.modified.push(line); if (indexState === 'M') { status.staged.push(line); } }, R: function (line, status) { var detail = /^(.+) -> (.+)$/.exec(line) || [null, line, line]; status.renamed.push({ from: detail[1], to: detail[2] }); }, UU: function (line, status) { status.conflicted.push(line); } }; StatusSummary.parsers.MM = StatusSummary.parsers.M; /* Map all unmerged status code combinations to UU to mark as conflicted */ StatusSummary.parsers.AA = StatusSummary.parsers.UU; StatusSummary.parsers.UD = StatusSummary.parsers.UU; StatusSummary.parsers.DU = StatusSummary.parsers.UU; StatusSummary.parsers.DD = StatusSummary.parsers.UU; StatusSummary.parsers.AU = StatusSummary.parsers.UU; StatusSummary.parsers.UA = StatusSummary.parsers.UU; StatusSummary.parse = function (text) { var file; var lines = text.trim().split('\n'); var status = new StatusSummary(); for (var i = 0, l = lines.length; i < l; i++) { file = splitLine(lines[i]); if (!file) { continue; } if (file.handler) { file.handler(file.path, status, file.index, file.workingDir); } if (file.code !== '##') { status.files.push(new FileStatusSummary(file.path, file.index, file.workingDir)); } } return status; }; function splitLine (lineStr) { var line = lineStr.trim().match(/(..?)(\s+)(.*)/); if (!line || !line[1].trim()) { line = lineStr.trim().match(/(..?)\s+(.*)/); } if (!line) { return; } var code = line[1]; if (line[2].length > 1) { code += ' '; } if (code.length === 1 && line[2].length === 1) { code = ' ' + code; } return { raw: code, code: code.trim(), index: code.charAt(0), workingDir: code.charAt(1), handler: StatusSummary.parsers[code.trim()], path: line[3] }; }