-# Copyright (C) 2005-2010 Aaron Bentley and Panometrics, Inc.
+# Copyright (C) 2005-2011 Aaron Bentley <abentley@panoramicfeedback.com>
# Ben Finney <benf@cybersource.com.au>
# Gianluca Montecchi <gian@grys.it>
-# Marien Zwart <marienz@gentoo.org>
+# Marien Zwart <marien.zwart@gmail.com>
# W. Trevor King <wking@drexel.edu>
#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
+# This file is part of Bugs Everywhere.
#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# Bugs Everywhere is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation, either version 2 of the License, or (at your
+# option) any later version.
#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+# Bugs Everywhere is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Bugs Everywhere. If not, see <http://www.gnu.org/licenses/>.
-"""
-Bazaar (bzr) backend.
+"""Bazaar_ (bzr) backend.
+
+.. _Bazaar: http://bazaar.canonical.com/
"""
try:
import shutil
import StringIO
import sys
+import types
import libbe
import base
return Bzr()
class Bzr(base.VCS):
+ """:class:`base.VCS` implementation for Bazaar.
+ """
name = 'bzr'
client = None # bzrlib module
return bzrlib.__version__
def version_cmp(self, *args):
- """
- Compare the installed Bazaar version V_i with another version
- V_o (given in *args). Returns
- 1 if V_i > V_o,
- 0 if V_i == V_o, and
- -1 if V_i < V_o
+ """Compare the installed Bazaar version `V_i` with another version
+ `V_o` (given in `*args`). Returns
+
+ === ===============
+ 1 if `V_i > V_o`
+ 0 if `V_i == V_o`
+ -1 if `V_i < V_o`
+ === ===============
+
+ Examples
+ --------
+
>>> b = Bzr(repo='.')
- >>> b._vcs_version = lambda : "2.3.1 (release)"
+ >>> b._version = '2.3.1 (release)'
>>> b.version_cmp(2,3,1)
0
>>> b.version_cmp(2,3,2)
1
>>> b.version_cmp(3)
-1
- >>> b._vcs_version = lambda : "2.0.0pre2"
+ >>> b._version = '2.0.0pre2'
>>> b._parsed_version = None
>>> b.version_cmp(3)
+ -1
+ >>> b.version_cmp(2,0,1)
Traceback (most recent call last):
...
- NotImplementedError: Cannot parse "2.0.0pre2" portion of Bazaar version "2.0.0pre2"
- invalid literal for int() with base 10: '0pre2'
+ NotImplementedError: Cannot parse non-integer portion "0pre2" of Bzr version "2.0.0pre2"
"""
if not hasattr(self, '_parsed_version') \
or self._parsed_version == None:
- num_part = self._vcs_version().split(' ')[0]
- try:
- self._parsed_version = [int(i) for i in num_part.split('.')]
- except ValueError, e:
+ num_part = self.version().split(' ')[0]
+ self._parsed_version = []
+ for num in num_part.split('.'):
+ try:
+ self._parsed_version.append(int(num))
+ except ValueError, e:
+ self._parsed_version.append(num)
+ for current,other in zip(self._parsed_version, args):
+ if type(current) != types.IntType:
raise NotImplementedError(
- 'Cannot parse "%s" portion of Bazaar version "%s"\n %s'
- % (num_part, self._vcs_version(), str(e)))
- cmps = [cmp(a,b) for a,b in zip(self._parsed_version, args)]
- for c in cmps:
+ 'Cannot parse non-integer portion "%s" of Bzr version "%s"'
+ % (current, self.version()))
+ c = cmp(current,other)
if c != 0:
return c
return 0
cmd = bzrlib.builtins.cmd_root()
cmd.outf = StringIO.StringIO()
cmd.run(filename=path)
+ cmd.cleanup_now()
return cmd.outf.getvalue().rstrip('\n')
def _vcs_init(self, path):
cmd = bzrlib.builtins.cmd_init()
cmd.outf = StringIO.StringIO()
cmd.run(location=path)
+ cmd.cleanup_now()
def _vcs_destroy(self):
vcs_dir = os.path.join(self.repo, '.bzr')
cmd = bzrlib.builtins.cmd_add()
cmd.outf = StringIO.StringIO()
cmd.run(file_list=[path], file_ids_from=self.repo)
+ cmd.cleanup_now()
def _vcs_exists(self, path, revision=None):
manifest = self._vcs_listdir(
cmd = bzrlib.builtins.cmd_remove()
cmd.outf = StringIO.StringIO()
cmd.run(file_list=[path], file_deletion_strategy='force')
+ cmd.cleanup_now()
def _vcs_update(self, path):
pass
revision = self._parse_revision_string(revision)
cmd = bzrlib.builtins.cmd_cat()
cmd.outf = StringIO.StringIO()
- if self.version_cmp(1,6,0) == -1:
+ if self.version_cmp(1,6,0) < 0:
# old bzrlib cmd_cat uses sys.stdout not self.outf for output.
stdout = sys.stdout
sys.stdout = cmd.outf
raise base.InvalidPath(path, root=self.repo, revision=revision)
raise
finally:
- if self.version_cmp(2,0,0) == -1:
+ if self.version_cmp(2,0,0) < 0:
cmd.outf = sys.stdout
sys.stdout = stdout
+ cmd.cleanup_now()
return cmd.outf.getvalue()
def _vcs_path(self, id, revision):
try:
if self.version_cmp(2,0,0) >= 0:
cmd.run(revision=revision, path=path, recursive=recursive)
- else: # Pre-2.0 Bazaar
+ else:
+ # Pre-2.0 Bazaar (non_recursive)
+ # + working around broken non_recursive+path implementation
+ # (https://bugs.launchpad.net/bzr/+bug/158690)
cmd.run(revision=revision, path=path,
- non_recursive=not recursive)
+ non_recursive=False)
except bzrlib.errors.BzrCommandError, e:
if 'not present in revision' in str(e):
raise base.InvalidPath(path, root=self.repo, revision=revision)
raise
+ finally:
+ cmd.cleanup_now()
children = cmd.outf.getvalue().rstrip('\n').splitlines()
children = [self._u_rel_path(c, path) for c in children]
+ if self.version_cmp(2,0,0) < 0 and recursive == False:
+ children = [c for c in children if os.path.sep not in c]
return children
def _vcs_commit(self, commitfile, allow_empty=False):
raise
finally:
os.chdir(cwd)
+ cmd.cleanup_now()
return self._vcs_revision_id(-1)
def _vcs_revision_id(self, index):
cmd = bzrlib.builtins.cmd_revno()
cmd.outf = StringIO.StringIO()
cmd.run(location=self.repo)
+ cmd.cleanup_now()
current_revision = int(cmd.outf.getvalue())
if index > current_revision or index < -current_revision:
return None
status = cmd.run(revision=revision, file_list=[self.repo])
finally:
sys.stdout = stdout
+ cmd.cleanup_now()
assert status in [0,1], "Invalid status %d" % status
return cmd.outf.getvalue()
def _parse_diff(self, diff_text):
- """
- Example diff text:
-
- === modified file 'dir/changed'
- --- dir/changed 2010-01-16 01:54:53 +0000
- +++ dir/changed 2010-01-16 01:54:54 +0000
- @@ -1,3 +1,3 @@
- hi
- -there
- +everyone and
- joe
-
- === removed file 'dir/deleted'
- --- dir/deleted 2010-01-16 01:54:53 +0000
- +++ dir/deleted 1970-01-01 00:00:00 +0000
- @@ -1,3 +0,0 @@
- -in
- -the
- -beginning
-
- === removed file 'dir/moved'
- --- dir/moved 2010-01-16 01:54:53 +0000
- +++ dir/moved 1970-01-01 00:00:00 +0000
- @@ -1,4 +0,0 @@
- -the
- -ants
- -go
- -marching
-
- === added file 'dir/moved2'
- --- dir/moved2 1970-01-01 00:00:00 +0000
- +++ dir/moved2 2010-01-16 01:54:34 +0000
- @@ -0,0 +1,4 @@
- +the
- +ants
- +go
- +marching
-
- === added file 'dir/new'
- --- dir/new 1970-01-01 00:00:00 +0000
- +++ dir/new 2010-01-16 01:54:54 +0000
- @@ -0,0 +1,2 @@
- +hello
- +world
-
+ """_parse_diff(diff_text) -> (new,modified,removed)
+
+ `new`, `modified`, and `removed` are lists of files.
+
+ Example diff text::
+
+ === modified file 'dir/changed'
+ --- dir/changed 2010-01-16 01:54:53 +0000
+ +++ dir/changed 2010-01-16 01:54:54 +0000
+ @@ -1,3 +1,3 @@
+ hi
+ -there
+ +everyone and
+ joe
+
+ === removed file 'dir/deleted'
+ --- dir/deleted 2010-01-16 01:54:53 +0000
+ +++ dir/deleted 1970-01-01 00:00:00 +0000
+ @@ -1,3 +0,0 @@
+ -in
+ -the
+ -beginning
+
+ === removed file 'dir/moved'
+ --- dir/moved 2010-01-16 01:54:53 +0000
+ +++ dir/moved 1970-01-01 00:00:00 +0000
+ @@ -1,4 +0,0 @@
+ -the
+ -ants
+ -go
+ -marching
+
+ === added file 'dir/moved2'
+ --- dir/moved2 1970-01-01 00:00:00 +0000
+ +++ dir/moved2 2010-01-16 01:54:34 +0000
+ @@ -0,0 +1,4 @@
+ +the
+ +ants
+ +go
+ +marching
+
+ === added file 'dir/new'
+ --- dir/new 1970-01-01 00:00:00 +0000
+ +++ dir/new 2010-01-16 01:54:54 +0000
+ @@ -0,0 +1,2 @@
+ +hello
+ +world
+
"""
new = []
modified = []