Merge lp:~mbp/bzr/417881-selftest-no-apport into lp:bzr
- 417881-selftest-no-apport
- Merge into bzr.dev
Proposed by
Martin Pool
on 2010-02-02
| Status: | Superseded | ||||
|---|---|---|---|---|---|
| Proposed branch: | lp:~mbp/bzr/417881-selftest-no-apport | ||||
| Merge into: | lp:bzr | ||||
| Diff against target: |
534 lines (+296/-73) 9 files modified
NEWS (+15/-0) bzrlib/builtins.py (+7/-0) bzrlib/config.py (+7/-3) bzrlib/crash.py (+143/-55) bzrlib/tests/__init__.py (+5/-0) bzrlib/tests/test_crash.py (+46/-15) contrib/apport/README (+13/-0) contrib/apport/bzr.conf (+6/-0) contrib/apport/source_bzr.py (+54/-0) |
||||
| To merge this branch: | bzr merge lp:~mbp/bzr/417881-selftest-no-apport | ||||
| Related bugs: |
|
| Reviewer | Review Type | Date Requested | Status |
|---|---|---|---|
| bzr-core | 2010-02-02 | Pending | |
|
Review via email:
|
|||
This proposal has been superseded by a proposal from 2010-02-03.
Commit Message
Description of the Change
To post a comment you must log in.
| Martin Pool (mbp) wrote : | # |
lp:~mbp/bzr/417881-selftest-no-apport
updated
on 2010-02-04
- 5002. By Martin Pool on 2010-02-04
-
Revert turning off apport in cmd_selftest
Unmerged revisions
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
| 1 | === modified file 'NEWS' |
| 2 | --- NEWS 2010-02-02 10:38:47 +0000 |
| 3 | +++ NEWS 2010-02-03 00:05:22 +0000 |
| 4 | @@ -19,6 +19,21 @@ |
| 5 | New Features |
| 6 | ************ |
| 7 | |
| 8 | +* If the Apport crash-reporting tool is available, bzr crashes are now |
| 9 | + stored into the ``/var/crash`` apport spool directory, and the user is |
| 10 | + invited to report them to the developers from there, either |
| 11 | + automatically or by running ``apport-bug``. No information is sent |
| 12 | + without specific permission from the user. (Martin Pool, #515052) |
| 13 | + |
| 14 | +Testing |
| 15 | +******* |
| 16 | + |
| 17 | +* Don't use Apport for errors while loading or running tests. |
| 18 | + (Martin Pool, #417881) |
| 19 | + |
| 20 | +* Stop sending apport crash files to ``.cache`` in the directory from |
| 21 | + which ``bzr selftest`` was run. (Martin Pool, #422350) |
| 22 | + |
| 23 | bzr 2.1.0 (not released yet) |
| 24 | ############################ |
| 25 | |
| 26 | |
| 27 | === modified file 'bzrlib/builtins.py' |
| 28 | --- bzrlib/builtins.py 2010-01-29 10:36:23 +0000 |
| 29 | +++ bzrlib/builtins.py 2010-02-03 00:05:22 +0000 |
| 30 | @@ -3524,6 +3524,13 @@ |
| 31 | |
| 32 | # Make deprecation warnings visible, unless -Werror is set |
| 33 | symbol_versioning.activate_deprecation_warnings(override=False) |
| 34 | + |
| 35 | + # Whatever you normally want, for the purposes of running selftest you |
| 36 | + # probably actually want to see the exception, not to turn it into an |
| 37 | + # apport failure. This is specifically turned off again for tests of |
| 38 | + # apport. We turn it off here so that eg a SyntaxError loading the |
| 39 | + # tests is caught. |
| 40 | + os.environ['APPORT_DISABLE'] = '1' |
| 41 | |
| 42 | if cache_dir is not None: |
| 43 | tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(cache_dir) |
| 44 | |
| 45 | === modified file 'bzrlib/config.py' |
| 46 | --- bzrlib/config.py 2009-12-17 10:01:25 +0000 |
| 47 | +++ bzrlib/config.py 2010-02-03 00:05:22 +0000 |
| 48 | @@ -1,4 +1,4 @@ |
| 49 | -# Copyright (C) 2005, 2007, 2008 Canonical Ltd |
| 50 | +# Copyright (C) 2005, 2007, 2008, 2010 Canonical Ltd |
| 51 | # Authors: Robert Collins <robert.collins@canonical.com> |
| 52 | # and others |
| 53 | # |
| 54 | @@ -866,12 +866,16 @@ |
| 55 | |
| 56 | This doesn't implicitly create it. |
| 57 | |
| 58 | - On Windows it's in the config directory; elsewhere in the XDG cache directory. |
| 59 | + On Windows it's in the config directory; elsewhere it's /var/crash |
| 60 | + which may be monitored by apport. It can be overridden by |
| 61 | + $APPORT_CRASH_DIR. |
| 62 | """ |
| 63 | if sys.platform == 'win32': |
| 64 | return osutils.pathjoin(config_dir(), 'Crash') |
| 65 | else: |
| 66 | - return osutils.pathjoin(xdg_cache_dir(), 'crash') |
| 67 | + # XXX: hardcoded in apport_python_hook.py; therefore here too -- mbp |
| 68 | + # 2010-01-31 |
| 69 | + return os.environ.get('APPORT_CRASH_DIR', '/var/crash') |
| 70 | |
| 71 | |
| 72 | def xdg_cache_dir(): |
| 73 | |
| 74 | === modified file 'bzrlib/crash.py' |
| 75 | --- bzrlib/crash.py 2009-08-20 05:47:53 +0000 |
| 76 | +++ bzrlib/crash.py 2010-02-03 00:05:22 +0000 |
| 77 | @@ -1,4 +1,4 @@ |
| 78 | -# Copyright (C) 2009 Canonical Ltd |
| 79 | +# Copyright (C) 2009, 2010 Canonical Ltd |
| 80 | # |
| 81 | # This program is free software; you can redistribute it and/or modify |
| 82 | # it under the terms of the GNU General Public License as published by |
| 83 | @@ -16,10 +16,32 @@ |
| 84 | |
| 85 | |
| 86 | """Handling and reporting crashes. |
| 87 | + |
| 88 | +A crash is an exception propagated up almost to the top level of Bazaar. |
| 89 | + |
| 90 | +If we have apport <https://launchpad.net/apport/>, we store a report of the |
| 91 | +crash using apport into it's /var/crash spool directory, from where the user |
| 92 | +can either manually send it to Launchpad. In some cases (at least Ubuntu |
| 93 | +development releases), Apport may pop up a window asking if they want |
| 94 | +to send it. |
| 95 | + |
| 96 | +Without apport, we just write a crash report to stderr and the user can report |
| 97 | +this manually if the wish. |
| 98 | + |
| 99 | +We never send crash data across the network without user opt-in. |
| 100 | + |
| 101 | +In principle apport can run on any platform though as of Feb 2010 there seem |
| 102 | +to be some portability bugs. |
| 103 | + |
| 104 | +To force this off in bzr turn set APPORT_DISBLE in the environment or |
| 105 | +-Dno_apport. |
| 106 | """ |
| 107 | |
| 108 | # for interactive testing, try the 'bzr assert-fail' command |
| 109 | # or see http://code.launchpad.net/~mbp/bzr/bzr-fail |
| 110 | +# |
| 111 | +# to test with apport it's useful to set |
| 112 | +# export APPORT_IGNORE_OBSOLETE_PACKAGES=1 |
| 113 | |
| 114 | import os |
| 115 | import platform |
| 116 | @@ -39,39 +61,42 @@ |
| 117 | |
| 118 | |
| 119 | def report_bug(exc_info, stderr): |
| 120 | - if 'no_apport' not in debug.debug_flags: |
| 121 | - try: |
| 122 | - report_bug_to_apport(exc_info, stderr) |
| 123 | + if ('no_apport' in debug.debug_flags) or \ |
| 124 | + os.environ.get('APPORT_DISABLE', None): |
| 125 | + return report_bug_legacy(exc_info, stderr) |
| 126 | + try: |
| 127 | + if report_bug_to_apport(exc_info, stderr): |
| 128 | + # wrote a file; if None then report the old way |
| 129 | return |
| 130 | - except ImportError, e: |
| 131 | - trace.mutter("couldn't find apport bug-reporting library: %s" % e) |
| 132 | - pass |
| 133 | - except Exception, e: |
| 134 | - # this should only happen if apport is installed but it didn't |
| 135 | - # work, eg because of an io error writing the crash file |
| 136 | - sys.stderr.write("bzr: failed to report crash using apport:\n " |
| 137 | - " %r\n" % e) |
| 138 | - pass |
| 139 | - report_bug_legacy(exc_info, stderr) |
| 140 | + except ImportError, e: |
| 141 | + trace.mutter("couldn't find apport bug-reporting library: %s" % e) |
| 142 | + pass |
| 143 | + except Exception, e: |
| 144 | + # this should only happen if apport is installed but it didn't |
| 145 | + # work, eg because of an io error writing the crash file |
| 146 | + stderr.write("bzr: failed to report crash using apport:\n " |
| 147 | + " %r\n" % e) |
| 148 | + pass |
| 149 | + return report_bug_legacy(exc_info, stderr) |
| 150 | |
| 151 | |
| 152 | def report_bug_legacy(exc_info, err_file): |
| 153 | """Report a bug by just printing a message to the user.""" |
| 154 | - trace.print_exception(exc_info, err_file) |
| 155 | - err_file.write('\n') |
| 156 | err_file.write('bzr %s on python %s (%s)\n' % \ |
| 157 | (bzrlib.__version__, |
| 158 | bzrlib._format_version_tuple(sys.version_info), |
| 159 | platform.platform(aliased=1))) |
| 160 | + err_file.write("plugins:\n") |
| 161 | + err_file.write(_format_plugin_list()) |
| 162 | err_file.write('arguments: %r\n' % sys.argv) |
| 163 | err_file.write( |
| 164 | 'encoding: %r, fsenc: %r, lang: %r\n' % ( |
| 165 | osutils.get_user_encoding(), sys.getfilesystemencoding(), |
| 166 | os.environ.get('LANG'))) |
| 167 | - err_file.write("plugins:\n") |
| 168 | - err_file.write(_format_plugin_list()) |
| 169 | + err_file.write('\n') |
| 170 | + trace.print_exception(exc_info, err_file) |
| 171 | err_file.write( |
| 172 | - "\n\n" |
| 173 | + "\n" |
| 174 | "*** Bazaar has encountered an internal error. This probably indicates a\n" |
| 175 | " bug in Bazaar. You can help us fix it by filing a bug report at\n" |
| 176 | " https://bugs.launchpad.net/bzr/+filebug\n" |
| 177 | @@ -81,47 +106,54 @@ |
| 178 | |
| 179 | def report_bug_to_apport(exc_info, stderr): |
| 180 | """Report a bug to apport for optional automatic filing. |
| 181 | + |
| 182 | + :returns: The name of the crash file, or None if we didn't write one. |
| 183 | """ |
| 184 | - # this is based on apport_package_hook.py, but omitting some of the |
| 185 | + # this function is based on apport_package_hook.py, but omitting some of the |
| 186 | # Ubuntu-specific policy about what to report and when |
| 187 | |
| 188 | - # if this fails its caught at a higher level; we don't want to open the |
| 189 | - # crash file unless apport can be loaded. |
| 190 | + # if the import fails, the exception will be caught at a higher level and |
| 191 | + # we'll report the error by other means |
| 192 | import apport |
| 193 | |
| 194 | - crash_file = _open_crash_file() |
| 195 | - try: |
| 196 | - _write_apport_report_to_file(exc_info, crash_file) |
| 197 | - finally: |
| 198 | - crash_file.close() |
| 199 | - |
| 200 | - stderr.write("bzr: ERROR: %s.%s: %s\n" |
| 201 | - "\n" |
| 202 | - "*** Bazaar has encountered an internal error. This probably indicates a\n" |
| 203 | - " bug in Bazaar. You can help us fix it by filing a bug report at\n" |
| 204 | - " https://bugs.launchpad.net/bzr/+filebug\n" |
| 205 | - " attaching the crash file\n" |
| 206 | - " %s\n" |
| 207 | - " and including a description of the problem.\n" |
| 208 | - "\n" |
| 209 | - " The crash file is plain text and you can inspect or edit it to remove\n" |
| 210 | - " private information.\n" |
| 211 | - % (exc_info[0].__module__, exc_info[0].__name__, exc_info[1], |
| 212 | - crash_file.name)) |
| 213 | - |
| 214 | - |
| 215 | -def _write_apport_report_to_file(exc_info, crash_file): |
| 216 | + crash_filename = _write_apport_report_to_file(exc_info) |
| 217 | + |
| 218 | + if crash_filename is None: |
| 219 | + stderr.write("\n" |
| 220 | + "apport is set to ignore crashes in this version of bzr.\n" |
| 221 | + ) |
| 222 | + else: |
| 223 | + trace.print_exception(exc_info, stderr) |
| 224 | + stderr.write("\n" |
| 225 | + "You can report this problem to Bazaar's developers by running\n" |
| 226 | + " apport-bug %s\n" |
| 227 | + "if a bug-reporting window does not automatically appear.\n" |
| 228 | + % (crash_filename)) |
| 229 | + # XXX: on Windows, Mac, and other platforms where we might have the |
| 230 | + # apport libraries but not have an apport always running, we could |
| 231 | + # synchronously file now |
| 232 | + |
| 233 | + return crash_filename |
| 234 | + |
| 235 | + |
| 236 | +def _write_apport_report_to_file(exc_info): |
| 237 | import traceback |
| 238 | from apport.report import Report |
| 239 | |
| 240 | exc_type, exc_object, exc_tb = exc_info |
| 241 | |
| 242 | pr = Report() |
| 243 | - # add_proc_info gives you the memory map of the process: this seems rarely |
| 244 | - # useful for Bazaar and it does make the report harder to scan, though it |
| 245 | - # does tell you what binary modules are loaded. |
| 246 | - # pr.add_proc_info() |
| 247 | + # add_proc_info gets the executable and interpreter path, which is needed, |
| 248 | + # plus some less useful stuff like the memory map |
| 249 | + pr.add_proc_info() |
| 250 | pr.add_user_info() |
| 251 | + |
| 252 | + # Package and SourcePackage are needed so that apport will report about even |
| 253 | + # non-packaged versions of bzr; also this reports on their packaged |
| 254 | + # dependencies which is useful. |
| 255 | + pr['SourcePackage'] = 'bzr' |
| 256 | + pr['Package'] = 'bzr' |
| 257 | + |
| 258 | pr['CommandLine'] = pprint.pformat(sys.argv) |
| 259 | pr['BzrVersion'] = bzrlib.__version__ |
| 260 | pr['PythonVersion'] = bzrlib._format_version_tuple(sys.version_info) |
| 261 | @@ -137,18 +169,74 @@ |
| 262 | traceback.print_exception(exc_type, exc_object, exc_tb, file=tb_file) |
| 263 | pr['Traceback'] = tb_file.getvalue() |
| 264 | |
| 265 | - pr.write(crash_file) |
| 266 | + _attach_log_tail(pr) |
| 267 | + |
| 268 | + # We want to use the 'bzr' crashdb so that it gets sent directly upstream, |
| 269 | + # which is a reasonable default for most internal errors. However, if we |
| 270 | + # set it here then apport will crash later if it doesn't know about that |
| 271 | + # crashdb. Instead, we rely on the bzr package installing both a |
| 272 | + # source hook telling crashes to go to this crashdb, and a crashdb |
| 273 | + # configuration describing it. |
| 274 | + |
| 275 | + # these may contain some sensitive info (smtp_passwords) |
| 276 | + # TODO: strip that out and attach the rest |
| 277 | + # |
| 278 | + #attach_file_if_exists(report, |
| 279 | + # os.path.join(dot_bzr, 'bazaar.conf', 'BzrConfig') |
| 280 | + #attach_file_if_exists(report, |
| 281 | + # os.path.join(dot_bzr, 'locations.conf', 'BzrLocations') |
| 282 | + |
| 283 | + # strip username, hostname, etc |
| 284 | + pr.anonymize() |
| 285 | + |
| 286 | + if pr.check_ignored(): |
| 287 | + # eg configured off in ~/.apport-ignore.xml |
| 288 | + return None |
| 289 | + else: |
| 290 | + crash_file_name, crash_file = _open_crash_file() |
| 291 | + pr.write(crash_file) |
| 292 | + crash_file.close() |
| 293 | + return crash_file_name |
| 294 | + |
| 295 | + |
| 296 | +def _attach_log_tail(pr): |
| 297 | + try: |
| 298 | + bzr_log = open(trace._get_bzr_log_filename(), 'rt') |
| 299 | + except (IOError, OSError), e: |
| 300 | + pr['BzrLogTail'] = repr(e) |
| 301 | + return |
| 302 | + try: |
| 303 | + lines = bzr_log.readlines() |
| 304 | + pr['BzrLogTail'] = ''.join(lines[-40:]) |
| 305 | + finally: |
| 306 | + bzr_log.close() |
| 307 | |
| 308 | |
| 309 | def _open_crash_file(): |
| 310 | crash_dir = config.crash_dir() |
| 311 | - # user-readable only, just in case the contents are sensitive. |
| 312 | if not osutils.isdir(crash_dir): |
| 313 | - os.makedirs(crash_dir, mode=0700) |
| 314 | - filename = 'bzr-%s-%s.crash' % ( |
| 315 | - osutils.compact_date(time.time()), |
| 316 | - os.getpid(),) |
| 317 | - return open(osutils.pathjoin(crash_dir, filename), 'wt') |
| 318 | + # on unix this should be /var/crash and should already exist; on |
| 319 | + # Windows or if it's manually configured it might need to be created, |
| 320 | + # and then it should be private |
| 321 | + os.makedirs(crash_dir, mode=0600) |
| 322 | + date_string = time.strftime('%Y-%m-%dT%H:%M', time.gmtime()) |
| 323 | + # XXX: getuid doesn't work on win32, but the crash directory is per-user |
| 324 | + if sys.platform == 'win32': |
| 325 | + user_part = '' |
| 326 | + else: |
| 327 | + user_part = '.%d' % os.getuid() |
| 328 | + filename = osutils.pathjoin( |
| 329 | + crash_dir, |
| 330 | + 'bzr%s.%s.crash' % ( |
| 331 | + user_part, |
| 332 | + date_string)) |
| 333 | + # be careful here that people can't play tmp-type symlink mischief in the |
| 334 | + # world-writable directory |
| 335 | + return filename, os.fdopen( |
| 336 | + os.open(filename, |
| 337 | + os.O_WRONLY|os.O_CREAT|os.O_EXCL, |
| 338 | + 0600), |
| 339 | + 'w') |
| 340 | |
| 341 | |
| 342 | def _format_plugin_list(): |
| 343 | |
| 344 | === modified file 'bzrlib/tests/__init__.py' |
| 345 | --- bzrlib/tests/__init__.py 2010-01-25 17:48:22 +0000 |
| 346 | +++ bzrlib/tests/__init__.py 2010-02-03 00:05:22 +0000 |
| 347 | @@ -1540,6 +1540,11 @@ |
| 348 | 'ftp_proxy': None, |
| 349 | 'FTP_PROXY': None, |
| 350 | 'BZR_REMOTE_PATH': None, |
| 351 | + # Generally speaking, we don't want apport reporting on crashes in |
| 352 | + # the test envirnoment unless we're specifically testing apport, |
| 353 | + # so that it doesn't leak into the real system environment. We |
| 354 | + # use an env var so it propagates to subprocesses. |
| 355 | + 'APPORT_DISABLE': '1', |
| 356 | } |
| 357 | self.__old_env = {} |
| 358 | self.addCleanup(self._restoreEnvironment) |
| 359 | |
| 360 | === modified file 'bzrlib/tests/test_crash.py' |
| 361 | --- bzrlib/tests/test_crash.py 2009-12-22 15:39:20 +0000 |
| 362 | +++ bzrlib/tests/test_crash.py 2010-02-03 00:05:22 +0000 |
| 363 | @@ -1,4 +1,4 @@ |
| 364 | -# Copyright (C) 2009 Canonical Ltd |
| 365 | +# Copyright (C) 2009, 2010 Canonical Ltd |
| 366 | # |
| 367 | # This program is free software; you can redistribute it and/or modify |
| 368 | # it under the terms of the GNU General Public License as published by |
| 369 | @@ -18,31 +18,62 @@ |
| 370 | from StringIO import StringIO |
| 371 | import sys |
| 372 | |
| 373 | + |
| 374 | +import os |
| 375 | + |
| 376 | + |
| 377 | from bzrlib import ( |
| 378 | + config, |
| 379 | crash, |
| 380 | tests, |
| 381 | - ) |
| 382 | - |
| 383 | -from bzrlib.tests import features |
| 384 | - |
| 385 | - |
| 386 | -class TestApportReporting(tests.TestCase): |
| 387 | + osutils, |
| 388 | + ) |
| 389 | + |
| 390 | +from bzrlib.tests import ( |
| 391 | + features, |
| 392 | + TestCaseInTempDir, |
| 393 | + ) |
| 394 | +from bzrlib.tests.features import ApportFeature |
| 395 | + |
| 396 | + |
| 397 | +class TestApportReporting(TestCaseInTempDir): |
| 398 | |
| 399 | _test_needs_features = [features.apport] |
| 400 | |
| 401 | - def test_apport_report_contents(self): |
| 402 | + def setUp(self): |
| 403 | + TestCaseInTempDir.setUp(self) |
| 404 | + self.requireFeature(ApportFeature) |
| 405 | + |
| 406 | + def test_apport_report(self): |
| 407 | + crash_dir = osutils.joinpath((self.test_base_dir, 'crash')) |
| 408 | + os.mkdir(crash_dir) |
| 409 | + os.environ['APPORT_CRASH_DIR'] = crash_dir |
| 410 | + self.assertEquals(crash_dir, config.crash_dir()) |
| 411 | + |
| 412 | + stderr = StringIO() |
| 413 | + |
| 414 | try: |
| 415 | raise AssertionError("my error") |
| 416 | except AssertionError, e: |
| 417 | pass |
| 418 | - outf = StringIO() |
| 419 | - crash._write_apport_report_to_file(sys.exc_info(), outf) |
| 420 | - report = outf.getvalue() |
| 421 | - |
| 422 | - self.assertContainsRe(report, '(?m)^BzrVersion:') |
| 423 | - # should be in the traceback |
| 424 | + |
| 425 | + crash_filename = crash.report_bug_to_apport(sys.exc_info(), |
| 426 | + stderr) |
| 427 | + |
| 428 | + # message explaining the crash |
| 429 | + self.assertContainsRe(stderr.getvalue(), |
| 430 | + " apport-bug %s" % crash_filename) |
| 431 | + |
| 432 | + crash_file = open(crash_filename) |
| 433 | + try: |
| 434 | + report = crash_file.read() |
| 435 | + finally: |
| 436 | + crash_file.close() |
| 437 | + |
| 438 | + self.assertContainsRe(report, |
| 439 | + '(?m)^BzrVersion:') # should be in the traceback |
| 440 | self.assertContainsRe(report, 'my error') |
| 441 | self.assertContainsRe(report, 'AssertionError') |
| 442 | - self.assertContainsRe(report, 'test_apport_report_contents') |
| 443 | + self.assertContainsRe(report, 'test_apport_report') |
| 444 | # should also be in there |
| 445 | self.assertContainsRe(report, '(?m)^CommandLine:') |
| 446 | |
| 447 | === added directory 'contrib/apport' |
| 448 | === added file 'contrib/apport/README' |
| 449 | --- contrib/apport/README 1970-01-01 00:00:00 +0000 |
| 450 | +++ contrib/apport/README 2010-02-03 00:05:22 +0000 |
| 451 | @@ -0,0 +1,13 @@ |
| 452 | +Bazaar supports semi-automatic bug reporting through Apport |
| 453 | +<https://launchpad.net/apport/>. |
| 454 | + |
| 455 | +If apport is not installed, an exception is printed to stderr in the usual way. |
| 456 | + |
| 457 | +For this to work properly it's suggested that two files be installed when a |
| 458 | +package of bzr is installed: |
| 459 | + |
| 460 | +``bzr.conf`` |
| 461 | + into ``/etc/apport/crashdb.conf.d`` |
| 462 | + |
| 463 | +``source_bzr.py`` |
| 464 | + into ``/usr/share/apport/package-hooks`` |
| 465 | |
| 466 | === added file 'contrib/apport/bzr.conf' |
| 467 | --- contrib/apport/bzr.conf 1970-01-01 00:00:00 +0000 |
| 468 | +++ contrib/apport/bzr.conf 2010-02-03 00:05:22 +0000 |
| 469 | @@ -0,0 +1,6 @@ |
| 470 | +bzr = { |
| 471 | + # most bzr bugs are upstream bugs; file them there |
| 472 | + 'impl': 'launchpad', |
| 473 | + 'project': 'bzr', |
| 474 | + 'bug_pattern_base': 'http://people.canonical.com/~pitti/bugpatterns', |
| 475 | +} |
| 476 | |
| 477 | === added file 'contrib/apport/source_bzr.py' |
| 478 | --- contrib/apport/source_bzr.py 1970-01-01 00:00:00 +0000 |
| 479 | +++ contrib/apport/source_bzr.py 2010-02-03 00:05:22 +0000 |
| 480 | @@ -0,0 +1,54 @@ |
| 481 | +'''apport package hook for Bazaar''' |
| 482 | + |
| 483 | +# Copyright (c) 2009, 2010 Canonical Ltd. |
| 484 | +# Author: Matt Zimmerman <mdz@canonical.com> |
| 485 | +# and others |
| 486 | + |
| 487 | +from apport.hookutils import * |
| 488 | +import os |
| 489 | + |
| 490 | +bzr_log = os.path.expanduser('~/.bzr.log') |
| 491 | +dot_bzr = os.path.expanduser('~/.bazaar') |
| 492 | + |
| 493 | +def _add_log_tail(report): |
| 494 | + # may have already been added in-process |
| 495 | + if 'BzrLogTail' in report: |
| 496 | + return |
| 497 | + |
| 498 | + bzr_log_lines = open(bzr_log).readlines() |
| 499 | + bzr_log_lines.reverse() |
| 500 | + |
| 501 | + bzr_log_tail = [] |
| 502 | + blanks = 0 |
| 503 | + for line in bzr_log_lines: |
| 504 | + if line == '\n': |
| 505 | + blanks += 1 |
| 506 | + bzr_log_tail.append(line) |
| 507 | + if blanks >= 2: |
| 508 | + break |
| 509 | + |
| 510 | + bzr_log_tail.reverse() |
| 511 | + report['BzrLogTail'] = ''.join(bzr_log_tail) |
| 512 | + |
| 513 | + |
| 514 | +def add_info(report): |
| 515 | + |
| 516 | + _add_log_tail() |
| 517 | + if 'BzrPlugins' not in report: |
| 518 | + # may already be present in-process |
| 519 | + report['BzrPlugins'] = command_output(['bzr', 'plugins', '-v']) |
| 520 | + |
| 521 | + # by default assume bzr crashes are upstream bugs; this relies on |
| 522 | + # having a bzr entry under /etc/apport/crashdb.conf.d/ |
| 523 | + report['CrashDB'] = 'bzr' |
| 524 | + |
| 525 | + # these may contain some sensitive info (smtp_passwords) |
| 526 | + # TODO: strip that out and attach the rest |
| 527 | + |
| 528 | + #attach_file_if_exists(report, |
| 529 | + # os.path.join(dot_bzr, 'bazaar.conf', 'BzrConfig') |
| 530 | + #attach_file_if_exists(report, |
| 531 | + # os.path.join(dot_bzr, 'locations.conf', 'BzrLocations') |
| 532 | + |
| 533 | + |
| 534 | +# vim: expandtab shiftwidth=4 |

Turn off apport during selftest, and put the traceback at the end where it's more useful to developers and less likely to be scrolled off by plugins.
Fixes bug 417881