/usr/lib/python2.7/dist-packages/cvs2svn_lib/fill_source.py is in cvs2svn 2.4.0-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | # (Be in -*- python -*- mode.)
#
# ====================================================================
# Copyright (c) 2000-2008 CollabNet. All rights reserved.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
# are also available at http://subversion.tigris.org/license-1.html.
# If newer versions of this license are posted there, you may use a
# newer version instead, at your option.
#
# This software consists of voluntary contributions made by many
# individuals. For exact contribution history, see the revision
# history and logs, available at http://cvs2svn.tigris.org/.
# ====================================================================
"""This module contains classes describing the sources of symbol fills."""
from cvs2svn_lib.common import InternalError
from cvs2svn_lib.common import FatalError
from cvs2svn_lib.common import SVN_INVALID_REVNUM
from cvs2svn_lib.svn_revision_range import SVNRevisionRange
from cvs2svn_lib.svn_revision_range import RevisionScores
class FillSource:
"""Representation of a fill source.
A FillSource keeps track of the paths that have to be filled in a
particular symbol fill.
This class holds a SVNRevisionRange instance for each CVSFile that
has to be filled within the subtree of the repository rooted at
self.cvs_path. The SVNRevisionRange objects are stored in a tree
in which the directory nodes are dictionaries mapping CVSPaths to
subnodes and the leaf nodes are the SVNRevisionRange objects telling
for what source_lod and what range of revisions the leaf could serve
as a source.
FillSource objects are able to compute the score for arbitrary
source LODs and source revision numbers.
These objects are used by the symbol filler in SVNOutputOption."""
def __init__(self, cvs_path, symbol, node_tree):
"""Create a fill source.
The best LOD and SVN REVNUM to use as the copy source can be
determined by calling compute_best_source().
Members:
cvs_path -- (CVSPath): the CVSPath described by this FillSource.
_symbol -- (Symbol) the symbol to be filled.
_node_tree -- (dict) a tree stored as a map { CVSPath : node },
where subnodes have the same form. Leaves are
SVNRevisionRange instances telling the source_lod and range
of SVN revision numbers from which the CVSPath can be
copied.
"""
self.cvs_path = cvs_path
self._symbol = symbol
self._node_tree = node_tree
def _set_node(self, cvs_file, svn_revision_range):
parent_node = self._get_node(cvs_file.parent_directory, create=True)
if cvs_file in parent_node:
raise InternalError(
'%s appeared twice in sources for %s' % (cvs_file, self._symbol)
)
parent_node[cvs_file] = svn_revision_range
def _get_node(self, cvs_path, create=False):
if cvs_path == self.cvs_path:
return self._node_tree
else:
parent_node = self._get_node(cvs_path.parent_directory, create=create)
try:
return parent_node[cvs_path]
except KeyError:
if create:
node = {}
parent_node[cvs_path] = node
return node
else:
raise
def compute_best_source(self, preferred_source):
"""Determine the best source_lod and subversion revision number to copy.
Return the best source found, as an SVNRevisionRange instance. If
PREFERRED_SOURCE is not None and its opening is among the sources
with the best scores, return it; otherwise, return the oldest such
revision on the first such source_lod (ordered by the natural LOD
sort order). The return value's source_lod is the best LOD to
copy from, and its opening_revnum is the best SVN revision."""
# Aggregate openings and closings from our rev tree
svn_revision_ranges = self._get_revision_ranges(self._node_tree)
# Score the lists
revision_scores = RevisionScores(svn_revision_ranges)
best_source_lod, best_revnum, best_score = \
revision_scores.get_best_revnum()
if (
preferred_source is not None
and revision_scores.get_score(preferred_source) == best_score
):
best_source_lod = preferred_source.source_lod
best_revnum = preferred_source.opening_revnum
if best_revnum == SVN_INVALID_REVNUM:
raise FatalError(
"failed to find a revision to copy from when copying %s"
% self._symbol.name
)
return SVNRevisionRange(best_source_lod, best_revnum)
def _get_revision_ranges(self, node):
"""Return a list of all the SVNRevisionRanges at and under NODE.
Include duplicates. This is a helper method used by
compute_best_source()."""
if isinstance(node, SVNRevisionRange):
# It is a leaf node.
return [ node ]
else:
# It is an intermediate node.
revision_ranges = []
for key, subnode in node.items():
revision_ranges.extend(self._get_revision_ranges(subnode))
return revision_ranges
def get_subsources(self):
"""Generate (CVSPath, FillSource) for all direct subsources."""
if not isinstance(self._node_tree, SVNRevisionRange):
for cvs_path, node in self._node_tree.items():
fill_source = FillSource(cvs_path, self._symbol, node)
yield (cvs_path, fill_source)
def get_subsource_map(self):
"""Return the map {CVSPath : FillSource} of direct subsources."""
src_entries = {}
for (cvs_path, fill_subsource) in self.get_subsources():
src_entries[cvs_path] = fill_subsource
return src_entries
def __str__(self):
"""For convenience only. The format is subject to change at any time."""
return '%s(%s:%s)' % (
self.__class__.__name__, self._symbol, self.cvs_path,
)
def __repr__(self):
"""For convenience only. The format is subject to change at any time."""
return '%s%r' % (self, self._node_tree,)
def get_source_set(symbol, range_map):
"""Return a FillSource describing the fill sources for RANGE_MAP.
SYMBOL is either a Branch or a Tag. RANGE_MAP is a map { CVSSymbol
: SVNRevisionRange } as returned by
SymbolingsReader.get_range_map().
Use the SVNRevisionRanges from RANGE_MAP to create a FillSource
instance describing the sources for filling SYMBOL."""
root_cvs_directory = symbol.project.get_root_cvs_directory()
fill_source = FillSource(root_cvs_directory, symbol, {})
for cvs_symbol, svn_revision_range in range_map.items():
fill_source._set_node(cvs_symbol.cvs_file, svn_revision_range)
return fill_source
|