mercurial/graphmod.py
author Martin von Zweigbergk <martinvonz@google.com>
Wed, 13 Dec 2017 17:03:39 -0800
changeset 35435 f01101100043
parent 33858 6f6c87888b22
child 35546 5e1d4ccab455
permissions -rw-r--r--
unamend: allow unamending if allowunstable is set I don't see why unamend should be disallowed when allowunstable is set. By switching to rewriteutil.precheck() we fix that and get more consistent error messages (and some additional ones). Differential Revision: https://phab.mercurial-scm.org/D1682
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
     1
# Revision graph generator for Mercurial
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
     2
#
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
     3
# Copyright 2008 Dirkjan Ochtman <dirkjan@ochtman.nl>
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
     4
# Copyright 2007 Joel Rosdahl <joel@rosdahl.net>
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
     5
#
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 7873
diff changeset
     6
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 10084
diff changeset
     7
# GNU General Public License version 2 or any later version.
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
     8
8840
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
     9
"""supports walking the history as DAGs suitable for graphical output
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    10
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    11
The most basic format we use is that of::
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    12
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    13
  (id, type, data, [parentids])
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    14
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    15
The node and parent ids are arbitrary integers which identify a node in the
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    16
context of the graph returned. Type is a constant specifying the node type.
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    17
Data depends on type.
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    18
"""
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    19
25951
69751804f2f5 graphmod: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24180
diff changeset
    20
from __future__ import absolute_import
8840
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    21
25951
69751804f2f5 graphmod: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24180
diff changeset
    22
from .node import nullrev
26003
62371c539c89 revset: remove grandparent by using reachableroots
Laurent Charignon <lcharignon@fb.com>
parents: 25951
diff changeset
    23
from . import (
32903
27932a76a88d dagop: split module hosting DAG-related algorithms from revset
Yuya Nishihara <yuya@tcha.org>
parents: 32160
diff changeset
    24
    dagop,
31023
aea06029919e revset: import set classes directly from smartset module
Yuya Nishihara <yuya@tcha.org>
parents: 29348
diff changeset
    25
    smartset,
26003
62371c539c89 revset: remove grandparent by using reachableroots
Laurent Charignon <lcharignon@fb.com>
parents: 25951
diff changeset
    26
    util,
62371c539c89 revset: remove grandparent by using reachableroots
Laurent Charignon <lcharignon@fb.com>
parents: 25951
diff changeset
    27
)
25951
69751804f2f5 graphmod: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24180
diff changeset
    28
8840
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    29
CHANGESET = 'C'
28376
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    30
PARENT = 'P'
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    31
GRANDPARENT = 'G'
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    32
MISSINGPARENT = 'M'
28601
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
    33
# Style of line to draw. None signals a line that ends and is removed at this
29134
8d5584d8345b graphmod: partial edge styling
Martijn Pieters <mjpieters@fb.com>
parents: 28998
diff changeset
    34
# point. A number prefix means only the last N characters of the current block
8d5584d8345b graphmod: partial edge styling
Martijn Pieters <mjpieters@fb.com>
parents: 28998
diff changeset
    35
# will use that style, the rest will use the PARENT style. Add a - sign
8d5584d8345b graphmod: partial edge styling
Martijn Pieters <mjpieters@fb.com>
parents: 28998
diff changeset
    36
# (so making N negative) and all but the first N characters use that style.
28627
d7af9b4ae7dd graphmod: set default edge styles for ascii graphs (BC)
Martijn Pieters <mjpieters@fb.com>
parents: 28601
diff changeset
    37
EDGES = {PARENT: '|', GRANDPARENT: ':', MISSINGPARENT: None}
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
    38
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    39
def dagwalker(repo, revs):
28376
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    40
    """cset DAG generator yielding (id, CHANGESET, ctx, [parentinfo]) tuples
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    41
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    42
    This generator function walks through revisions (which should be ordered
28376
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    43
    from bigger to lower). It returns a tuple for each node.
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    44
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    45
    Each parentinfo entry is a tuple with (edgetype, parentid), where edgetype
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    46
    is one of PARENT, GRANDPARENT or MISSINGPARENT. The node and parent ids
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    47
    are arbitrary integers which identify a node in the context of the graph
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    48
    returned.
28376
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    49
8836
11ff34956ee7 graphmod/graphlog: move log walks to graphmod
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8835
diff changeset
    50
    """
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    51
    if not revs:
