/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/views.py

  • Committer: Jelmer Vernooij
  • Date: 2020-04-05 19:11:34 UTC
  • mto: (7490.7.16 work)
  • mto: This revision was merged to the branch mainline in revision 7501.
  • Revision ID: jelmer@jelmer.uk-20200405191134-0aebh8ikiwygxma5
Populate the .gitignore file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
  tree.views.lookup_view()
23
23
"""
24
24
 
 
25
from __future__ import absolute_import
25
26
 
26
27
import re
27
28
 
28
 
from bzrlib import (
 
29
from . import (
29
30
    errors,
30
31
    osutils,
31
32
    )
32
33
 
33
34
 
34
 
_VIEWS_FORMAT_MARKER_RE = re.compile(r'Bazaar views format (\d+)')
35
 
_VIEWS_FORMAT1_MARKER = "Bazaar views format 1\n"
 
35
_VIEWS_FORMAT_MARKER_RE = re.compile(b'Bazaar views format (\\d+)')
 
36
_VIEWS_FORMAT1_MARKER = b"Bazaar views format 1\n"
 
37
 
 
38
 
 
39
class NoSuchView(errors.BzrError):
 
40
    """A view does not exist.
 
41
    """
 
42
 
 
43
    _fmt = u"No such view: %(view_name)s."
 
44
 
 
45
    def __init__(self, view_name):
 
46
        self.view_name = view_name
 
47
 
 
48
 
 
49
class ViewsNotSupported(errors.BzrError):
 
50
    """Views are not supported by a tree format.
 
51
    """
 
52
 
 
53
    _fmt = ("Views are not supported by %(tree)s;"
 
54
            " use 'brz upgrade' to change your tree to a later format.")
 
55
 
 
56
    def __init__(self, tree):
 
57
        self.tree = tree
 
58
 
 
59
 
 
60
class FileOutsideView(errors.BzrError):
 
61
 
 
62
    _fmt = ('Specified file "%(file_name)s" is outside the current view: '
 
63
            '%(view_str)s')
 
64
 
 
65
    def __init__(self, file_name, view_files):
 
66
        self.file_name = file_name
 
67
        self.view_str = ", ".join(view_files)
36
68
 
37
69
 
38
70
class _Views(object):
94
126
        :param views: a map from view name to list of files/directories
95
127
        """
96
128
        if current is not None and current not in views:
97
 
            raise errors.NoSuchView(current)
98
 
        self.tree.lock_write()
99
 
        try:
 
129
            raise NoSuchView(current)
 
130
        with self.tree.lock_write():
100
131
            self._current = current
101
132
            self._views = views
102
133
            self._save_view_info()
103
 
        finally:
104
 
            self.tree.unlock()
105
134
 
106
135
    def lookup_view(self, view_name=None):
107
136
        """Return the contents of a view.
118
147
                    return []
119
148
            return self._views[view_name]
120
149
        except KeyError:
121
 
            raise errors.NoSuchView(view_name)
 
150
            raise NoSuchView(view_name)
122
151
 
123
152
    def set_view(self, view_name, view_files, make_current=True):
124
153
        """Add or update a view definition.
127
156
        :param view_files: the list of files/directories in the view
128
157
        :param make_current: make this view the current one or not
129
158
        """
130
 
        self.tree.lock_write()
131
 
        try:
 
159
        with self.tree.lock_write():
132
160
            self._load_view_info()
133
161
            self._views[view_name] = view_files
134
162
            if make_current:
135
163
                self._current = view_name
136
164
            self._save_view_info()
137
 
        finally:
138
 
            self.tree.unlock()
139
165
 
140
166
    def delete_view(self, view_name):
141
167
        """Delete a view definition.
142
168
 
143
169
        If the view deleted is the current one, the current view is reset.
144
170
        """
145
 
        self.tree.lock_write()
146
 
        try:
 
171
        with self.tree.lock_write():
147
172
            self._load_view_info()
148
173
            try:
149
174
                del self._views[view_name]
150
175
            except KeyError:
151
 
                raise errors.NoSuchView(view_name)
 
176
                raise NoSuchView(view_name)
152
177
            if view_name == self._current:
153
178
                self._current = None
154
179
            self._save_view_info()
155
 
        finally:
156
 
            self.tree.unlock()
157
180
 
158
181
    def _save_view_info(self):
159
182
        """Save the current view and all view definitions.
