Merge property changes from 0.4.
[jelmer/subvertpy.git] / mapping3 / __init__.py
index cbba276ffa754eb06ece826182b7988ffced000f..08393a851c38468e18b16eeb4364a01c46e730e0 100644 (file)
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from bzrlib import osutils, ui
+from bzrlib.errors import InvalidRevisionId
 from bzrlib.trace import mutter
-from bzrlib.plugins.svn import mapping
-from mapping3.scheme import (BranchingScheme, guess_scheme_from_branch_path, 
+from bzrlib.plugins.svn import core, constants, mapping, properties
+from bzrlib.plugins.svn.layout import RepositoryLayout
+from bzrlib.plugins.svn.mapping3.scheme import (BranchingScheme, guess_scheme_from_branch_path, 
                              guess_scheme_from_history, ListBranchingScheme, 
-                             parse_list_scheme_text)
+                             parse_list_scheme_text, NoBranchingScheme,
+                             TrunkBranchingScheme, ListBranchingScheme)
 import sha
 
 SVN_PROP_BZR_BRANCHING_SCHEME = 'bzr:branching-scheme'
@@ -26,6 +29,69 @@ SVN_PROP_BZR_BRANCHING_SCHEME = 'bzr:branching-scheme'
 # Number of revisions to evaluate when guessing the branching scheme
 SCHEME_GUESS_SAMPLE_SIZE = 2000
 
+def expand_branch_pattern(begin, todo, check_path, get_children):
+    path = "/".join(begin)
+    if len(todo) == 0:
+        if check_path(path):
+            return [path]
+        else:
+            return []
+    if not "*" in todo[0]:
+        return expand_branch_pattern(begin+[todo[0]], todo[1:], check_path, get_children)
+    children = get_children(path)
+    if children is None:
+        return []
+    ret = []
+    for c in children:
+        if len(todo) == 1:
+            ret.append("/".join(begin+[c]))
+        else:
+            ret += expand_branch_pattern(begin+[c], todo[1:], check_path, get_children)
+    return ret
+
+
+class SchemeDerivedLayout(RepositoryLayout):
+    def __init__(self, repository, scheme):
+        self.repository = repository
+        self.scheme = scheme
+
+    def parse(self, path):
+        (bp, rp) = self.scheme.unprefix(path)
+        if self.scheme.is_tag(bp):
+            type = "tag"
+        else:
+            type = "branch"
+        return (type, "", bp, rp)
+
+    def get_branches(self, revnum, project=""):
+        def check_path(path):
+            return self.repository.transport.check_path(path, revnum) == core.NODE_DIR
+        def find_children(path):
+            try:
+                assert not path.startswith("/")
+                dirents = self.repository.transport.get_dir(path, revnum)[0]
+            except core.SubversionException, (msg, num):
+                if num == constants.ERR_FS_NOT_DIRECTORY:
+                    return None
+                if num == constants.ERR_FS_NOT_FOUND:
+                    return None
+                raise
+            return dirents.keys()
+
+        for pattern in self.scheme.branch_list:
+            for bp in expand_branch_pattern([], pattern.split("/"), check_path,
+                    find_children):
+                yield "", bp, bp.split("/")[-1]
+
+    def is_branch_parent(self, path):
+        # Na, na, na...
+        return self.scheme.is_branch_parent(path)
+
+    def is_tag_parent(self, path):
+        # Na, na, na...
+        return self.scheme.is_tag_parent(path)
+
+
 def get_stored_scheme(repository):
     """Retrieve the stored branching scheme, either in the repository 
     or in the configuration file.
@@ -41,6 +107,7 @@ def get_stored_scheme(repository):
 
     return (None, False)
 
+
 def get_property_scheme(repository, revnum=None):
     if revnum is None:
         revnum = repository.get_latest_revnum()
@@ -49,11 +116,12 @@ def get_property_scheme(repository, revnum=None):
         return None
     return ListBranchingScheme(parse_list_scheme_text(text))
 
+
 def set_property_scheme(repository, scheme):
     def done(revmetadata, pool):
         pass
     editor = repository.transport.get_commit_editor(
-            {svn.core.SVN_PROP_REVISION_LOG: "Updating branching scheme for Bazaar."},
+            {properties.PROP_REVISION_LOG: "Updating branching scheme for Bazaar."},
             done, None, False)
     root = editor.open_root(-1)
     editor.change_dir_prop(root, SVN_PROP_BZR_BRANCHING_SCHEME, 
@@ -61,19 +129,25 @@ def set_property_scheme(repository, scheme):
     editor.close_directory(root)
     editor.close()
 
+
 def repository_guess_scheme(repository, last_revnum, branch_path=None):
     pb = ui.ui_factory.nested_progress_bar()
     try:
         scheme = guess_scheme_from_history(
-            repository._log.iter_changes("", last_revnum, max(0, last_revnum-SCHEME_GUESS_SAMPLE_SIZE), pb=pb), last_revnum, branch_path)
+            repository._log.iter_changes(None, last_revnum, max(0, last_revnum-SCHEME_GUESS_SAMPLE_SIZE), pb=pb), last_revnum, branch_path)
     finally:
         pb.finished()
     mutter("Guessed branching scheme: %r" % scheme)
     return scheme
 
-def set_branching_scheme(repository, scheme, mandatory=False):
-    repository.get_config().set_branching_scheme(str(scheme), mandatory=mandatory)
 
+def config_set_scheme(repository, scheme, mandatory=False):
+    repository.get_config().set_branching_scheme(str(scheme), 
+                                                 mandatory=mandatory)
+
+def set_branching_scheme(repository, scheme, mandatory=False):
+    repository.get_mapping().scheme = scheme
+    config_set_scheme(repository, scheme, mandatory)
 
 
 class BzrSvnMappingv3(mapping.BzrSvnMapping):
@@ -89,6 +163,9 @@ class BzrSvnMappingv3(mapping.BzrSvnMapping):
         self.scheme = scheme
         assert not isinstance(scheme, str)
 
+    def get_mandated_layout(self, repository):
+        return SchemeDerivedLayout(repository, self.scheme)
+
     @classmethod
     def from_repository(cls, repository, _hinted_branch_path=None):
         (scheme, mandatory) = get_stored_scheme(repository)
@@ -103,7 +180,7 @@ class BzrSvnMappingv3(mapping.BzrSvnMapping):
         last_revnum = repository.get_latest_revnum()
         scheme = repository_guess_scheme(repository, last_revnum, _hinted_branch_path)
         if last_revnum > 20:
-            set_branching_scheme(repository, scheme, mandatory=False)
+            config_set_scheme(repository, scheme, mandatory=False)
 
         return cls(scheme)