/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
5409.4.1 by Martin Pool
Split out user interaction developer guide to a separate file
1
==========================================
2
Bazaar Developer Guide to User Interaction
3
==========================================
4
5
Getting Input
6
=============
7
8
Processing Command Lines
9
------------------------
10
11
bzrlib has a standard framework for parsing command lines and calling
12
processing routines associated with various commands. See builtins.py
13
for numerous examples.
14
15
16
Standard Parameter Types
17
------------------------
18
19
There are some common requirements in the library: some parameters need to be
20
unicode safe, some need byte strings, and so on. At the moment we have
21
only codified one specific pattern: Parameters that need to be unicode
22
should be checked via ``bzrlib.osutils.safe_unicode``. This will coerce the
23
input into unicode in a consistent fashion, allowing trivial strings to be
24
used for programmer convenience, but not performing unpredictably in the
25
presence of different locales.
26
27
28
Writing Output
29
==============
30
31
(The strategy described here is what we want to get to, but it's not
32
consistently followed in the code at the moment.)
33
34
bzrlib is intended to be a generically reusable library.  It shouldn't
35
write messages to stdout or stderr, because some programs that use it
36
might want to display that information through a GUI or some other
37
mechanism.
38
39
We can distinguish two types of output from the library:
40
41
 1. Structured data representing the progress or result of an
42
    operation.  For example, for a commit command this will be a list
43
    of the modified files and the finally committed revision number
44
    and id.
45
46
    These should be exposed either through the return code or by calls
47
    to a callback parameter.
48
49
    A special case of this is progress indicators for long-lived
50
    operations, where the caller should pass a ProgressBar object.
51
52
 2. Unstructured log/debug messages, mostly for the benefit of the
53
    developers or users trying to debug problems.  This should always
54
    be sent through ``bzrlib.trace`` and Python ``logging``, so that
55
    it can be redirected by the client.
56
57
The distinction between the two is a bit subjective, but in general if
58
there is any chance that a library would want to see something as
59
structured data, we should make it so.
60
61
The policy about how output is presented in the text-mode client
62
should be only in the command-line tool.
63
64
65
Progress and Activity Indications
66
---------------------------------
67
68
bzrlib has a way for code to display to the user that stuff is happening
69
during a long operation.  There are two particular types: *activity* which
70
means that IO is happening on a Transport, and *progress* which means that
71
higher-level application work is occurring.  Both are drawn together by
72
the `ui_factory`.
73
74
Transport objects are responsible for calling `report_transport_activity`
75
when they do IO.
76
77
Progress uses a model/view pattern: application code acts on a
78
`ProgressTask` object, which notifies the UI when it needs to be
79
displayed.  Progress tasks form a stack.  To create a new progress task on
80
top of the stack, call `bzrlib.ui.ui_factory.nested_progress_bar()`, then
81
call `update()` on the returned ProgressTask.  It can be updated with just
82
a text description, with a numeric count, or with a numeric count and
83
expected total count.  If an expected total count is provided the view
84
can show the progress moving along towards the expected total.
85
86
The user should call `finish` on the `ProgressTask` when the logical
87
operation has finished, so it can be removed from the stack.
88
89
Progress tasks have a complex relationship with generators: it's a very
90
good place to use them, but because python2.4 does not allow ``finally``
91
blocks in generators it's hard to clean them up properly.  In this case
92
it's probably better to have the code calling the generator allocate a
93
progress task for its use and then call `finalize` when it's done, which
94
will close it if it was not already closed.  The generator should also
95
finish the progress task when it exits, because it may otherwise be a long
96
time until the finally block runs.
97
98
99
Message guidelines
100
------------------
101
102
When filenames or similar variables are presented inline within a message,
103
they should be enclosed in double quotes (ascii 0x22, not chiral unicode
104
quotes)::
105
106
  bzr: ERROR: No such file "asdf"
107
108
When we print just a list of filenames there should not be any quoting:
109
see `bug 544297`_.
110
111
.. _bug 544297: https://bugs.launchpad.net/bugs/544297
112
113
https://wiki.ubuntu.com/UnitsPolicy provides a good explanation about
114
which unit should be used when. Roughly speaking, IEC standard applies
115
for base-2 units and SI standard applies for base-10 units:
116
117
* for network bandwidth and disk sizes, use base-10 (Mbits/s, kB/s, GB)
118
119
* for RAM sizes, use base-2 (GiB, TiB)
120
121
122
123
Displaying help
124
===============
125
126
Bazaar has online help for various topics through ``bzr help COMMAND`` or
127
equivalently ``bzr command -h``.  We also have help on command options,
128
and on other help topics.  (See ``help_topics.py``.)
129
130
As for python docstrings, the first paragraph should be a single-sentence
131
synopsis of the command. These are user-visible and should be prefixed with
132
``__doc__ =`` so help works under ``python -OO`` with docstrings stripped.
133
134
The help for options should be one or more proper sentences, starting with
135
a capital letter and finishing with a full stop (period).
136
137
All help messages and documentation should have two spaces between
138
sentences.
139
140
141
Handling Errors and Exceptions
142
==============================
143
144
Commands should return non-zero when they encounter circumstances that
145
the user should really pay attention to - which includes trivial shell
146
pipelines.
147
148
Recommended values are:
149
150
    0. OK.
151
    1. Conflicts in merge-like operations, or changes are present in
152
       diff-like operations.
153
    2. Unrepresentable diff changes (i.e. binary files that we cannot show
154
       a diff of).
155
    3. An error or exception has occurred.
156
    4. An internal error occurred (one that shows a traceback.)
157
158
Errors are handled through Python exceptions. Exceptions should be defined
159
inside bzrlib.errors, so that we can see the whole tree at a glance.
160
161
We broadly classify errors as either being either internal or not,
162
depending on whether ``internal_error`` is set or not.  If we think it's our
163
fault, we show a backtrace, an invitation to report the bug, and possibly
164
other details.  This is the default for errors that aren't specifically
165
recognized as being caused by a user error.  Otherwise we show a briefer
166
message, unless -Derror was given.
167
168
Many errors originate as "environmental errors" which are raised by Python
169
or builtin libraries -- for example IOError.  These are treated as being
170
our fault, unless they're caught in a particular tight scope where we know
171
that they indicate a user errors.  For example if the repository format
172
is not found, the user probably gave the wrong path or URL.  But if one of
173
the files inside the repository is not found, then it's our fault --
174
either there's a bug in bzr, or something complicated has gone wrong in
175
the environment that means one internal file was deleted.
176
177
Many errors are defined in ``bzrlib/errors.py`` but it's OK for new errors
178
to be added near the place where they are used.
179
180
Exceptions are formatted for the user by conversion to a string
181
(eventually calling their ``__str__`` method.)  As a convenience the
182
``._fmt`` member can be used as a template which will be mapped to the
183
error's instance dict.
184
185
New exception classes should be defined when callers might want to catch
186
that exception specifically, or when it needs a substantially different
187
format string.
188
189
#. If it is something that a caller can recover from, a custom exception
190
   is reasonable.
191
192
#. If it is a data consistency issue, using a builtin like
193
   ``ValueError``/``TypeError`` is reasonable.
194
195
#. If it is a programmer error (using an api incorrectly)
196
   ``AssertionError`` is reasonable.
197
198
#. Otherwise, use ``BzrError`` or ``InternalBzrError``.
199
200
Exception strings should start with a capital letter and should not have a
201
final fullstop.  If long, they may contain newlines to break the text.