1 # Copyright (C) 2006 Jelmer Vernooij <jelmer@samba.org>
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 from bzrlib.errors import NotBranchError
19 class BranchingScheme:
20 """ Divides SVN repository data up into branches. Since there
21 is no proper way to do this, there are several subclasses of this class
22 each of which handles a particular convention that may be in use.
24 def is_branch(self, path):
25 """Check whether a location refers to a branch.
27 :param path: Path to check.
29 raise NotImplementedError
31 def unprefix(self, path):
32 """Split up a Subversion path into a branch-path and inside-branch path.
34 :param path: Path to split up.
35 :return: Tuple with branch-path and inside-branch path.
37 raise NotImplementedError
40 def guess_scheme(relpath):
41 """Try to guess the branching scheme based on a partial URL.
43 :param relpath: Relative URL to a branch.
44 :return: New BranchingScheme instance.
46 parts = relpath.strip("/").split("/")
47 for i in range(0,len(parts)):
48 if parts[i] == "trunk" or \
49 parts[i] == "branches" or \
51 return TrunkBranchingScheme(level=i)
53 return NoBranchingScheme()
56 class TrunkBranchingScheme:
57 def __init__(self, level=0):
60 def is_branch(self, path):
61 """See BranchingScheme.is_branch()."""
62 parts = path.strip("/").split("/")
63 if len(parts) == self.level+1 and parts[self.level] == "trunk":
66 if len(parts) == self.level+2 and \
67 (parts[self.level] == "branches" or parts[self.level] == "tags"):
72 def unprefix(self, path):
73 """See BranchingScheme.unprefix()."""
74 parts = path.strip("/").split("/")
75 if len(parts) == 0 or self.level >= len(parts):
76 raise NotBranchError(path=path)
78 if parts[self.level] == "trunk" or parts[self.level] == "hooks":
79 return ("/".join(parts[0:self.level+1]).strip("/"),
80 "/".join(parts[self.level+1:]).strip("/"))
81 elif parts[self.level] == "tags" or parts[self.level] == "branches":
82 return ("/".join(parts[0:self.level+2]).strip("/"),
83 "/".join(parts[self.level+2:]).strip("/"))
85 raise NotBranchError(path=path)
88 return "trunk%d" % self.level
91 class NoBranchingScheme:
92 def is_branch(self, path):
93 """See BranchingScheme.is_branch()."""
94 return path.strip("/") == ""
96 def unprefix(self, path):
97 """See BranchingScheme.unprefix()."""
98 return ("", path.strip("/"))
104 class ListBranchingScheme:
105 def __init__(self, branch_list):
106 """Create new ListBranchingScheme instance.
108 :param branch_list: List of know branch locations.
110 self.branch_list = []
111 for p in branch_list:
112 self.branch_list.append(p.strip("/"))
114 def is_branch(self, path):
115 """See BranchingScheme.is_branch()."""
116 return path.strip("/") in self.branch_list
118 def unprefix(self, path):
119 """See BranchingScheme.unprefix()."""
120 path = path.strip("/")
121 for i in self.branch_list:
122 if (path+"/").startswith(i+"/"):
123 return (i, path[len(i):].strip("/"))
125 raise NotBranchError(path=path)