UNPKG

mermaid

Version:

Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams and gantt charts.

217 lines (194 loc) 6.34 kB
var Logger = require('../../logger'); var _ = require('lodash'); //var log = new Logger.Log(); var log = new Logger.Log(1); var commits = {}; var head = null; var branches = { 'master' : head }; var curBranch = 'master'; var direction = 'LR'; var seq = 0; function getRandomInt(min, max) { return Math.floor(Math.random() * (max - min)) + min; } function getId() { var pool='0123456789abcdef'; var id = ''; for (var i = 0; i < 7; i++) { id += pool[getRandomInt(0,16)] } return id; } function isfastforwardable(currentCommit, otherCommit) { log.debug('Entering isfastforwardable:', currentCommit.id, otherCommit.id); while (currentCommit.seq <= otherCommit.seq && currentCommit != otherCommit) { // only if other branch has more commits if (otherCommit.parent == null) break; if (Array.isArray(otherCommit.parent)){ log.debug('In merge commit:', otherCommit.parent); return isfastforwardable(currentCommit, commits[otherCommit.parent[0]]) || isfastforwardable(currentCommit, commits[otherCommit.parent[1]]) } else { otherCommit = commits[otherCommit.parent]; } } log.debug(currentCommit.id, otherCommit.id); return currentCommit.id == otherCommit.id; } function isReachableFrom(currentCommit, otherCommit) { var currentSeq = currentCommit.seq; var otherSeq = otherCommit.seq; if (currentSeq > otherSeq) return isfastforwardable(otherCommit, currentCommit); return false; } exports.setDirection = function(dir) { direction = dir; } var options = {}; exports.setOptions = function(rawOptString) { log.debug('options str', rawOptString); rawOptString = rawOptString && rawOptString.trim(); rawOptString = rawOptString || '{}'; try { options = JSON.parse(rawOptString) } catch(e) { log.error('error while parsing gitGraph options', e.message); } } exports.getOptions = function() { return options; } exports.commit = function(msg) { var commit = { id: getId(), message: msg, seq: seq++, parent: head == null ? null : head.id}; head = commit; commits[commit.id] = commit; branches[curBranch] = commit.id; log.debug('in pushCommit ' + commit.id); } exports.branch = function(name) { branches[name] = head != null ? head.id: null; log.debug('in createBranch'); } exports.merge = function(otherBranch) { var currentCommit = commits[branches[curBranch]]; var otherCommit = commits[branches[otherBranch]]; if (isReachableFrom(currentCommit, otherCommit)) { log.debug('Already merged'); return; } if (isfastforwardable(currentCommit, otherCommit)){ branches[curBranch] = branches[otherBranch]; head = commits[branches[curBranch]]; } else { // create merge commit var commit = { id: getId(), message: 'merged branch ' + otherBranch + ' into ' + curBranch, seq: seq++, parent: [head == null ? null : head.id, branches[otherBranch]] }; head = commit; commits[commit.id] = commit; branches[curBranch] = commit.id; } log.debug(branches); log.debug('in mergeBranch'); } exports.checkout = function(branch) { log.debug('in checkout'); curBranch = branch; var id = branches[curBranch]; head = commits[id]; } exports.reset = function(commitRef) { log.debug('in reset', commitRef); var ref = commitRef.split(':')[0]; var parentCount = parseInt(commitRef.split(':')[1]); var commit = ref == 'HEAD' ? head : commits[branches[ref]]; log.debug(commit, parentCount); while (parentCount > 0) { commit = commits[commit.parent]; parentCount--; if (!commit) { var err = 'Critical error - unique parent commit not found during reset'; log.error(err); throw err; } } head = commit; branches[curBranch] = commit.id; } function upsert(arr, key, newval) { var match = _.find(arr, key); if(match){ var index = _.indexOf(arr, _.find(arr, key)); arr.splice(index, 1, newval); } else { arr.push(newval); } //console.log(arr); } function prettyPrintCommitHistory(commitArr) { var commit = _.maxBy(commitArr, 'seq'); var line = ''; _.each(commitArr, function(c) { if (c == commit) { line += '\t*' } else { line +='\t|' } }); var label = [line, commit.id, commit.seq]; _.each(branches, function(v,k){ if (v == commit.id) label.push(k); }); log.debug(label.join(' ')); if (Array.isArray(commit.parent)) { //console.log("here", commit.parent); var newCommit = commits[commit.parent[0]]; upsert(commitArr, commit, newCommit); commitArr.push(commits[commit.parent[1]]); //console.log("shoudl have 2", commitArr); } else if(commit.parent == null){ return; } else { var nextCommit = commits[commit.parent]; upsert(commitArr, commit, nextCommit); } commitArr = _.uniqBy(commitArr, 'id'); prettyPrintCommitHistory(commitArr); } exports.prettyPrint = function() { log.debug(commits); var node = exports.getCommitsArray()[0]; prettyPrintCommitHistory([node]); } exports.clear = function () { commits = {}; head = null; branches = { 'master' : head }; curBranch = 'master'; seq =0; } exports.getBranchesAsObjArray = function() { var branchArr = _.map(branches, function(v,k) { return {'name': k, 'commit': commits[v]}; }); //return _.orderBy(branchArr, [function(b) { return b.commit.seq}], ['desc']); return branchArr; } exports.getBranches = function() { return branches; } exports.getCommits = function() { return commits; } exports.getCommitsArray = function() { var commitArr = Object.keys(commits).map(function (key) { return commits[key]; }); _.each(commitArr, function(o) { log.debug(o.id) }); return _.orderBy(commitArr, ['seq'], ['desc']); } exports.getCurrentBranch = function() { return curBranch; } exports.getDirection = function() { return direction; } exports.getHead = function() { return head; }