paul@56 | 1 | # HG changeset patch |
paul@56 | 2 | # User Paul Boddie <paul@boddie.org.uk> |
paul@57 | 3 | # Date 1337552405 -7200 |
paul@57 | 4 | # Node ID 6bf09cdbff531a07c2ccce0ee63baca33955608a |
paul@57 | 5 | # Parent 99f369f5a8dbc192cd520aece8437f3182b1ac50 |
paul@56 | 6 | hgweb: make graph data suitable for template usage |
paul@56 | 7 | |
paul@56 | 8 | Previously, graph data has been encoded for processing done by |
paul@56 | 9 | JavaScript code run in the browser, employing simple structures |
paul@56 | 10 | with implicit member positions. This patch modifies the graph |
paul@56 | 11 | command to also produce data employing a dictionary-based |
paul@56 | 12 | structure suitable for use with the templating mechanism, thus |
paul@56 | 13 | permitting other ways of presenting repository graphs using that |
paul@56 | 14 | mechanism. |
paul@56 | 15 | |
paul@56 | 16 | In order to test these changes, the raw theme has been modified |
paul@56 | 17 | to include templates for graph nodes and edges. In a similar |
paul@56 | 18 | fashion, themes could employ technologies such as SVG that lend |
paul@56 | 19 | themselves to templating to produce the graph display. This patch |
paul@56 | 20 | makes use of a much simpler output representation than SVG in |
paul@56 | 21 | order to maintain clarity. |
paul@56 | 22 | |
paul@57 | 23 | diff -r 99f369f5a8db -r 6bf09cdbff53 mercurial/hgweb/webcommands.py |
paul@57 | 24 | --- a/mercurial/hgweb/webcommands.py Tue May 15 07:01:35 2012 +0200 |
paul@57 | 25 | +++ b/mercurial/hgweb/webcommands.py Mon May 21 00:20:05 2012 +0200 |
paul@57 | 26 | @@ -784,28 +784,73 @@ |
paul@56 | 27 | |
paul@56 | 28 | dag = graphmod.dagwalker(web.repo, range(startrev, downrev - 1, -1)) |
paul@52 | 29 | tree = list(graphmod.colored(dag, web.repo)) |
paul@56 | 30 | - canvasheight = (len(tree) + 1) * bg_height - 27 |
paul@56 | 31 | - data = [] |
paul@56 | 32 | - for (id, type, ctx, vtx, edges) in tree: |
paul@56 | 33 | - if type != graphmod.CHANGESET: |
paul@56 | 34 | - continue |
paul@56 | 35 | - node = str(ctx) |
paul@56 | 36 | - age = templatefilters.age(ctx.date()) |
paul@56 | 37 | - desc = templatefilters.firstline(ctx.description()) |
paul@56 | 38 | - desc = cgi.escape(templatefilters.nonempty(desc)) |
paul@56 | 39 | - user = cgi.escape(templatefilters.person(ctx.user())) |
paul@56 | 40 | - branch = ctx.branch() |
paul@57 | 41 | - try: |
paul@57 | 42 | - branchnode = web.repo.branchtip(branch) |
paul@57 | 43 | - except error.RepoLookupError: |
paul@57 | 44 | - branchnode = None |
paul@57 | 45 | - branch = branch, branchnode == ctx.node() |
paul@52 | 46 | - data.append((node, vtx, edges, desc, user, age, branch, ctx.tags(), |
paul@52 | 47 | - ctx.bookmarks())) |
paul@57 | 48 | |
paul@56 | 49 | + def getcolumns(tree): |
paul@56 | 50 | + cols = 0 |
paul@56 | 51 | + for (id, type, ctx, vtx, edges) in tree: |
paul@56 | 52 | + if type != graphmod.CHANGESET: |
paul@56 | 53 | + continue |
paul@56 | 54 | + cols = max(cols, max([edge[0] for edge in edges] or [0]), |
paul@56 | 55 | + max([edge[1] for edge in edges] or [0])) |
paul@56 | 56 | + return cols |
paul@57 | 57 | + |
paul@56 | 58 | + def graphdata(usetuples, **map): |
paul@56 | 59 | + data = [] |
paul@57 | 60 | + |
paul@56 | 61 | + row = 0 |
paul@56 | 62 | + for (id, type, ctx, vtx, edges) in tree: |
paul@56 | 63 | + if type != graphmod.CHANGESET: |
paul@56 | 64 | + continue |
paul@56 | 65 | + node = str(ctx) |
paul@56 | 66 | + age = templatefilters.age(ctx.date()) |
paul@56 | 67 | + desc = templatefilters.firstline(ctx.description()) |
paul@56 | 68 | + desc = cgi.escape(templatefilters.nonempty(desc)) |
paul@56 | 69 | + user = cgi.escape(templatefilters.person(ctx.user())) |
paul@56 | 70 | + branch = ctx.branch() |
paul@57 | 71 | + try: |
paul@57 | 72 | + branchnode = web.repo.branchtip(branch) |
paul@57 | 73 | + except error.RepoLookupError: |
paul@57 | 74 | + branchnode = None |
paul@57 | 75 | + branch = branch, branchnode == ctx.node() |
paul@52 | 76 | + |
paul@56 | 77 | + if usetuples: |
paul@56 | 78 | + data.append((node, vtx, edges, desc, user, age, branch, ctx.tags(), |
paul@56 | 79 | + ctx.bookmarks())) |
paul@56 | 80 | + else: |
paul@56 | 81 | + edgedata = [dict(col=edge[0], nextcol=edge[1], |
paul@56 | 82 | + color=(edge[2] - 1) % 6 + 1, |
paul@56 | 83 | + width=edge[3], bcolor=edge[4]) for edge in edges] |
paul@57 | 84 | + |
paul@56 | 85 | + data.append(dict(node=node, |
paul@56 | 86 | + col=vtx[0], |
paul@56 | 87 | + color=(vtx[1] - 1) % 6 + 1, |
paul@56 | 88 | + edges=edgedata, |
paul@56 | 89 | + row=row, |
paul@56 | 90 | + nextrow=row+1, |
paul@56 | 91 | + desc=desc, |
paul@56 | 92 | + user=user, |
paul@56 | 93 | + age=age, |
paul@56 | 94 | + bookmarks=webutil.nodebookmarksdict(web.repo, ctx.node()), |
paul@56 | 95 | + branches=webutil.nodebranchdict(web.repo, ctx), |
paul@56 | 96 | + inbranch=webutil.nodeinbranch(web.repo, ctx), |
paul@56 | 97 | + tags=webutil.nodetagsdict(web.repo, ctx.node()))) |
paul@57 | 98 | + |
paul@56 | 99 | + row += 1 |
paul@57 | 100 | + |
paul@56 | 101 | + return data |
paul@56 | 102 | + |
paul@56 | 103 | + cols = getcolumns(tree) |
paul@56 | 104 | + rows = len(tree) |
paul@56 | 105 | + canvasheight = (rows + 1) * bg_height - 27 |
paul@57 | 106 | + |
paul@52 | 107 | return tmpl('graph', rev=rev, revcount=revcount, uprev=uprev, |
paul@52 | 108 | lessvars=lessvars, morevars=morevars, downrev=downrev, |
paul@56 | 109 | - canvasheight=canvasheight, jsdata=data, bg_height=bg_height, |
paul@56 | 110 | + cols=cols, rows=rows, |
paul@56 | 111 | + canvaswidth=(cols+1)*bg_height, |
paul@56 | 112 | + truecanvasheight=rows*bg_height, |
paul@56 | 113 | + canvasheight=canvasheight, bg_height=bg_height, |
paul@56 | 114 | + jsdata=lambda **x: graphdata(True, **x), |
paul@56 | 115 | + nodes=lambda **x: graphdata(False, **x), |
paul@56 | 116 | node=revnode_hex, changenav=changenav) |
paul@52 | 117 | |
paul@52 | 118 | def _getdoc(e): |
paul@57 | 119 | diff -r 99f369f5a8db -r 6bf09cdbff53 mercurial/templates/raw/graph.tmpl |
paul@57 | 120 | --- /dev/null Thu Jan 01 00:00:00 1970 +0000 |
paul@57 | 121 | +++ b/mercurial/templates/raw/graph.tmpl Mon May 21 00:20:05 2012 +0200 |
paul@57 | 122 | @@ -0,0 +1,6 @@ |
paul@57 | 123 | +{header} |
paul@57 | 124 | +# HG graph |
paul@57 | 125 | +# Node ID {node} |
paul@57 | 126 | +# Rows shown {rows} |
paul@57 | 127 | + |
paul@57 | 128 | +{nodes%graphnode} |
paul@57 | 129 | diff -r 99f369f5a8db -r 6bf09cdbff53 mercurial/templates/raw/graphedge.tmpl |
paul@57 | 130 | --- /dev/null Thu Jan 01 00:00:00 1970 +0000 |
paul@57 | 131 | +++ b/mercurial/templates/raw/graphedge.tmpl Mon May 21 00:20:05 2012 +0200 |
paul@57 | 132 | @@ -0,0 +1,1 @@ |
paul@57 | 133 | +edge: ({col}, {row}) -> ({nextcol}, {nextrow}) (color {color}) |
paul@57 | 134 | diff -r 99f369f5a8db -r 6bf09cdbff53 mercurial/templates/raw/graphnode.tmpl |
paul@57 | 135 | --- /dev/null Thu Jan 01 00:00:00 1970 +0000 |
paul@57 | 136 | +++ b/mercurial/templates/raw/graphnode.tmpl Mon May 21 00:20:05 2012 +0200 |
paul@57 | 137 | @@ -0,0 +1,7 @@ |
paul@57 | 138 | +changeset: {node} |
paul@57 | 139 | +user: {user} |
paul@57 | 140 | +date: {age} |
paul@57 | 141 | +summary: {desc} |
paul@57 | 142 | +{branches%branchname}{tags%tagname}{bookmarks%bookmarkname} |
paul@57 | 143 | +node: ({col}, {row}) (color {color}) |
paul@57 | 144 | +{edges%graphedge} |
paul@57 | 145 | diff -r 99f369f5a8db -r 6bf09cdbff53 mercurial/templates/raw/map |
paul@57 | 146 | --- a/mercurial/templates/raw/map Tue May 15 07:01:35 2012 +0200 |
paul@57 | 147 | +++ b/mercurial/templates/raw/map Mon May 21 00:20:05 2012 +0200 |
paul@55 | 148 | @@ -28,3 +28,9 @@ |
paul@55 | 149 | bookmarkentry = '{bookmark} {node}\n' |
paul@55 | 150 | branches = '{entries%branchentry}' |
paul@55 | 151 | branchentry = '{branch} {node} {status}\n' |
paul@55 | 152 | +graph = graph.tmpl |
paul@55 | 153 | +graphnode = graphnode.tmpl |
paul@55 | 154 | +graphedge = graphedge.tmpl |
paul@55 | 155 | +bookmarkname = 'bookmark: {name}\n' |
paul@55 | 156 | +branchname = 'branch: {name}\n' |
paul@55 | 157 | +tagname = 'tag: {name}\n' |
paul@57 | 158 | diff -r 99f369f5a8db -r 6bf09cdbff53 tests/test-hgweb-commands.t |
paul@57 | 159 | --- a/tests/test-hgweb-commands.t Tue May 15 07:01:35 2012 +0200 |
paul@57 | 160 | +++ b/tests/test-hgweb-commands.t Mon May 21 00:20:05 2012 +0200 |
paul@57 | 161 | @@ -1047,6 +1047,55 @@ |
paul@55 | 162 | </body> |
paul@55 | 163 | </html> |
paul@56 | 164 | |
paul@55 | 165 | +raw graph |
paul@55 | 166 | + |
paul@55 | 167 | + $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/graph/?style=raw' |
paul@55 | 168 | + 200 Script output follows |
paul@55 | 169 | + |
paul@55 | 170 | + |
paul@55 | 171 | + # HG graph |
paul@55 | 172 | + # Node ID ba87b23d29ca67a305625d81a20ac279c1e3f444 |
paul@55 | 173 | + # Rows shown 4 |
paul@55 | 174 | + |
paul@55 | 175 | + changeset: ba87b23d29ca |
paul@55 | 176 | + user: test |
paul@55 | 177 | + date: 1970-01-01 |
paul@55 | 178 | + summary: branch |
paul@55 | 179 | + branch: unstable |
paul@55 | 180 | + tag: tip |
paul@55 | 181 | + bookmark: something |
paul@55 | 182 | + |
paul@55 | 183 | + node: (0, 0) (color 1) |
paul@55 | 184 | + edge: (0, 0) -> (0, 1) (color 1) |
paul@55 | 185 | + |
paul@55 | 186 | + changeset: 1d22e65f027e |
paul@55 | 187 | + user: test |
paul@55 | 188 | + date: 1970-01-01 |
paul@55 | 189 | + summary: branch |
paul@55 | 190 | + branch: stable |
paul@55 | 191 | + |
paul@55 | 192 | + node: (0, 1) (color 1) |
paul@55 | 193 | + edge: (0, 1) -> (0, 2) (color 1) |
paul@55 | 194 | + |
paul@55 | 195 | + changeset: a4f92ed23982 |
paul@55 | 196 | + user: test |
paul@55 | 197 | + date: 1970-01-01 |
paul@55 | 198 | + summary: Added tag 1.0 for changeset 2ef0ac749a14 |
paul@55 | 199 | + branch: default |
paul@55 | 200 | + |
paul@55 | 201 | + node: (0, 2) (color 1) |
paul@55 | 202 | + edge: (0, 2) -> (0, 3) (color 1) |
paul@55 | 203 | + |
paul@55 | 204 | + changeset: 2ef0ac749a14 |
paul@55 | 205 | + user: test |
paul@55 | 206 | + date: 1970-01-01 |
paul@55 | 207 | + summary: base |
paul@55 | 208 | + tag: 1.0 |
paul@55 | 209 | + bookmark: anotherthing |
paul@55 | 210 | + |
paul@55 | 211 | + node: (0, 3) (color 1) |
paul@55 | 212 | + |
paul@56 | 213 | + |
paul@54 | 214 | |
paul@54 | 215 | capabilities |
paul@54 | 216 | |