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 | }; | ||