14087
f3d585c9b042 graphmod: restore generator nature of dagwalker
Idan Kamara <idankk86@gmail.com>
parents: 14064
diff changeset
    52
        return
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    53
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    54
    gpcache = {}
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    55
14087
f3d585c9b042 graphmod: restore generator nature of dagwalker
Idan Kamara <idankk86@gmail.com>
parents: 14064
diff changeset
    56
    for rev in revs:
f3d585c9b042 graphmod: restore generator nature of dagwalker
Idan Kamara <idankk86@gmail.com>
parents: 14064
diff changeset
    57
        ctx = repo[rev]
28376
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    58
        # partition into parents in the rev set and missing parents, then
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    59
        # augment the lists with markers, to inform graph drawing code about
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    60
        # what kind of edge to draw between nodes.
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    61
        pset = set(p.rev() for p in ctx.parents() if p.rev() in revs)
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    62
        mpars = [p.rev() for p in ctx.parents()
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    63
                 if p.rev() != nullrev and p.rev() not in pset]
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    64
        parents = [(PARENT, p) for p in sorted(pset)]
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    65
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    66
        for mpar in mpars:
14131
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
    67
            gp = gpcache.get(mpar)
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    68
            if gp is None:
26187
9cf65f43b49b graphmod: compute slow revset query once prior to reachableroots (issue4782)
Yuya Nishihara <yuya@tcha.org>
parents: 26092
diff changeset
    69
                # precompute slow query as we know reachableroots() goes
9cf65f43b49b graphmod: compute slow revset query once prior to reachableroots (issue4782)
Yuya Nishihara <yuya@tcha.org>
parents: 26092
diff changeset
    70
                # through all revs (issue4782)
31023
aea06029919e revset: import set classes directly from smartset module
Yuya Nishihara <yuya@tcha.org>
parents: 29348
diff changeset
    71
                if not isinstance(revs, smartset.baseset):
aea06029919e revset: import set classes directly from smartset module
Yuya Nishihara <yuya@tcha.org>
parents: 29348
diff changeset
    72
                    revs = smartset.baseset(revs)
32903
27932a76a88d dagop: split module hosting DAG-related algorithms from revset
Yuya Nishihara <yuya@tcha.org>
parents: 32160
diff changeset
    73
                gp = gpcache[mpar] = sorted(set(dagop.reachableroots(
28376
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    74
                    repo, revs, [mpar])))
14131
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
    75
            if not gp:
28376
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    76
                parents.append((MISSINGPARENT, mpar))
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    77
                pset.add(mpar)
14131
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
    78
            else:
28376
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    79
                parents.extend((GRANDPARENT, g) for g in gp if g not in pset)
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    80
                pset.update(gp)
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    81
14087
f3d585c9b042 graphmod: restore generator nature of dagwalker
Idan Kamara <idankk86@gmail.com>
parents: 14064
diff changeset
    82
        yield (ctx.rev(), CHANGESET, ctx, parents)
8836
11ff34956ee7 graphmod/graphlog: move log walks to graphmod
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8835
diff changeset
    83
8837
d8e3a98018cb graphmod/graphlog: extract nodelistwalk
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8836
diff changeset
    84
def nodes(repo, nodes):
8840
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    85
    """cset DAG generator yielding (id, CHANGESET, ctx, [parentids]) tuples
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    86
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    87
    This generator function walks the given nodes. It only returns parents
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    88
    that are in nodes, too.
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    89
    """
8837
d8e3a98018cb graphmod/graphlog: extract nodelistwalk
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8836
diff changeset
    90
    include = set(nodes)
d8e3a98018cb graphmod/graphlog: extract nodelistwalk
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8836
diff changeset
    91
    for node in nodes:
d8e3a98018cb graphmod/graphlog: extract nodelistwalk
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8836
diff changeset
    92
        ctx = repo[node]
