From d937a3c5527c59ed7b13f48e3e7e61c501597e91 Mon Sep 17 00:00:00 2001 From: Raghu Rajagopalan Date: Sun, 27 Mar 2016 11:00:44 +0530 Subject: [PATCH] support orientation, commit msg, branch checkout --- src/diagrams/gitGraph/gitGraphAst.js | 18 ++++- src/diagrams/gitGraph/gitGraphParser.spec.js | 52 ++++++++++++-- src/diagrams/gitGraph/parser/gitGraph.jison | 20 +++++- src/diagrams/gitGraph/parser/gitGraph.js | 72 ++++++++++++++------ 4 files changed, 130 insertions(+), 32 deletions(-) diff --git a/src/diagrams/gitGraph/gitGraphAst.js b/src/diagrams/gitGraph/gitGraphAst.js index 88ab6229d..2259b9b36 100644 --- a/src/diagrams/gitGraph/gitGraphAst.js +++ b/src/diagrams/gitGraph/gitGraphAst.js @@ -2,16 +2,23 @@ var crypto = require("crypto"); var Logger = require('../../logger'); var log = new Logger.Log(); + var commits = {}; var head = null; var branches = { "master" : head }; var curBranch = "master"; +var direction = "LR"; function getId() { return crypto.randomBytes(20).toString('hex').substring(0, 7); } -exports.pushCommit = function() { + +exports.setDirection = function(dir) { + direction = dir; +} +exports.pushCommit = function(msg) { var commit = { id: getId(), + message: msg, parent: head == null ? null : head.id}; head = commit; commits[commit.id] = commit; @@ -20,7 +27,7 @@ exports.pushCommit = function() { } exports.createBranch = function(name) { - branches[name] = head.id; + branches[name] = head != null ? head.id: null; log.debug("in createBranch"); } @@ -28,6 +35,12 @@ exports.mergeBranch = function() { log.debug("in mergeBranch"); } +exports.checkout = function(branch) { + log.debug("in checkout"); + curBranch = branch; + var id = branches[curBranch]; + head = commits[id]; +} exports.reset = function () { commits = {}; head = null; @@ -38,3 +51,4 @@ exports.reset = function () { exports.getBranches = function() { return branches; } exports.getCommits = function() { return commits; } exports.getCurrentBranch = function() { return curBranch; } +exports.getDirection = function() { return direction; } diff --git a/src/diagrams/gitGraph/gitGraphParser.spec.js b/src/diagrams/gitGraph/gitGraphParser.spec.js index 202c9409f..d9c516be1 100644 --- a/src/diagrams/gitGraph/gitGraphParser.spec.js +++ b/src/diagrams/gitGraph/gitGraphParser.spec.js @@ -1,14 +1,14 @@ -var proxyquire = require('proxyquire'); var parser = require('./parser/gitGraph').parser; var ast = require("./gitGraphAst.js"); describe('when parsing a gitGraph',function() { + "use strict"; beforeEach(function () { parser.yy = ast; parser.yy.reset(); }); it('should handle a gitGraph defintion', function () { - str = 'gitGraph:\n' + - 'commit'; + var str = 'gitGraph:\n' + + 'commit\n'; parser.parse(str); var commits = parser.yy.getCommits(); @@ -16,17 +16,58 @@ describe('when parsing a gitGraph',function() { expect(Object.keys(commits).length).toBe(1); expect(parser.yy.getCurrentBranch()).toBe("master"); + expect(parser.yy.getDirection()).toBe("LR"); expect(Object.keys(parser.yy.getBranches()).length).toBe(1); }); + + it('should handle set direction', function () { + var str = 'gitGraph TB:\n' + + 'commit\n'; + + parser.parse(str); + var commits = parser.yy.getCommits(); + console.log(commits); + + expect(Object.keys(commits).length).toBe(1); + expect(parser.yy.getCurrentBranch()).toBe("master"); + expect(parser.yy.getDirection()).toBe("TB"); + expect(Object.keys(parser.yy.getBranches()).length).toBe(1); + }); + it('should checkout a branch', function () { + var str = 'gitGraph:\n' + + 'branch new\n' + + 'checkout new\n' + + parser.parse(str); + var commits = parser.yy.getCommits(); + + expect(Object.keys(commits).length).toBe(0); + expect(parser.yy.getCurrentBranch()).toBe("new"); + }); + + it('should handle commit with args', function () { + var str = 'gitGraph:\n' + + 'commit "a commit"\n'; + + parser.parse(str); + var commits = parser.yy.getCommits(); + console.log(commits); + + expect(Object.keys(commits).length).toBe(1); + var key = Object.keys(commits)[0]; + expect(commits[key].message).toBe("a commit"); + expect(parser.yy.getCurrentBranch()).toBe("master"); + }); + it('should handle branch statement', function () { - str = 'gitGraph:\n' + + var str = 'gitGraph:\n' + 'commit\n' + 'commit\n' + 'branch newbranch\n' + 'commit\n' + 'commit\n'; - parser.parse(str); + console.log(parser.parse(str)); var commits = parser.yy.getCommits(); console.log(commits); @@ -35,4 +76,5 @@ describe('when parsing a gitGraph',function() { expect(Object.keys(parser.yy.getBranches())).toContain('newbranch'); expect(Object.keys(parser.yy.getBranches()).length).toBe(2); }); + }); diff --git a/src/diagrams/gitGraph/parser/gitGraph.jison b/src/diagrams/gitGraph/parser/gitGraph.jison index 6cff3cc85..e21d7c0e7 100644 --- a/src/diagrams/gitGraph/parser/gitGraph.jison +++ b/src/diagrams/gitGraph/parser/gitGraph.jison @@ -8,6 +8,7 @@ */ %lex +%x string %options case-insensitive %% @@ -21,7 +22,14 @@ "branch" return 'BRANCH'; "merge" return 'MERGE'; "reset" return 'RESET'; -":" return ':'; +"checkout" return 'CHECKOUT'; +"LR" return 'DIR'; +"TB" return 'DIR'; +"BT" return 'DIR'; +":" return ':'; +["] this.begin("string"); +["] this.popState(); +[^"]* return 'STR'; [a-zA-Z][a-zA-Z0-9_]+ return 'ID'; <> return 'EOF'; @@ -35,6 +43,7 @@ start : GG ':' document EOF{ return $3; } + | GG DIR ':' document EOF {yy.setDirection($2); return $4;} ; document @@ -43,13 +52,18 @@ document ; line - : statement {$$ =$1} + : statement NL{$$ =$1} | NL ; statement - : COMMIT {yy.pushCommit()} + : COMMIT commit_arg {yy.pushCommit($2)} | BRANCH ID {yy.createBranch($2)} + | CHECKOUT ID {yy.checkout($2)} | MERGE ID {yy.mergeBranch($2)} ; +commit_arg + : /* empty */ {$$ = ""} + | STR {$$=$1} + ; diff --git a/src/diagrams/gitGraph/parser/gitGraph.js b/src/diagrams/gitGraph/parser/gitGraph.js index 57e9725e2..b223fe904 100644 --- a/src/diagrams/gitGraph/parser/gitGraph.js +++ b/src/diagrams/gitGraph/parser/gitGraph.js @@ -72,12 +72,14 @@ } */ var gitGraph = (function(){ -var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[7,10,11,12,14]; -var parser = {trace: function trace() { }, +var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[7,11,12,14,16,17],$V1=[2,3],$V2=[1,10],$V3=[1,11],$V4=[1,12],$V5=[1,13],$V6=[1,14]; +var parser = {trace: function trace() { + Jison.print.apply(null, arguments); + }, yy: {}, -symbols_: {"error":2,"start":3,"GG":4,":":5,"document":6,"EOF":7,"line":8,"statement":9,"NL":10,"COMMIT":11,"BRANCH":12,"ID":13,"MERGE":14,"$accept":0,"$end":1}, -terminals_: {2:"error",4:"GG",5:":",7:"EOF",10:"NL",11:"COMMIT",12:"BRANCH",13:"ID",14:"MERGE"}, -productions_: [0,[3,4],[6,0],[6,2],[8,1],[8,1],[9,1],[9,2],[9,2]], +symbols_: {"error":2,"start":3,"GG":4,":":5,"document":6,"EOF":7,"DIR":8,"line":9,"statement":10,"NL":11,"COMMIT":12,"commit_arg":13,"BRANCH":14,"ID":15,"CHECKOUT":16,"MERGE":17,"STR":18,"$accept":0,"$end":1}, +terminals_: {2:"error",4:"GG",5:":",7:"EOF",8:"DIR",11:"NL",12:"COMMIT",14:"BRANCH",15:"ID",16:"CHECKOUT",17:"MERGE",18:"STR"}, +productions_: [0,[3,4],[3,5],[6,0],[6,2],[9,2],[9,1],[10,2],[10,2],[10,2],[10,2],[13,0],[13,1]], performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) { /* this == yyval */ @@ -87,27 +89,39 @@ case 1: return $$[$0-1]; break; case 2: -this.$ =[] +yy.setDirection($$[$0-3]); return $$[$0-1]; break; case 3: -$$[$0-1].push($$[$0]); this.$ = $$[$0-1] +this.$ =[] break; case 4: -this.$ =$$[$0] +$$[$0-1].push($$[$0]); this.$ = $$[$0-1] break; -case 6: -yy.pushCommit() +case 5: +this.$ =$$[$0-1] break; case 7: -yy.createBranch($$[$0]) +yy.pushCommit($$[$0]) break; case 8: +yy.createBranch($$[$0]) +break; +case 9: +yy.checkout($$[$0]) +break; +case 10: yy.mergeBranch($$[$0]) break; +case 11: +this.$ = "" +break; +case 12: +this.$=$$[$0] +break; } }, -table: [{3:1,4:[1,2]},{1:[3]},{5:[1,3]},o($V0,[2,2],{6:4}),{7:[1,5],8:6,9:7,10:[1,8],11:[1,9],12:[1,10],14:[1,11]},{1:[2,1]},o($V0,[2,3]),o($V0,[2,4]),o($V0,[2,5]),o($V0,[2,6]),{13:[1,12]},{13:[1,13]},o($V0,[2,7]),o($V0,[2,8])], -defaultActions: {5:[2,1]}, +table: [{3:1,4:[1,2]},{1:[3]},{5:[1,3],8:[1,4]},o($V0,$V1,{6:5}),{5:[1,6]},{7:[1,7],9:8,10:9,11:$V2,12:$V3,14:$V4,16:$V5,17:$V6},o($V0,$V1,{6:15}),{1:[2,1]},o($V0,[2,4]),{11:[1,16]},o($V0,[2,6]),{11:[2,11],13:17,18:[1,18]},{15:[1,19]},{15:[1,20]},{15:[1,21]},{7:[1,22],9:8,10:9,11:$V2,12:$V3,14:$V4,16:$V5,17:$V6},o($V0,[2,5]),{11:[2,7]},{11:[2,12]},{11:[2,8]},{11:[2,9]},{11:[2,10]},{1:[2,2]}], +defaultActions: {7:[2,1],17:[2,7],18:[2,12],19:[2,8],20:[2,9],21:[2,10],22:[2,2]}, parseError: function parseError(str, hash) { if (hash.recoverable) { this.trace(str); @@ -586,7 +600,7 @@ options: {"case-insensitive":true}, performAction: function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) { var YYSTATE=YY_START; switch($avoiding_name_collisions) { -case 0:return 10; +case 0:return 11; break; case 1:/* skip all whitespace */ break; @@ -596,24 +610,38 @@ case 3:/* skip comments */ break; case 4:return 4; break; -case 5:return 11; +case 5:return 12; break; -case 6:return 12; +case 6:return 14; break; -case 7:return 14; +case 7:return 17; break; case 8:return 'RESET'; break; -case 9:return 5; +case 9:return 16; break; -case 10:return 13; +case 10:return 8; break; -case 11:return 7; +case 11:return 8; +break; +case 12:return 8; +break; +case 13:return 5; +break; +case 14:this.begin("string"); +break; +case 15:this.popState(); +break; +case 16:return 18; +break; +case 17:return 15; +break; +case 18:return 7; break; } }, -rules: [/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:gitGraph\b)/i,/^(?:commit\b)/i,/^(?:branch\b)/i,/^(?:merge\b)/i,/^(?:reset\b)/i,/^(?::)/i,/^(?:[a-zA-Z][a-zA-Z0-9_]+)/i,/^(?:$)/i], -conditions: {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11],"inclusive":true}} +rules: [/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:gitGraph\b)/i,/^(?:commit\b)/i,/^(?:branch\b)/i,/^(?:merge\b)/i,/^(?:reset\b)/i,/^(?:checkout\b)/i,/^(?:LR\b)/i,/^(?:TB\b)/i,/^(?:BT\b)/i,/^(?::)/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[a-zA-Z][a-zA-Z0-9_]+)/i,/^(?:$)/i], +conditions: {"string":{"rules":[15,16],"inclusive":false},"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17,18],"inclusive":true}} }); return lexer; })();