Merge lp:~vila/bzr/deprecation-warning-preference into lp:bzr
- deprecation-warning-preference
- Merge into bzr.dev
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | John A Meinel | ||||
Approved revision: | no longer in the source branch. | ||||
Merged at revision: | not available | ||||
Proposed branch: | lp:~vila/bzr/deprecation-warning-preference | ||||
Merge into: | lp:bzr | ||||
Diff against target: |
404 lines (+189/-39) 9 files modified
NEWS (+9/-0) bzrlib/branch.py (+2/-0) bzrlib/config.py (+26/-1) bzrlib/help_topics/en/configuration.txt (+12/-0) bzrlib/remote.py (+5/-0) bzrlib/repofmt/pack_repo.py (+2/-8) bzrlib/repository.py (+16/-9) bzrlib/tests/blackbox/test_exceptions.py (+66/-11) bzrlib/tests/test_config.py (+51/-10) |
||||
To merge this branch: | bzr merge lp:~vila/bzr/deprecation-warning-preference | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
John A Meinel | Approve | ||
Review via email: mp+16233@code.launchpad.net |
Commit message
Description of the change
Vincent Ladeuil (vila) wrote : | # |
John A Meinel (jameinel) wrote : | # |
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Vincent Ladeuil wrote:
> Vincent Ladeuil has proposed merging lp:~vila/bzr/deprecation-warning-preference into lp:bzr.
>
> Requested reviews:
> bzr-core (bzr-core)
>
>
...
>
> I didn't address John idea about filtering by format as I think we plan to
> reduce the number of formats and push people to use the default ones.
> The rationale is that: 1) you care or you don't care about being warned, 2) you can set
> the option in various ways, the finest grain being the branch. I think that's
> good enough.
>
>
>
Well, *I* may not care about using --1.9, but I don't want to be using
- --weave anymore. Not to say other people are in that boat.
v- Is the extra 's' for extra suppression ?
+* The ``suppresss_
+ accept the ``format_
+ warning for repositories. It can be set to in either ``bazaar.conf``,
+ ``locations.conf`` or ``branch.conf``.
+ (Ted Gould, Matthew Fuller, Vincent Ladeuil)
You can use
config.
support per-repo configuration.
Otherwise:
review: approve
merge: approve
John
=:->
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Using GnuPG with Mozilla - http://
iEYEARECAAYFAks
+9UAnRLpaeeM3hj
=Y17e
-----END PGP SIGNATURE-----
Martin Pool (mbp) wrote : | # |
Skimmed, looks good, thanks!
--
Martin <http://
Vincent Ladeuil (vila) wrote : | # |
>>>>> "jam" == John A Meinel <email address hidden> writes:
<snip/>
jam> Well, *I* may not care about using --1.9, but I don't
jam> want to be using --weave anymore. Not to say other
jam> people are in that boat.
What I meant (and forgot to add when writing the cover letter) is
that it's highly likely that people are coherent and use the same
format inside project boundaries so giving a path-based control
over the warning should be pretty close in ease of use to a
format-based control.
But the later is harder to implement and likely harder to use
(and my main point was that we don't want people to get involved
into all of your existing formats if we can avoid it :-)
jam> v- Is the extra 's' for extra suppression ?
Exactly, I think I made that typo at least 50 times so be
grateful that I left only one as I'm grateful you caught it :D
jam> +* The ``suppresss_
jam> + accept the ``format_
jam> + warning for repositories. It can be set to in either ``bazaar.conf``,
jam> + ``locations.conf`` or ``branch.conf``.
jam> + (Ted Gould, Matthew Fuller, Vincent Ladeuil)
jam> You can use
jam> config.
jam> support per-repo configuration.
I almost implemented it. I almost mentioned it in the cover letter.
But I had a bad feeling about it, it smells like a workaround. I
don't want to create yet another config file but at the same time
I have a feeling that it may address some other needs.
This needs discussion anyway so I didn't feel bad enough to
implement config.
jam> Otherwise:
jam> review: approve
jam> merge: approve
Thanks, you didn't comment on the remaining points so I've filed
bug #497694, comments there welcome.
Vincent
Preview Diff
1 | === modified file 'NEWS' |
2 | --- NEWS 2009-12-15 19:59:00 +0000 |
3 | +++ NEWS 2009-12-16 10:09:27 +0000 |
4 | @@ -95,6 +95,7 @@ |
5 | * ``bzr commit`` now has a ``--commit-time`` option. |
6 | (Alexander Sack, #459276) |
7 | |
8 | +<<<<<<< TREE |
9 | * ``-Dhpss`` now increases logging done when run on the bzr server, |
10 | similarly to how it works on the client. (John Arbash Meinel) |
11 | |
12 | @@ -108,6 +109,14 @@ |
13 | lengths. |
14 | (Vincent Ladeuil) |
15 | |
16 | +======= |
17 | +* The ``suppresss_warnings`` configuration option has been introduced and |
18 | + accept the ``format_deprecation`` value to disable the corresponding |
19 | + warning for repositories. It can be set to in either ``bazaar.conf``, |
20 | + ``locations.conf`` or ``branch.conf``. |
21 | + (Ted Gould, Matthew Fuller, Vincent Ladeuil) |
22 | + |
23 | +>>>>>>> MERGE-SOURCE |
24 | Bug Fixes |
25 | ********* |
26 | |
27 | |
28 | === modified file 'bzrlib/branch.py' |
29 | --- bzrlib/branch.py 2009-12-04 22:13:52 +0000 |
30 | +++ bzrlib/branch.py 2009-12-16 10:09:27 +0000 |
31 | @@ -2143,6 +2143,7 @@ |
32 | # All-in-one needs to always unlock/lock. |
33 | repo_control = getattr(self.repository, 'control_files', None) |
34 | if self.control_files == repo_control or not self.is_locked(): |
35 | + self.repository._warn_if_deprecated(self) |
36 | self.repository.lock_write() |
37 | took_lock = True |
38 | else: |
39 | @@ -2160,6 +2161,7 @@ |
40 | # All-in-one needs to always unlock/lock. |
41 | repo_control = getattr(self.repository, 'control_files', None) |
42 | if self.control_files == repo_control or not self.is_locked(): |
43 | + self.repository._warn_if_deprecated(self) |
44 | self.repository.lock_read() |
45 | took_lock = True |
46 | else: |
47 | |
48 | === modified file 'bzrlib/config.py' |
49 | --- bzrlib/config.py 2009-12-02 22:04:04 +0000 |
50 | +++ bzrlib/config.py 2009-12-16 10:09:27 +0000 |
51 | @@ -190,11 +190,23 @@ |
52 | """Get a generic option as a boolean - no special process, no default. |
53 | |
54 | :return None if the option doesn't exist or its value can't be |
55 | - interpreted as a boolean. Returns True or False ortherwise. |
56 | + interpreted as a boolean. Returns True or False otherwise. |
57 | """ |
58 | s = self._get_user_option(option_name) |
59 | return ui.bool_from_string(s) |
60 | |
61 | + def get_user_option_as_list(self, option_name): |
62 | + """Get a generic option as a list - no special process, no default. |
63 | + |
64 | + :return None if the option doesn't exist. Returns the value as a list |
65 | + otherwise. |
66 | + """ |
67 | + l = self._get_user_option(option_name) |
68 | + if isinstance(l, (str, unicode)): |
69 | + # A single value, most probably the user forgot the final ',' |
70 | + l = [l] |
71 | + return l |
72 | + |
73 | def gpg_signing_command(self): |
74 | """What program should be used to sign signatures?""" |
75 | result = self._gpg_signing_command() |
76 | @@ -313,6 +325,19 @@ |
77 | path = 'bzr' |
78 | return path |
79 | |
80 | + def suppress_warning(self, warning): |
81 | + """Should the warning be suppressed or emitted. |
82 | + |
83 | + :param warning: The name of the warning being tested. |
84 | + |
85 | + :returns: True if the warning should be suppressed, False otherwise. |
86 | + """ |
87 | + warnings = self.get_user_option_as_list('suppress_warnings') |
88 | + if warnings is None or warning not in warnings: |
89 | + return False |
90 | + else: |
91 | + return True |
92 | + |
93 | |
94 | class IniBasedConfig(Config): |
95 | """A configuration policy that draws from ini files.""" |
96 | |
97 | === modified file 'bzrlib/help_topics/en/configuration.txt' |
98 | --- bzrlib/help_topics/en/configuration.txt 2009-10-02 09:11:43 +0000 |
99 | +++ bzrlib/help_topics/en/configuration.txt 2009-12-16 10:09:27 +0000 |
100 | @@ -428,6 +428,18 @@ |
101 | A publically-accessible version of this branch (implying that this version is |
102 | not publically-accessible). Used (and set) by ``bzr send``. |
103 | |
104 | +suppress_warnings |
105 | +~~~~~~~~~~~~~~~~~ |
106 | + |
107 | +A list of strings, each string represent a warning that can be emitted by |
108 | +bzr. Mentioning a warning in this list tells bzr to not emit it. |
109 | + |
110 | +Valid values: |
111 | + |
112 | +* ``format_deprecation``: |
113 | + whether the format deprecation warning is shown on repositories that are |
114 | + using deprecated formats. |
115 | + |
116 | |
117 | Branch type specific options |
118 | ---------------------------- |
119 | |
120 | === modified file 'bzrlib/remote.py' |
121 | --- bzrlib/remote.py 2009-11-11 06:50:40 +0000 |
122 | +++ bzrlib/remote.py 2009-12-16 10:09:27 +0000 |
123 | @@ -951,6 +951,11 @@ |
124 | def is_write_locked(self): |
125 | return self._lock_mode == 'w' |
126 | |
127 | + def _warn_if_deprecated(self, branch=None): |
128 | + # If we have a real repository, the check will be done there, if we |
129 | + # don't the check will be done remotely. |
130 | + pass |
131 | + |
132 | def lock_read(self): |
133 | # wrong eventually - want a local lock cache context |
134 | if not self._lock_mode: |
135 | |
136 | === modified file 'bzrlib/repofmt/pack_repo.py' |
137 | --- bzrlib/repofmt/pack_repo.py 2009-10-29 05:54:49 +0000 |
138 | +++ bzrlib/repofmt/pack_repo.py 2009-12-16 10:09:27 +0000 |
139 | @@ -2234,16 +2234,10 @@ |
140 | self._reconcile_fixes_text_parents = True |
141 | self._reconcile_backsup_inventory = False |
142 | |
143 | - def _warn_if_deprecated(self): |
144 | + def _warn_if_deprecated(self, branch=None): |
145 | # This class isn't deprecated, but one sub-format is |
146 | if isinstance(self._format, RepositoryFormatKnitPack5RichRootBroken): |
147 | - from bzrlib import repository |
148 | - if repository._deprecation_warning_done: |
149 | - return |
150 | - repository._deprecation_warning_done = True |
151 | - warning("Format %s for %s is deprecated - please use" |
152 | - " 'bzr upgrade --1.6.1-rich-root'" |
153 | - % (self._format, self.bzrdir.transport.base)) |
154 | + super(KnitPackRepository, self)._warn_if_deprecated(branch) |
155 | |
156 | def _abort_write_group(self): |
157 | self.revisions._index._key_dependencies.clear() |
158 | |
159 | === modified file 'bzrlib/repository.py' |
160 | --- bzrlib/repository.py 2009-12-03 05:31:03 +0000 |
161 | +++ bzrlib/repository.py 2009-12-16 10:09:27 +0000 |
162 | @@ -24,6 +24,7 @@ |
163 | bzrdir, |
164 | check, |
165 | chk_map, |
166 | + config, |
167 | debug, |
168 | errors, |
169 | fetch as _mod_fetch, |
170 | @@ -1304,11 +1305,6 @@ |
171 | self._reconcile_does_inventory_gc = True |
172 | self._reconcile_fixes_text_parents = False |
173 | self._reconcile_backsup_inventory = True |
174 | - # not right yet - should be more semantically clear ? |
175 | - # |
176 | - # TODO: make sure to construct the right store classes, etc, depending |
177 | - # on whether escaping is required. |
178 | - self._warn_if_deprecated() |
179 | self._write_group = None |
180 | # Additional places to query for data. |
181 | self._fallback_repositories = [] |
182 | @@ -1389,6 +1385,7 @@ |
183 | locked = self.is_locked() |
184 | result = self.control_files.lock_write(token=token) |
185 | if not locked: |
186 | + self._warn_if_deprecated() |
187 | self._note_lock('w') |
188 | for repo in self._fallback_repositories: |
189 | # Writes don't affect fallback repos |
190 | @@ -1400,6 +1397,7 @@ |
191 | locked = self.is_locked() |
192 | self.control_files.lock_read() |
193 | if not locked: |
194 | + self._warn_if_deprecated() |
195 | self._note_lock('r') |
196 | for repo in self._fallback_repositories: |
197 | repo.lock_read() |
198 | @@ -2782,13 +2780,22 @@ |
199 | result.check(callback_refs) |
200 | return result |
201 | |
202 | - def _warn_if_deprecated(self): |
203 | + def _warn_if_deprecated(self, branch=None): |
204 | global _deprecation_warning_done |
205 | if _deprecation_warning_done: |
206 | return |
207 | - _deprecation_warning_done = True |
208 | - warning("Format %s for %s is deprecated - please use 'bzr upgrade' to get better performance" |
209 | - % (self._format, self.bzrdir.transport.base)) |
210 | + try: |
211 | + if branch is None: |
212 | + conf = config.GlobalConfig() |
213 | + else: |
214 | + conf = branch.get_config() |
215 | + if conf.suppress_warning('format_deprecation'): |
216 | + return |
217 | + warning("Format %s for %s is deprecated -" |
218 | + " please use 'bzr upgrade' to get better performance" |
219 | + % (self._format, self.bzrdir.transport.base)) |
220 | + finally: |
221 | + _deprecation_warning_done = True |
222 | |
223 | def supports_rich_root(self): |
224 | return self._format.rich_root_data |
225 | |
226 | === modified file 'bzrlib/tests/blackbox/test_exceptions.py' |
227 | --- bzrlib/tests/blackbox/test_exceptions.py 2009-08-20 06:25:02 +0000 |
228 | +++ bzrlib/tests/blackbox/test_exceptions.py 2009-12-16 10:09:27 +0000 |
229 | @@ -22,8 +22,11 @@ |
230 | |
231 | from bzrlib import ( |
232 | bzrdir, |
233 | + config, |
234 | errors, |
235 | + osutils, |
236 | repository, |
237 | + tests, |
238 | trace, |
239 | ) |
240 | |
241 | @@ -45,18 +48,70 @@ |
242 | self.assertContainsRe(err, r'Bazaar has encountered an internal error') |
243 | |
244 | |
245 | -class TestDeprecationWarning(TestCaseInTempDir): |
246 | +class TestDeprecationWarning(tests.TestCaseWithTransport): |
247 | + """The deprecation warning is controlled via a global variable: |
248 | + repository._deprecation_warning_done. As such, it can be emitted only once |
249 | + during a bzr invocation, no matter how many repositories are involved. |
250 | + |
251 | + It would be better if it was a repo attribute instead but that's far more |
252 | + work than I want to do right now -- vila 20091215. |
253 | + """ |
254 | + |
255 | + def setUp(self): |
256 | + super(TestDeprecationWarning, self).setUp() |
257 | + self.disable_deprecation_warning() |
258 | + |
259 | + def enable_deprecation_warning(self, repo=None): |
260 | + """repo is not used yet since _deprecation_warning_done is a global""" |
261 | + repository._deprecation_warning_done = False |
262 | + |
263 | + def disable_deprecation_warning(self, repo=None): |
264 | + """repo is not used yet since _deprecation_warning_done is a global""" |
265 | + repository._deprecation_warning_done = True |
266 | + |
267 | + def make_obsolete_repo(self, path): |
268 | + # We don't want the deprecation raising during the repo creation |
269 | + tree = self.make_branch_and_tree(path, format=bzrdir.BzrDirFormat5()) |
270 | + return tree |
271 | + |
272 | + def check_warning(self, present): |
273 | + if present: |
274 | + check = self.assertContainsRe |
275 | + else: |
276 | + check = self.assertNotContainsRe |
277 | + check(self._get_log(keep_log_file=True), 'WARNING.*bzr upgrade') |
278 | |
279 | def test_repository_deprecation_warning(self): |
280 | """Old formats give a warning""" |
281 | - # the warning's normally off for testing but we reenable it |
282 | - repository._deprecation_warning_done = False |
283 | - try: |
284 | - os.mkdir('foo') |
285 | - bzrdir.BzrDirFormat5().initialize('foo') |
286 | - out, err = self.run_bzr("status foo") |
287 | - self.assertContainsRe(self._get_log(keep_log_file=True), |
288 | - "bzr upgrade") |
289 | - finally: |
290 | - repository._deprecation_warning_done = True |
291 | + self.make_obsolete_repo('foo') |
292 | + self.enable_deprecation_warning() |
293 | + out, err = self.run_bzr('status', working_dir='foo') |
294 | + self.check_warning(True) |
295 | + |
296 | + def test_repository_deprecation_warning_suppressed_global(self): |
297 | + """Old formats give a warning""" |
298 | + conf = config.GlobalConfig() |
299 | + conf.set_user_option('suppress_warnings', 'format_deprecation') |
300 | + self.make_obsolete_repo('foo') |
301 | + self.enable_deprecation_warning() |
302 | + out, err = self.run_bzr('status', working_dir='foo') |
303 | + self.check_warning(False) |
304 | + |
305 | + def test_repository_deprecation_warning_suppressed_locations(self): |
306 | + """Old formats give a warning""" |
307 | + self.make_obsolete_repo('foo') |
308 | + conf = config.LocationConfig(osutils.pathjoin(self.test_dir, 'foo')) |
309 | + conf.set_user_option('suppress_warnings', 'format_deprecation') |
310 | + self.enable_deprecation_warning() |
311 | + out, err = self.run_bzr('status', working_dir='foo') |
312 | + self.check_warning(False) |
313 | + |
314 | + def test_repository_deprecation_warning_suppressed_branch(self): |
315 | + """Old formats give a warning""" |
316 | + tree = self.make_obsolete_repo('foo') |
317 | + conf = tree.branch.get_config() |
318 | + conf.set_user_option('suppress_warnings', 'format_deprecation') |
319 | + self.enable_deprecation_warning() |
320 | + out, err = self.run_bzr('status', working_dir='foo') |
321 | + self.check_warning(False) |
322 | |
323 | |
324 | === modified file 'bzrlib/tests/test_config.py' |
325 | --- bzrlib/tests/test_config.py 2009-10-31 01:43:48 +0000 |
326 | +++ bzrlib/tests/test_config.py 2009-12-16 10:09:27 +0000 |
327 | @@ -369,6 +369,14 @@ |
328 | |
329 | class TestIniConfig(tests.TestCase): |
330 | |
331 | + def make_config_parser(self, s): |
332 | + conf = config.IniBasedConfig(None) |
333 | + parser = conf._get_parser(file=StringIO(s.encode('utf-8'))) |
334 | + return conf, parser |
335 | + |
336 | + |
337 | +class TestIniConfigBuilding(TestIniConfig): |
338 | + |
339 | def test_contructs(self): |
340 | my_config = config.IniBasedConfig("nothing") |
341 | |
342 | @@ -385,20 +393,53 @@ |
343 | parser = my_config._get_parser(file=config_file) |
344 | self.failUnless(my_config._get_parser() is parser) |
345 | |
346 | + |
347 | +class TestGetUserOptionAs(TestIniConfig): |
348 | + |
349 | def test_get_user_option_as_bool(self): |
350 | - config_file = StringIO(""" |
351 | + conf, parser = self.make_config_parser(""" |
352 | a_true_bool = true |
353 | a_false_bool = 0 |
354 | an_invalid_bool = maybe |
355 | -a_list = hmm, who knows ? # This interpreted as a list ! |
356 | -""".encode('utf-8')) |
357 | - my_config = config.IniBasedConfig(None) |
358 | - parser = my_config._get_parser(file=config_file) |
359 | - get_option = my_config.get_user_option_as_bool |
360 | - self.assertEqual(True, get_option('a_true_bool')) |
361 | - self.assertEqual(False, get_option('a_false_bool')) |
362 | - self.assertIs(None, get_option('an_invalid_bool')) |
363 | - self.assertIs(None, get_option('not_defined_in_this_config')) |
364 | +a_list = hmm, who knows ? # This is interpreted as a list ! |
365 | +""") |
366 | + get_bool = conf.get_user_option_as_bool |
367 | + self.assertEqual(True, get_bool('a_true_bool')) |
368 | + self.assertEqual(False, get_bool('a_false_bool')) |
369 | + self.assertIs(None, get_bool('an_invalid_bool')) |
370 | + self.assertIs(None, get_bool('not_defined_in_this_config')) |
371 | + |
372 | + |
373 | + def test_get_user_option_as_list(self): |
374 | + conf, parser = self.make_config_parser(""" |
375 | +a_list = a,b,c |
376 | +length_1 = 1, |
377 | +one_item = x |
378 | +""") |
379 | + get_list = conf.get_user_option_as_list |
380 | + self.assertEqual(['a', 'b', 'c'], get_list('a_list')) |
381 | + self.assertEqual(['1'], get_list('length_1')) |
382 | + self.assertEqual('x', conf.get_user_option('one_item')) |
383 | + # automatically cast to list |
384 | + self.assertEqual(['x'], get_list('one_item')) |
385 | + |
386 | + |
387 | +class TestSupressWarning(TestIniConfig): |
388 | + |
389 | + def make_warnings_config(self, s): |
390 | + conf, parser = self.make_config_parser(s) |
391 | + return conf.suppress_warning |
392 | + |
393 | + def test_suppress_warning_unknown(self): |
394 | + suppress_warning = self.make_warnings_config('') |
395 | + self.assertEqual(False, suppress_warning('unknown_warning')) |
396 | + |
397 | + def test_suppress_warning_known(self): |
398 | + suppress_warning = self.make_warnings_config('suppress_warnings=a,b') |
399 | + self.assertEqual(False, suppress_warning('c')) |
400 | + self.assertEqual(True, suppress_warning('a')) |
401 | + self.assertEqual(True, suppress_warning('b')) |
402 | + |
403 | |
404 | class TestGetConfig(tests.TestCase): |
405 |
This patch supersedes https:/ /code.edge. launchpad. net/~ted/ bzr/deprecation -warning- preference/ +merge/ 15455
It's a patch pilot attempt to land a work started by fullermd far too long ago and re-started by ted more recently.
I tried to capture most of the comments by Ian, Martin and John without spending too much time on it (but still...).
This patch adds:
- specifying a suppress_warnings variable in any configuration file,
- explicitly requiring a config variable as a list,
- a suppres_warning() method to config files,
- checks for format_deprecation at lock time on branch objects (which can then provide
their config to the repo before locking it),
- checks for format_deprecation at lock on repo objects but relying on bazaar.conf only
in that case.
I may file a bug or three for the remaining points so please comment if you disagree
with some decision made here but mention if you agree with postponing it (good) or you
think it's required to land (bad :).
The idea was to implement something that we could tweak further
but that will not require some upgrade dance in the future (so mainly: keep the same
variable name, don't force setting it in bazaar.conf so the default behaviour for
new branches is still to raise the warning).
These remaining points are:
- the actual implementation use a single global variable for the whole code base,
forget about being warned for the second repo accessed (or the 20th for bzrlib users),
that should be implemented as a repo attribute instead,
- working trees can raise format deprecation warnings too, they should use the new
facility (I don't think we want to proliferate warning variables gratuitously)
- hpss remote repositories doesn't raise the warning locally (AFAICS but feel free
to prove me wrong),
- no distinction is made between read and write access (I'm not sure I understand
the need here),
- there is no config file for repositories were such an option can be specified.
My intent here is to provide a base for future work without addressing some existing problems (some of which have been revealed while writing this patch).
I didn't address John idea about filtering by format as I think we plan to
reduce the number of formats and push people to use the default ones.
The rationale is that: 1) you care or you don't care about being warned, 2) you can set
the option in various ways, the finest grain being the branch. I think that's
good enough.