Rev 3143: Add find_branch, find_trees, find_bzrdirs methods (abentley) in file:///home/pqm/archives/thelove/bzr/%2Btrunk/
Canonical.com Patch Queue Manager
pqm at pqm.ubuntu.com
Sat Dec 22 00:03:26 GMT 2007
At file:///home/pqm/archives/thelove/bzr/%2Btrunk/
------------------------------------------------------------
revno: 3143
revision-id:pqm at pqm.ubuntu.com-20071222000314-vq5b7m2jkaxvofm9
parent: pqm at pqm.ubuntu.com-20071221185957-5w2bqxno9wfqadyx
parent: abentley at panoramicfeedback.com-20071221230131-zsheywe5tanfcm60
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Sat 2007-12-22 00:03:14 +0000
message:
Add find_branch, find_trees, find_bzrdirs methods (abentley)
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/bzrdir.py bzrdir.py-20060131065624-156dfea39c4387cb
bzrlib/remote.py remote.py-20060720103555-yeeg2x51vn0rbtdp-1
bzrlib/repository.py rev_storage.py-20051111201905-119e9401e46257e3
bzrlib/tests/repository_implementations/test_repository.py test_repository.py-20060131092128-ad07f494f5c9d26c
bzrlib/tests/test_bzrdir.py test_bzrdir.py-20060131065654-deba40eef51cf220
bzrlib/tests/test_workingtree.py testworkingtree.py-20051004024258-b88d0fe8f101d468
bzrlib/workingtree.py workingtree.py-20050511021032-29b6ec0a681e02e3
------------------------------------------------------------
revno: 3140.1.7
revision-id:abentley at panoramicfeedback.com-20071221230131-zsheywe5tanfcm60
parent: abentley at panoramicfeedback.com-20071221223412-bkq5b1e9urirg4dh
committer: Aaron Bentley <abentley at panoramicfeedback.com>
branch nick: find-branches
timestamp: Fri 2007-12-21 18:01:31 -0500
message:
Update docs
modified:
bzrlib/bzrdir.py bzrdir.py-20060131065624-156dfea39c4387cb
bzrlib/repository.py rev_storage.py-20051111201905-119e9401e46257e3
------------------------------------------------------------
revno: 3140.1.6
revision-id:abentley at panoramicfeedback.com-20071221223412-bkq5b1e9urirg4dh
parent: abentley at panoramicfeedback.com-20071221204857-r9pxxwx34iuyt46d
committer: Aaron Bentley <abentley at panoramicfeedback.com>
branch nick: find-branches
timestamp: Fri 2007-12-21 17:34:12 -0500
message:
Add test that nested branches are returned
modified:
bzrlib/tests/repository_implementations/test_repository.py test_repository.py-20060131092128-ad07f494f5c9d26c
------------------------------------------------------------
revno: 3140.1.5
revision-id:abentley at panoramicfeedback.com-20071221204857-r9pxxwx34iuyt46d
parent: abentley at panoramicfeedback.com-20071221204727-t3mw37sray6nx1b8
committer: Aaron Bentley <abentley at panoramicfeedback.com>
branch nick: find-branches
timestamp: Fri 2007-12-21 15:48:57 -0500
message:
Update NEWS
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
------------------------------------------------------------
revno: 3140.1.4
revision-id:abentley at panoramicfeedback.com-20071221204727-t3mw37sray6nx1b8
parent: abentley at panoramicfeedback.com-20071221203222-owkqyiye6o5usdwr
committer: Aaron Bentley <abentley at panoramicfeedback.com>
branch nick: find-branches
timestamp: Fri 2007-12-21 15:47:27 -0500
message:
Add WorkingTree.find_trees
modified:
bzrlib/tests/test_workingtree.py testworkingtree.py-20051004024258-b88d0fe8f101d468
bzrlib/workingtree.py workingtree.py-20050511021032-29b6ec0a681e02e3
------------------------------------------------------------
revno: 3140.1.3
revision-id:abentley at panoramicfeedback.com-20071221203222-owkqyiye6o5usdwr
parent: abentley at panoramicfeedback.com-20071221195630-u9lqadyl8letkois
committer: Aaron Bentley <abentley at panoramicfeedback.com>
branch nick: find-branches
timestamp: Fri 2007-12-21 15:32:22 -0500
message:
Add support for finding branches to BzrDir
modified:
bzrlib/bzrdir.py bzrdir.py-20060131065624-156dfea39c4387cb
bzrlib/tests/repository_implementations/test_repository.py test_repository.py-20060131092128-ad07f494f5c9d26c
bzrlib/tests/test_bzrdir.py test_bzrdir.py-20060131065654-deba40eef51cf220
------------------------------------------------------------
revno: 3140.1.2
revision-id:abentley at panoramicfeedback.com-20071221195630-u9lqadyl8letkois
parent: abentley at panoramicfeedback.com-20071221182048-epdl0q3at7ktf74v
committer: Aaron Bentley <abentley at panoramicfeedback.com>
branch nick: find-branches
timestamp: Fri 2007-12-21 14:56:30 -0500
message:
Add ability to find branches inside repositories
modified:
bzrlib/remote.py remote.py-20060720103555-yeeg2x51vn0rbtdp-1
bzrlib/repository.py rev_storage.py-20051111201905-119e9401e46257e3
bzrlib/tests/repository_implementations/test_repository.py test_repository.py-20060131092128-ad07f494f5c9d26c
------------------------------------------------------------
revno: 3140.1.1
revision-id:abentley at panoramicfeedback.com-20071221182048-epdl0q3at7ktf74v
parent: pqm at pqm.ubuntu.com-20071221161317-zdipotctmw8p1yhx
committer: Aaron Bentley <abentley at panoramicfeedback.com>
branch nick: find-branches
timestamp: Fri 2007-12-21 13:20:48 -0500
message:
Implement find_bzrdir functionality
modified:
bzrlib/bzrdir.py bzrdir.py-20060131065624-156dfea39c4387cb
bzrlib/tests/test_bzrdir.py test_bzrdir.py-20060131065654-deba40eef51cf220
=== modified file 'NEWS'
--- a/NEWS 2007-12-21 17:09:16 +0000
+++ b/NEWS 2007-12-22 00:03:14 +0000
@@ -102,6 +102,9 @@
INTERNALS:
+ * find_* methods available for BzrDirs, Branches and WorkingTrees.
+ (Aaron Bentley)
+
* Help topics can now be loaded from files.
(Ian Clatworthy, Alexander Belchenko)
=== modified file 'bzrlib/bzrdir.py'
--- a/bzrlib/bzrdir.py 2007-12-21 15:51:02 +0000
+++ b/bzrlib/bzrdir.py 2007-12-22 00:03:14 +0000
@@ -245,6 +245,80 @@
format = BzrDirFormat.get_default_format()
return format.initialize_on_transport(t)
+ @staticmethod
+ def find_bzrdirs(transport, evaluate=None, list_current=None):
+ """Find bzrdirs recursively from current location.
+
+ This is intended primarily as a building block for more sophisticated
+ functionality, like finding trees under a directory, or finding
+ branches that use a given repository.
+ :param evaluate: An optional callable that yields recurse, value,
+ where recurse controls whether this bzrdir is recursed into
+ and value is the value to yield. By default, all bzrdirs
+ are recursed into, and the return value is the bzrdir.
+ :param list_current: if supplied, use this function to list the current
+ directory, instead of Transport.list_dir
+ :return: a generator of found bzrdirs, or whatever evaluate returns.
+ """
+ if list_current is None:
+ def list_current(transport):
+ return transport.list_dir('')
+ if evaluate is None:
+ def evaluate(bzrdir):
+ return True, bzrdir
+
+ pending = [transport]
+ while len(pending) > 0:
+ current_transport = pending.pop()
+ recurse = True
+ try:
+ bzrdir = BzrDir.open_from_transport(current_transport)
+ except errors.NotBranchError:
+ pass
+ else:
+ recurse, value = evaluate(bzrdir)
+ yield value
+ try:
+ subdirs = list_current(current_transport)
+ except errors.NoSuchFile:
+ continue
+ if recurse:
+ for subdir in sorted(subdirs, reverse=True):
+ pending.append(current_transport.clone(subdir))
+
+ @staticmethod
+ def find_branches(transport):
+ """Find all branches under a transport.
+
+ This will find all branches below the transport, including branches
+ inside other branches. Where possible, it will use
+ Repository.find_branches.
+
+ To list all the branches that use a particular Repository, see
+ Repository.find_branches
+ """
+ def evaluate(bzrdir):
+ try:
+ repository = bzrdir.open_repository()
+ except errors.NoRepositoryPresent:
+ pass
+ else:
+ return False, (None, repository)
+ try:
+ branch = bzrdir.open_branch()
+ except errors.NotBranchError:
+ return True, (None, None)
+ else:
+ return True, (branch, None)
+ branches = []
+ for branch, repo in BzrDir.find_bzrdirs(transport, evaluate=evaluate):
+ if repo is not None:
+ branches.extend(repo.find_branches())
+ if branch is not None:
+ branches.append(branch)
+ return branches
+
+
def destroy_repository(self):
"""Destroy the repository in this BzrDir"""
raise NotImplementedError(self.destroy_repository)
=== modified file 'bzrlib/remote.py'
--- a/bzrlib/remote.py 2007-12-19 08:12:34 +0000
+++ b/bzrlib/remote.py 2007-12-21 19:56:30 +0000
@@ -415,6 +415,12 @@
return result
+ def find_branches(self, using=False):
+ """See Repository.find_branches()."""
+ # should be an API call to the server.
+ self._ensure_real()
+ return self._real_repository.find_branches(using=using)
+
def get_physical_lock_status(self):
"""See Repository.get_physical_lock_status()."""
# should be an API call to the server.
=== modified file 'bzrlib/repository.py'
--- a/bzrlib/repository.py 2007-12-19 08:12:34 +0000
+++ b/bzrlib/repository.py 2007-12-21 23:01:31 +0000
@@ -766,6 +766,45 @@
result['size'] = t
return result
+ def find_branches(self, using=False):
+ """Find branches underneath this repository.
+
+ This will include branches inside other branches.
+
+ :param using: If True, list only branches using this repository.
+ """
+
+ class Evaluator(object):
+
+ def __init__(self):
+ self.first_call = True
+
+ def __call__(self, bzrdir):
+ # On the first call, the parameter is always the bzrdir
+ # containing the current repo.
+ if not self.first_call:
+ try:
+ repository = bzrdir.open_repository()
+ except errors.NoRepositoryPresent:
+ pass
+ else:
+ return False, (None, repository)
+ self.first_call = False
+ try:
+ value = (bzrdir.open_branch(), None)
+ except errors.NotBranchError:
+ value = (None, None)
+ return True, value
+
+ branches = []
+ for branch, repository in bzrdir.BzrDir.find_bzrdirs(
+ self.bzrdir.root_transport, evaluate=Evaluator()):
+ if branch is not None:
+ branches.append(branch)
+ if not using and repository is not None:
+ branches.extend(repository.find_branches())
+ return branches
+
def get_data_stream(self, revision_ids):
raise NotImplementedError(self.get_data_stream)
=== modified file 'bzrlib/tests/repository_implementations/test_repository.py'
--- a/bzrlib/tests/repository_implementations/test_repository.py 2007-12-19 08:12:34 +0000
+++ b/bzrlib/tests/repository_implementations/test_repository.py 2007-12-21 22:34:12 +0000
@@ -636,6 +636,46 @@
repo = self.make_repository('repo')
repo._make_parents_provider().get_parent_map
+ def make_repository_and_foo_bar(self, shared):
+ made_control = self.make_bzrdir('repository')
+ repo = made_control.create_repository(shared=shared)
+ bzrdir.BzrDir.create_branch_convenience(self.get_url('repository/foo'),
+ force_new_repo=False)
+ bzrdir.BzrDir.create_branch_convenience(self.get_url('repository/bar'),
+ force_new_repo=True)
+ baz = self.make_bzrdir('repository/baz')
+ qux = self.make_branch('repository/baz/qux')
+ quxx = self.make_branch('repository/baz/qux/quxx')
+ return repo
+
+ def test_find_branches(self):
+ repo = self.make_repository_and_foo_bar(shared=False)
+ branches = repo.find_branches()
+ self.assertContainsRe(branches[-1].base, 'repository/foo/$')
+ self.assertContainsRe(branches[-3].base, 'repository/baz/qux/$')
+ self.assertContainsRe(branches[-2].base, 'repository/baz/qux/quxx/$')
+ # in some formats, creating a repo creates a branch
+ if len(branches) == 6:
+ self.assertContainsRe(branches[-4].base, 'repository/baz/$')
+ self.assertContainsRe(branches[-5].base, 'repository/bar/$')
+ self.assertContainsRe(branches[-6].base, 'repository/$')
+ else:
+ self.assertEqual(4, len(branches))
+ self.assertContainsRe(branches[-4].base, 'repository/bar/$')
+
+ def test_find_branches_using(self):
+ try:
+ repo = self.make_repository_and_foo_bar(shared=True)
+ except errors.IncompatibleFormat:
+ raise TestNotApplicable
+ branches = repo.find_branches(using=True)
+ self.assertContainsRe(branches[-1].base, 'repository/foo/$')
+ # in some formats, creating a repo creates a branch
+ if len(branches) == 2:
+ self.assertContainsRe(branches[-2].base, 'repository/$')
+ else:
+ self.assertEqual(1, len(branches))
+
class TestRepositoryLocking(TestCaseWithRepository):
=== modified file 'bzrlib/tests/test_bzrdir.py'
--- a/bzrlib/tests/test_bzrdir.py 2007-12-20 14:07:01 +0000
+++ b/bzrlib/tests/test_bzrdir.py 2007-12-21 20:32:22 +0000
@@ -591,6 +591,66 @@
self.failUnlessExists('repo/tree2/subtree')
self.failIfExists('repo/tree2/subtree/file')
+ def make_foo_bar_baz(self):
+ foo = bzrdir.BzrDir.create_branch_convenience('foo').bzrdir
+ bar = self.make_branch('foo/bar').bzrdir
+ baz = self.make_branch('baz').bzrdir
+ return foo, bar, baz
+
+ def test_find_bzrdirs(self):
+ foo, bar, baz = self.make_foo_bar_baz()
+ transport = get_transport(self.get_url())
+ self.assertEqualBzrdirs([baz, foo, bar],
+ bzrdir.BzrDir.find_bzrdirs(transport))
+
+ def test_find_bzrdirs_list_current(self):
+ def list_current(transport):
+ return [s for s in transport.list_dir('') if s != 'baz']
+
+ foo, bar, baz = self.make_foo_bar_baz()
+ transport = get_transport(self.get_url())
+ self.assertEqualBzrdirs([foo, bar],
+ bzrdir.BzrDir.find_bzrdirs(transport,
+ list_current=list_current))
+
+
+ def test_find_bzrdirs_evaluate(self):
+ def evaluate(bzrdir):
+ try:
+ repo = bzrdir.open_repository()
+ except NoRepositoryPresent:
+ return True, bzrdir.root_transport.base
+ else:
+ return False, bzrdir.root_transport.base
+
+ foo, bar, baz = self.make_foo_bar_baz()
+ transport = get_transport(self.get_url())
+ self.assertEqual([baz.root_transport.base, foo.root_transport.base],
+ list(bzrdir.BzrDir.find_bzrdirs(transport,
+ evaluate=evaluate)))
+
+ def assertEqualBzrdirs(self, first, second):
+ first = list(first)
+ second = list(second)
+ self.assertEqual(len(first), len(second))
+ for x, y in zip(first, second):
+ self.assertEqual(x.root_transport.base, y.root_transport.base)
+
+ def test_find_branches(self):
+ root = self.make_repository('', shared=True)
+ foo, bar, baz = self.make_foo_bar_baz()
+ qux = self.make_bzrdir('foo/qux')
+ transport = get_transport(self.get_url())
+ branches = bzrdir.BzrDir.find_branches(transport)
+ self.assertEqual(baz.root_transport.base, branches[0].base)
+ self.assertEqual(foo.root_transport.base, branches[1].base)
+ self.assertEqual(bar.root_transport.base, branches[2].base)
+
+ # ensure this works without a top-level repo
+ branches = bzrdir.BzrDir.find_branches(transport.clone('foo'))
+ self.assertEqual(foo.root_transport.base, branches[0].base)
+ self.assertEqual(bar.root_transport.base, branches[1].base)
+
class TestMeta1DirFormat(TestCaseWithTransport):
"""Tests specific to the meta1 dir format."""
=== modified file 'bzrlib/tests/test_workingtree.py'
--- a/bzrlib/tests/test_workingtree.py 2007-12-18 23:12:06 +0000
+++ b/bzrlib/tests/test_workingtree.py 2007-12-21 20:47:27 +0000
@@ -376,3 +376,15 @@
file_conflict = conflicts.TextConflict('file', None, 'hello-id')
tree.set_conflicts(conflicts.ConflictList([file_conflict]))
tree.auto_resolve()
+
+
+class TestFindTrees(TestCaseWithTransport):
+
+ def test_find_trees(self):
+ self.make_branch_and_tree('foo')
+ self.make_branch_and_tree('foo/bar')
+ # Sticking a tree inside a control dir is heinous, so let's skip it
+ self.make_branch_and_tree('foo/.bzr/baz')
+ self.make_branch('qux')
+ trees = workingtree.WorkingTree.find_trees('.')
+ self.assertEqual(2, len(list(trees)))
=== modified file 'bzrlib/workingtree.py'
--- a/bzrlib/workingtree.py 2007-12-20 15:21:48 +0000
+++ b/bzrlib/workingtree.py 2007-12-21 20:47:27 +0000
@@ -359,6 +359,22 @@
"""
return WorkingTree.open(path, _unsupported=True)
+ @staticmethod
+ def find_trees(location):
+ def list_current(transport):
+ return [d for d in transport.list_dir('') if d != '.bzr']
+ def evaluate(bzrdir):
+ try:
+ tree = bzrdir.open_workingtree()
+ except errors.NoWorkingTree:
+ return True, None
+ else:
+ return True, tree
+ transport = get_transport(location)
+ iterator = bzrdir.BzrDir.find_bzrdirs(transport, evaluate=evaluate,
+ list_current=list_current)
+ return [t for t in iterator if t is not None]
+
# should be deprecated - this is slow and in any case treating them as a
# container is (we now know) bad style -- mbp 20070302
## @deprecated_method(zero_fifteen)
More information about the bazaar-commits
mailing list