Showing the changes to node_modules/simple-git/src/responses (13 of 41 files). Show all
Unified · Split
| @@ -0,0 +1,26 @@ | ||
| 1 | + | |
| 2 | +module.exports = BranchDeletion; | |
| 3 | + | |
| 4 | +function BranchDeletion (branch, hash) { | |
| 5 | + this.branch = branch; | |
| 6 | + this.hash = hash; | |
| 7 | + this.success = hash !== null; | |
| 8 | +} | |
| 9 | + | |
| 10 | +BranchDeletion.deleteSuccessRegex = /(\S+)\s+\(\S+\s([^\)]+)\)/; | |
| 11 | +BranchDeletion.deleteErrorRegex = /^error[^']+'([^']+)'/; | |
| 12 | + | |
| 13 | +BranchDeletion.parse = function (data, asArray) { | |
| 14 | + var result; | |
| 15 | + var branchDeletions = data.trim().split('\n').map(function (line) { | |
| 16 | + if (result = BranchDeletion.deleteSuccessRegex.exec(line)) { | |
| 17 | + return new BranchDeletion(result[1], result[2]); | |
| 18 | + } | |
| 19 | + else if (result = BranchDeletion.deleteErrorRegex.exec(line)) { | |
| 20 | + return new BranchDeletion(result[1], null); | |
| 21 | + } | |
| 22 | + }) | |
| 23 | + .filter(Boolean); | |
| 24 | + | |
| 25 | + return asArray ? branchDeletions : branchDeletions.pop(); | |
| 26 | +}; | |
| @@ -0,0 +1,52 @@ | ||
| 1 | + | |
| 2 | +module.exports = BranchSummary; | |
| 3 | + | |
| 4 | +function BranchSummary () { | |
| 5 | + this.detached = false; | |
| 6 | + this.current = ''; | |
| 7 | + this.all = []; | |
| 8 | + this.branches = {}; | |
| 9 | +} | |
| 10 | + | |
| 11 | +BranchSummary.prototype.push = function (current, detached, name, commit, label) { | |
| 12 | + if (current) { | |
| 13 | + this.detached = detached; | |
| 14 | + this.current = name; | |
| 15 | + } | |
| 16 | + this.all.push(name); | |
| 17 | + this.branches[name] = { | |
| 18 | + current: current, | |
| 19 | + name: name, | |
| 20 | + commit: commit, | |
| 21 | + label: label | |
| 22 | + }; | |
| 23 | +}; | |
| 24 | + | |
| 25 | +BranchSummary.detachedRegex = /^(\*?\s+)\((?:HEAD )?detached (?:from|at) (\S+)\)\s+([a-z0-9]+)\s(.*)$/; | |
| 26 | +BranchSummary.branchRegex = /^(\*?\s+)(\S+)\s+([a-z0-9]+)\s(.*)$/; | |
| 27 | + | |
| 28 | +BranchSummary.parse = function (commit) { | |
| 29 | + var branchSummary = new BranchSummary(); | |
| 30 | + | |
| 31 | + commit.split('\n') | |
| 32 | + .forEach(function (line) { | |
| 33 | + var detached = true; | |
| 34 | + var branch = BranchSummary.detachedRegex.exec(line); | |
| 35 | + if (!branch) { | |
| 36 | + detached = false; | |
| 37 | + branch = BranchSummary.branchRegex.exec(line); | |
| 38 | + } | |
| 39 | + | |
| 40 | + if (branch) { | |
| 41 | + branchSummary.push( | |
| 42 | + branch[1].charAt(0) === '*', | |
| 43 | + detached, | |
| 44 | + branch[2], | |
| 45 | + branch[3], | |
| 46 | + branch[4] | |
| 47 | + ); | |
| 48 | + } | |
| 49 | + }); | |
| 50 | + | |
| 51 | + return branchSummary; | |
| 52 | +}; | |
| @@ -0,0 +1,60 @@ | ||
| 1 | + | |
| 2 | +module.exports = CommitSummary; | |
| 3 | + | |
| 4 | +function CommitSummary () { | |
| 5 | + this.branch = ''; | |
| 6 | + this.commit = ''; | |
| 7 | + this.summary = { | |
| 8 | + changes: 0, | |
| 9 | + insertions: 0, | |
| 10 | + deletions: 0 | |
| 11 | + }; | |
| 12 | + this.author = null; | |
| 13 | +} | |
| 14 | + | |
| 15 | +var COMMIT_BRANCH_MESSAGE_REGEX = /\[([^\s]+) ([^\]]+)/; | |
| 16 | +var COMMIT_AUTHOR_MESSAGE_REGEX = /\s*Author:\s(.+)/i; | |
| 17 | + | |
| 18 | +function setBranchFromCommit (commitSummary, commitData) { | |
| 19 | + if (commitData) { | |
| 20 | + commitSummary.branch = commitData[1]; | |
| 21 | + commitSummary.commit = commitData[2]; | |
| 22 | + } | |
| 23 | +} | |
| 24 | + | |
| 25 | +function setSummaryFromCommit (commitSummary, commitData) { | |
| 26 | + if (commitSummary.branch && commitData) { | |
| 27 | + commitSummary.summary.changes = commitData[1] || 0; | |
| 28 | + commitSummary.summary.insertions = commitData[2] || 0; | |
| 29 | + commitSummary.summary.deletions = commitData[3] || 0; | |
| 30 | + } | |
| 31 | +} | |
| 32 | + | |
| 33 | +function setAuthorFromCommit (commitSummary, commitData) { | |
| 34 | + var parts = commitData[1].split('<'); | |
| 35 | + var email = parts.pop(); | |
| 36 | + | |
| 37 | + if (email.indexOf('@') <= 0) { | |
| 38 | + return; | |
| 39 | + } | |
| 40 | + | |
| 41 | + commitSummary.author = { | |
| 42 | + email: email.substr(0, email.length - 1), | |
| 43 | + name: parts.join('<').trim() | |
| 44 | + }; | |
| 45 | +} | |
| 46 | + | |
| 47 | +CommitSummary.parse = function (commit) { | |
| 48 | + var lines = commit.trim().split('\n'); | |
| 49 | + var commitSummary = new CommitSummary(); | |
| 50 | + | |
| 51 | + setBranchFromCommit(commitSummary, COMMIT_BRANCH_MESSAGE_REGEX.exec(lines.shift())); | |
| 52 | + | |
| 53 | + if (COMMIT_AUTHOR_MESSAGE_REGEX.test(lines[0])) { | |
| 54 | + setAuthorFromCommit(commitSummary, COMMIT_AUTHOR_MESSAGE_REGEX.exec(lines.shift())); | |
| 55 | + } | |
| 56 | + | |
| 57 | + setSummaryFromCommit(commitSummary, /(\d+)[^,]*(?:,\s*(\d+)[^,]*)?(?:,\s*(\d+))?/g.exec(lines.shift())); | |
| 58 | + | |
| 59 | + return commitSummary; | |
| 60 | +}; | |
| @@ -0,0 +1,92 @@ | ||
| 1 | + | |
| 2 | +module.exports = DiffSummary; | |
| 3 | + | |
| 4 | +/** | |
| 5 | + * The DiffSummary is returned as a response to getting `git().status()` | |
| 6 | + * | |
| 7 | + * @constructor | |
| 8 | + */ | |
| 9 | +function DiffSummary () { | |
| 10 | + this.files = []; | |
| 11 | + this.insertions = 0; | |
| 12 | + this.deletions = 0; | |
| 13 | + this.changed = 0; | |
| 14 | +} | |
| 15 | + | |
| 16 | +/** | |
| 17 | + * Number of lines added | |
| 18 | + * @type {number} | |
| 19 | + */ | |
| 20 | +DiffSummary.prototype.insertions = 0; | |
| 21 | + | |
| 22 | +/** | |
| 23 | + * Number of lines deleted | |
| 24 | + * @type {number} | |
| 25 | + */ | |
| 26 | +DiffSummary.prototype.deletions = 0; | |
| 27 | + | |
| 28 | +/** | |
| 29 | + * Number of files changed | |
| 30 | + * @type {number} | |
| 31 | + */ | |
| 32 | +DiffSummary.prototype.changed = 0; | |
| 33 | + | |
| 34 | +DiffSummary.parse = function (text) { | |
| 35 | + var line, handler; | |
| 36 | + | |
| 37 | + var lines = text.trim().split('\n'); | |
| 38 | + var status = new DiffSummary(); | |
| 39 | + | |
| 40 | + var summary = lines.pop(); | |
| 41 | + if (summary) { | |
| 42 | + summary.trim().split(', ').forEach(function (text) { | |
| 43 | + var summary = /(\d+)\s([a-z]+)/.exec(text); | |
| 44 | + if (!summary) { | |
| 45 | + return; | |
| 46 | + } | |
| 47 | + | |
| 48 | + if (/files?/.test(summary[2])) { | |
| 49 | + status.changed = parseInt(summary[1], 10); | |
| 50 | + } | |
| 51 | + else { | |
| 52 | + status[summary[2].replace(/s$/, '') + 's'] = parseInt(summary[1], 10); | |
| 53 | + } | |
| 54 | + }); | |
| 55 | + } | |
| 56 | + | |
| 57 | + while (line = lines.shift()) { | |
| 58 | + textFileChange(line, status.files) || binaryFileChange(line, status.files); | |
| 59 | + } | |
| 60 | + | |
| 61 | + return status; | |
| 62 | +}; | |
| 63 | + | |
| 64 | +function textFileChange (line, files) { | |
| 65 | + line = line.trim().match(/^(.+)\s+\|\s+(\d+)(\s+[+\-]+)?$/); | |
| 66 | + | |
| 67 | + if (line) { | |
| 68 | + var alterations = (line[3] || '').trim(); | |
| 69 | + files.push({ | |
| 70 | + file: line[1].trim(), | |
| 71 | + changes: parseInt(line[2], 10), | |
| 72 | + insertions: alterations.replace(/-/g, '').length, | |
| 73 | + deletions: alterations.replace(/\+/g, '').length, | |
| 74 | + binary: false | |
| 75 | + }); | |
| 76 | + | |
| 77 | + return true; | |
| 78 | + } | |
| 79 | +} | |
| 80 | + | |
| 81 | +function binaryFileChange (line, files) { | |
| 82 | + line = line.match(/^(.+) \|\s+Bin ([0-9.]+) -> ([0-9.]+) ([a-z]+)$/); | |
| 83 | + if (line) { | |
| 84 | + files.push({ | |
| 85 | + file: line[1].trim(), | |
| 86 | + before: +line[2], | |
| 87 | + after: +line[3], | |
| 88 | + binary: true | |
| 89 | + }); | |
| 90 | + return true; | |
| 91 | + } | |
| 92 | +} | |
| @@ -0,0 +1,55 @@ | ||
| 1 | +'use strict'; | |
| 2 | + | |
| 3 | +function FetchSummary (raw) { | |
| 4 | + this.raw = raw; | |
| 5 | + | |
| 6 | + this.remote = null; | |
| 7 | + this.branches = []; | |
| 8 | + this.tags = []; | |
| 9 | +} | |
| 10 | + | |
| 11 | +FetchSummary.parsers = [ | |
| 12 | + [ | |
| 13 | + /From (.+)$/, function (fetchSummary, matches) { | |
| 14 | + fetchSummary.remote = matches[0]; | |
| 15 | + } | |
| 16 | + ], | |
| 17 | + [ | |
| 18 | + /\* \[new branch\]\s+(\S+)\s*\-> (.+)$/, function (fetchSummary, matches) { | |
| 19 | + fetchSummary.branches.push({ | |
| 20 | + name: matches[0], | |
| 21 | + tracking: matches[1] | |
| 22 | + }); | |
| 23 | + } | |
| 24 | + ], | |
| 25 | + [ | |
| 26 | + /\* \[new tag\]\s+(\S+)\s*\-> (.+)$/, function (fetchSummary, matches) { | |
| 27 | + fetchSummary.tags.push({ | |
| 28 | + name: matches[0], | |
| 29 | + tracking: matches[1] | |
| 30 | + }); | |
| 31 | + } | |
| 32 | + ] | |
| 33 | +]; | |
| 34 | + | |
| 35 | +FetchSummary.parse = function (data) { | |
| 36 | + var fetchSummary = new FetchSummary(data); | |
| 37 | + | |
| 38 | + String(data) | |
| 39 | + .trim() | |
| 40 | + .split('\n') | |
| 41 | + .forEach(function (line) { | |
| 42 | + var original = line.trim(); | |
| 43 | + FetchSummary.parsers.some(function (parser) { | |
| 44 | + var parsed = parser[0].exec(original); | |
| 45 | + if (parsed) { | |
| 46 | + parser[1](fetchSummary, parsed.slice(1)); | |
| 47 | + return true; | |
| 48 | + } | |
| 49 | + }); | |
| 50 | + }); | |
| 51 | + | |
| 52 | + return fetchSummary; | |
| 53 | +}; | |
| 54 | + | |
| 55 | +module.exports = FetchSummary; | |
| @@ -0,0 +1,22 @@ | ||
| 1 | +'use strict'; | |
| 2 | + | |
| 3 | +function FileStatusSummary (path, index, working_dir) { | |
| 4 | + this.path = path; | |
| 5 | + this.index = index; | |
| 6 | + this.working_dir = working_dir; | |
| 7 | + | |
| 8 | + if ('R' === index + working_dir) { | |
| 9 | + var detail = FileStatusSummary.fromPathRegex.exec(path) || [null, path, path]; | |
| 10 | + this.from = detail[1]; | |
| 11 | + this.path = detail[2]; | |
| 12 | + } | |
| 13 | +} | |
| 14 | + | |
| 15 | +FileStatusSummary.fromPathRegex = /^(.+) -> (.+)$/; | |
| 16 | + | |
| 17 | +FileStatusSummary.prototype = { | |
| 18 | + path: '', | |
| 19 | + from: '' | |
| 20 | +}; | |
| 21 | + | |
| 22 | +module.exports = FileStatusSummary; | |
| @@ -0,0 +1,72 @@ | ||
| 1 | + | |
| 2 | +module.exports = ListLogSummary; | |
| 3 | + | |
| 4 | +var DiffSummary = require('./DiffSummary'); | |
| 5 | + | |
| 6 | +/** | |
| 7 | + * The ListLogSummary is returned as a response to getting `git().log()` or `git().stashList()` | |
| 8 | + * | |
| 9 | + * @constructor | |
| 10 | + */ | |
| 11 | +function ListLogSummary (all) { | |
| 12 | + this.all = all; | |
| 13 | + this.latest = all.length && all[0] || null; | |
| 14 | + this.total = all.length; | |
| 15 | +} | |
| 16 | + | |
| 17 | +/** | |
| 18 | + * Detail for each of the log lines | |
| 19 | + * @type {ListLogLine[]} | |
| 20 | + */ | |
| 21 | +ListLogSummary.prototype.all = null; | |
| 22 | + | |
| 23 | +/** | |
| 24 | + * Most recent entry in the log | |
| 25 | + * @type {ListLogLine} | |
| 26 | + */ | |
| 27 | +ListLogSummary.prototype.latest = null; | |
| 28 | + | |
| 29 | +/** | |
| 30 | + * Number of items in the log | |
| 31 | + * @type {number} | |
| 32 | + */ | |
| 33 | +ListLogSummary.prototype.total = 0; | |
| 34 | + | |
| 35 | +function ListLogLine (line, fields) { | |
| 36 | + for (var k = 0; k < fields.length; k++) { | |
| 37 | + this[fields[k]] = line[k] || ''; | |
| 38 | + } | |
| 39 | +} | |
| 40 | + | |
| 41 | +/** | |
| 42 | + * When the log was generated with a summary, the `diff` property contains as much detail | |
| 43 | + * as was provided in the log (whether generated with `--stat` or `--shortstat`. | |
| 44 | + * @type {DiffSummary} | |
| 45 | + */ | |
| 46 | +ListLogLine.prototype.diff = null; | |
| 47 | + | |
| 48 | +ListLogSummary.START_BOUNDARY = 'òòòòòò '; | |
| 49 | + | |
| 50 | +ListLogSummary.COMMIT_BOUNDARY = ' òò'; | |
| 51 | + | |
| 52 | +ListLogSummary.SPLITTER = ' ò '; | |
| 53 | + | |
| 54 | +ListLogSummary.parse = function (text, splitter, fields) { | |
| 55 | + fields = fields || ['hash', 'date', 'message', 'refs', 'author_name', 'author_email']; | |
| 56 | + return new ListLogSummary( | |
| 57 | + text | |
| 58 | + .trim() | |
| 59 | + .split(ListLogSummary.START_BOUNDARY) | |
| 60 | + .filter(function(item) { return !!item.trim(); }) | |
| 61 | + .map(function (item) { | |
| 62 | + var lineDetail = item.trim().split(ListLogSummary.COMMIT_BOUNDARY); | |
| 63 | + var listLogLine = new ListLogLine(lineDetail[0].trim().split(splitter), fields); | |
| 64 | + | |
| 65 | + if (lineDetail.length > 1 && !!lineDetail[1].trim()) { | |
| 66 | + listLogLine.diff = DiffSummary.parse(lineDetail[1]); | |
| 67 | + } | |
| 68 | + | |
| 69 | + return listLogLine; | |
| 70 | + }) | |
| 71 | + ); | |
| 72 | +}; | |
| @@ -0,0 +1,103 @@ | ||
| 1 | +module.exports = MergeSummary; | |
| 2 | +module.exports.MergeConflict = MergeConflict; | |
| 3 | + | |
| 4 | +var PullSummary = require('./PullSummary'); | |
| 5 | + | |
| 6 | +function MergeConflict (reason, file, meta) { | |
| 7 | + this.reason = reason; | |
| 8 | + this.file = file; | |
| 9 | + if (meta) { | |
| 10 | + this.meta = meta; | |
| 11 | + } | |
| 12 | +} | |
| 13 | + | |
| 14 | +MergeConflict.prototype.meta = null; | |
| 15 | + | |
| 16 | +MergeConflict.prototype.toString = function () { | |
| 17 | + return this.file + ':' + this.reason; | |
| 18 | +}; | |
| 19 | + | |
| 20 | +function MergeSummary () { | |
| 21 | + PullSummary.call(this); | |
| 22 | + | |
| 23 | + this.conflicts = []; | |
| 24 | + this.merges = []; | |
| 25 | +} | |
| 26 | + | |
| 27 | +MergeSummary.prototype = Object.create(PullSummary.prototype); | |
| 28 | + | |
| 29 | +MergeSummary.prototype.result = 'success'; | |
| 30 | + | |
| 31 | +MergeSummary.prototype.toString = function () { | |
| 32 | + if (this.conflicts.length) { | |
| 33 | + return 'CONFLICTS: ' + this.conflicts.join(', '); | |
| 34 | + } | |
| 35 | + return 'OK'; | |
| 36 | +}; | |
| 37 | + | |
| 38 | +Object.defineProperty(MergeSummary.prototype, 'failed', { | |
| 39 | + get: function () { | |
| 40 | + return this.conflicts.length > 0; | |
| 41 | + } | |
| 42 | +}); | |
| 43 | + | |
| 44 | +MergeSummary.parsers = [ | |
| 45 | + { | |
| 46 | + test: /^Auto-merging\s+(.+)$/, | |
| 47 | + handle: function (result, mergeSummary) { | |
| 48 | + mergeSummary.merges.push(result[1]); | |
| 49 | + } | |
| 50 | + }, | |
| 51 | + { | |
| 52 | + // Parser for standard merge conflicts | |
| 53 | + test: /^CONFLICT\s+\((.+)\): Merge conflict in (.+)$/, | |
| 54 | + handle: function (result, mergeSummary) { | |
| 55 | + mergeSummary.conflicts.push(new MergeConflict(result[1], result[2])); | |
| 56 | + } | |
| 57 | + }, | |
| 58 | + { | |
| 59 | + // Parser for modify/delete merge conflicts (modified by us/them, deleted by them/us) | |
| 60 | + test: /^CONFLICT\s+\((.+\/delete)\): (.+) deleted in (.+) and/, | |
| 61 | + handle: function (result, mergeSummary) { | |
| 62 | + mergeSummary.conflicts.push( | |
| 63 | + new MergeConflict(result[1], result[2], {deleteRef: result[3]}) | |
| 64 | + ); | |
| 65 | + } | |
| 66 | + }, | |
| 67 | + { | |
| 68 | + // Catch-all parser for unknown/unparsed conflicts | |
| 69 | + test: /^CONFLICT\s+\((.+)\):/, | |
| 70 | + handle: function (result, mergeSummary) { | |
| 71 | + mergeSummary.conflicts.push(new MergeConflict(result[1], null)); | |
| 72 | + } | |
| 73 | + }, | |
| 74 | + { | |
| 75 | + test: /^Automatic merge failed;\s+(.+)$/, | |
| 76 | + handle: function (result, mergeSummary) { | |
| 77 | + mergeSummary.reason = mergeSummary.result = result[1]; | |
| 78 | + } | |
| 79 | + } | |
| 80 | +]; | |
| 81 | + | |
| 82 | +MergeSummary.parse = function (output) { | |
| 83 | + let mergeSummary = new MergeSummary(); | |
| 84 | + | |
| 85 | + output.trim().split('\n').forEach(function (line) { | |
| 86 | + for (var i = 0, iMax = MergeSummary.parsers.length; i < iMax; i++) { | |
| 87 | + let parser = MergeSummary.parsers[i]; | |
| 88 | + | |
| 89 | + var result = parser.test.exec(line); | |
| 90 | + if (result) { | |
| 91 | + parser.handle(result, mergeSummary); | |
| 92 | + break; | |
| 93 | + } | |
| 94 | + } | |
| 95 | + }); | |
| 96 | + | |
| 97 | + let pullSummary = PullSummary.parse(output); | |
| 98 | + if (pullSummary.summary.changes) { | |
| 99 | + Object.assign(mergeSummary, pullSummary); | |
| 100 | + } | |
| 101 | + | |
| 102 | + return mergeSummary; | |
| 103 | +}; | |
| @@ -0,0 +1,32 @@ | ||
| 1 | + | |
| 2 | +module.exports = MoveSummary; | |
| 3 | + | |
| 4 | +/** | |
| 5 | + * The MoveSummary is returned as a response to getting `git().status()` | |
| 6 | + * | |
| 7 | + * @constructor | |
| 8 | + */ | |
| 9 | +function MoveSummary () { | |
| 10 | + this.moves = []; | |
| 11 | + this.sources = {}; | |
| 12 | +} | |
| 13 | + | |
| 14 | +MoveSummary.SUMMARY_REGEX = /^Renaming (.+) to (.+)$/; | |
| 15 | + | |
| 16 | +MoveSummary.parse = function (text) { | |
| 17 | + var lines = text.split('\n'); | |
| 18 | + var summary = new MoveSummary(); | |
| 19 | + | |
| 20 | + for (var i = 0, iMax = lines.length, line; i < iMax; i++) { | |
| 21 | + line = MoveSummary.SUMMARY_REGEX.exec(lines[i].trim()); | |
| 22 | + | |
| 23 | + if (line) { | |
| 24 | + summary.moves.push({ | |
| 25 | + from: line[1], | |
| 26 | + to: line[2] | |
| 27 | + }); | |
| 28 | + } | |
| 29 | + } | |
| 30 | + | |
| 31 | + return summary; | |
| 32 | +}; | |
| @@ -0,0 +1,137 @@ | ||
| 1 | + | |
| 2 | +module.exports = PullSummary; | |
| 3 | + | |
| 4 | +/** | |
| 5 | + * The PullSummary is returned as a response to getting `git().pull()` | |
| 6 | + * | |
| 7 | + * @constructor | |
| 8 | + */ | |
| 9 | +function PullSummary () { | |
| 10 | + this.files = []; | |
| 11 | + this.insertions = {}; | |
| 12 | + this.deletions = {}; | |
| 13 | + | |
| 14 | + this.summary = { | |
| 15 | + changes: 0, | |
| 16 | + insertions: 0, | |
| 17 | + deletions: 0 | |
| 18 | + }; | |
| 19 | + | |
| 20 | + this.created = []; | |
| 21 | + this.deleted = []; | |
| 22 | +} | |
| 23 | + | |
| 24 | +/** | |
| 25 | + * Array of files that were created | |
| 26 | + * @type {string[]} | |
| 27 | + */ | |
| 28 | +PullSummary.prototype.created = null; | |
| 29 | + | |
| 30 | +/** | |
| 31 | + * Array of files that were deleted | |
| 32 | + * @type {string[]} | |
| 33 | + */ | |
| 34 | +PullSummary.prototype.deleted = null; | |
| 35 | + | |
| 36 | +/** | |
| 37 | + * The array of file paths/names that have been modified in any part of the pulled content | |
| 38 | + * @type {string[]} | |
| 39 | + */ | |
| 40 | +PullSummary.prototype.files = null; | |
| 41 | + | |
| 42 | +/** | |
| 43 | + * A map of file path to number to show the number of insertions per file. | |
| 44 | + * @type {Object} | |
| 45 | + */ | |
| 46 | +PullSummary.prototype.insertions = null; | |
| 47 | + | |
| 48 | +/** | |
| 49 | + * A map of file path to number to show the number of deletions per file. | |
| 50 | + * @type {Object} | |
| 51 | + */ | |
| 52 | +PullSummary.prototype.deletions = null; | |
| 53 | + | |
| 54 | +/** | |
| 55 | + * Overall summary of changes/insertions/deletions and the number associated with each | |
| 56 | + * across all content that was pulled. | |
| 57 | + * @type {Object} | |
| 58 | + */ | |
| 59 | +PullSummary.prototype.summary = null; | |
| 60 | + | |
| 61 | +PullSummary.FILE_UPDATE_REGEX = /^\s*(.+?)\s+\|\s+\d+\s*(\+*)(-*)/; | |
| 62 | +PullSummary.SUMMARY_REGEX = /(\d+)\D+((\d+)\D+\(\+\))?(\D+(\d+)\D+\(-\))?/; | |
| 63 | +PullSummary.ACTION_REGEX = /(create|delete) mode \d+ (.+)/; | |
| 64 | + | |
| 65 | +PullSummary.parse = function (text) { | |
| 66 | + var pullSummary = new PullSummary; | |
| 67 | + var lines = text.split('\n'); | |
| 68 | + | |
| 69 | + while (lines.length) { | |
| 70 | + var line = lines.shift().trim(); | |
| 71 | + if (!line) { | |
| 72 | + continue; | |
| 73 | + } | |
| 74 | + | |
| 75 | + update(pullSummary, line) || summary(pullSummary, line) || action(pullSummary, line); | |
| 76 | + } | |
| 77 | + | |
| 78 | + return pullSummary; | |
| 79 | +}; | |
| 80 | + | |
| 81 | +function update (pullSummary, line) { | |
| 82 | + | |
| 83 | + var update = PullSummary.FILE_UPDATE_REGEX.exec(line); | |
| 84 | + if (!update) { | |
| 85 | + return false; | |
| 86 | + } | |
| 87 | + | |
| 88 | + pullSummary.files.push(update[1]); | |
| 89 | + | |
| 90 | + var insertions = update[2].length; | |
| 91 | + if (insertions) { | |
| 92 | + pullSummary.insertions[update[1]] = insertions; | |
| 93 | + } | |
| 94 | + | |
| 95 | + var deletions = update[3].length; | |
| 96 | + if (deletions) { | |
| 97 | + pullSummary.deletions[update[1]] = deletions; | |
| 98 | + } | |
| 99 | + | |
| 100 | + return true; | |
| 101 | +} | |
| 102 | + | |
| 103 | +function summary (pullSummary, line) { | |
| 104 | + if (!pullSummary.files.length) { | |
| 105 | + return false; | |
| 106 | + } | |
| 107 | + | |
| 108 | + var update = PullSummary.SUMMARY_REGEX.exec(line); | |
| 109 | + if (!update || (update[3] === undefined && update[5] === undefined)) { | |
| 110 | + return false; | |
| 111 | + } | |
| 112 | + | |
| 113 | + pullSummary.summary.changes = +update[1] || 0; | |
| 114 | + pullSummary.summary.insertions = +update[3] || 0; | |
| 115 | + pullSummary.summary.deletions = +update[5] || 0; | |
| 116 | + | |
| 117 | + return true; | |
| 118 | +} | |
| 119 | + | |
| 120 | +function action (pullSummary, line) { | |
| 121 | + | |
| 122 | + var match = PullSummary.ACTION_REGEX.exec(line); | |
| 123 | + if (!match) { | |
| 124 | + return false; | |
| 125 | + } | |
| 126 | + | |
| 127 | + var file = match[2]; | |
| 128 | + | |
| 129 | + if (pullSummary.files.indexOf(file) < 0) { | |
| 130 | + pullSummary.files.push(file); | |
| 131 | + } | |
| 132 | + | |
| 133 | + var container = (match[1] === 'create') ? pullSummary.created : pullSummary.deleted; | |
| 134 | + container.push(file); | |
| 135 | + | |
| 136 | + return true; | |
| 137 | +} | |
| @@ -0,0 +1,188 @@ | ||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | +var FileStatusSummary = require('./FileStatusSummary'); | |
| 5 | + | |
| 6 | +module.exports = StatusSummary; | |
| 7 | + | |
| 8 | +/** | |
| 9 | + * The StatusSummary is returned as a response to getting `git().status()` | |
| 10 | + * | |
| 11 | + * @constructor | |
| 12 | + */ | |
| 13 | +function StatusSummary () { | |
| 14 | + this.not_added = []; | |
| 15 | + this.conflicted = []; | |
| 16 | + this.created = []; | |
| 17 | + this.deleted = []; | |
| 18 | + this.modified = []; | |
| 19 | + this.renamed = []; | |
| 20 | + this.files = []; | |
| 21 | + this.staged = []; | |
| 22 | +} | |
| 23 | + | |
| 24 | + | |
| 25 | +/** | |
| 26 | + * Number of commits ahead of the tracked branch | |
| 27 | + * @type {number} | |
| 28 | + */ | |
| 29 | +StatusSummary.prototype.ahead = 0; | |
| 30 | + | |
| 31 | +/** | |
| 32 | + * Number of commits behind the tracked branch | |
| 33 | + * @type {number} | |
| 34 | + */ | |
| 35 | +StatusSummary.prototype.behind = 0; | |
| 36 | + | |
| 37 | +/** | |
| 38 | + * Name of the current branch | |
| 39 | + * @type {null} | |
| 40 | + */ | |
| 41 | +StatusSummary.prototype.current = null; | |
| 42 | + | |
| 43 | +/** | |
| 44 | + * Name of the branch being tracked | |
| 45 | + * @type {string} | |
| 46 | + */ | |
| 47 | +StatusSummary.prototype.tracking = null; | |
| 48 | + | |
| 49 | +/** | |
| 50 | + * All files represented as an array of objects containing the `path` and status in `index` and | |
| 51 | + * in the `working_dir`. | |
| 52 | + * | |
| 53 | + * @type {Array} | |
| 54 | + */ | |
| 55 | +StatusSummary.prototype.files = null; | |
| 56 | + | |
| 57 | +/** | |
| 58 | + * Gets whether this StatusSummary represents a clean working branch. | |
| 59 | + * | |
| 60 | + * @return {boolean} | |
| 61 | + */ | |
| 62 | +StatusSummary.prototype.isClean = function () { | |
| 63 | + return 0 === Object.keys(this).filter(function (name) { | |
| 64 | + return Array.isArray(this[name]) && this[name].length; | |
| 65 | + }, this).length; | |
| 66 | +}; | |
| 67 | + | |
| 68 | +StatusSummary.parsers = { | |
| 69 | + '##': function (line, status) { | |
| 70 | + var aheadReg = /ahead (\d+)/; | |
| 71 | + var behindReg = /behind (\d+)/; | |
| 72 | + var currentReg = /^(.+?(?=(?:\.{3}|\s|$)))/; | |
| 73 | + var trackingReg = /\.{3}(\S*)/; | |
| 74 | + var regexResult; | |
| 75 | + | |
| 76 | + regexResult = aheadReg.exec(line); | |
| 77 | + status.ahead = regexResult && +regexResult[1] || 0; | |
| 78 | + | |
| 79 | + regexResult = behindReg.exec(line); | |
| 80 | + status.behind = regexResult && +regexResult[1] || 0; | |
| 81 | + | |
| 82 | + regexResult = currentReg.exec(line); | |
| 83 | + status.current = regexResult && regexResult[1]; | |
| 84 | + | |
| 85 | + regexResult = trackingReg.exec(line); | |
| 86 | + status.tracking = regexResult && regexResult[1]; | |
| 87 | + }, | |
| 88 | + | |
| 89 | + '??': function (line, status) { | |
| 90 | + status.not_added.push(line); | |
| 91 | + }, | |
| 92 | + | |
| 93 | + A: function (line, status) { | |
| 94 | + status.created.push(line); | |
| 95 | + }, | |
| 96 | + | |
| 97 | + AM: function (line, status) { | |
| 98 | + status.created.push(line); | |
| 99 | + }, | |
| 100 | + | |
| 101 | + D: function (line, status) { | |
| 102 | + status.deleted.push(line); | |
| 103 | + }, | |
| 104 | + | |
| 105 | + M: function (line, status, indexState) { | |
| 106 | + status.modified.push(line); | |
| 107 | + | |
| 108 | + if (indexState === 'M') { | |
| 109 | + status.staged.push(line); | |
| 110 | + } | |
| 111 | + }, | |
| 112 | + | |
| 113 | + R: function (line, status) { | |
| 114 | + var detail = /^(.+) -> (.+)$/.exec(line) || [null, line, line]; | |
| 115 | + | |
| 116 | + status.renamed.push({ | |
| 117 | + from: detail[1], | |
| 118 | + to: detail[2] | |
| 119 | + }); | |
| 120 | + }, | |
| 121 | + | |
| 122 | + UU: function (line, status) { | |
| 123 | + status.conflicted.push(line); | |
| 124 | + } | |
| 125 | +}; | |
| 126 | + | |
| 127 | +StatusSummary.parsers.MM = StatusSummary.parsers.M; | |
| 128 | + | |
| 129 | +/* Map all unmerged status code combinations to UU to mark as conflicted */ | |
| 130 | +StatusSummary.parsers.AA = StatusSummary.parsers.UU; | |
| 131 | +StatusSummary.parsers.UD = StatusSummary.parsers.UU; | |
| 132 | +StatusSummary.parsers.DU = StatusSummary.parsers.UU; | |
| 133 | +StatusSummary.parsers.DD = StatusSummary.parsers.UU; | |
| 134 | +StatusSummary.parsers.AU = StatusSummary.parsers.UU; | |
| 135 | +StatusSummary.parsers.UA = StatusSummary.parsers.UU; | |
| 136 | + | |
| 137 | +StatusSummary.parse = function (text) { | |
| 138 | + var file; | |
| 139 | + var lines = text.trim().split('\n'); | |
| 140 | + var status = new StatusSummary(); | |
| 141 | + | |
| 142 | + for (var i = 0, l = lines.length; i < l; i++) { | |
| 143 | + file = splitLine(lines[i]); | |
| 144 | + | |
| 145 | + if (!file) { | |
| 146 | + continue; | |
| 147 | + } | |
| 148 | + | |
| 149 | + if (file.handler) { | |
| 150 | + file.handler(file.path, status, file.index, file.workingDir); | |
| 151 | + } | |
| 152 | + | |
| 153 | + if (file.code !== '##') { | |
| 154 | + status.files.push(new FileStatusSummary(file.path, file.index, file.workingDir)); | |
| 155 | + } | |
| 156 | + } | |
| 157 | + | |
| 158 | + return status; | |
| 159 | +}; | |
| 160 | + | |
| 161 | + | |
| 162 | +function splitLine (lineStr) { | |
| 163 | + var line = lineStr.trim().match(/(..?)(\s+)(.*)/); | |
| 164 | + if (!line || !line[1].trim()) { | |
| 165 | + line = lineStr.trim().match(/(..?)\s+(.*)/); | |
| 166 | + } | |
| 167 | + | |
| 168 | + if (!line) { | |
| 169 | + return; | |
| 170 | + } | |
| 171 | + | |
| 172 | + var code = line[1]; | |
| 173 | + if (line[2].length > 1) { | |
| 174 | + code += ' '; | |
| 175 | + } | |
| 176 | + if (code.length === 1 && line[2].length === 1) { | |
| 177 | + code = ' ' + code; | |
| 178 | + } | |
| 179 | + | |
| 180 | + return { | |
| 181 | + raw: code, | |
| 182 | + code: code.trim(), | |
| 183 | + index: code.charAt(0), | |
| 184 | + workingDir: code.charAt(1), | |
| 185 | + handler: StatusSummary.parsers[code.trim()], | |
| 186 | + path: line[3] | |
| 187 | + }; | |
| 188 | +} | |
| @@ -0,0 +1,50 @@ | ||
| 1 | + | |
| 2 | +module.exports = TagList; | |
| 3 | + | |
| 4 | +function TagList (tagList, latest) { | |
| 5 | + this.latest = latest; | |
| 6 | + this.all = tagList | |
| 7 | +} | |
| 8 | + | |
| 9 | +TagList.parse = function (data, customSort) { | |
| 10 | + var number = function (input) { | |
| 11 | + if (typeof input === 'string') { | |
| 12 | + return parseInt(input.replace(/^\D+/g, ''), 10) || 0; | |
| 13 | + } | |
| 14 | + | |
| 15 | + return 0; | |
| 16 | + }; | |
| 17 | + | |
| 18 | + var tags = data | |
| 19 | + .trim() | |
| 20 | + .split('\n') | |
| 21 | + .map(function (item) { return item.trim(); }) | |
| 22 | + .filter(Boolean); | |
| 23 | + | |
| 24 | + if (!customSort) { | |
| 25 | + tags.sort(function (tagA, tagB) { | |
| 26 | + var partsA = tagA.split('.'); | |
| 27 | + var partsB = tagB.split('.'); | |
| 28 | + | |
| 29 | + if (partsA.length === 1 || partsB.length === 1) { | |
| 30 | + return tagA - tagB > 0 ? 1 : -1; | |
| 31 | + } | |
| 32 | + | |
| 33 | + for (var i = 0, l = Math.max(partsA.length, partsB.length); i < l; i++) { | |
| 34 | + var a = number(partsA[i]); | |
| 35 | + var b = number(partsB[i]); | |
| 36 | + | |
| 37 | + var diff = a - b; | |
| 38 | + if (diff) { | |
| 39 | + return diff > 0 ? 1 : -1; | |
| 40 | + } | |
| 41 | + } | |
| 42 | + | |
| 43 | + return 0; | |
| 44 | + }); | |
| 45 | + } | |
| 46 | + | |
| 47 | + var latest = customSort ? tags[0] : tags.filter(function (tag) { return tag.indexOf('.') >= 0; }).pop(); | |
| 48 | + | |
| 49 | + return new TagList(tags, latest); | |
| 50 | +}; | |
| @@ -0,0 +1,15 @@ | ||
| 1 | + | |
| 2 | +module.exports = { | |
| 3 | + BranchDeleteSummary: require('./BranchDeleteSummary'), | |
| 4 | + BranchSummary: require('./BranchSummary'), | |
| 5 | + CommitSummary: require('./CommitSummary'), | |
| 6 | + DiffSummary: require('./DiffSummary'), | |
| 7 | + FetchSummary: require('./FetchSummary'), | |
| 8 | + FileStatusSummary: require('./FileStatusSummary'), | |
| 9 | + ListLogSummary: require('./ListLogSummary'), | |
| 10 | + MergeSummary: require('./MergeSummary'), | |
| 11 | + MoveSummary: require('./MoveSummary'), | |
| 12 | + PullSummary: require('./PullSummary'), | |
| 13 | + StatusSummary: require('./StatusSummary'), | |
| 14 | + TagList: require('./TagList'), | |
| 15 | +}; | |