28376
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    93
        parents = set((PARENT, p.rev()) for p in ctx.parents()
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    94
                      if p.node() in include)
8840
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    95
        yield (ctx.rev(), CHANGESET, ctx, sorted(parents))
8837
d8e3a98018cb graphmod/graphlog: extract nodelistwalk
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8836
diff changeset
    96
16129
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
    97
def colored(dag, repo):
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
    98
    """annotates a DAG with colored edge information
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
    99
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   100
    For each DAG node this function emits tuples::
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   101
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   102
      (id, type, data, (col, color), [(col, nextcol, color)])
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   103
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   104
    with the following new elements:
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   105
8835
ec5483efc31f graphmod: code cleanup and doc fix
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8225
diff changeset
   106
      - Tuple (col, color) with column and color index for the current node
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   107
      - A list of tuples indicating the edges between the current node and its
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   108
        parents.
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   109
    """
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   110
    seen = []
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   111
    colors = {}
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   112
    newcolor = 1
16129
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   113
    config = {}
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   114
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   115
    for key, val in repo.ui.configitems('graph'):
16131
6f236c8bdc01 graphmod: rewrite graph config validation
Matt Mackall <mpm@selenic.com>
parents: 16130
diff changeset
   116
        if '.' in key:
6f236c8bdc01 graphmod: rewrite graph config validation
Matt Mackall <mpm@selenic.com>
parents: 16130
diff changeset
   117
            branch, setting = key.rsplit('.', 1)
6f236c8bdc01 graphmod: rewrite graph config validation
Matt Mackall <mpm@selenic.com>
parents: 16130
diff changeset
   118
            # Validation
6f236c8bdc01 graphmod: rewrite graph config validation
Matt Mackall <mpm@selenic.com>
parents: 16130
diff changeset
   119
            if setting == "width" and val.isdigit():
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   120
                config.setdefault(branch, {})[setting] = int(val)
16131
6f236c8bdc01 graphmod: rewrite graph config validation
Matt Mackall <mpm@selenic.com>
parents: 16130
diff changeset
   121
            elif setting == "color" and val.isalnum():
6f236c8bdc01 graphmod: rewrite graph config validation
Matt Mackall <mpm@selenic.com>
parents: 16130
diff changeset
   122
                config.setdefault(branch, {})[setting] = val
16129
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   123
16132
41fc1e078d68 graphmod: add config cache
Matt Mackall <mpm@selenic.com>
parents: 16131
diff changeset
   124
    if config:
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   125
        getconf = util.lrucachefunc(
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   126
            lambda rev: config.get(repo[rev].branch(), {}))
16132
41fc1e078d68 graphmod: add config cache
Matt Mackall <mpm@selenic.com>
parents: 16131
diff changeset
   127
    else:
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   128
        getconf = lambda rev: {}
16129
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   129
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   130
    for (cur, type, data, parents) in dag:
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   131
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   132
        # Compute seen and next
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   133
        if cur not in seen:
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   134
            seen.append(cur) # new head
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   135
            colors[cur] = newcolor
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   136
            newcolor += 1
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   137
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   138
        col = seen.index(cur)
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   139
        color = colors.pop(cur)
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   140
        next = seen[:]
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   141
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   142
        # Add parents to next
28376
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
   143
        addparents = [p for pt, p in parents if p not in next]
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   144
        next[col:col + 1] = addparents
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   145
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   146
        # Set colors for the parents
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   147
        for i, p in enumerate(addparents):
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   148
            if not i:
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   149
                colors[p] = color
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   150
            else:
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   151
                colors[p] = newcolor
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   152
                newcolor += 1
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   153
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   154
        # Add edges to the graph
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   155
        edges = []
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   156
        for ecol, eid in enumerate(seen):
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   157
            if eid in next:
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   158
                bconf = getconf(eid)
16129
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   159
                edges.append((
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   160
                    ecol, next.index(eid), colors[eid],
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   161
                    bconf.get('width', -1),
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   162
                    bconf.get('color', '')))
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   163
            elif eid == cur:
