Alien-SVN

 view release on metacpan or  search on metacpan

src/subversion/tools/dev/mergegraph/mergegraph.py  view on Meta::CPAN

#!/usr/bin/env python

# ====================================================================
#    Licensed to the Apache Software Foundation (ASF) under one
#    or more contributor license agreements.  See the NOTICE file
#    distributed with this work for additional information
#    regarding copyright ownership.  The ASF licenses this file
#    to you under the Apache License, Version 2.0 (the
#    "License"); you may not use this file except in compliance
#    with the License.  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing,
#    software distributed under the License is distributed on an
#    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
#    KIND, either express or implied.  See the License for the
#    specific language governing permissions and limitations
#    under the License.
# ====================================================================

# Config file format:
example = """
  [graph]
  filename = merge-sync-1.png
  title = Sync Merge: CC vs SVN
  # Branches: (branch name, branched from node, first rev, last rev).
  branches = [
    ('A', 'O0', 1, 4),
    ('O', None, 0, 0),
    ('B', 'O0', 1, 5)
    ]
  # Changes: nodes in which a change was committed; merge targets need not
  # be listed here.
  changes = [
    'A1', 'A2', 'A3', 'A4',
    'B1', 'B2', 'B3', 'B4', 'B5'
    ]
  # Merges: (base node, source-right node, target node, label).
  # Base is also known as source-left.
  merges = [
    ('O0', 'A:1', 'B3', 'sync'),
    ('A2', 'A:3', 'B5', 'sync'),
    ]
  # Annotations for nodes: (node, annotation text).
  annotations = [
    ('A2', 'cc:YCA')
    ]
"""

# Notes about different kinds of merge.
#
# A basic 3-way merge is ...
#
# The ClearCase style of merge is a 3-way merge.
#
# The Subversion style of merge (that is, one phase of a Subversion merge)
# is a three-way merge with its base (typically the YCA) on the source branch.


import sys
import pydot
from pydot import Node, Edge


def mergeinfo_to_node_list(mi):
  """Convert a mergeinfo string such as '/foo:1,3-5*' into a list of
     node names such as ['foo1', 'foo3', 'foo4', 'foo5'].
  """
  ### Doesn't yet strip the leading slash.
  l = []
  if mi:
    for mi_str in mi.split(' '):
      path, ranges = mi_str.split(':')
      for r in ranges.split(','):
        if r.endswith('*'):
          # TODO: store & use this 'non-inheritable' flag
          # Remove the flag
          r = r[:-1]
        rlist = r.split('-')
        r1 = int(rlist[0])
        if len(rlist) == 2:
          r2 = int(rlist[1])
        else:
          r2 = r1

src/subversion/tools/dev/mergegraph/mergegraph.py  view on Meta::CPAN

                                             'merges': '[]',
                                             'annotations': '[]' })
    files_read = config.read(config_filename)
    if len(files_read) == 0:
      print >> sys.stderr, 'graph: unable to read graph config from "' + config_filename + '"'
      sys.exit(1)
    graph.basename = config.get('graph', 'basename')
    graph.title = config.get('graph', 'title')
    graph.branches = eval(config.get('graph', 'branches'))
    graph.changes = eval(config.get('graph', 'changes'))
    graph.merges = eval(config.get('graph', 'merges'))
    graph.annotations = eval(config.get('graph', 'annotations'))

  def construct(graph):
    """"""
    # Origin nodes (done first, in an attempt to set the order)
    for br, orig, r1, head in graph.branches:
      name = br + '0'
      if r1 > 0:
        graph.mk_origin_node(name, br)
      else:
        graph.mk_node(name, label=br)

    # Edges and target nodes for merges
    for merge in graph.merges:
      # Emphasize the last merge, as it's the important one
      important = (merge == graph.merges[-1])
      graph.add_merge(merge, important)

    # Parallel edges for basic lines of descent
    for br, orig, r1, head in graph.branches:
      sub_g = MergeSubgraph(ordering='out')
      for i in range(1, head + 1):
        prev_n = br + str(i - 1)
        this_n = br + str(i)

        # Normal edges and nodes
        if i < r1:
          graph.mk_invis_node(this_n)
        else:
          graph.mk_node(this_n)
        if i <= r1:
          graph.mk_invis_edge(prev_n, this_n)
        else:
          graph.mk_edge(prev_n, this_n)

      # Branch creation edges
      if orig:
        sub_g.mk_br_edge(orig, br + str(r1))

      graph.add_subgraph(sub_g)

    # Annotations
    for node, label in graph.annotations:
      graph.add_annotation(node, label)

    # A title for the graph (added last so it goes at the top)
    if graph.title:
      graph.add_node(Node('title', shape='plaintext', label='"' + graph.title + '"'))

  def save(graph, format='png', filename=None):
    """Save this merge graph to the given file format. If filename is None,
       construct a filename from the basename of the original file (as passed
       to the constructor and then stored in graph.basename) and the suffix
       according to the given format.
    """
    if not filename:
      filename = graph.basename + '.' + format
    if format == 'sh':
      import save_as_sh
      save_as_sh.write_sh_file(graph, filename)
    else:
      pydot.Dot.write(graph, filename, format=format)



( run in 1.875 second using v1.01-cache-2.11-cpan-df04353d9ac )