1 # (Be in -*- python -*- mode.)
3 # ====================================================================
4 # Copyright (c) 2000-2006 CollabNet. All rights reserved.
6 # This software is licensed as described in the file COPYING, which
7 # you should have received as part of this distribution. The terms
8 # are also available at http://subversion.tigris.org/license-1.html.
9 # If newer versions of this license are posted there, you may use a
10 # newer version instead, at your option.
12 # This software consists of voluntary contributions made by many
13 # individuals. For exact contribution history, see the revision
14 # history and logs, available at http://cvs2svn.tigris.org/.
15 # ====================================================================
17 """This module contains database facilities used by cvs2svn."""
20 from __future__
import generators
24 from artifact_manager
import artifact_manager
27 def match_regexp_list(regexp_list
, s
):
28 """Test whether string S matches any of the compiled regexps in
31 for regexp
in regexp_list
:
38 """This database records information on all symbols in the RCS
39 files. It is created in pass 1 and it is used in pass 2."""
42 # A hash that maps tag names to commit counts
44 # A hash that maps branch names to lists of the format
45 # [ create_count, commit_count, blockers ], where blockers
46 # is a hash that lists the symbols that depend on the
47 # the branch. The blockers hash is used as a set, so the
48 # values are not used.
51 def register_tag_creation(self
, name
):
52 """Register the creation of the tag NAME."""
54 self
.tags
[name
] = self
.tags
.get(name
, 0) + 1
56 def _branch(self
, name
):
57 """Helper function to get a branch node that will create and
58 initialize the node if it does not exist."""
60 if not self
.branches
.has_key(name
):
61 self
.branches
[name
] = [ 0, 0, { } ]
62 return self
.branches
[name
]
64 def register_branch_creation(self
, name
):
65 """Register the creation of the branch NAME."""
67 self
._branch
(name
)[0] += 1
69 def register_branch_commit(self
, name
):
70 """Register a commit on the branch NAME."""
72 self
._branch
(name
)[1] += 1
74 def register_branch_blocker(self
, name
, blocker
):
75 """Register BLOCKER as a blocker on the branch NAME."""
77 self
._branch
(name
)[2][blocker
] = None
79 def branch_has_commit(self
, name
):
80 """Return non-zero if NAME has commits. Returns 0 if name
81 is not a branch or if it has no commits."""
83 return self
.branches
.has_key(name
) and self
.branches
[name
][1]
85 def find_excluded_symbols(self
, regexp_list
):
86 """Returns a hash of all symbols that match the regexps in
87 REGEXP_LIST. The hash is used as a set so the values are
92 if match_regexp_list(regexp_list
, tag
):
94 for branch
in self
.branches
:
95 if match_regexp_list(regexp_list
, branch
):
96 excludes
[branch
] = None
99 def find_branch_exclude_blockers(self
, branch
, excludes
):
100 """Find all blockers of BRANCH, excluding the ones in the hash
104 if excludes
.has_key(branch
):
105 for blocker
in self
.branches
[branch
][2]:
106 if not excludes
.has_key(blocker
):
107 blockers
[blocker
] = None
110 def find_blocked_excludes(self
, excludes
):
111 """Find all branches not in EXCLUDES that have blocking symbols that
112 are not themselves excluded. Return a hash that maps branch names
113 to a hash of blockers. The hash of blockes is used as a set so the
114 values are not used."""
116 blocked_branches
= { }
117 for branch
in self
.branches
:
118 blockers
= self
.find_branch_exclude_blockers(branch
, excludes
)
120 blocked_branches
[branch
] = blockers
121 return blocked_branches
123 def find_mismatches(self
, excludes
=None):
124 """Find all symbols that are defined as both tags and branches,
125 excluding the ones in EXCLUDES. Returns a list of 4-tuples with
126 the symbol name, tag count, branch count and commit count."""
131 for branch
in self
.branches
:
132 if not excludes
.has_key(branch
) and self
.tags
.has_key(branch
):
133 mismatches
.append((branch
, # name
134 self
.tags
[branch
], # tag count
135 self
.branches
[branch
][0], # branch count
136 self
.branches
[branch
][1])) # commit count
140 """Read the symbol database from files."""
142 f
= open(artifact_manager
.get_temp_file(config
.TAGS_LIST
))
147 tag
, count
= line
.split()
148 self
.tags
[tag
] = int(count
)
150 f
= open(artifact_manager
.get_temp_file(config
.BRANCHES_LIST
))
156 self
.branches
[words
[0]] = [ int(words
[1]), int(words
[2]), { } ]
157 for blocker
in words
[3:]:
158 self
.branches
[words
[0]][2][blocker
] = None
161 """Store the symbol database to files."""
163 f
= open(artifact_manager
.get_temp_file(config
.TAGS_LIST
), "w")
164 for tag
, count
in self
.tags
.items():
165 f
.write("%s %d\n" % (tag
, count
))
167 f
= open(artifact_manager
.get_temp_file(config
.BRANCHES_LIST
), "w")
168 for branch
, info
in self
.branches
.items():
169 f
.write("%s %d %d" % (branch
, info
[0], info
[1]))
172 f
.write(" ".join(info
[2].keys()))