161
184
        Be sure to have initialised self._current and self._views before
162
185
        calling this method.
163
186
        """
164
 
        self.tree.lock_write()
165
 
        try:
 
187
        with self.tree.lock_write():
166
188
            if self._current is None:
167
189
                keywords = {}
168
190
            else:
169
191
                keywords = {'current': self._current}
170
 
            self.tree._transport.put_bytes('views',
171
 
                self._serialize_view_content(keywords, self._views))
172
 
        finally:
173
 
            self.tree.unlock()
 
192
            self.tree._transport.put_bytes(
 
193
                'views', self._serialize_view_content(keywords, self._views))
174
194
 
175
195
    def _load_view_info(self):
176
196
        """Load the current view and dictionary of view definitions."""
177
197
        if not self._loaded:
178
 
            self.tree.lock_read()
179
 
            try:
 
198
            with self.tree.lock_read():
180
199
                try:
181
200
                    view_content = self.tree._transport.get_bytes('views')
182
 
                except errors.NoSuchFile, e:
 
201
                except errors.NoSuchFile:
183
202
                    self._current, self._views = None, {}
184
203
                else:
185
204
                    keywords, self._views = \
186
205
                        self._deserialize_view_content(view_content)
187
206
                    self._current = keywords.get('current')
188
 
            finally:
189
 
                self.tree.unlock()
190
207
            self._loaded = True
191
208
 
192
209
    def _serialize_view_content(self, keywords, view_dict):
193
210
        """Convert view keywords and a view dictionary into a stream."""
194
211
        lines = [_VIEWS_FORMAT1_MARKER]
195
212
        for key in keywords:
196
 
            line = "%s=%s\n" % (key,keywords[key])
 
213
            line = "%s=%s\n" % (key, keywords[key])
197
214
            lines.append(line.encode('utf-8'))
198
215
        if view_dict:
199
216
            lines.append("views:\n".encode('utf-8'))
200
217
            for view in sorted(view_dict):
201
218
                view_data = "%s\0%s\n" % (view, "\0".join(view_dict[view]))
202
219
                lines.append(view_data.encode('utf-8'))
203
 
        return "".join(lines)
 
220
        return b"".join(lines)
204
221
 
205
222
    def _deserialize_view_content(self, view_content):
206
223
        """Convert a stream into view keywords and a dictionary of views."""
207
224
        # as a special case to make initialization easy, an empty definition
208
225
        # maps to no current view and an empty view dictionary
209
 
        if view_content == '':
 
226
        if view_content == b'':
210
227
            return {}, {}
211
228
        lines = view_content.splitlines()
212
229
        match = _VIEWS_FORMAT_MARKER_RE.match(lines[0])
213
230
        if not match:
214
231
            raise ValueError(
215
232
                "format marker missing from top of views file")
216
 
        elif match.group(1) != '1':
 
233
        elif match.group(1) != b'1':
217
234
            raise ValueError(
218
235
                "cannot decode views format %s" % match.group(1))
219
236
        try:
235
252
                    keywords[keyword] = value
236
253
                else:
237
254
                    raise ValueError("failed to deserialize views line %s",
238
 
                        text)
 
255
                                     text)
239
256
            return keywords, views
240
 
        except ValueError, e:
 
257
        except ValueError as e:
241
258
            raise ValueError("failed to deserialize views content %r: %s"
242
 
                % (view_content, e))
 
259
                             % (view_content, e))
243
260
 
244
261
 
245
262
class DisabledViews(_Views):
255
272
        return False
256
273
 
257
274
    def _not_supported(self, *a, **k):
258
 
        raise errors.ViewsNotSupported(self.tree)
 
275
        raise ViewsNotSupported(self.tree)
259
276
 
260
277
    get_view_info = _not_supported
261
278
    set_view_info = _not_supported
280
297
    """If a working tree has a view enabled, check the path is within it."""
281
298
    if tree.supports_views():
282
299
        view_files = tree.views.lookup_view()
283
 
        if  view_files and not osutils.is_inside_any(view_files, relpath):
284
 
            raise errors.FileOutsideView(relpath, view_files)
 
300
        if view_files and not osutils.is_inside_any(view_files, relpath):
 
301
            raise FileOutsideView(relpath, view_files)