mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-09-19 23:39:50 +02:00
getting there
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { logger } from '../../logger';
|
||||
import { log } from '../../logger';
|
||||
import { random } from '../../utils';
|
||||
let commits = {};
|
||||
let head = null;
|
||||
@@ -11,13 +11,19 @@ function getId() {
|
||||
return random({ length: 7 });
|
||||
}
|
||||
|
||||
/**
|
||||
* @param currentCommit
|
||||
* @param otherCommit
|
||||
*/
|
||||
function isfastforwardable(currentCommit, otherCommit) {
|
||||
logger.debug('Entering isfastforwardable:', currentCommit.id, otherCommit.id);
|
||||
while (currentCommit.seq <= otherCommit.seq && currentCommit !== otherCommit) {
|
||||
log.debug('Entering isfastforwardable:', currentCommit.id, otherCommit.id);
|
||||
let cnt = 0;
|
||||
while (currentCommit.seq <= otherCommit.seq && currentCommit !== otherCommit && cnt < 1000) {
|
||||
cnt++;
|
||||
// only if other branch has more commits
|
||||
if (otherCommit.parent == null) break;
|
||||
if (Array.isArray(otherCommit.parent)) {
|
||||
logger.debug('In merge commit:', otherCommit.parent);
|
||||
log.debug('In merge commit:', otherCommit.parent);
|
||||
return (
|
||||
isfastforwardable(currentCommit, commits[otherCommit.parent[0]]) ||
|
||||
isfastforwardable(currentCommit, commits[otherCommit.parent[1]])
|
||||
@@ -26,10 +32,14 @@ function isfastforwardable(currentCommit, otherCommit) {
|
||||
otherCommit = commits[otherCommit.parent];
|
||||
}
|
||||
}
|
||||
logger.debug(currentCommit.id, otherCommit.id);
|
||||
log.debug(currentCommit.id, otherCommit.id);
|
||||
return currentCommit.id === otherCommit.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param currentCommit
|
||||
* @param otherCommit
|
||||
*/
|
||||
function isReachableFrom(currentCommit, otherCommit) {
|
||||
const currentSeq = currentCommit.seq;
|
||||
const otherSeq = otherCommit.seq;
|
||||
@@ -37,6 +47,10 @@ function isReachableFrom(currentCommit, otherCommit) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param list
|
||||
* @param fn
|
||||
*/
|
||||
function uniqBy(list, fn) {
|
||||
const recordMap = Object.create(null);
|
||||
return list.reduce((out, item) => {
|
||||
@@ -49,22 +63,22 @@ function uniqBy(list, fn) {
|
||||
}, []);
|
||||
}
|
||||
|
||||
export const setDirection = function(dir) {
|
||||
export const setDirection = function (dir) {
|
||||
direction = dir;
|
||||
};
|
||||
let options = {};
|
||||
export const setOptions = function(rawOptString) {
|
||||
logger.debug('options str', rawOptString);
|
||||
export const setOptions = function (rawOptString) {
|
||||
log.debug('options str', rawOptString);
|
||||
rawOptString = rawOptString && rawOptString.trim();
|
||||
rawOptString = rawOptString || '{}';
|
||||
try {
|
||||
options = JSON.parse(rawOptString);
|
||||
} catch (e) {
|
||||
logger.error('error while parsing gitGraph options', e.message);
|
||||
log.error('error while parsing gitGraph options', e.message);
|
||||
}
|
||||
};
|
||||
|
||||
export const getOptions = function() {
|
||||
export const getOptions = function () {
|
||||
return options;
|
||||
};
|
||||
|
||||
@@ -75,24 +89,24 @@ export const commit = function(msg, id, type, tag) {
|
||||
seq: seq++,
|
||||
type: type ? type : commitType.NORMAL,
|
||||
tag: tag ? tag : '',
|
||||
parent: head == null ? null : head.id
|
||||
parent: head == null ? null : head.id,
|
||||
};
|
||||
head = commit;
|
||||
commits[commit.id] = commit;
|
||||
branches[curBranch] = commit.id;
|
||||
logger.debug('in pushCommit ' + commit.id);
|
||||
log.debug('in pushCommit ' + commit.id);
|
||||
};
|
||||
|
||||
export const branch = function(name) {
|
||||
export const branch = function (name) {
|
||||
branches[name] = head != null ? head.id : null;
|
||||
logger.debug('in createBranch');
|
||||
log.debug('in createBranch');
|
||||
};
|
||||
|
||||
export const merge = function(otherBranch) {
|
||||
export const merge = function (otherBranch) {
|
||||
const currentCommit = commits[branches[curBranch]];
|
||||
const otherCommit = commits[branches[otherBranch]];
|
||||
if (isReachableFrom(currentCommit, otherCommit)) {
|
||||
logger.debug('Already merged');
|
||||
log.debug('Already merged');
|
||||
return;
|
||||
}
|
||||
if (isfastforwardable(currentCommit, otherCommit)) {
|
||||
@@ -104,35 +118,35 @@ export const merge = function(otherBranch) {
|
||||
id: getId(),
|
||||
message: 'merged branch ' + otherBranch + ' into ' + curBranch,
|
||||
seq: seq++,
|
||||
parent: [head == null ? null : head.id, branches[otherBranch]]
|
||||
parent: [head == null ? null : head.id, branches[otherBranch]],
|
||||
};
|
||||
head = commit;
|
||||
commits[commit.id] = commit;
|
||||
branches[curBranch] = commit.id;
|
||||
}
|
||||
logger.debug(branches);
|
||||
logger.debug('in mergeBranch');
|
||||
log.debug(branches);
|
||||
log.debug('in mergeBranch');
|
||||
};
|
||||
|
||||
export const checkout = function(branch) {
|
||||
logger.debug('in checkout');
|
||||
export const checkout = function (branch) {
|
||||
log.debug('in checkout');
|
||||
curBranch = branch;
|
||||
const id = branches[curBranch];
|
||||
head = commits[id];
|
||||
};
|
||||
|
||||
export const reset = function(commitRef) {
|
||||
logger.debug('in reset', commitRef);
|
||||
export const reset = function (commitRef) {
|
||||
log.debug('in reset', commitRef);
|
||||
const ref = commitRef.split(':')[0];
|
||||
let parentCount = parseInt(commitRef.split(':')[1]);
|
||||
let commit = ref === 'HEAD' ? head : commits[branches[ref]];
|
||||
logger.debug(commit, parentCount);
|
||||
log.debug(commit, parentCount);
|
||||
while (parentCount > 0) {
|
||||
commit = commits[commit.parent];
|
||||
parentCount--;
|
||||
if (!commit) {
|
||||
const err = 'Critical error - unique parent commit not found during reset';
|
||||
logger.error(err);
|
||||
log.error(err);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
@@ -140,6 +154,11 @@ export const reset = function(commitRef) {
|
||||
branches[curBranch] = commit.id;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param arr
|
||||
* @param key
|
||||
* @param newval
|
||||
*/
|
||||
function upsert(arr, key, newval) {
|
||||
const index = arr.indexOf(key);
|
||||
if (index === -1) {
|
||||
@@ -149,13 +168,14 @@ function upsert(arr, key, newval) {
|
||||
}
|
||||
}
|
||||
|
||||
/** @param commitArr */
|
||||
function prettyPrintCommitHistory(commitArr) {
|
||||
const commit = commitArr.reduce((out, commit) => {
|
||||
if (out.seq > commit.seq) return out;
|
||||
return commit;
|
||||
}, commitArr[0]);
|
||||
let line = '';
|
||||
commitArr.forEach(function(c) {
|
||||
commitArr.forEach(function (c) {
|
||||
if (c === commit) {
|
||||
line += '\t*';
|
||||
} else {
|
||||
@@ -166,7 +186,7 @@ function prettyPrintCommitHistory(commitArr) {
|
||||
for (let branch in branches) {
|
||||
if (branches[branch] === commit.id) label.push(branch);
|
||||
}
|
||||
logger.debug(label.join(' '));
|
||||
log.debug(label.join(' '));
|
||||
if (Array.isArray(commit.parent)) {
|
||||
const newCommit = commits[commit.parent[0]];
|
||||
upsert(commitArr, commit, newCommit);
|
||||
@@ -177,17 +197,17 @@ function prettyPrintCommitHistory(commitArr) {
|
||||
const nextCommit = commits[commit.parent];
|
||||
upsert(commitArr, commit, nextCommit);
|
||||
}
|
||||
commitArr = uniqBy(commitArr, c => c.id);
|
||||
commitArr = uniqBy(commitArr, (c) => c.id);
|
||||
prettyPrintCommitHistory(commitArr);
|
||||
}
|
||||
|
||||
export const prettyPrint = function() {
|
||||
logger.debug(commits);
|
||||
export const prettyPrint = function () {
|
||||
log.debug(commits);
|
||||
const node = getCommitsArray()[0];
|
||||
prettyPrintCommitHistory([node]);
|
||||
};
|
||||
|
||||
export const clear = function() {
|
||||
export const clear = function () {
|
||||
commits = {};
|
||||
head = null;
|
||||
branches = { master: head };
|
||||
@@ -195,7 +215,7 @@ export const clear = function() {
|
||||
seq = 0;
|
||||
};
|
||||
|
||||
export const getBranchesAsObjArray = function() {
|
||||
export const getBranchesAsObjArray = function () {
|
||||
const branchArr = [];
|
||||
for (let branch in branches) {
|
||||
branchArr.push({ name: branch, commit: commits[branches[branch]] });
|
||||
@@ -203,29 +223,29 @@ export const getBranchesAsObjArray = function() {
|
||||
return branchArr;
|
||||
};
|
||||
|
||||
export const getBranches = function() {
|
||||
export const getBranches = function () {
|
||||
return branches;
|
||||
};
|
||||
export const getCommits = function() {
|
||||
export const getCommits = function () {
|
||||
return commits;
|
||||
};
|
||||
export const getCommitsArray = function() {
|
||||
const commitArr = Object.keys(commits).map(function(key) {
|
||||
export const getCommitsArray = function () {
|
||||
const commitArr = Object.keys(commits).map(function (key) {
|
||||
return commits[key];
|
||||
});
|
||||
commitArr.forEach(function(o) {
|
||||
logger.debug(o.id);
|
||||
commitArr.forEach(function (o) {
|
||||
log.debug(o.id);
|
||||
});
|
||||
commitArr.sort((a, b) => b.seq - a.seq);
|
||||
return commitArr;
|
||||
};
|
||||
export const getCurrentBranch = function() {
|
||||
export const getCurrentBranch = function () {
|
||||
return curBranch;
|
||||
};
|
||||
export const getDirection = function() {
|
||||
export const getDirection = function () {
|
||||
return direction;
|
||||
};
|
||||
export const getHead = function() {
|
||||
export const getHead = function () {
|
||||
return head;
|
||||
};
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
/* eslint-env jasmine */
|
||||
|
||||
// Todo reintroduce without cryptoRandomString
|
||||
import gitGraphAst from './gitGraphAst';
|
||||
import { parser } from './parser/gitGraph';
|
||||
@@ -21,7 +21,7 @@ describe('when parsing a gitGraph', function() {
|
||||
afterEach(function() {
|
||||
cryptoRandomString.mockReset();
|
||||
});
|
||||
it('should handle a gitGraph defintion', function() {
|
||||
it('should handle a gitGraph definition', function() {
|
||||
const str = 'gitGraph:\n' + 'commit\n';
|
||||
|
||||
parser.parse(str);
|
||||
@@ -33,7 +33,7 @@ describe('when parsing a gitGraph', function() {
|
||||
expect(Object.keys(parser.yy.getBranches()).length).toBe(1);
|
||||
});
|
||||
|
||||
it('should handle a gitGraph defintion with empty options', function() {
|
||||
it('should handle a gitGraph definition with empty options', function() {
|
||||
const str = 'gitGraph:\n' + 'options\n' + 'end\n' + 'commit\n';
|
||||
|
||||
parser.parse(str);
|
||||
@@ -46,7 +46,7 @@ describe('when parsing a gitGraph', function() {
|
||||
expect(Object.keys(parser.yy.getBranches()).length).toBe(1);
|
||||
});
|
||||
|
||||
it('should handle a gitGraph defintion with valid options', function() {
|
||||
it('should handle a gitGraph definition with valid options', function() {
|
||||
const str = 'gitGraph:\n' + 'options\n' + '{"key": "value"}\n' + 'end\n' + 'commit\n';
|
||||
|
||||
parser.parse(str);
|
||||
|
@@ -1,19 +1,20 @@
|
||||
/* eslint-disable */
|
||||
import { curveBasis, line, select } from 'd3';
|
||||
import { interpolateToCurve, getStylesFromArray, configureSvgSize } from '../../utils';
|
||||
import { logger } from '../../logger'; // eslint-disable-line
|
||||
// import db from './gitGraphAst';
|
||||
import * as db from './mockDb';
|
||||
import gitGraphParser from './parser/gitGraph';
|
||||
import { getConfig } from '../../config';
|
||||
import { log } from '../../logger';
|
||||
/* eslint-disable */
|
||||
|
||||
import { getConfig } from '../../config';
|
||||
let allCommitsDict = {};
|
||||
let branchNum;
|
||||
|
||||
// let apiConfig = {};
|
||||
// export const setConf = function(c) {
|
||||
// apiConfig = c;
|
||||
// };
|
||||
/** @param svg */
|
||||
function svgCreateDefs(svg) {
|
||||
const config = getConfig().gitGraph;
|
||||
svg
|
||||
@@ -37,17 +38,48 @@ function svgCreateDefs(svg) {
|
||||
.html('');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param svg
|
||||
* @param points
|
||||
* @param colorIdx
|
||||
* @param interpolate
|
||||
*/
|
||||
/**
|
||||
// Pass in the element and its pre-transform coords
|
||||
*
|
||||
* @param element
|
||||
* @param coords
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param svg
|
||||
* @param fromId
|
||||
* @param toId
|
||||
* @param direction
|
||||
* @param color
|
||||
*/
|
||||
|
||||
const drawText = (txt) => {
|
||||
const svgLabel = document.createElementNS('http://www.w3.org/2000/svg', 'text');
|
||||
// svgLabel.setAttribute('style', style.replace('color:', 'fill:'));
|
||||
let rows = [];
|
||||
|
||||
|
||||
|
||||
|
||||
if (typeof txt === 'string') {
|
||||
rows = txt.split(/\\n|\n|<br\s*\/?>/gi);
|
||||
} else if (Array.isArray(txt)) {
|
||||
rows = txt;
|
||||
|
||||
|
||||
} else {
|
||||
rows = [];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
for (let j = 0; j < rows.length; j++) {
|
||||
const tspan = document.createElementNS('http://www.w3.org/2000/svg', 'tspan');
|
||||
@@ -58,9 +90,19 @@ const drawText = (txt) => {
|
||||
tspan.textContent = rows[j].trim();
|
||||
svgLabel.appendChild(tspan);
|
||||
}
|
||||
/**
|
||||
* @param svg
|
||||
* @param selector
|
||||
*/
|
||||
return svgLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param svg
|
||||
* @param commitid
|
||||
* @param branches
|
||||
* @param direction
|
||||
*/
|
||||
const drawBranches = (svg, branches) => {
|
||||
const g = svg.append('g')
|
||||
let pos = 0;
|
||||
@@ -82,7 +124,7 @@ const drawBranches = (svg, branches) => {
|
||||
const label = branchLabel.insert('g').attr('class', 'label');
|
||||
label.node().appendChild(labelElement);
|
||||
let bbox = labelElement.getBBox();
|
||||
logger.info(bbox);
|
||||
//logger.info(bbox);
|
||||
bkg.attr('class', 'branchLabelBkg label' + index)
|
||||
.attr('rx', 4)
|
||||
.attr('ry', 4)
|
||||
@@ -95,9 +137,16 @@ const drawBranches = (svg, branches) => {
|
||||
bkg.attr('transform', 'translate(' + -19 + ', ' + (pos - bbox.height/2) + ')');
|
||||
pos += 50;
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
export const draw = function(txt, id, ver) {
|
||||
/**
|
||||
* @param svg
|
||||
* @param commit
|
||||
* @param direction
|
||||
* @param branchColor
|
||||
*/
|
||||
export const draw = function (txt, id, ver) {
|
||||
const config = getConfig().gitGraph;
|
||||
|
||||
// try {
|
||||
@@ -105,7 +154,7 @@ export const draw = function(txt, id, ver) {
|
||||
parser.yy = db;
|
||||
parser.yy.clear();
|
||||
|
||||
logger.debug('in gitgraph renderer', txt + '\n', 'id:', id, ver);
|
||||
log.debug('in gitgraph renderer', txt + '\n', 'id:', id, ver);
|
||||
// // Parse the graph definition
|
||||
// parser.parse(txt + '\n');
|
||||
|
||||
@@ -113,7 +162,7 @@ export const draw = function(txt, id, ver) {
|
||||
const direction = db.getDirection();
|
||||
allCommitsDict = db.getCommits();
|
||||
const branches = db.getBranchesAsObjArray();
|
||||
logger.debug('effective options', config, branches);
|
||||
log.debug('effective options', config, branches);
|
||||
|
||||
const diagram = select(`[id="${id}"]`);
|
||||
svgCreateDefs(diagram);
|
||||
@@ -127,10 +176,10 @@ export const draw = function(txt, id, ver) {
|
||||
|
||||
configureSvgSize(diagram, height, width, config.useMaxWidth);
|
||||
const vBox = `${svgBounds.x - padding} ${svgBounds.y - padding} ${width} ${height}`;
|
||||
logger.debug(`viewBox ${vBox}`);
|
||||
// logger.debug(`viewBox ${vBox}`);
|
||||
diagram.attr('viewBox', vBox);
|
||||
};
|
||||
|
||||
export default {
|
||||
draw
|
||||
draw,
|
||||
};
|
||||
|
@@ -5,7 +5,7 @@ const getStyles = options =>
|
||||
.branch-label {
|
||||
fill: lightgrey;
|
||||
color: lightgrey;
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
font-family: 'trebuchet ms', verdana, arial, sans-serif;
|
||||
font-family: var(--mermaid-font-family);
|
||||
}
|
||||
.branch {
|
||||
|
Reference in New Issue
Block a user