Status: | Merged |
---|---|
Approved by: | Jelmer Vernooij |
Approved revision: | no longer in the source branch. |
Merged at revision: | 6347 |
Proposed branch: | lp:~bzr/bzr/doc |
Merge into: | lp:bzr |
Diff against target: |
920 lines (+833/-32) 3 files modified
doc/developers/configuration.txt (+52/-12) doc/developers/new-config-rationale.txt (+778/-0) doc/developers/plans.txt (+3/-20) |
To merge this branch: | bzr merge lp:~bzr/bzr/doc |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jelmer Vernooij (community) | Approve | ||
Vincent Ladeuil | Pending | ||
Review via email: mp+84069@code.launchpad.net |
Commit message
Simple explanations about how to use the new config options.
Description of the change
This tries to answer the questions I have about the new config api. Are my answers right?
I was just saying to Vincent on irc I think the right order for developer documentation is:
0- broadly what is this for (1-3 paragraphs)
1- how do you do the most typical things for it (one or two screens - more useful for things that are meant to be widespread apis like config)
2- overview of the thing
3- changes we want to make to how it works; this is kind of worth having accessible but it's too confusing to start with it
We can possibly merge in more stuff from devnotes but it will need some rework.
Jelmer Vernooij (jelmer) wrote : | # |
Vincent Ladeuil (vila) wrote : | # |
> Are my answers right?
Yes. I lightly edited it after validating that it will show up correctly on doc.bazaar.c.c.
> We can possibly merge in more stuff from devnotes but it will need some rework.
I started with an simple approach: bring in the devnotes version as a separate document.
If that's already too much, I'll do a separate proposal.
I wanted to refresh both the actual version and the devnotes ones anyway so I'll make another proposal for that based on this proposal.
So basically, with the versions I'll push shortly:
0 - not done yet
1 - started with your proposal, more to come
2 - pretty much matches the content before your proposal, should be correct
3 - now in new-config-
Jelmer Vernooij (jelmer) : | # |
Vincent Ladeuil (vila) wrote : | # |
sent to pqm by email
Vincent Ladeuil (vila) wrote : | # |
sent to pqm by email
Preview Diff
1 | === modified file 'doc/developers/configuration.txt' |
2 | --- doc/developers/configuration.txt 2011-11-14 16:36:31 +0000 |
3 | +++ doc/developers/configuration.txt 2011-12-06 15:18:25 +0000 |
4 | @@ -1,12 +1,46 @@ |
5 | Configuring Bazaar |
6 | ================== |
7 | |
8 | -A configuration option has: |
9 | - |
10 | -* a name: a valid python identifier (even if it's not used as an |
11 | - identifier in python itself) |
12 | - |
13 | -* a value: a unicode string or a list of unicode strings. |
14 | +.. contents:: |
15 | + :depth: 2 |
16 | + |
17 | + |
18 | +The short story |
19 | +--------------- |
20 | + |
21 | +As a Bazaar developer there are three things you need to know about |
22 | +configuration. |
23 | + |
24 | +1. Get a value. |
25 | + |
26 | +You construct or get a reference to a ConfigStack subclass that's relevant |
27 | +to the context where you want to look up a value. For instance, given a |
28 | +branch:: |
29 | + |
30 | + print branch.get_config_stack().get('log_format') |
31 | + |
32 | +This will look up the stack through all relevant configuration sources. |
33 | +The value returned is of the type declared for that Option and if nothing |
34 | +is specifically declared you will get the default for that option. |
35 | + |
36 | +2. Add a new option. |
37 | + |
38 | +You add a new ``Option`` to the ``option_registry``, either inside |
39 | +``bzrlib/config.py`` or during initialization of your plugin. New plugins |
40 | +should have systematic hierarchical names so that related values are grouped |
41 | +together:: |
42 | + |
43 | + option_registry.register( |
44 | + Option('dirstate.fdatasync', default=True, |
45 | + from_unicode=bool_from_store, |
46 | + help="Flush dirstate changes onto physical disk? ....")) |
47 | + |
48 | + |
49 | +3. Old and new configuration code. |
50 | + |
51 | +There is (as of late 2011) some older and some newer configuration code. The |
52 | +old code has specific methods for various checks or uses classes like |
53 | +``GlobalConfig``. Don't add to to it; try to remove it. |
54 | |
55 | Option |
56 | ------ |
57 | @@ -16,6 +50,10 @@ |
58 | * name: a name: a valid python identifier (even if it's not used as an |
59 | identifier in python itself). This is also used to register the option. |
60 | |
61 | +* from_unicode: a callable accepting a unicode string and returning a |
62 | + suitable value for the option. If the string cannot be coerced it should |
63 | + return None. |
64 | + |
65 | * default: the default value that Stack.get() should return if no |
66 | value can be found for the option. |
67 | |
68 | @@ -25,15 +63,17 @@ |
69 | |
70 | * help: a doc string describing the option, the first line should be a |
71 | summary and can be followed by a blank line and a more detailed |
72 | - explanation. |
73 | + explanation. This will be displayed to the user with:: |
74 | |
75 | -* from_unicode: a callable accepting a unicode string and returning a |
76 | - suitable value for the option. If the string cannot be coerced it should |
77 | - return None. |
78 | + bzr help <option name> |
79 | |
80 | * invalid: the action to be taken when an invalid value is encountered in a |
81 | store (during a Stack.get()). |
82 | |
83 | +The value of an option is a unicode string or ``None`` if it's not |
84 | +defined. By using ``from_unicode`` you can turn this string into a more |
85 | +appropriate representation (a list of unicode strings for example). |
86 | + |
87 | Sections |
88 | -------- |
89 | |
90 | @@ -119,8 +159,8 @@ |
91 | Stacks |
92 | ------ |
93 | |
94 | -An option can take different values depending on the context it is used. Such |
95 | -a context can involve configuration files, options from the command line, |
96 | +An option can take different values depending on the context it is |
97 | +used. This can involve configuration files, options from the command line, |
98 | default values in bzrlib and then some. |
99 | |
100 | Such a context is implemented by creating a list of ``Section`` stacked upon |
101 | |
102 | === added file 'doc/developers/new-config-rationale.txt' |
103 | --- doc/developers/new-config-rationale.txt 1970-01-01 00:00:00 +0000 |
104 | +++ doc/developers/new-config-rationale.txt 2011-12-06 15:18:25 +0000 |
105 | @@ -0,0 +1,778 @@ |
106 | +================================ |
107 | +Simplifying Bazaar Configuration |
108 | +================================ |
109 | + |
110 | +Goal |
111 | +==== |
112 | + |
113 | +Not all needs can be addressed by the default values used inside bzr and |
114 | +bzrlib, no matter how well they are chosen (and they are ;). |
115 | + |
116 | +Options that are rarely used don't deserve a corresponding command line |
117 | +switch in one or several commands. |
118 | + |
119 | +Many parts of ``bzrlib`` depends on some constants though and the user |
120 | +should be able to customize the behavior to suit his needs so these |
121 | +constants need to become configuration options or more generally, be easier |
122 | +to set. |
123 | + |
124 | +These options can be set from the command-line, acquired from an environment |
125 | +variable or recorded in a configuration file. |
126 | + |
127 | +To simplify writing (and reading), this document refers to the old and new |
128 | +config designs: |
129 | +* the old design is using ``Config`` as a base class for all config files, |
130 | +* the new design use ``ConfigStacks`` of ``Section`` from config ``Stores``. |
131 | + |
132 | + |
133 | +Current issues |
134 | +============== |
135 | + |
136 | +* Many parts of ``bzrlib`` declare constants and there is no way for the |
137 | + user to look at or modify them (see http://pad.lv/832061). |
138 | + |
139 | +* The old design requires a configuration object to create, modify or delete |
140 | + a configuration option in a given configuration file. ``bzr config`` |
141 | + makes it almost transparent for the user. Internally though, not all cases |
142 | + are handled: only BranchConfig implements chained configs, nothing is |
143 | + provided at the repository level and too many plugins define their own |
144 | + section or even their own config file. (config.Stack now provides a way to |
145 | + chain config files, BranchStack properly implements the desired behavior, |
146 | + ``bzr config`` uses the new design). |
147 | + |
148 | +* ``locations.conf`` defines the options that need to override any setting |
149 | + in ``branch.conf`` for both local and remotes branches (but some remote |
150 | + branch options just ignore ``locations.conf``). Many users want a way to |
151 | + define default values for options that are not defined in ``branch.conf`` |
152 | + (and even more users think that ``locations.conf`` provide default values, |
153 | + see also http://pad.lv/843211 and http://pad.lv/832046). This could be |
154 | + approximated today by *not* defining these options in ``branch.conf`` but |
155 | + in ``locations.conf`` instead. This workaround doesn't allow a user to |
156 | + define defaults in ``locations.conf`` and override them in |
157 | + ``branch.conf``. (Allowing sections in 'bazaar.conf' (or introducing a new |
158 | + defaults.conf' allowing sections) can now address that. Defining and using |
159 | + a new file is easier as it avoids handling a migration path for |
160 | + bazaar.conf and doesn't require banning the use of sections for special |
161 | + purpose needs (ALIASES and BOOKMARKS for example)). |
162 | + |
163 | +* Defining a new option requires adding a new method in the ``Config`` |
164 | + object to get access to features like: |
165 | + |
166 | + * should the option be inherited by more specific sections, (this was more |
167 | + or less the default in the old design, it is addressed by section |
168 | + matchers in the new one). |
169 | + |
170 | + * should the inherited value append the relative path between the |
171 | + section one and the location it applies to (see http://pad.lv/832013), |
172 | + |
173 | + * the default value (including calling any python code that may be |
174 | + required to calculate this value)(see http://pad.lv/832064), |
175 | + |
176 | + * priority between sections in various config files (this is defined by |
177 | + the section matcher associated with a given config store for stacks, |
178 | + http://pad.lv/832046 is about adding a section matcher with clearer |
179 | + semantics than the one used for locations.conf). |
180 | + |
181 | + A related problem is that, in the actual implementation, some |
182 | + configuration options have defined methods, others don't and this is |
183 | + inconsistent. (Using only Stacks addresses that). |
184 | + |
185 | +* Access to the 'active' configuration option value from the command line |
186 | + doesn't give access to the specific section. (This is only a concern if |
187 | + the user has no other way to address a specific configuration option |
188 | + including Store and Section when using ``bzr config``) (see http://pad.lv/725234). |
189 | + |
190 | +* Rules for configuration options are not clearly defined for remote |
191 | + branches (they may differ between dumb and smart servers the former will |
192 | + use the local ``bazaar.conf`` and ``locations.conf`` files while the later |
193 | + will use (or ignore ?) the remote ones). |
194 | + |
195 | +* The features offered by the Bazaar configuration files should be easily |
196 | + accessible to plugin authors either by supporting plugin configuration |
197 | + options in the configuration files or allowing the plugins to define their |
198 | + own configuration files. (Separating Section, Store and Stack starts |
199 | + addressing that, a stack registry should complete the needed means). |
200 | + |
201 | +* While the actual configuration files support sections, they are used in |
202 | + mutually exclusive ways that make it impossible to offer the same set of |
203 | + features to all configuration files: |
204 | + |
205 | + * ``bazaar.conf`` use arbitrary names for sections. ``DEFAULT`` is used |
206 | + for global options, ``ALIASES`` are used to define command aliases, |
207 | + plugins can define their own sections, some plugins do that |
208 | + (``bzr-bookmarks`` use ``BOOKMARKS`` for example), some other define |
209 | + their own sections (this is addressed with the new design by using only |
210 | + the ``DEFAULT`` section and ignore the others. When needed, one can |
211 | + create a specific stack to get access to a specific section). |
212 | + |
213 | + * ``locations.conf`` use globs as section names. This provides an easy |
214 | + way to associate a set of options to a matching working tree or |
215 | + branch, including remote ones. |
216 | + |
217 | + * ``branch.conf`` doesn't use any section. |
218 | + |
219 | +* There is no easy way to get configuration options for a given repository |
220 | + or an arbitrary path. Working trees and branches are generally organized |
221 | + in hierarchies and being able to share the option definitions is an often |
222 | + required feature. This can also address some needs exhibited by various |
223 | + branch schemes like looms, pipeline, colocated branches and nested |
224 | + trees. Being able to specify options *in* a working tree could also help |
225 | + support conflict resolution options for a given file, directory or |
226 | + subtree (see http://pad.lv/359320). |
227 | + |
228 | +* Since sections allow different definitions for the same option, a total |
229 | + order should be defined between sections to select the right definition |
230 | + for a given context (paths or globs for ``locations.conf`` but other |
231 | + schemes can be used, window names for qbzr for example). Allowing globs |
232 | + for section names is harmful in this respect since the order is currently |
233 | + defined as being the lexicographical one. The caveat here is that if the |
234 | + order is always defined for a given set of sections it can change when one |
235 | + or several globs are modified and the user may get surprising and unwanted |
236 | + results in these cases. The lexicographical order is otherwise fine to |
237 | + define what section is more specific than another. (This may not be a |
238 | + problem in real life since longer globs are generally more specific than |
239 | + shorter ones and explicit paths should also be longer than matching |
240 | + globs. That may leave a glob and a path of equal length in a gray area but |
241 | + in practice using ``bzr config`` should give enough feedback to address |
242 | + them. See also http://pad.lv/832046 asking for a less magical section matcher). |
243 | + |
244 | +* Internally, configuration files (and their fallbacks, ``bazaar.conf`` and |
245 | + ``locations.conf`` for ``branch.conf``) are read every time *one* option is |
246 | + queried. Likewise, setting or deleting a configuration option implies |
247 | + writing the configuration file *immediately* after re-reading the file to |
248 | + avoid racing updates (see http://pad.lv/832042). |
249 | + |
250 | +* The current implementation use a mix of transport-based and direct file |
251 | + systems operations (Addressed by Store implementation relying on |
252 | + transports only). |
253 | + |
254 | +* While the underlying ``ConfigObj`` implementation provides an |
255 | + interpolation feature, the ``bzrlib`` implementation doesn't provide an |
256 | + easy handling of templates where other configuration options can be |
257 | + interpolated. Instead, ``locations.conf`` (and only it) allows for |
258 | + ``appendpath`` and ``norecurse``. (Partially implemented, cross-section |
259 | + and cross-file interpolation still to be implemented, see |
260 | + http://pad.lv/832013 for the remaining parts). |
261 | + |
262 | +* Inherited list values can't be modified, a more specific configuration can |
263 | + only redefine the whole list. |
264 | + |
265 | +* There is no easy way to define dicts (the most obvious one being to use a |
266 | + dedicated section which is already overloaded). Using embedded sections |
267 | + for this would not be practical either if we keep using a no-name section |
268 | + for default values. In a few known cases, a bencoded dict is stored in a |
269 | + config value, so while this isn't user-friendly, not providing a better |
270 | + alternative shouldn't be a concern. A possible, limited, implementation |
271 | + can be envisioned: limiting the dict to a single level only, with simple |
272 | + names as keys and unicode strings as values. The keys can then be mapped |
273 | + to options prefixed with the dict name. |
274 | + |
275 | + |
276 | +Proposed implementation |
277 | +======================= |
278 | + |
279 | + |
280 | +Configuration files definition |
281 | +------------------------------ |
282 | + |
283 | +While of course configurations files can be versioned they are not intended |
284 | +to be accessed in sync with the files they refer to (one can imagine |
285 | +handling versioned properties this way but this is *not* what the bazaar |
286 | +configuration files are targeted at). ``bzr`` will always refer to |
287 | +configuration files as they exist on disk when an option is queried or set. |
288 | + |
289 | +The configuration files are generally local to the file system but some of |
290 | +them can be accessed remotely (``branch.conf``, ``repo.conf``). |
291 | + |
292 | + |
293 | +Naming |
294 | +------ |
295 | + |
296 | +Option names are organized into a name space for a given configuration file |
297 | +(or a set of related configuration files). One such set includes |
298 | +``bazaar.conf``, ``locations.conf``, ``branch.conf``, etc. Plugins can |
299 | +define their own sets for their own needs. |
300 | + |
301 | +Using a name space is meant to help: |
302 | + |
303 | +* avoid collisions between bzr and plugins and between plugins, |
304 | + |
305 | +* discover the available options and making them easier to remember, |
306 | + |
307 | +* organise the documentation for the option set. |
308 | + |
309 | +Using valid python identifiers is recommended but not enforced (but we may |
310 | +do so in the future). |
311 | + |
312 | +The option name space is organized by topic: |
313 | + |
314 | +* bzrlib options are grouped by topic (``branch``, ``tree``, ``repo``) |
315 | + |
316 | +* plugins are encouraged (but not required) to prefix their specific options |
317 | + with their name (``qbzr.`` for qbzr) |
318 | + |
319 | +* collisions are detected at registration time so users are protected from |
320 | + incompatibilities between plugins, |
321 | + |
322 | +* options that need to be used by several plugins (or shared between ``bzr`` |
323 | + core and plugins) should be discussed but these discussions are already |
324 | + happening so the risk of misuse is low enough. |
325 | + |
326 | +Value |
327 | +----- |
328 | + |
329 | +All option values are text. They are provided as Unicode strings to API |
330 | +users with some refinements: |
331 | + |
332 | +* boolean values can be obtained for a set of acceptable strings (yes/no, |
333 | + y/n, on/off, etc), (implemented with the ``from_unicode`` parameter) |
334 | + |
335 | +* a list of strings from a value containing a comma separated list of |
336 | + strings. |
337 | + |
338 | +Since the configuration files can be edited by the user, ``bzr`` doesn't |
339 | +expect their content to be valid at all times. Instead, the code using |
340 | +options should be ready to handle *invalid* values by warning the user and |
341 | +falling back to a default value. |
342 | + |
343 | +Likely, if an option is not defined in any configuration file, the code |
344 | +should fallback to a default value (helpers should be provided by the API to |
345 | +handle common cases: warning the user, getting a particular type of value, |
346 | +returning a default value)(most of that is now handled at Option definition). |
347 | + |
348 | +This also ensures compatibility with values provided via environment |
349 | +variables or from the command line (where no validation can be expected |
350 | +either)(done in the new design, some cases missing, see http://pad.lv/832064). |
351 | + |
352 | + |
353 | +Option expansion |
354 | +---------------- |
355 | + |
356 | +Some option values can be templates and contain references to other |
357 | +options. This is especially useful to define URLs in sections shared for |
358 | +multiple branches for example. It can also be used to describe commands |
359 | +where some parameters are set by ``bzrlib`` at runtime. |
360 | + |
361 | +Since option values are text-only, and to avoid clashing with other option |
362 | +expansion (also known as interpolation) syntaxes, references are enclosed |
363 | +with curly brackets:: |
364 | + |
365 | + push_location = lp:~{launchpad_username}/bzr/{nick} |
366 | + |
367 | +In the example above, ``launchpad_username`` is an already defined |
368 | +configuration option while ``nick`` is the branch nickname and is set when a |
369 | +configuration applies to a given branch. |
370 | + |
371 | +The interpolation implementation should accept an additional dict so that |
372 | +``bzrlib`` or plugins can define references that can be expanded without |
373 | +being existing configuration options:: |
374 | + |
375 | + diff_command={cmd} {cmd_opts} {file_a} {file_b} |
376 | + |
377 | +There are two common errors that should be handled when handling interpolation: |
378 | + |
379 | +* loops: when a configuration value refers to itself, directly or indirectly, |
380 | + |
381 | +* undefined references: when a configuration value refers to an unknown option. |
382 | + |
383 | +The loop handling can be modified to allow cross-sections and cross-files |
384 | +interpolation: if an option refers to itself (directly or indirectly) during |
385 | +an expansion, the fallback sections or files can be queried for its value. |
386 | + |
387 | +This allows list values to refer to the definition in the less specific |
388 | +configurations:: |
389 | + |
390 | + bazaar.conf: |
391 | + debug_flags = hpss |
392 | + |
393 | + branch.conf for mybranch: |
394 | + debug_flags = {debug_flags}, hpssdetail |
395 | + |
396 | + $ bzr -d mybranch config debug_flags |
397 | + hpss, hpssdetail |
398 | + |
399 | +Undefined references are detected if they are not defined in any |
400 | +configuration. This will trigger errors while displaying the value. Diagnosing |
401 | +typos should be doable in this case. |
402 | + |
403 | +Configuration file syntax |
404 | +------------------------- |
405 | + |
406 | +The configuration file is mostly an ``ini-file``. It contains ``name = value`` |
407 | +lines grouped in sections. A section starts with a string enclosed in squared |
408 | +brackets ('[section_name]`), this string uniquely identifies the section in |
409 | +the file. Comments are allowed by prefixing them with the '#' character. |
410 | + |
411 | +A section is named by the path (or some other unuique identifier) it should |
412 | +apply to (more examples below). |
413 | + |
414 | +When sections are used, they provide a finer grain of configuration by |
415 | +defining option sets that apply to some working trees, branches, |
416 | +repositories (or any kind of context) or part of them. The relationship |
417 | +between a given context and the sections it applies to is defined by the |
418 | +config file. |
419 | + |
420 | +So far, Bazaar uses a glob in ``locations.conf`` and select the sections |
421 | +that apply to a given url (or a local path). |
422 | + |
423 | +The subset is defined by the common leading path or a glob. |
424 | + |
425 | +Different kinds of section names can be defined: |
426 | + |
427 | +* a full url: used to described options for remote branches and |
428 | + repositories (LocationMatcher supports this). |
429 | + |
430 | +* local absolute path: used for working trees, branches or repositories |
431 | + on the local disks (LocationMatcher supports this). |
432 | + |
433 | +* relative path: the path is relative to the configuration file and can be |
434 | + used for colocated branches or threads in a loom, i.e any working tree, |
435 | + branch or repository that is located in a place related to the |
436 | + configuration file path. Some configuration files may define this path |
437 | + relationship in specific ways to make them easier to use (i.e. if a config |
438 | + file is somewhere below ``.bzr`` and refers to threads in a loom for |
439 | + example, the relative path would be the thread name, it doesn't have to be |
440 | + an *exact* relative path, as long as its interpretation is unambiguous and |
441 | + clear for the user) (No section matchers support this so far, needs to |
442 | + file a bug) |
443 | + |
444 | +Section matching |
445 | +---------------- |
446 | + |
447 | +Section names define another name space (than the option names one) with an |
448 | +entirely different purpose: in a given configuration file, for a given |
449 | +context, only some sections will be relevant and will be queried in a |
450 | +specific order. |
451 | + |
452 | +This matching is specific to each config file and implemented by the |
453 | +SectionMatcher objects. |
454 | + |
455 | +Whatever this matching does, the user can observe the results with the ``bzr |
456 | +config`` command which displays the sections in the order they are queried. |
457 | + |
458 | +LocationMatcher |
459 | +~~~~~~~~~~~~~~~ |
460 | + |
461 | +The context here is either: |
462 | + |
463 | +* an URL, |
464 | + |
465 | +* a local path. |
466 | + |
467 | +Note that for both the provided context and the section names, if an URL uses |
468 | +a ``file:///`` form, it is converted to a local path. |
469 | + |
470 | +The sections names can use globs for each path component |
471 | +(i.e. ``/dir/*/subdir`` is allowed but ``/dir/\*\*/subdir`` will match |
472 | +``/dir/a/subdir`` but not ``/dir/a/b/subdir``. |
473 | + |
474 | +The reason is that the ordering is defined by sorting the section names |
475 | +matching the context on the number of path components followed by the path |
476 | +itself in lexicographical order. This results in most specific sections being |
477 | +queried before the more generic ones. |
478 | + |
479 | +PathMatcher |
480 | +~~~~~~~~~~~ |
481 | + |
482 | +``LocationMatcher`` has some obscure (for unaware users) edge cases and |
483 | +limitations that can be surprising. ``PathMatcher`` aims at addressing these |
484 | +issues by providing simpler rules while still giving full control to the |
485 | +user (http://pad.lv/832046). |
486 | + |
487 | +The context here is a local path, absolute or relative. If the path is |
488 | +relative it is interpreted from the file base directory. |
489 | + |
490 | +Note that 'base directory' for configuration files in Bazaar directories is |
491 | +really: |
492 | + |
493 | +* the home directory for files under ``~/.bazaar``, |
494 | + |
495 | +* the ``.bzr`` base directory for files under ``.bzr``. |
496 | + |
497 | +The order is the one observed in the file so most generic values are specified |
498 | +first and most specific ones last. As such, the order in the file is the |
499 | +opposite of the one displayed by ``bzr config`` which displays most specific |
500 | +values first. This seems to be the most natural order in both cases. |
501 | + |
502 | +A section matches if the section name is a prefix of the context path |
503 | +(relative paths being converted to absolute on the fly). |
504 | + |
505 | +The Option object |
506 | +----------------- |
507 | + |
508 | +(copied from a recent version of bzr.dev for easier reading, refer to the |
509 | +original for an up to date version) |
510 | + |
511 | +The Option object is used to define its properties: |
512 | + |
513 | +* name: a name: a valid python identifier (even if it's not used as an |
514 | + identifier in python itself). This is also used to register the option. |
515 | + |
516 | +* default: the default value that Stack.get() should return if no |
517 | + value can be found for the option. |
518 | + |
519 | +* default_from_env: a list of environment variables. The first variable set |
520 | + will provide a default value overriding 'default' which remains the |
521 | + default value if *no* environment variable is set. |
522 | + |
523 | +* help: a doc string describing the option, the first line should be a |
524 | + summary and can be followed by a blank line and a more detailed |
525 | + explanation. |
526 | + |
527 | +* from_unicode: a callable accepting a unicode string and returning a |
528 | + suitable value for the option. If the string cannot be coerced it should |
529 | + return None. |
530 | + |
531 | +* invalid: the action to be taken when an invalid value is encountered in a |
532 | + store (during a Stack.get()). |
533 | + |
534 | +The Section object |
535 | +------------------ |
536 | + |
537 | +Options are grouped into sections which share some properties with the well |
538 | +known dict objects: |
539 | + |
540 | +* the key is the name, |
541 | +* you can get, set and remove an option, |
542 | +* the value is a unicode string. |
543 | + |
544 | +MutableSection is needed to set or remove an option, ReadOnlySection should |
545 | +be used otherwise. |
546 | + |
547 | +The Store object |
548 | +---------------- |
549 | + |
550 | +This is an implementation-level object that should rarely be used directly. |
551 | + |
552 | +* it can be local or remote |
553 | + |
554 | +* locking |
555 | + |
556 | + All lock operations should be implemented via transport objects. (True for |
557 | + Store). |
558 | + |
559 | +* option life cycle |
560 | + |
561 | + Working trees, branches and repositories should define a config attribute |
562 | + following the same life cycle as their lock: the associated config file is |
563 | + read once and written once if needed. This should minimize the file system |
564 | + accesses or the network requests. There is no known racing scenarios for |
565 | + configuration options, changing the existing implementation to this less |
566 | + constrained one shouldn't introduce any. Yet, in order to detect such |
567 | + racing scenarios, we can add a check that the current content of the |
568 | + configuration file is the expected one before writing the new content and |
569 | + emit warnings if differences occur. The checks should be performed for the |
570 | + modified values only. As of today (and in the foreseeable future), the |
571 | + size of the configuration files are small enough to be kept in memory (see |
572 | + http://pad.lv/832042). |
573 | + |
574 | +The Stack object |
575 | +----------------- |
576 | + |
577 | +This the object that provides access to the needed features: |
578 | + |
579 | +* getting an option value, |
580 | + |
581 | +* setting an option value, |
582 | + |
583 | +* deleting an option value, |
584 | + |
585 | +* handling a list of configuration files and for each of them a section |
586 | + matcher providing the sections that should be tried in the given order to |
587 | + find an option. |
588 | + |
589 | +* handling a Store and a section where option creation, modification and |
590 | + deletion will occur. |
591 | + |
592 | +Depending on the files involved, a working tree, branch or repository object |
593 | +(or more generally a context) should be provided to access the corresponding |
594 | +configuration files. Note that providing a working tree object also |
595 | +implicitly provides the associated branch and repository object so only one |
596 | +of them is required (or none for configuration files specific to the user |
597 | +like ``bazaar.conf``). |
598 | + |
599 | +Getting an option value |
600 | +~~~~~~~~~~~~~~~~~~~~~~~ |
601 | + |
602 | +Depending on the option, there are various places where it can be defined |
603 | +and several ways to override these settings when needed. |
604 | + |
605 | +The following lists all possible places where a configuration option can |
606 | +be defined, but some options will make sense in only some of them. The |
607 | +first to define a value for an option wins (None is therefore used to |
608 | +express that an option is not set). |
609 | + |
610 | +* command-line |
611 | + ``-Ooption=value`` see http://pad.lv/491196. |
612 | + |
613 | +* ``~/.bazaar/locations.conf`` |
614 | + |
615 | + When an option is set in ``locations.conf`` it overrides any other |
616 | + configuration file. This should be used with care as it allows setting a |
617 | + different value than what is recommended by the project |
618 | + |
619 | +* ``tree`` (Not Implemented Yet) |
620 | + |
621 | + The options related to the working tree. |
622 | + |
623 | + This includes all options related to commits, ignored files, junk files, |
624 | + etc. |
625 | + |
626 | + Note that the sections defined there can use relative paths if some |
627 | + options should apply to a subtree or some specific files only. |
628 | + |
629 | + See http://pad.lv/430538 and http://pad.lv/654998. |
630 | + |
631 | +* ``branch`` located in ``.bzr/branch/branch.conf`` |
632 | + |
633 | + The options related to the branch. |
634 | + |
635 | + Sections can be defined for colocated branches or loom threads. |
636 | + |
637 | +* ``repository`` (Not Implemented Yet) |
638 | + |
639 | + The options related to the repository. |
640 | + |
641 | + Using an option to describe whether or not a repository is shared could |
642 | + help address http://pad.lv/342119 but this will probably requires a format |
643 | + bump). |
644 | + |
645 | +* ``project`` (Not Implemented Yet) |
646 | + |
647 | + The options common to all branches and working trees for a project. |
648 | + |
649 | +* ``organization`` (Not Implemented Yet) |
650 | + |
651 | + The options common to all branches and working trees for an organization. |
652 | + |
653 | + See http://pad.lv/419854. |
654 | + |
655 | +* ``system`` (Not Implemented Yet but see http://pad.lv/419854 and |
656 | + https://code.launchpad.net/~thomir/bzr/add-global-config/+merge/69592) |
657 | + |
658 | + The options common to all users of a system (may be /etc/bzr/defaults |
659 | + or /usr/local/etc/bzr/defaults or |
660 | + /Library/Preferences/com.canonical.defaults or c:\windows\bazaar.conf |
661 | + (someone fix this one please ;) depending on the OS). |
662 | + |
663 | +* ``bazaar.conf`` |
664 | + |
665 | + The options the user has selected for the host he is using. |
666 | + |
667 | + Sections can be defined for both remote and local branches to define |
668 | + default values (i.e. the most common use of ``locations.conf`` today). |
669 | + |
670 | +* default (implemented by the OptionRegistry) |
671 | + |
672 | + The options defined in the ``bzr`` source code. |
673 | + |
674 | + This will be implemented via the Option objects. |
675 | + |
676 | +Plugins can define additional configuration files as they see fit and |
677 | +insert them in this list, see their documentation for details. |
678 | + |
679 | +Compatibility |
680 | +============= |
681 | + |
682 | +There are ways to keep the same files while ensuring compatibility via various |
683 | +tricks but there are cases where using new files to replace the old ones is |
684 | +definitely easier: |
685 | + |
686 | +* no need to ensure that the new files are correctly handled by old bzr |
687 | + versions, |
688 | + |
689 | +* making it clear for users that there is a switch and let them migrate at |
690 | + their own pace. |
691 | + |
692 | +The known cases so far are described below. |
693 | + |
694 | +Obvious at this point: |
695 | + |
696 | +* Branch provides ``get_config`` for the old design and ``get_config_stack`` |
697 | + for the new design so that both designs are supported. Once the store |
698 | + sharing is implemented, we may want to use an attribute for the stack and |
699 | + deprecate both ``get_config`` and ``get_config_stack``. |
700 | + |
701 | +* Sections names in ``bazaar.conf`` are arbitrary (except ``DEFAULT``) so |
702 | + it's easier to leave the file untouched and let plugin authors and users |
703 | + migrate away (or not) from them. For ``bzr`` itself, that means |
704 | + ``DEFAULT`` is the only section used for most of the options and provides |
705 | + user defaults. ``ALIASES`` requires a specific stack but only the ``bzr |
706 | + alias`` command cares about that. |
707 | + |
708 | +* Option policies should be deprecated: |
709 | + |
710 | + * The ``norecurse`` policy is useless, all options are recursive by |
711 | + default. If specific values are needed for specific paths, they can just |
712 | + be defined as such (in the appropriate sections or files). |
713 | + |
714 | + * The ``appendpath`` policy should be implemented via interpolation and a |
715 | + ``relpath`` option provided by the configuration framework |
716 | + (http://pad.lv/832013). |
717 | + |
718 | +* Section order in ``locations.conf`` has issues which make a migration to a |
719 | + different way to organize the sections (hence the file content) far easier |
720 | + with a new file. |
721 | + |
722 | +* ``locations.conf`` is really for overrides but many users have been using it |
723 | + to provide defaults. There is no way to know if the whole content has been |
724 | + used for defaults or overrides or a mix of both. So there is no way to |
725 | + migrate this automatically. |
726 | + |
727 | +Unclear at this point: |
728 | + |
729 | +* [BOOKMARKS] section can be replaced by ``bookmarks.xxx`` options (the |
730 | + bookmarks plugins already uses ``bookmarks_xxx`` in branch.conf since no |
731 | + sections were supported there). The easiest here is probably to just merge |
732 | + the plugin into core and use the appropriate option names consistently. A |
733 | + ``config:`` directory service may even be better as any option can be used |
734 | + as a bookmark. This allows things like:: |
735 | + |
736 | + [/whatever/path] |
737 | + my_push = lp:<launchpad.login>/xxx/{nick} |
738 | + web_site=ftp://example.com/ |
739 | + |
740 | + bzr push config:web_site |
741 | + |
742 | + Which means we completely replace the plugin and don't need to care about |
743 | + migrating the section. |
744 | + |
745 | +* [ALIASES] section can be replaced by corresponding bzr.alias.xxx |
746 | + options. This could be automated by creating the corresponding options ? |
747 | + |
748 | +* I don't know about other sections, feedback welcome. Plugin authors are |
749 | + encouraged to migrate to the new name space scheme by prefixing their |
750 | + options with their plugin name. |
751 | + |
752 | +Notes |
753 | +===== |
754 | + |
755 | +These are random notes about concepts, ideas or issues not implemented yet. |
756 | + |
757 | +Developer facing concepts |
758 | +------------------------- |
759 | + |
760 | +Option |
761 | +~~~~~~ |
762 | + |
763 | +* list of allowed Config IDs (this allows a list of possible config files in |
764 | + bazaar.conf only option and use it while bootstrapping the config |
765 | + creations). |
766 | + |
767 | +* blacklist of config IDs (some options *can't* be stored (modified) by the |
768 | + user) |
769 | + |
770 | +An alternative is to just let the devs decide which stack they use for a |
771 | +given option, ``stacked_on_location`` for example is said to relate to the |
772 | +branch only and changing it or setting it in a different config file may not |
773 | +be appropriate. This may not be a good example as there is also the |
774 | +``default_stack_on`` option which can be set only in ``control.conf`` |
775 | +though... |
776 | + |
777 | +Stack |
778 | +~~~~~ |
779 | + |
780 | +* a lazy cache for the option values (should be reset on modifications as |
781 | + interpolations will make it tricky to update incrementally) (see FIXME in |
782 | + config.py Stack.get())) |
783 | + |
784 | +* ensures that the Stores involved generate as less IOs as possible (see |
785 | + http://pad.lv/832042) |
786 | + |
787 | +* ensures that the transaction is the object life time (i.e. modifications |
788 | + will be taken into account *iff* they are committed explicitly). |
789 | + |
790 | +StackRegistry |
791 | +~~~~~~~~~~~~~ |
792 | + |
793 | +* ensures that a config ID is a unique identifier |
794 | +* register Stacks |
795 | + |
796 | +Store |
797 | +~~~~~ |
798 | + |
799 | +* ensures that the transaction is the object life time (i.e. modifications |
800 | + will be taken into account *iff* they are committed explicitly). |
801 | + |
802 | +Examples |
803 | +-------- |
804 | + |
805 | +store examples: |
806 | +~~~~~~~~~~~~~~~ |
807 | + |
808 | +* ConfigObj (bazaar.conf) |
809 | + |
810 | +* DB (<scheme>://bazaar.launchpad.net/bazaar.conf) |
811 | + |
812 | + |
813 | +Why and when locking config files matter |
814 | +---------------------------------------- |
815 | + |
816 | +This is relevant for http://pad.lv/832042. |
817 | + |
818 | +``bzr`` behavior, as well as the objects it acts upon, is configured via a |
819 | +set of so-called configuration files. |
820 | + |
821 | +These files allow to define working trees, branches and repositories, their |
822 | +relationships and how ``bzr`` should handle them. |
823 | + |
824 | +The default behavior of ``bzr`` is aimed at making this configuration as |
825 | +transparent as possible by keeping track of how these objects are created |
826 | +and modified when they are used. In short, they are useless until you want |
827 | +to change the default behavior in some specific context. |
828 | + |
829 | +We mostly **read** config options. Therefore all we care about is to |
830 | +guarantee that: |
831 | + |
832 | +* we get a valid config file at all times when reading, |
833 | + |
834 | +* we always leave a valid config file when writing (via the rename dance) |
835 | + |
836 | +From there, conceptually, all operations can clearly define whether or not |
837 | +they need to modify a config file and do so only when they succeed. All |
838 | +modifications occurring during such an operation are delayed until the very |
839 | +end of the operation. |
840 | + |
841 | +Now, we want to minimize the overlapping times where one bzr operation has |
842 | +changed a value and another concurrent operation is unaware of this |
843 | +modification. |
844 | + |
845 | +These overlapping periods are *as of today* rare. |
846 | + |
847 | +The only known case, http://pad.lv/525571 has been fixed in bzr-2.1.3. The |
848 | +bug there was triggered when two processes tried to write the same config |
849 | +file at the same time leaving an invalid file in the end. |
850 | + |
851 | +Such a period can be recognized and detected though: when changing an option |
852 | +value, if the preserved original value is different in the config file, |
853 | +someone else modified it and the operation can be invalid because it relied |
854 | +on the original value. |
855 | + |
856 | +For the sake of the example, if an option value represent a global unique ID |
857 | +via a simple counter (very bad idea), if two operations try to increment it, |
858 | +both will use the same value that won't be unique anymore. Checking the |
859 | +value present in the file when trying to save the updated value with |
860 | +identify such a collision. |
861 | + |
862 | +An assumption is floating around: it should be enough to report when an |
863 | +operation is modifying an already modified option and observe that no-one |
864 | +reports such occurrences. |
865 | + |
866 | +Note that this assumption is made in a context where *no* known scenarios |
867 | +exist in the bzr code base not in any plugin (for a best effort value of |
868 | +'any', feedback highly welcome, bug reports even ;) |
869 | + |
870 | +With this in mind, we can change the definition of config options, stores |
871 | +and stacks to ensure that: |
872 | + |
873 | +* a config file is read only once when in read access, |
874 | + |
875 | +* a config file is read only once and written only once when in write |
876 | + access, adding the check mentioned above will require *one* additional |
877 | + read. |
878 | + |
879 | +A reader can then safely assume that reading a config file gives it a valid |
880 | +(and coherent) definition of the configuration when the operation |
881 | +starts. All the operation has to do is to declare which config files may be |
882 | +modified by an operation (whether or not we can be liberal on this 'may be' |
883 | +is yet to be defined). |
884 | |
885 | === modified file 'doc/developers/plans.txt' |
886 | --- doc/developers/plans.txt 2011-10-14 01:18:16 +0000 |
887 | +++ doc/developers/plans.txt 2011-12-06 15:18:25 +0000 |
888 | @@ -2,29 +2,12 @@ |
889 | ===== |
890 | |
891 | .. toctree:: |
892 | - :hidden: |
893 | + :maxdepth: 1 |
894 | |
895 | - performance-roadmap |
896 | + Performance roadmap <performance-roadmap> |
897 | colocated-branches |
898 | feature-flags |
899 | + new-config-rationale |
900 | tortoise-strategy |
901 | improved_chk_index |
902 | |
903 | - |
904 | -* `Performance roadmap <performance-roadmap.html>`_ |--| The roadmap |
905 | - for fixing performance in bzr over the next few releases. |
906 | - |
907 | -* `Co-located branches <colocated-branches.html>`_ |--| Planned(?) support |
908 | - for storing multiple branches in one file-system directory. |
909 | - |
910 | -* `Bazaar Windows Shell Extension Options <tortoise-strategy.html>`_ |--| |
911 | - Implementation strategy for Bazaar Windows Shell Extensions, aka |
912 | - TortoiseBzr. |
913 | - |
914 | -* `CHK Optimized index <improved_chk_index.html>`_ |
915 | - |
916 | - |
917 | -.. |--| unicode:: U+2014 |
918 | - |
919 | -.. |
920 | - vim: ft=rst tw=74 ai |
It seems right to me, but perhaps our config czar should also have a look :-)