1.1 --- a/patches/patch-hgweb-graph-data.diff Sun Apr 29 20:57:36 2012 +0200
1.2 +++ b/patches/patch-hgweb-graph-data.diff Sun May 20 18:39:14 2012 +0200
1.3 @@ -1,86 +1,116 @@
1.4 -diff -r 55982f62651f mercurial/hgweb/webcommands.py
1.5 ---- a/mercurial/hgweb/webcommands.py Wed Apr 18 01:20:16 2012 +0300
1.6 -+++ b/mercurial/hgweb/webcommands.py Sun Apr 29 20:56:26 2012 +0200
1.7 -@@ -785,6 +785,8 @@
1.8 +# HG changeset patch
1.9 +# User Paul Boddie <paul@boddie.org.uk>
1.10 +# Date 1337531723 -7200
1.11 +# Node ID 9488fd4c05876377ad4e3b2ca4c60713d20bf917
1.12 +# Parent d7c9976b930e1fdbf8608a65462cd124977c7d53
1.13 +hgweb: make graph data suitable for template usage
1.14 +
1.15 +Previously, graph data has been encoded for processing done by
1.16 +JavaScript code run in the browser, employing simple structures
1.17 +with implicit member positions. This patch modifies the graph
1.18 +command to also produce data employing a dictionary-based
1.19 +structure suitable for use with the templating mechanism, thus
1.20 +permitting other ways of presenting repository graphs using that
1.21 +mechanism.
1.22 +
1.23 +In order to test these changes, the raw theme has been modified
1.24 +to include templates for graph nodes and edges. In a similar
1.25 +fashion, themes could employ technologies such as SVG that lend
1.26 +themselves to templating to produce the graph display. This patch
1.27 +makes use of a much simpler output representation than SVG in
1.28 +order to maintain clarity.
1.29 +
1.30 +diff -r d7c9976b930e -r 9488fd4c0587 mercurial/hgweb/webcommands.py
1.31 +--- a/mercurial/hgweb/webcommands.py Wed May 02 13:20:06 2012 +0200
1.32 ++++ b/mercurial/hgweb/webcommands.py Sun May 20 18:35:23 2012 +0200
1.33 +@@ -783,24 +783,69 @@
1.34 +
1.35 + dag = graphmod.dagwalker(web.repo, range(startrev, downrev - 1, -1))
1.36 tree = list(graphmod.colored(dag, web.repo))
1.37 - canvasheight = (len(tree) + 1) * bg_height - 27
1.38 - data = []
1.39 -+ cols = 0
1.40 -+ row = 0
1.41 - for (id, type, ctx, vtx, edges) in tree:
1.42 - if type != graphmod.CHANGESET:
1.43 - continue
1.44 -@@ -795,13 +797,38 @@
1.45 - user = cgi.escape(templatefilters.person(ctx.user()))
1.46 - branch = ctx.branch()
1.47 - branch = branch, web.repo.branchtags().get(branch) == ctx.node()
1.48 +- canvasheight = (len(tree) + 1) * bg_height - 27
1.49 +- data = []
1.50 +- for (id, type, ctx, vtx, edges) in tree:
1.51 +- if type != graphmod.CHANGESET:
1.52 +- continue
1.53 +- node = str(ctx)
1.54 +- age = templatefilters.age(ctx.date())
1.55 +- desc = templatefilters.firstline(ctx.description())
1.56 +- desc = cgi.escape(templatefilters.nonempty(desc))
1.57 +- user = cgi.escape(templatefilters.person(ctx.user()))
1.58 +- branch = ctx.branch()
1.59 +- branch = branch, web.repo.branchtags().get(branch) == ctx.node()
1.60 - data.append((node, vtx, edges, desc, user, age, branch, ctx.tags(),
1.61 - ctx.bookmarks()))
1.62 +
1.63 -+ edgedata = [dict(col=edge[0], nextcol=edge[1],
1.64 -+ color=(edge[2] - 1) % 6 + 1,
1.65 -+ width=edge[3], bcolor=edge[4]) for edge in edges]
1.66 ++ def getcolumns(tree):
1.67 ++ cols = 0
1.68 ++ for (id, type, ctx, vtx, edges) in tree:
1.69 ++ if type != graphmod.CHANGESET:
1.70 ++ continue
1.71 ++ cols = max(cols, max([edge[0] for edge in edges] or [0]),
1.72 ++ max([edge[1] for edge in edges] or [0]))
1.73 ++ return cols
1.74 ++
1.75 ++ def graphdata(usetuples, **map):
1.76 ++ data = []
1.77 ++
1.78 ++ row = 0
1.79 ++ for (id, type, ctx, vtx, edges) in tree:
1.80 ++ if type != graphmod.CHANGESET:
1.81 ++ continue
1.82 ++ node = str(ctx)
1.83 ++ age = templatefilters.age(ctx.date())
1.84 ++ desc = templatefilters.firstline(ctx.description())
1.85 ++ desc = cgi.escape(templatefilters.nonempty(desc))
1.86 ++ user = cgi.escape(templatefilters.person(ctx.user()))
1.87 ++ branch = ctx.branch()
1.88 ++ branch = branch, web.repo.branchtags().get(branch) == ctx.node()
1.89 +
1.90 -+ data.append(dict(node=node,
1.91 -+ col=vtx[0],
1.92 -+ color=(vtx[1] - 1) % 6 + 1,
1.93 -+ edges=edgedata,
1.94 -+ row=row,
1.95 -+ nextrow=row+1,
1.96 -+ desc=desc,
1.97 -+ user=user,
1.98 -+ age=age,
1.99 -+ bookmarks=webutil.nodebookmarksdict(web.repo, ctx.node()),
1.100 -+ branches=webutil.nodebranchdict(web.repo, ctx),
1.101 -+ inbranch=webutil.nodeinbranch(web.repo, ctx),
1.102 -+ tags=webutil.nodetagsdict(web.repo, ctx.node()),
1.103 -+ # convenience values for the canvas graph
1.104 -+ branchname=branch[0],
1.105 -+ branchtip=branch[1]))
1.106 ++ if usetuples:
1.107 ++ data.append((node, vtx, edges, desc, user, age, branch, ctx.tags(),
1.108 ++ ctx.bookmarks()))
1.109 ++ else:
1.110 ++ edgedata = [dict(col=edge[0], nextcol=edge[1],
1.111 ++ color=(edge[2] - 1) % 6 + 1,
1.112 ++ width=edge[3], bcolor=edge[4]) for edge in edges]
1.113 +
1.114 -+ cols = max(cols, max([edge[0] for edge in edges] or [0]),
1.115 -+ max([edge[1] for edge in edges] or [0]))
1.116 -+ row += 1
1.117 ++ data.append(dict(node=node,
1.118 ++ col=vtx[0],
1.119 ++ color=(vtx[1] - 1) % 6 + 1,
1.120 ++ edges=edgedata,
1.121 ++ row=row,
1.122 ++ nextrow=row+1,
1.123 ++ desc=desc,
1.124 ++ user=user,
1.125 ++ age=age,
1.126 ++ bookmarks=webutil.nodebookmarksdict(web.repo, ctx.node()),
1.127 ++ branches=webutil.nodebranchdict(web.repo, ctx),
1.128 ++ inbranch=webutil.nodeinbranch(web.repo, ctx),
1.129 ++ tags=webutil.nodetagsdict(web.repo, ctx.node())))
1.130 ++
1.131 ++ row += 1
1.132 ++
1.133 ++ return data
1.134 ++
1.135 ++ cols = getcolumns(tree)
1.136 ++ rows = len(tree)
1.137 ++ canvasheight = (rows + 1) * bg_height - 27
1.138
1.139 return tmpl('graph', rev=rev, revcount=revcount, uprev=uprev,
1.140 lessvars=lessvars, morevars=morevars, downrev=downrev,
1.141 - canvasheight=canvasheight, jsdata=data, bg_height=bg_height,
1.142 -- node=revnode_hex, changenav=changenav)
1.143 -+ node=revnode_hex, changenav=changenav,
1.144 -+ rows=row, cols=cols, canvaswidth=(cols+1)*bg_height,
1.145 -+ truecanvasheight=row*bg_height)
1.146 +- canvasheight=canvasheight, jsdata=data, bg_height=bg_height,
1.147 ++ cols=cols, rows=rows,
1.148 ++ canvaswidth=(cols+1)*bg_height,
1.149 ++ truecanvasheight=rows*bg_height,
1.150 ++ canvasheight=canvasheight, bg_height=bg_height,
1.151 ++ jsdata=lambda **x: graphdata(True, **x),
1.152 ++ nodes=lambda **x: graphdata(False, **x),
1.153 + node=revnode_hex, changenav=changenav)
1.154
1.155 def _getdoc(e):
1.156 - doc = e[0].__doc__
1.157 -diff -r 55982f62651f mercurial/templates/raw/graph.tmpl
1.158 ---- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.159 -+++ b/mercurial/templates/raw/graph.tmpl Sun Apr 29 20:56:26 2012 +0200
1.160 -@@ -0,0 +1,6 @@
1.161 -+{header}
1.162 -+# HG graph
1.163 -+# Node ID {node}
1.164 -+# Rows shown {rows}
1.165 -+
1.166 -+{jsdata%graphnode}
1.167 -diff -r 55982f62651f mercurial/templates/raw/graphedge.tmpl
1.168 ---- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.169 -+++ b/mercurial/templates/raw/graphedge.tmpl Sun Apr 29 20:56:26 2012 +0200
1.170 -@@ -0,0 +1,1 @@
1.171 -+edge: ({col}, {row}) -> ({nextcol}, {nextrow}) (color {color})
1.172 -diff -r 55982f62651f mercurial/templates/raw/graphnode.tmpl
1.173 ---- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.174 -+++ b/mercurial/templates/raw/graphnode.tmpl Sun Apr 29 20:56:26 2012 +0200
1.175 -@@ -0,0 +1,7 @@
1.176 -+changeset: {node}
1.177 -+user: {user}
1.178 -+date: {age}
1.179 -+summary: {desc}
1.180 -+{branches%branchname}{tags%tagname}{bookmarks%bookmarkname}
1.181 -+node: ({col}, {row}) (color {color})
1.182 -+{edges%graphedge}
1.183 -diff -r 55982f62651f mercurial/templates/raw/map
1.184 ---- a/mercurial/templates/raw/map Wed Apr 18 01:20:16 2012 +0300
1.185 -+++ b/mercurial/templates/raw/map Sun Apr 29 20:56:26 2012 +0200
1.186 +diff -r d7c9976b930e -r 9488fd4c0587 mercurial/templates/raw/map
1.187 +--- a/mercurial/templates/raw/map Wed May 02 13:20:06 2012 +0200
1.188 ++++ b/mercurial/templates/raw/map Sun May 20 18:35:23 2012 +0200
1.189 @@ -28,3 +28,9 @@
1.190 bookmarkentry = '{bookmark} {node}\n'
1.191 branches = '{entries%branchentry}'
1.192 @@ -91,95 +121,13 @@
1.193 +bookmarkname = 'bookmark: {name}\n'
1.194 +branchname = 'branch: {name}\n'
1.195 +tagname = 'tag: {name}\n'
1.196 -diff -r 55982f62651f mercurial/templates/static/mercurial.js
1.197 ---- a/mercurial/templates/static/mercurial.js Wed Apr 18 01:20:16 2012 +0300
1.198 -+++ b/mercurial/templates/static/mercurial.js Sun Apr 29 20:56:26 2012 +0200
1.199 -@@ -108,21 +108,22 @@
1.200 - this.bg[1] += this.bg_height;
1.201 -
1.202 - var cur = data[i];
1.203 -- var node = cur[1];
1.204 -- var edges = cur[2];
1.205 -+ var column = cur["col"];
1.206 -+ var color;
1.207 -+ var edges = cur["edges"];
1.208 - var fold = false;
1.209 -
1.210 - var prevWidth = this.ctx.lineWidth;
1.211 - for (var j in edges) {
1.212 -
1.213 - line = edges[j];
1.214 -- start = line[0];
1.215 -- end = line[1];
1.216 -- color = line[2];
1.217 -- var width = line[3];
1.218 -+ start = line["col"];
1.219 -+ end = line["nextcol"];
1.220 -+ color = line["color"];
1.221 -+ var width = line["width"];
1.222 - if(width < 0)
1.223 - width = prevWidth;
1.224 -- var branchcolor = line[4];
1.225 -+ var branchcolor = line["bcolor"];
1.226 - if(branchcolor)
1.227 - color = branchcolor;
1.228 -
1.229 -@@ -146,13 +147,12 @@
1.230 -
1.231 - // Draw the revision node in the right column
1.232 -
1.233 -- column = node[0]
1.234 -- color = node[1]
1.235 -+ color = cur["color"];
1.236 -
1.237 - radius = this.box_size / 8;
1.238 - x = this.cell[0] + this.box_size * column + this.box_size / 2;
1.239 - y = this.bg[1] - this.bg_height / 2;
1.240 -- var add = this.vertex(x, y, color, parity, cur);
1.241 -+ var add = this.vertexForEntry(x, y, color, parity, cur);
1.242 - backgrounds += add[0];
1.243 - nodedata += add[1];
1.244 -
1.245 -@@ -165,6 +165,21 @@
1.246 -
1.247 - }
1.248 -
1.249 -+ this.vertexForEntry = function(x, y, color, parity, cur) {
1.250 -+ var tags = [], bookmarks = [];
1.251 -+ for (var i in cur["tags"]) {
1.252 -+ tags.push(cur["tags"][i]["name"]);
1.253 -+ }
1.254 -+ for (var i in cur["bookmarks"]) {
1.255 -+ bookmarks.push(cur["bookmarks"][i]["name"]);
1.256 -+ }
1.257 -+ return this.vertex(x, y, color, parity, [
1.258 -+ cur["node"], [cur["col"], cur["color"]],
1.259 -+ cur["edges"], cur["desc"], cur["user"], cur["age"],
1.260 -+ [cur["branchname"], cur["branchtip"]],
1.261 -+ tags, bookmarks
1.262 -+ ])
1.263 -+ }
1.264 - }
1.265 -
1.266 -
1.267 -diff -r 55982f62651f tests/test-hgweb-commands.t
1.268 ---- a/tests/test-hgweb-commands.t Wed Apr 18 01:20:16 2012 +0300
1.269 -+++ b/tests/test-hgweb-commands.t Sun Apr 29 20:56:26 2012 +0200
1.270 -@@ -957,7 +957,7 @@
1.271 - <script>
1.272 - <!-- hide script content
1.273 -
1.274 -- var data = [["ba87b23d29ca", [0, 1], [[0, 0, 1, 3, "FF0000"]], "branch", "test", "1970-01-01", ["unstable", true], ["tip"], ["something"]], ["1d22e65f027e", [0, 1], [[0, 0, 1, 3, ""]], "branch", "test", "1970-01-01", ["stable", true], [], []], ["a4f92ed23982", [0, 1], [[0, 0, 1, 3, ""]], "Added tag 1.0 for changeset 2ef0ac749a14", "test", "1970-01-01", ["default", true], [], []], ["2ef0ac749a14", [0, 1], [], "base", "test", "1970-01-01", ["default", false], ["1.0"], ["anotherthing"]]];
1.275 -+ var data = [{"node": "ba87b23d29ca", "branches": [{"name": "unstable"}], "desc": "branch", "tags": [{"name": "tip"}], "color": 1, "age": "1970-01-01", "inbranch": [], "nextrow": 1, "edges": [{"color": 1, "width": 3, "nextcol": 0, "bcolor": "FF0000", "col": 0}], "user": "test", "branchtip": true, "bookmarks": [{"name": "something"}], "branchname": "unstable", "col": 0, "row": 0}, {"node": "1d22e65f027e", "branches": [{"name": "stable"}], "desc": "branch", "tags": [], "color": 1, "age": "1970-01-01", "inbranch": [], "nextrow": 2, "edges": [{"color": 1, "width": 3, "nextcol": 0, "bcolor": "", "col": 0}], "user": "test", "branchtip": true, "bookmarks": [], "branchname": "stable", "col": 0, "row": 1}, {"node": "a4f92ed23982", "branches": [{"name": "default"}], "desc": "Added tag 1.0 for changeset 2ef0ac749a14", "tags": [], "color": 1, "age": "1970-01-01", "inbranch": [], "nextrow": 3, "edges": [{"color": 1, "width": 3, "nextcol": 0, "bcolor": "", "col": 0}], "user": "test", "branchtip": true, "bookmarks": [], "branchname": "default", "col": 0, "row": 2}, {"node": "2ef0ac749a14", "branches": [], "desc": "base", "tags": [{"name": "1.0"}], "color": 1, "age": "1970-01-01", "inbranch": [], "nextrow": 4, "edges": [], "user": "test", "branchtip": false, "bookmarks": [{"name": "anotherthing"}], "branchname": "default", "col": 0, "row": 3}];
1.276 - var graph = new Graph();
1.277 - graph.scale(39);
1.278 -
1.279 -@@ -1037,6 +1037,56 @@
1.280 - </div>
1.281 +diff -r d7c9976b930e -r 9488fd4c0587 tests/test-hgweb-commands.t
1.282 +--- a/tests/test-hgweb-commands.t Wed May 02 13:20:06 2012 +0200
1.283 ++++ b/tests/test-hgweb-commands.t Sun May 20 18:35:23 2012 +0200
1.284 +@@ -1038,6 +1038,55 @@
1.285 </body>
1.286 </html>
1.287 -+
1.288 -+
1.289 +
1.290 +raw graph
1.291 +
1.292 + $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/graph/?style=raw'
1.293 @@ -228,15 +176,7 @@
1.294 +
1.295 + node: (0, 3) (color 1)
1.296 +
1.297 -
1.298 -
1.299 - capabilities
1.300 -@@ -1214,7 +1264,7 @@
1.301 -
1.302 - $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/graph/' \
1.303 - > | grep '^var data ='
1.304 -- var data = [["548001d11f45", [0, 1], [[0, 0, 1, -1, ""]], "\u80fd", "test", "1970-01-01", ["unstable", true], ["tip"], ["something"]], ["ba87b23d29ca", [0, 1], [[0, 0, 1, 3, "FF0000"]], "branch", "test", "1970-01-01", ["unstable", false], [], []], ["1d22e65f027e", [0, 1], [[0, 0, 1, 3, ""]], "branch", "test", "1970-01-01", ["stable", true], [], []], ["a4f92ed23982", [0, 1], [[0, 0, 1, 3, ""]], "Added tag 1.0 for changeset 2ef0ac749a14", "test", "1970-01-01", ["default", true], [], []], ["2ef0ac749a14", [0, 1], [], "base", "test", "1970-01-01", ["default", false], ["1.0"], ["anotherthing"]]];
1.305 -+ var data = [{"node": "548001d11f45", "branches": [{"name": "unstable"}], "desc": "\u80fd", "tags": [{"name": "tip"}], "color": 1, "age": "1970-01-01", "inbranch": [], "nextrow": 1, "edges": [{"color": 1, "width": -1, "nextcol": 0, "bcolor": "", "col": 0}], "user": "test", "branchtip": true, "bookmarks": [{"name": "something"}], "branchname": "unstable", "col": 0, "row": 0}, {"node": "ba87b23d29ca", "branches": [], "desc": "branch", "tags": [], "color": 1, "age": "1970-01-01", "inbranch": [{"name": "unstable"}], "nextrow": 2, "edges": [{"color": 1, "width": 3, "nextcol": 0, "bcolor": "FF0000", "col": 0}], "user": "test", "branchtip": false, "bookmarks": [], "branchname": "unstable", "col": 0, "row": 1}, {"node": "1d22e65f027e", "branches": [{"name": "stable"}], "desc": "branch", "tags": [], "color": 1, "age": "1970-01-01", "inbranch": [], "nextrow": 3, "edges": [{"color": 1, "width": 3, "nextcol": 0, "bcolor": "", "col": 0}], "user": "test", "branchtip": true, "bookmarks": [], "branchname": "stable", "col": 0, "row": 2}, {"node": "a4f92ed23982", "branches": [{"name": "default"}], "desc": "Added tag 1.0 for changeset 2ef0ac749a14", "tags": [], "color": 1, "age": "1970-01-01", "inbranch": [], "nextrow": 4, "edges": [{"color": 1, "width": 3, "nextcol": 0, "bcolor": "", "col": 0}], "user": "test", "branchtip": true, "bookmarks": [], "branchname": "default", "col": 0, "row": 3}, {"node": "2ef0ac749a14", "branches": [], "desc": "base", "tags": [{"name": "1.0"}], "color": 1, "age": "1970-01-01", "inbranch": [], "nextrow": 5, "edges": [], "user": "test", "branchtip": false, "bookmarks": [{"name": "anotherthing"}], "branchname": "default", "col": 0, "row": 4}];
1.306 ++
1.307
1.308 capabilities
1.309