28376
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
   164
                for ptype, p in parents:
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   165
                    bconf = getconf(p)
16129
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   166
                    edges.append((
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   167
                        ecol, next.index(p), color,
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   168
                        bconf.get('width', -1),
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   169
                        bconf.get('color', '')))
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   170
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   171
        # Yield and move on
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   172
        yield (cur, type, data, (col, color), edges)
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   173
        seen = next
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   174
33858
6f6c87888b22 log: add a "graphwidth" template variable
Danny Hooper <hooper@google.com>
parents: 32903
diff changeset
   175
def asciiedges(type, char, state, rev, parents):
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   176
    """adds edge info to changelog DAG walk suitable for ascii()"""
28375
97cb1aeaca78 graphmod: refactor state handling
Martijn Pieters <mjpieters@fb.com>
parents: 26187
diff changeset
   177
    seen = state['seen']
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   178
    if rev not in seen:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   179
        seen.append(rev)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   180
    nodeidx = seen.index(rev)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   181
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   182
    knownparents = []
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   183
    newparents = []
28376
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
   184
    for ptype, parent in parents:
31552
d0b9e9803caf graphlog: draw multiple edges towards null node (issue5440)
Yuya Nishihara <yuya@tcha.org>
parents: 31023
diff changeset
   185
        if parent == rev:
d0b9e9803caf graphlog: draw multiple edges towards null node (issue5440)
Yuya Nishihara <yuya@tcha.org>
parents: 31023
diff changeset
   186
            # self reference (should only be seen in null rev)
d0b9e9803caf graphlog: draw multiple edges towards null node (issue5440)
Yuya Nishihara <yuya@tcha.org>
parents: 31023
diff changeset
   187
            continue
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   188
        if parent in seen:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   189
            knownparents.append(parent)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   190
        else:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   191
            newparents.append(parent)
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   192
            state['edges'][parent] = state['styles'].get(ptype, '|')
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   193
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   194
    ncols = len(seen)
33858
6f6c87888b22 log: add a "graphwidth" template variable
Danny Hooper <hooper@google.com>
parents: 32903
diff changeset
   195
    width = 1 + ncols * 2
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   196
    nextseen = seen[:]
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   197
    nextseen[nodeidx:nodeidx + 1] = newparents
31552
d0b9e9803caf graphlog: draw multiple edges towards null node (issue5440)
Yuya Nishihara <yuya@tcha.org>
parents: 31023
diff changeset
   198
    edges = [(nodeidx, nextseen.index(p)) for p in knownparents]
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   199
28998
f303b569134c graphmod: fix seen state handling for > 2 parents (issue5174)
Martijn Pieters <mjpieters@fb.com>
parents: 28891
diff changeset
   200
    seen[:] = nextseen
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   201
    while len(newparents) > 2:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   202
        # ascii() only knows how to add or remove a single column between two
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   203
        # calls. Nodes with more than two parents break this constraint so we
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   204
        # introduce intermediate expansion lines to grow the active node list
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   205
        # slowly.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   206
        edges.append((nodeidx, nodeidx))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   207
        edges.append((nodeidx, nodeidx + 1))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   208
        nmorecols = 1
33858
6f6c87888b22 log: add a "graphwidth" template variable
Danny Hooper <hooper@google.com>
parents: 32903
diff changeset
   209
        width += 2
6f6c87888b22 log: add a "graphwidth" template variable
Danny Hooper <hooper@google.com>
parents: 32903
diff changeset
   210
        yield (type, char, width, (nodeidx, edges, ncols, nmorecols))
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   211
        char = '\\'
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   212
        nodeidx += 1
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   213
        ncols += 1
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   214
        edges = []
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   215
        del newparents[0]
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   216
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   217
    if len(newparents) > 0:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   218
        edges.append((nodeidx, nodeidx))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   219
    if len(newparents) > 1:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   220
        edges.append((nodeidx, nodeidx + 1))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   221
    nmorecols = len(nextseen) - ncols
33858
6f6c87888b22 log: add a "graphwidth" template variable
Danny Hooper <hooper@google.com>
parents: 32903
diff changeset
   222
    if nmorecols > 0:
6f6c87888b22 log: add a "graphwidth" template variable
Danny Hooper <hooper@google.com>
parents: 32903
diff changeset
   223
        width += 2
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   224
    # remove current node from edge characters, no longer needed
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   225
    state['edges'].pop(rev, None)
33858
6f6c87888b22 log: add a "graphwidth" template variable
Danny Hooper <hooper@google.com>
parents: 32903
diff changeset
   226
    yield (type, char, width, (nodeidx, edges, ncols, nmorecols))
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   227
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   228
def _fixlongrightedges(edges):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   229
    for (i, (start, end)) in enumerate(edges):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   230
        if end > start:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   231
            edges[i] = (start, end + 1)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   232
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   233
def _getnodelineedgestail(
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   234
        echars, idx, pidx, ncols, coldiff, pdiff, fix_tail):
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   235
    if fix_tail and coldiff == pdiff and coldiff != 0:
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   236
        # Still going in the same non-vertical direction.
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   237
        if coldiff == -1:
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   238
            start = max(idx + 1, pidx)
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   239
            tail = echars[idx * 2:(start - 1) * 2]
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   240
            tail.extend(["/", " "] * (ncols - start))
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   241
            return tail
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   242
        else:
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   243
            return ["\\", " "] * (ncols - idx - 1)
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   244
    else:
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   245
        remainder = (ncols - idx - 1)
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   246
        return echars[-(remainder * 2):] if remainder > 0 else []
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   247
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   248
def _drawedges(echars, edges, nodeline, interline):
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   249
    for (start, end) in edges:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   250
        if start == end + 1:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   251
            interline[2 * end + 1] = "/"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   252
        elif start == end - 1:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   253
            interline[2 * start + 1] = "\\"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   254
        elif start == end:
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   255
            interline[2 * start] = echars[2 * start]
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   256
        else:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   257
            if 2 * end >= len(nodeline):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   258
                continue
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   259
            nodeline[2 * end] = "+"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   260
            if start > end:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   261
                (start, end) = (end, start)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   262
            for i in range(2 * start + 1, 2 * end):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   263
                if nodeline[i] != "+":
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   264
                    nodeline[i] = "-"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   265
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   266
def _getpaddingline(echars, idx, ncols, edges):
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   267
    # all edges up to the current node
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   268
    line = echars[:idx * 2]
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   269
    # an edge for the current node, if there is one
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   270
    if (idx, idx - 1) in edges or (idx, idx) in edges:
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   271
        # (idx, idx - 1)      (idx, idx)
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   272
        # | | | |           | | | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   273
        # +---o |           | o---+
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   274
        # | | X |           | X | |
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   275
        # | |/ /            | |/ /
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   276
        # | | |             | | |
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   277
        line.extend(echars[idx * 2:(idx + 1) * 2])
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   278
    else:
32160
906da89821ce py3: use list of bytes rather than bytestring while extending bytes into lists
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31552
diff changeset
   279
        line.extend([' ', ' '])
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   280
    # all edges to the right of the current node
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   281
    remainder = ncols - idx - 1
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   282
    if remainder > 0:
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   283
        line.extend(echars[-(remainder * 2):])
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   284
    return line
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   285
28601
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   286
def _drawendinglines(lines, extra, edgemap, seen):
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   287
    """Draw ending lines for missing parent edges
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   288
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   289
    None indicates an edge that ends at between this node and the next
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   290
    Replace with a short line ending in ~ and add / lines to any edges to
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   291
    the right.
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   292
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   293
    """
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   294
    if None not in edgemap.values():
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   295
        return
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   296
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   297
    # Check for more edges to the right of our ending edges.
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   298
    # We need enough space to draw adjustment lines for these.
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   299
    edgechars = extra[::2]
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   300
    while edgechars and edgechars[-1] is None:
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   301
        edgechars.pop()
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   302
    shift_size = max((edgechars.count(None) * 2) - 1, 0)
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   303
    while len(lines) < 3 + shift_size:
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   304
        lines.append(extra[:])
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   305
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   306
    if shift_size:
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   307
        empties = []
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   308
        toshift = []
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   309
        first_empty = extra.index(None)
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   310
        for i, c in enumerate(extra[first_empty::2], first_empty // 2):
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   311
            if c is None:
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   312
                empties.append(i * 2)
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   313
            else:
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   314
                toshift.append(i * 2)
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   315
        targets = list(range(first_empty, first_empty + len(toshift) * 2, 2))
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   316
        positions = toshift[:]
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   317
        for line in lines[-shift_size:]:
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   318
            line[first_empty:] = [' '] * (len(line) - first_empty)
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   319
            for i in range(len(positions)):
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   320
                pos = positions[i] - 1
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   321
                positions[i] = max(pos, targets[i])
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   322
                line[pos] = '/' if pos > targets[i] else extra[toshift[i]]
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   323
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   324
    map = {1: '|', 2: '~'}
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   325
    for i, line in enumerate(lines):
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   326
        if None not in line:
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   327
            continue
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   328
        line[:] = [c or map.get(i, ' ') for c in line]
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   329
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   330
    # remove edges that ended
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   331
    remove = [p for p, c in edgemap.items() if c is None]
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   332
    for parent in remove:
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   333
        del edgemap[parent]
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   334
        seen.remove(parent)
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   335
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   336
def asciistate():
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   337
    """returns the initial value for the "state" argument to ascii()"""
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   338
    return {
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   339
        'seen': [],
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   340
        'edges': {},
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   341
        'lastcoldiff': 0,
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   342
        'lastindex': 0,
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   343
        'styles': EDGES.copy(),
28891
ac30adb260ea graphmod: shorten graph
santiagopim <santiagopim@gmail.com>
parents: 28627
diff changeset
   344
        'graphshorten': False,
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   345
    }
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   346
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   347
def ascii(ui, state, type, char, text, coldata):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   348
    """prints an ASCII graph of the DAG
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   349
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   350
    takes the following arguments (one call per node in the graph):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   351
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   352
      - ui to write to
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   353
      - Somewhere to keep the needed state in (init to asciistate())
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   354
      - Column of the current node in the set of ongoing edges.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   355
      - Type indicator of node data, usually 'C' for changesets.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   356
      - Payload: (char, lines):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   357
        - Character to use as node's symbol.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   358
        - List of lines to display as the node's text.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   359
      - Edges; a list of (col, next_col) indicating the edges between
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   360
        the current node and its parents.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   361
      - Number of columns (ongoing edges) in the current revision.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   362
      - The difference between the number of columns (ongoing edges)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   363
        in the next revision and the number of columns (ongoing edges)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   364
        in the current revision. That is: -1 means one column removed;
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   365
        0 means no columns added or removed; 1 means one column added.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   366
    """
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   367
    idx, edges, ncols, coldiff = coldata
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   368
    assert -2 < coldiff < 2
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   369
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   370
    edgemap, seen = state['edges'], state['seen']
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   371
    # Be tolerant of history issues; make sure we have at least ncols + coldiff
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   372
    # elements to work with. See test-glog.t for broken history test cases.
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   373
    echars = [c for p in seen for c in (edgemap.get(p, '|'), ' ')]
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   374
    echars.extend(('|', ' ') * max(ncols + coldiff - len(seen), 0))
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   375
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   376
    if coldiff == -1:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   377
        # Transform
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   378
        #
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   379
        #     | | |        | | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   380
        #     o | |  into  o---+
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   381
        #     |X /         |/ /
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   382
        #     | |          | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   383
        _fixlongrightedges(edges)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   384
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   385
    # add_padding_line says whether to rewrite
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   386
    #
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   387
    #     | | | |        | | | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   388
    #     | o---+  into  | o---+
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   389
    #     |  / /         |   | |  # <--- padding line
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   390
    #     o | |          |  / /
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   391
    #                    o | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   392
    add_padding_line = (len(text) > 2 and coldiff == -1 and
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   393
                        [x for (x, y) in edges if x + 1 < y])
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   394
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   395
    # fix_nodeline_tail says whether to rewrite
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   396
    #
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   397
    #     | | o | |        | | o | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   398
    #     | | |/ /         | | |/ /
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   399
    #     | o | |    into  | o / /   # <--- fixed nodeline tail
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   400
    #     | |/ /           | |/ /
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   401
    #     o | |            o | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   402
    fix_nodeline_tail = len(text) <= 2 and not add_padding_line
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   403
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   404
    # nodeline is the line containing the node character (typically o)
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   405
    nodeline = echars[:idx * 2]
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   406
    nodeline.extend([char, " "])
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   407
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   408
    nodeline.extend(
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   409
        _getnodelineedgestail(
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   410
            echars, idx, state['lastindex'], ncols, coldiff,
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   411
            state['lastcoldiff'], fix_nodeline_tail))
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   412
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   413
    # shift_interline is the line containing the non-vertical
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   414
    # edges between this entry and the next
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   415
    shift_interline = echars[:idx * 2]
32160
906da89821ce py3: use list of bytes rather than bytestring while extending bytes into lists
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31552
diff changeset
   416
    for i in xrange(2 + coldiff):
906da89821ce py3: use list of bytes rather than bytestring while extending bytes into lists
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31552
diff changeset
   417
        shift_interline.append(' ')
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   418
    count = ncols - idx - 1
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   419
    if coldiff == -1:
32160
906da89821ce py3: use list of bytes rather than bytestring while extending bytes into lists
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31552
diff changeset
   420
        for i in xrange(count):
906da89821ce py3: use list of bytes rather than bytestring while extending bytes into lists
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31552
diff changeset
   421
            shift_interline.extend(['/', ' '])
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   422
    elif coldiff == 0:
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   423
        shift_interline.extend(echars[(idx + 1) * 2:ncols * 2])
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   424
    else:
32160
906da89821ce py3: use list of bytes rather than bytestring while extending bytes into lists
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31552
diff changeset
   425
        for i in xrange(count):
906da89821ce py3: use list of bytes rather than bytestring while extending bytes into lists
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31552
diff changeset
   426
            shift_interline.extend(['\\', ' '])
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   427
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   428
    # draw edges from the current node to its parents
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   429
    _drawedges(echars, edges, nodeline, shift_interline)
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   430
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   431
    # lines is the list of all graph lines to print
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   432
    lines = [nodeline]
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   433
    if add_padding_line:
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   434
        lines.append(_getpaddingline(echars, idx, ncols, edges))
28891
ac30adb260ea graphmod: shorten graph
santiagopim <santiagopim@gmail.com>
parents: 28627
diff changeset
   435
ac30adb260ea graphmod: shorten graph
santiagopim <santiagopim@gmail.com>
parents: 28627
diff changeset
   436
    # If 'graphshorten' config, only draw shift_interline
ac30adb260ea graphmod: shorten graph
santiagopim <santiagopim@gmail.com>
parents: 28627
diff changeset
   437
    # when there is any non vertical flow in graph.
ac30adb260ea graphmod: shorten graph
santiagopim <santiagopim@gmail.com>
parents: 28627
diff changeset
   438
    if state['graphshorten']:
ac30adb260ea graphmod: shorten graph
santiagopim <santiagopim@gmail.com>
parents: 28627
diff changeset
   439
        if any(c in '\/' for c in shift_interline if c):
ac30adb260ea graphmod: shorten graph
santiagopim <santiagopim@gmail.com>
parents: 28627
diff changeset
   440
            lines.append(shift_interline)
ac30adb260ea graphmod: shorten graph
santiagopim <santiagopim@gmail.com>
parents: 28627
diff changeset
   441
    # Else, no 'graphshorten' config so draw shift_interline.
ac30adb260ea graphmod: shorten graph
santiagopim <santiagopim@gmail.com>
parents: 28627
diff changeset
   442
    else:
ac30adb260ea graphmod: shorten graph
santiagopim <santiagopim@gmail.com>
parents: 28627
diff changeset
   443
        lines.append(shift_interline)
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   444
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   445
    # make sure that there are as many graph lines as there are
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   446
    # log strings
28601
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   447
    extra_interline = echars[:(ncols + coldiff) * 2]
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   448
    if len(lines) < len(text):
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   449
        while len(lines) < len(text):
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   450
            lines.append(extra_interline[:])
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   451
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   452
    _drawendinglines(lines, extra_interline, edgemap, seen)
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   453
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   454
    while len(text) < len(lines):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   455
        text.append("")
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   456
29134
8d5584d8345b graphmod: partial edge styling
Martijn Pieters <mjpieters@fb.com>
parents: 28998
diff changeset
   457
    if any(len(char) > 1 for char in edgemap.values()):
8d5584d8345b graphmod: partial edge styling
Martijn Pieters <mjpieters@fb.com>
parents: 28998
diff changeset
   458
        # limit drawing an edge to the first or last N lines of the current
8d5584d8345b graphmod: partial edge styling
Martijn Pieters <mjpieters@fb.com>
parents: 28998
diff changeset
   459
        # section the rest of the edge is drawn like a parent line.
8d5584d8345b graphmod: partial edge styling
Martijn Pieters <mjpieters@fb.com>
parents: 28998
diff changeset
   460
        parent = state['styles'][PARENT][-1]
8d5584d8345b graphmod: partial edge styling
Martijn Pieters <mjpieters@fb.com>
parents: 28998
diff changeset
   461
        def _drawgp(char, i):
8d5584d8345b graphmod: partial edge styling
Martijn Pieters <mjpieters@fb.com>
parents: 28998
diff changeset
   462
            # should a grandparent character be drawn for this line?
8d5584d8345b graphmod: partial edge styling
Martijn Pieters <mjpieters@fb.com>
parents: 28998
diff changeset
   463
            if len(char) < 2:
8d5584d8345b graphmod: partial edge styling
Martijn Pieters <mjpieters@fb.com>
parents: 28998
diff changeset
   464
                return True
8d5584d8345b graphmod: partial edge styling
Martijn Pieters <mjpieters@fb.com>
parents: 28998
diff changeset
   465
            num = int(char[:-1])
8d5584d8345b graphmod: partial edge styling
Martijn Pieters <mjpieters@fb.com>
parents: 28998
diff changeset
   466
            # either skip first num lines or take last num lines, based on sign
8d5584d8345b graphmod: partial edge styling
Martijn Pieters <mjpieters@fb.com>
parents: 28998
diff changeset
   467
            return -num <= i if num < 0 else (len(lines) - i) <= num
8d5584d8345b graphmod: partial edge styling
Martijn Pieters <mjpieters@fb.com>
parents: 28998
diff changeset
   468
        for i, line in enumerate(lines):
8d5584d8345b graphmod: partial edge styling
Martijn Pieters <mjpieters@fb.com>
parents: 28998
diff changeset
   469
            line[:] = [c[-1] if _drawgp(c, i) else parent for c in line]
29184
09d0022cad83 graphmod: update edgemap in-place
Martijn Pieters <mjpieters@fb.com>
parents: 29134
diff changeset
   470
        edgemap.update(
09d0022cad83 graphmod: update edgemap in-place
Martijn Pieters <mjpieters@fb.com>
parents: 29134
diff changeset
   471
            (e, (c if len(c) < 2 else parent)) for e, c in edgemap.items())
29134
8d5584d8345b graphmod: partial edge styling
Martijn Pieters <mjpieters@fb.com>
parents: 28998
diff changeset
   472
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   473
    # print lines
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   474
    indentation_level = max(ncols, ncols + coldiff)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   475
    for (line, logstr) in zip(lines, text):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   476
        ln = "%-*s %s" % (2 * indentation_level, "".join(line), logstr)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   477
        ui.write(ln.rstrip() + '\n')
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   478
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   479
    # ... and start over
28375
97cb1aeaca78 graphmod: refactor state handling
Martijn Pieters <mjpieters@fb.com>
parents: 26187
diff changeset
   480
    state['lastcoldiff'] = coldiff
97cb1aeaca78 graphmod: refactor state handling
Martijn Pieters <mjpieters@fb.com>
parents: 26187
diff changeset
   481
    state['lastindex'] = idx