Rev 2446: (robertc) bzr --fixes support to allow recording of bugs that are fixed by commits. (Jonathan Lange, James Henstridge, Robert Collins) in file:///home/pqm/archives/thelove/bzr/%2Btrunk/
Canonical.com Patch Queue Manager
pqm at pqm.ubuntu.com
Mon Apr 23 08:50:18 BST 2007
At file:///home/pqm/archives/thelove/bzr/%2Btrunk/
------------------------------------------------------------
revno: 2446
revision-id: pqm at pqm.ubuntu.com-20070423075015-340ajk1vo3pzxheu
parent: pqm at pqm.ubuntu.com-20070423070809-7imm5hgj6g0n78s5
parent: jml at canonical.com-20070423065558-wbkypy8qlhzrxugz
committer: Canonical.com Patch Queue Manager<pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Mon 2007-04-23 08:50:15 +0100
message:
(robertc) bzr --fixes support to allow recording of bugs that are fixed by commits. (Jonathan Lange, James Henstridge, Robert Collins)
added:
bzrlib/bugtracker.py bugtracker.py-20070410073305-vu1vu1qosjurg8kb-1
bzrlib/tests/test_bugtracker.py test_bugtracker.py-20070410073305-vu1vu1qosjurg8kb-2
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/builtins.py builtins.py-20050830033751-fc01482b9ca23183
bzrlib/errors.py errors.py-20050309040759-20512168c4e14fbd
bzrlib/help_topics.py help_topics.py-20060920210027-rnim90q9e0bwxvy4-1
bzrlib/option.py option.py-20051014052914-661fb36e76e7362f
bzrlib/tests/__init__.py selftest.py-20050531073622-8d0e3c8845c97a64
bzrlib/tests/blackbox/test_commit.py test_commit.py-20060212094538-ae88fc861d969db0
bzrlib/tests/test_errors.py test_errors.py-20060210110251-41aba2deddf936a8
bzrlib/tests/test_options.py testoptions.py-20051014093702-96457cfc86319a8f
doc/configuration.txt configuration.txt-20060314161707-868350809502af01
------------------------------------------------------------
revno: 2376.4.43
merged: jml at canonical.com-20070423065558-wbkypy8qlhzrxugz
parent: jml at canonical.com-20070423055929-chgdr92da63lhcri
parent: pqm at pqm.ubuntu.com-20070423041629-v7moohhajrjbc2xw
committer: Jonathan Lange <jml at canonical.com>
branch nick: bug-support
timestamp: Mon 2007-04-23 16:55:58 +1000
message:
Merge from mainline, resolving conflict in help_topics
------------------------------------------------------------
revno: 2376.4.42
merged: jml at canonical.com-20070423055929-chgdr92da63lhcri
parent: jml at canonical.com-20070423052447-q9qv5n7mhkdsqj46
committer: Jonathan Lange <jml at canonical.com>
branch nick: lp-bugs
timestamp: Mon 2007-04-23 15:59:29 +1000
message:
Parametrize URLParametrizedIntegerBugTracker even further so we don't need to
subclass.
------------------------------------------------------------
revno: 2376.4.41
merged: jml at canonical.com-20070423052447-q9qv5n7mhkdsqj46
parent: jml at canonical.com-20070423052217-nz0zuaesa0dcbvy2
committer: Jonathan Lange <jml at canonical.com>
branch nick: lp-bugs
timestamp: Mon 2007-04-23 15:24:47 +1000
message:
Update UniqueIntegerBugTracker docstring for new API
------------------------------------------------------------
revno: 2376.4.40
merged: jml at canonical.com-20070423052217-nz0zuaesa0dcbvy2
parent: jml at canonical.com-20070423013035-zuqiamuro8h1hba9
committer: Jonathan Lange <jml at canonical.com>
branch nick: lp-bugs
timestamp: Mon 2007-04-23 15:22:17 +1000
message:
Redo the hierarchy of bug trackers to reduce duplication.
------------------------------------------------------------
revno: 2376.4.39
merged: jml at canonical.com-20070423013035-zuqiamuro8h1hba9
parent: jml at canonical.com-20070422230056-mfu7bo3ydrbbag7p
committer: Jonathan Lange <jml at canonical.com>
branch nick: lp-bugs
timestamp: Mon 2007-04-23 11:30:35 +1000
message:
Can also set the bug config options in branch.conf
------------------------------------------------------------
revno: 2376.4.38
merged: jml at canonical.com-20070422230056-mfu7bo3ydrbbag7p
parent: jml at canonical.com-20070422224848-cm8v6p5wmpx1psco
parent: pqm at pqm.ubuntu.com-20070421151139-5wau2ukbpx5z1hv2
committer: Jonathan Lange <jml at canonical.com>
branch nick: lp-bugs
timestamp: Mon 2007-04-23 09:00:56 +1000
message:
Merge bzr.dev, resolving conflicts in error code.
------------------------------------------------------------
revno: 2376.4.37
merged: jml at canonical.com-20070422224848-cm8v6p5wmpx1psco
parent: jml at canonical.com-20070422224519-wixpd8wnwxw70641
committer: Jonathan Lange <jml at canonical.com>
branch nick: lp-bugs
timestamp: Mon 2007-04-23 08:48:48 +1000
message:
Mention API additions in NEWS.
------------------------------------------------------------
revno: 2376.4.36
merged: jml at canonical.com-20070422224519-wixpd8wnwxw70641
parent: jml at canonical.com-20070422222300-7xlpc7u275pvh2iw
committer: Jonathan Lange <jml at canonical.com>
branch nick: lp-bugs
timestamp: Mon 2007-04-23 08:45:19 +1000
message:
Provide really basic help topic for our bug tracker support.
------------------------------------------------------------
revno: 2376.4.35
merged: jml at canonical.com-20070422222300-7xlpc7u275pvh2iw
parent: jml at canonical.com-20070422222226-pkjyasbt28k1aug7
committer: Jonathan Lange <jml at canonical.com>
branch nick: lp-bugs
timestamp: Mon 2007-04-23 08:23:00 +1000
message:
Include configuration documentation for tracker config options.
------------------------------------------------------------
revno: 2376.4.34
merged: jml at canonical.com-20070422222226-pkjyasbt28k1aug7
parent: jml at canonical.com-20070420041308-93e07kmw1s9t1ceg
committer: Jonathan Lange <jml at canonical.com>
branch nick: lp-bugs
timestamp: Mon 2007-04-23 08:22:26 +1000
message:
Remove spurious quote mark in docstring.
------------------------------------------------------------
revno: 2376.4.33
merged: jml at canonical.com-20070420041308-93e07kmw1s9t1ceg
parent: jml at canonical.com-20070420041143-td2407zcd2xygk70
parent: pqm at pqm.ubuntu.com-20070419224637-jvlshh6kibtj43a5
committer: Jonathan Lange <jml at canonical.com>
branch nick: lp-bugs
timestamp: Fri 2007-04-20 14:13:08 +1000
message:
Merge from bzr.dev
------------------------------------------------------------
revno: 2376.4.32
merged: jml at canonical.com-20070420041143-td2407zcd2xygk70
parent: jml at canonical.com-20070420035328-i3hfywon1imyw0q7
committer: Jonathan Lange <jml at canonical.com>
branch nick: lp-bugs
timestamp: Fri 2007-04-20 14:11:43 +1000
message:
Basic documentation for --fixes option
------------------------------------------------------------
revno: 2376.4.31
merged: jml at canonical.com-20070420035328-i3hfywon1imyw0q7
parent: jml at canonical.com-20070420034009-ii53ulxxwj1jnppt
committer: Jonathan Lange <jml at canonical.com>
branch nick: lp-bugs
timestamp: Fri 2007-04-20 13:53:28 +1000
message:
Whitespace normalization and use squid as an example rather than apache.
------------------------------------------------------------
revno: 2376.4.30
merged: jml at canonical.com-20070420034009-ii53ulxxwj1jnppt
parent: jml at canonical.com-20070420031943-ufx3jtikoxp0mlpb
committer: Jonathan Lange <jml at canonical.com>
branch nick: lp-bugs
timestamp: Fri 2007-04-20 13:40:09 +1000
message:
Support for Bugzilla bug trackers.
------------------------------------------------------------
revno: 2376.4.29
merged: jml at canonical.com-20070420031943-ufx3jtikoxp0mlpb
parent: jml at canonical.com-20070420031049-kwt6hkq8qdlgtm3z
committer: Jonathan Lange <jml at canonical.com>
branch nick: lp-bugs
timestamp: Fri 2007-04-20 13:19:43 +1000
message:
Tests for builtin trackers.
------------------------------------------------------------
revno: 2376.4.28
merged: jml at canonical.com-20070420031049-kwt6hkq8qdlgtm3z
parent: jml at canonical.com-20070420022738-07tr3bqahw14ftdh
committer: Jonathan Lange <jml at canonical.com>
branch nick: lp-bugs
timestamp: Fri 2007-04-20 13:10:49 +1000
message:
Focus the tests better and clean up some dodgy bits in UnknownBugTrackerAbbreviation
------------------------------------------------------------
revno: 2376.4.27
merged: jml at canonical.com-20070420022738-07tr3bqahw14ftdh
parent: jml at canonical.com-20070420022157-ampptjzryc2fju7t
committer: Jonathan Lange <jml at canonical.com>
branch nick: lp-bugs
timestamp: Fri 2007-04-20 12:27:38 +1000
message:
Include branch information in UnknownBugTrackerAbbreviation
------------------------------------------------------------
revno: 2376.4.26
merged: jml at canonical.com-20070420022157-ampptjzryc2fju7t
parent: jml at canonical.com-20070420021008-eqpr2ta14upnb0ne
committer: Jonathan Lange <jml at canonical.com>
branch nick: lp-bugs
timestamp: Fri 2007-04-20 12:21:57 +1000
message:
Tests for MalformedBugIdentifier and new error UnknownBugTrackerAbbreviation.
------------------------------------------------------------
revno: 2376.4.25
merged: jml at canonical.com-20070420021008-eqpr2ta14upnb0ne
parent: jml at canonical.com-20070420015214-y9ufmdqpwd75zog8
committer: Jonathan Lange <jml at canonical.com>
branch nick: lp-bugs
timestamp: Fri 2007-04-20 12:10:08 +1000
message:
Make singleton bug tracker thing work via instances.
------------------------------------------------------------
revno: 2376.4.24
merged: jml at canonical.com-20070420015214-y9ufmdqpwd75zog8
parent: jml at canonical.com-20070420005627-p6rrsxowxkf7w5sy
committer: Jonathan Lange <jml at canonical.com>
branch nick: lp-bugs
timestamp: Fri 2007-04-20 11:52:14 +1000
message:
Make the Tracker class attribute 'abbrevation', not 'abbreviated_bugtracker_name'
------------------------------------------------------------
revno: 2376.4.23
merged: jml at canonical.com-20070420005627-p6rrsxowxkf7w5sy
parent: jml at canonical.com-20070417075942-1vfzpwjf8rvbty1f
committer: Jonathan Lange <jml at canonical.com>
branch nick: lp-bugs
timestamp: Fri 2007-04-20 10:56:27 +1000
message:
Change 'tag' to 'abbreviated_tracker_name'
------------------------------------------------------------
revno: 2376.4.22
merged: jml at canonical.com-20070417075942-1vfzpwjf8rvbty1f
parent: jml at canonical.com-20070417073819-m0r79gdukrq2j8kv
committer: Jonathan Lange <jml at canonical.com>
branch nick: lp-bugs
timestamp: Tue 2007-04-17 17:59:42 +1000
message:
Variety of whitespace cleanups, tightening of tests and docstring changes in
response to review of bug support.
------------------------------------------------------------
revno: 2376.4.21
merged: jml at canonical.com-20070417073819-m0r79gdukrq2j8kv
parent: jml at canonical.com-20070413072937-ndsxwg5svbk2542f
committer: Jonathan Lange <jml at canonical.com>
branch nick: lp-bugs
timestamp: Tue 2007-04-17 17:38:19 +1000
message:
Change the bugs separator to \n from ,
------------------------------------------------------------
revno: 2376.4.20
merged: jml at canonical.com-20070413072937-ndsxwg5svbk2542f
parent: jml at canonical.com-20070413071912-vkcaqm87lduwlfs7
committer: Jonathan Lange <jml at canonical.com>
branch nick: lp-bugs
timestamp: Fri 2007-04-13 17:29:37 +1000
message:
Direct tests for UniqueBugTracker and UniqueIntegerBugTracker
------------------------------------------------------------
revno: 2376.4.19
merged: jml at canonical.com-20070413071912-vkcaqm87lduwlfs7
parent: jml at canonical.com-20070413065621-hv9tv4ws25remckj
committer: Jonathan Lange <jml at canonical.com>
branch nick: lp-bugs
timestamp: Fri 2007-04-13 17:19:12 +1000
message:
Rename SimpleBugTracker to UniqueBugTracker
------------------------------------------------------------
revno: 2376.4.18
merged: jml at canonical.com-20070413065621-hv9tv4ws25remckj
parent: jml at canonical.com-20070413064225-cmuz00itroirlro4
committer: Jonathan Lange <jml at canonical.com>
branch nick: lp-bugs
timestamp: Fri 2007-04-13 16:56:21 +1000
message:
Store all bug fix URLs in a single property.
------------------------------------------------------------
revno: 2376.4.17
merged: jml at canonical.com-20070413064225-cmuz00itroirlro4
parent: jml at canonical.com-20070413062439-tn32nfugq13jg6kg
committer: Jonathan Lange <jml at canonical.com>
branch nick: lp-bugs
timestamp: Fri 2007-04-13 16:42:25 +1000
message:
Use urlutils.join instead of ugly, buggy, string mashing
------------------------------------------------------------
revno: 2376.4.16
merged: jml at canonical.com-20070413062439-tn32nfugq13jg6kg
parent: jml at canonical.com-20070413061233-v14vlu2n6k1rxjgz
committer: Jonathan Lange <jml at canonical.com>
branch nick: lp-bugs
timestamp: Fri 2007-04-13 16:24:39 +1000
message:
"bug tracker" is two words, so use BugTracker in class names, not 'Bugtracker'
------------------------------------------------------------
revno: 2376.4.15
merged: jml at canonical.com-20070413061233-v14vlu2n6k1rxjgz
parent: jml at canonical.com-20070413061123-r2vzcu0mpqcyaret
committer: Jonathan Lange <jml at canonical.com>
branch nick: lp-bugs
timestamp: Fri 2007-04-13 16:12:33 +1000
message:
Whitespace cleanup
------------------------------------------------------------
revno: 2376.4.14
merged: jml at canonical.com-20070413061123-r2vzcu0mpqcyaret
parent: jml at canonical.com-20070413051007-cq318kt5uj59k1ty
parent: jw+debian at jameswestby.net-20070412205830-77i29wqt0002bbxj
committer: Jonathan Lange <jml at canonical.com>
branch nick: lp-bugs
timestamp: Fri 2007-04-13 16:11:23 +1000
message:
Merge James Westby's refactoring
------------------------------------------------------------
revno: 2376.4.8.1.1
merged: jw+debian at jameswestby.net-20070412205830-77i29wqt0002bbxj
parent: jml at canonical.com-20070411042318-y7tqzml42jkh1ux2
committer: James Westby <jw+debian at jameswestby.net>
branch nick: bzr.dev.bug
timestamp: Thu 2007-04-12 21:58:30 +0100
message:
Add a superclass for easy bug trackers. Also add bugs.debian.org as deb:
------------------------------------------------------------
revno: 2376.4.13
merged: jml at canonical.com-20070413051007-cq318kt5uj59k1ty
parent: jml at canonical.com-20070413045808-fx86n9ctjcbf4hvq
committer: Jonathan Lange <jml at canonical.com>
branch nick: lp-bugs
timestamp: Fri 2007-04-13 15:10:07 +1000
message:
Some stylistic cleanups
------------------------------------------------------------
revno: 2376.4.12
merged: jml at canonical.com-20070413045808-fx86n9ctjcbf4hvq
parent: jml at canonical.com-20070413035248-l5lqpwr1t0yzp872
committer: Jonathan Lange <jml at canonical.com>
branch nick: lp-bugs
timestamp: Fri 2007-04-13 14:58:08 +1000
message:
Update NEWS file.
Use non-lazy import
Use run_bzr for running bzr in fixes tests.
------------------------------------------------------------
revno: 2376.4.11
merged: jml at canonical.com-20070413035248-l5lqpwr1t0yzp872
parent: jml at canonical.com-20070413035020-z4gdg5sgmd5szc3o
committer: Jonathan Lange <jml at canonical.com>
branch nick: lp-bugs
timestamp: Fri 2007-04-13 13:52:48 +1000
message:
Provide a way of resetting list options (specifying '-' as the argument)
------------------------------------------------------------
revno: 2376.4.10
merged: jml at canonical.com-20070413035020-z4gdg5sgmd5szc3o
parent: jml at canonical.com-20070413034711-pn129rtch4usvmdk
committer: Jonathan Lange <jml at canonical.com>
branch nick: lp-bugs
timestamp: Fri 2007-04-13 13:50:20 +1000
message:
Oops. Update tests to account for changed options to commit.
------------------------------------------------------------
revno: 2376.4.9
merged: jml at canonical.com-20070413034711-pn129rtch4usvmdk
parent: jml at canonical.com-20070411042318-y7tqzml42jkh1ux2
parent: pqm at pqm.ubuntu.com-20070412150356-jeie6iap22sae8xf
committer: Jonathan Lange <jml at canonical.com>
branch nick: lp-bugs
timestamp: Fri 2007-04-13 13:47:11 +1000
message:
Merge from mainline.
------------------------------------------------------------
revno: 2376.4.8
merged: jml at canonical.com-20070411042318-y7tqzml42jkh1ux2
parent: jml at canonical.com-20070411035653-himmtk357n8d3fbv
committer: jml at canonical.com
branch nick: lp-bugs
timestamp: Wed 2007-04-11 14:23:18 +1000
message:
Import sub-module, not member, following advice in HACKING
------------------------------------------------------------
revno: 2376.4.7
merged: jml at canonical.com-20070411035653-himmtk357n8d3fbv
parent: jml at canonical.com-20070411002703-2jbq0152stafryqg
committer: jml at canonical.com
branch nick: lp-bugs
timestamp: Wed 2007-04-11 13:56:53 +1000
message:
- Add docstrings to tests.
- Make the 'commit' command use the bugtracker infrastructure.
- Update the blackbox tests
- Move the 'is this a valid bug id' logic to the tracker
------------------------------------------------------------
revno: 2376.4.6
merged: jml at canonical.com-20070411002703-2jbq0152stafryqg
parent: jml at canonical.com-20070410232958-2pl3j2qwujq5yjy9
committer: jml at canonical.com
branch nick: lp-bugs
timestamp: Wed 2007-04-11 10:27:03 +1000
message:
Basic docstrings for bugtracker.py
------------------------------------------------------------
revno: 2376.4.5
merged: jml at canonical.com-20070410232958-2pl3j2qwujq5yjy9
parent: jml at canonical.com-20070410073307-3nrm81zu32wz9qbs
committer: jml at canonical.com
branch nick: lp-bugs
timestamp: Wed 2007-04-11 09:29:58 +1000
message:
Rename get_by_tag to get_tracker, to be more accurate.
------------------------------------------------------------
revno: 2376.4.4
merged: jml at canonical.com-20070410073307-3nrm81zu32wz9qbs
parent: jml at canonical.com-20070410012227-k5ixuw4mik7z9kfh
committer: jml at canonical.com
branch nick: lp-bugs
timestamp: Tue 2007-04-10 17:33:07 +1000
message:
Beginnings of generic bug-tracker plugin system.
------------------------------------------------------------
revno: 2376.4.3
merged: jml at canonical.com-20070410012227-k5ixuw4mik7z9kfh
parent: jml at canonical.com-20070402072630-0bjkptemr6wh50s3
parent: pqm at pqm.ubuntu.com-20070405073143-8fa894c829ab5e50
committer: jml at canonical.com
branch nick: lp-bugs
timestamp: Tue 2007-04-10 11:22:27 +1000
message:
Merge RF
------------------------------------------------------------
revno: 2376.4.2
merged: jml at canonical.com-20070402072630-0bjkptemr6wh50s3
parent: jml at canonical.com-20070328065202-1r825jxnabsy31ak
committer: jml at canonical.com
branch nick: lp-bugs
timestamp: Mon 2007-04-02 17:26:30 +1000
message:
More sophisticated error handling for --fixes option
------------------------------------------------------------
revno: 2376.4.1
merged: jml at canonical.com-20070328065202-1r825jxnabsy31ak
parent: pqm at pqm.ubuntu.com-20070326073003-37941d0fa5a5a6c4
committer: jml at canonical.com
branch nick: lp-bugs
timestamp: Wed 2007-03-28 16:52:02 +1000
message:
Blackbox-driven --fixes option to commit.
=== added file 'bzrlib/bugtracker.py'
--- a/bzrlib/bugtracker.py 1970-01-01 00:00:00 +0000
+++ b/bzrlib/bugtracker.py 2007-04-23 05:59:29 +0000
@@ -0,0 +1,173 @@
+# Copyright (C) 2007 Canonical Ltd
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+import textwrap
+
+from bzrlib import registry, help_topics
+from bzrlib.lazy_import import lazy_import
+lazy_import(globals(), """
+from bzrlib import errors, urlutils
+""")
+
+
+"""Provides a shorthand for referring to bugs on a variety of bug trackers.
+
+'commit --fixes' stores references to bugs as a <bug_url> -> <bug_status>
+mapping in the properties for that revision.
+
+However, it's inconvenient to type out full URLs for bugs on the command line,
+particularly given that many users will be using only a single bug tracker per
+branch.
+
+Thus, this module provides a registry of types of bug tracker (e.g. Launchpad,
+Trac). Given an abbreviated name (e.g. 'lp', 'twisted') and a branch with
+configuration information, these tracker types can return an instance capable
+of converting bug IDs into URLs.
+"""
+
+
+def get_bug_url(abbreviated_bugtracker_name, branch, bug_id):
+ """Return a URL pointing to the canonical web page of the bug identified by
+ 'bug_id'.
+ """
+ tracker = tracker_registry.get_tracker(abbreviated_bugtracker_name, branch)
+ return tracker.get_bug_url(bug_id)
+
+
+class TrackerRegistry(registry.Registry):
+ """Registry of bug tracker types."""
+
+ def get_tracker(self, abbreviated_bugtracker_name, branch):
+ """Return the first registered tracker that understands
+ 'abbreviated_bugtracker_name'.
+
+ If no such tracker is found, raise KeyError.
+ """
+ for tracker_name in self.keys():
+ tracker_type = self.get(tracker_name)
+ tracker = tracker_type.get(abbreviated_bugtracker_name, branch)
+ if tracker is not None:
+ return tracker
+ raise errors.UnknownBugTrackerAbbreviation(abbreviated_bugtracker_name,
+ branch)
+
+ def help_topic(self, topic):
+ return textwrap.dedent("""\
+ Bazaar provides the ability to store information about bugs being fixed
+ as metadata on a revision.
+
+ For each bug marked as fixed, an entry is included in the 'bugs'
+ revision property stating '<url> <status>'.
+ """)
+
+
+tracker_registry = TrackerRegistry()
+"""Registry of bug trackers."""
+
+
+class BugTracker(object):
+ """Base class for bug trackers."""
+
+ def check_bug_id(self, bug_id):
+ """Check that the bug_id is valid.
+
+ The base implementation assumes that all bug_ids are valid.
+ """
+
+ def get_bug_url(self, bug_id):
+ """Return the URL for bug_id. Raise an error if bug ID is malformed."""
+ self.check_bug_id(bug_id)
+ return self._get_bug_url(bug_id)
+
+ def _get_bug_url(self, bug_id):
+ """Given a validated bug_id, return the bug's web page's URL."""
+
+
+class IntegerBugTracker(BugTracker):
+ """A bug tracker that only allows integer bug IDs."""
+
+ def check_bug_id(self, bug_id):
+ try:
+ int(bug_id)
+ except ValueError:
+ raise errors.MalformedBugIdentifier(bug_id, "Must be an integer")
+
+
+class UniqueIntegerBugTracker(IntegerBugTracker):
+ """A style of bug tracker that exists in one place only, such as Launchpad.
+
+ If you have one of these trackers then register an instance passing in an
+ abbreviated name for the bug tracker and a base URL.
+ """
+
+ def __init__(self, abbreviated_bugtracker_name, base_url):
+ self.abbreviation = abbreviated_bugtracker_name
+ self.base_url = base_url
+
+ def get(self, abbreviated_bugtracker_name, branch):
+ """Returns the tracker if the abbreviation matches. Returns None
+ otherwise."""
+ if abbreviated_bugtracker_name != self.abbreviation:
+ return None
+ return self
+
+ def _get_bug_url(self, bug_id):
+ """Return the URL for bug_id."""
+ return urlutils.join(self.base_url, bug_id)
+
+
+tracker_registry.register(
+ 'launchpad', UniqueIntegerBugTracker('lp', 'https://launchpad.net/bugs/'))
+
+
+tracker_registry.register(
+ 'debian', UniqueIntegerBugTracker('deb', 'http://bugs.debian.org/'))
+
+
+class URLParametrizedIntegerBugTracker(IntegerBugTracker):
+ """A type of bug tracker that can be found on a variety of different sites,
+ and thus needs to have the base URL configured.
+
+ Looks for a config setting in the form '<type_name>_<abbreviation>_url'.
+ `type_name` is the name of the type of tracker (e.g. 'bugzilla' or 'trac')
+ and `abbreviation` is a short name for the particular instance (e.g.
+ 'squid' or 'apache').
+ """
+
+ def get(self, abbreviation, branch):
+ config = branch.get_config()
+ url = config.get_user_option(
+ "%s_%s_url" % (self.type_name, abbreviation))
+ if url is None:
+ return None
+ self._base_url = url
+ return self
+
+ def __init__(self, type_name, bug_area):
+ self.type_name = type_name
+ self._bug_area = bug_area
+
+ def _get_bug_url(self, bug_id):
+ """Return a URL for a bug on this Trac instance."""
+ return urlutils.join(self._base_url, self._bug_area) + str(bug_id)
+
+
+tracker_registry.register(
+ 'trac', URLParametrizedIntegerBugTracker('trac', 'ticket/'))
+
+tracker_registry.register(
+ 'bugzilla',
+ URLParametrizedIntegerBugTracker('bugzilla', 'show_bug.cgi?id='))
=== added file 'bzrlib/tests/test_bugtracker.py'
--- a/bzrlib/tests/test_bugtracker.py 1970-01-01 00:00:00 +0000
+++ b/bzrlib/tests/test_bugtracker.py 2007-04-23 05:59:29 +0000
@@ -0,0 +1,185 @@
+# Copyright (C) 2007 Canonical Ltd
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+from bzrlib import bugtracker, errors, urlutils
+from bzrlib.tests import TestCaseWithMemoryTransport
+
+
+class TestGetBugURL(TestCaseWithMemoryTransport):
+ """Tests for bugtracker.get_bug_url"""
+
+ class TransientTracker(object):
+ """An transient tracker used for testing."""
+
+ @classmethod
+ def get(klass, abbreviation, branch):
+ klass.log.append(('get', abbreviation, branch))
+ if abbreviation != 'transient':
+ return None
+ return klass()
+
+ def get_bug_url(self, bug_id):
+ self.log.append(('get_bug_url', bug_id))
+ return "http://bugs.com/%s" % bug_id
+
+ def setUp(self):
+ TestCaseWithMemoryTransport.setUp(self)
+ self.tracker_type = TestGetBugURL.TransientTracker
+ self.tracker_type.log = []
+ bugtracker.tracker_registry.register('transient', self.tracker_type)
+ self.addCleanup(lambda:
+ bugtracker.tracker_registry.remove('transient'))
+
+ def test_get_bug_url_for_transient_tracker(self):
+ branch = self.make_branch('some_branch')
+ self.assertEqual('http://bugs.com/1234',
+ bugtracker.get_bug_url('transient', branch, '1234'))
+ self.assertEqual(
+ [('get', 'transient', branch), ('get_bug_url', '1234')],
+ self.tracker_type.log)
+
+ def test_unrecognized_abbreviation_raises_error(self):
+ """If the abbreviation is unrecognized, then raise an error."""
+ branch = self.make_branch('some_branch')
+ self.assertRaises(errors.UnknownBugTrackerAbbreviation,
+ bugtracker.get_bug_url, 'xxx', branch, '1234')
+ self.assertEqual([('get', 'xxx', branch)], self.tracker_type.log)
+
+
+class TestBuiltinTrackers(TestCaseWithMemoryTransport):
+ """Test that the builtin trackers are registered and return sane URLs."""
+
+ def test_launchpad_registered(self):
+ """The Launchpad bug tracker should be registered by default and
+ generate Launchpad bug page URLs.
+ """
+ branch = self.make_branch('some_branch')
+ tracker = bugtracker.tracker_registry.get_tracker('lp', branch)
+ self.assertEqual('https://launchpad.net/bugs/1234',
+ tracker.get_bug_url('1234'))
+
+ def test_debian_registered(self):
+ """The Debian bug tracker should be registered by default and generate
+ bugs.debian.org bug page URLs.
+ """
+ branch = self.make_branch('some_branch')
+ tracker = bugtracker.tracker_registry.get_tracker('deb', branch)
+ self.assertEqual('http://bugs.debian.org/1234',
+ tracker.get_bug_url('1234'))
+
+ def test_trac_registered(self):
+ """The Trac bug tracker should be registered by default and generate
+ Trac bug page URLs when the appropriate configuration is present.
+ """
+ branch = self.make_branch('some_branch')
+ config = branch.get_config()
+ config.set_user_option('trac_foo_url', 'http://bugs.com/trac')
+ tracker = bugtracker.tracker_registry.get_tracker('foo', branch)
+ self.assertEqual('http://bugs.com/trac/ticket/1234',
+ tracker.get_bug_url('1234'))
+
+ def test_bugzilla_registered(self):
+ """The Bugzilla bug tracker should be registered by default and
+ generate Bugzilla bug page URLs when the appropriate configuration is
+ present.
+ """
+ branch = self.make_branch('some_branch')
+ config = branch.get_config()
+ config.set_user_option('bugzilla_foo_url', 'http://bugs.com')
+ tracker = bugtracker.tracker_registry.get_tracker('foo', branch)
+ self.assertEqual('http://bugs.com/show_bug.cgi?id=1234',
+ tracker.get_bug_url('1234'))
+
+
+class TestUniqueIntegerBugTracker(TestCaseWithMemoryTransport):
+
+ def test_joins_id_to_base_url(self):
+ """The URL of a bug is the base URL joined to the identifier."""
+ tracker = bugtracker.UniqueIntegerBugTracker('xxx', 'http://bugs.com')
+ self.assertEqual('http://bugs.com/1234', tracker.get_bug_url('1234'))
+
+ def test_returns_tracker_if_abbreviation_matches(self):
+ """The get() method should return an instance of the tracker if the
+ given abbreviation matches the tracker's abbreviated name.
+ """
+ tracker = bugtracker.UniqueIntegerBugTracker('xxx', 'http://bugs.com')
+ branch = self.make_branch('some_branch')
+ self.assertIs(tracker, tracker.get('xxx', branch))
+
+ def test_returns_none_if_abbreviation_doesnt_match(self):
+ """The get() method should return None if the given abbreviated name
+ doesn't match the tracker's abbreviation.
+ """
+ tracker = bugtracker.UniqueIntegerBugTracker('xxx', 'http://bugs.com')
+ branch = self.make_branch('some_branch')
+ self.assertIs(None, tracker.get('yyy', branch))
+
+ def test_doesnt_consult_branch(self):
+ """A UniqueIntegerBugTracker shouldn't consult the branch for tracker
+ information.
+ """
+ tracker = bugtracker.UniqueIntegerBugTracker('xxx', 'http://bugs.com')
+ self.assertIs(tracker, tracker.get('xxx', None))
+ self.assertIs(None, tracker.get('yyy', None))
+
+ def test_check_bug_id_only_accepts_integers(self):
+ """A UniqueIntegerBugTracker accepts integers as bug IDs."""
+ tracker = bugtracker.UniqueIntegerBugTracker('xxx', 'http://bugs.com')
+ tracker.check_bug_id('1234')
+
+ def test_check_bug_id_doesnt_accept_non_integers(self):
+ """A UniqueIntegerBugTracker rejects non-integers as bug IDs."""
+ tracker = bugtracker.UniqueIntegerBugTracker('xxx', 'http://bugs.com')
+ self.assertRaises(
+ errors.MalformedBugIdentifier, tracker.check_bug_id, 'red')
+
+
+class TestURLParametrizedIntegerBugTracker(TestCaseWithMemoryTransport):
+ """Tests for TracTracker."""
+
+ def setUp(self):
+ TestCaseWithMemoryTransport.setUp(self)
+ self.url = 'http://twistedmatrix.com/trac'
+ self.tracker = bugtracker.URLParametrizedIntegerBugTracker('some',
+ 'ticket/')
+
+ def test_get_with_unsupported_tag(self):
+ """If asked for an unrecognized or unconfigured tag, return None."""
+ branch = self.make_branch('some_branch')
+ self.assertEqual(None, self.tracker.get('lp', branch))
+ self.assertEqual(None, self.tracker.get('twisted', branch))
+
+ def test_get_with_supported_tag(self):
+ """If asked for a valid tag, return a tracker instance that can map bug
+ IDs to <base_url>/<bug_area> + <bug_id>."""
+ bugtracker.tracker_registry.register('some', self.tracker)
+ self.addCleanup(lambda: bugtracker.tracker_registry.remove('some'))
+
+ branch = self.make_branch('some_branch')
+ config = branch.get_config()
+ config.set_user_option('some_twisted_url', self.url)
+ tracker = self.tracker.get('twisted', branch)
+ self.assertEqual(
+ urlutils.join(self.url, 'ticket/') + '1234',
+ tracker.get_bug_url('1234'))
+
+ def test_get_bug_url_for_bad_bug(self):
+ """When given a bug identifier that is invalid for Trac, get_bug_url
+ should raise an error.
+ """
+ self.assertRaises(
+ errors.MalformedBugIdentifier, self.tracker.get_bug_url, 'bad')
=== modified file 'NEWS'
--- a/NEWS 2007-04-23 07:08:09 +0000
+++ b/NEWS 2007-04-23 07:50:15 +0000
@@ -5,6 +5,14 @@
* Merge directives can now be supplied as input to `merge` and `pull`,
like bundles can. (Aaron Bentley)
+ * New option ``--fixes`` to commit, which stores bug fixing annotations as
+ revision properties. Built-in support for Launchpad, Debian, Trac and
+ Bugzilla bug trackers. (Jonathan Lange, James Henstridge, Robert Collins)
+
+ * New API, ``bzrlib.bugtracker.tracker_registry``, for adding support for
+ other bug trackers to ``fixes``. (Jonathan Lange, James Henstridge,
+ Robert Collins)
+
* ``selftest`` has new short options ``-f`` and ``-1``. (Martin
Pool)
=== modified file 'bzrlib/builtins.py'
--- a/bzrlib/builtins.py 2007-04-23 04:38:50 +0000
+++ b/bzrlib/builtins.py 2007-04-23 07:50:15 +0000
@@ -31,6 +31,7 @@
import bzrlib
from bzrlib import (
branch,
+ bugtracker,
bundle,
bzrdir,
delta,
@@ -59,7 +60,7 @@
""")
from bzrlib.commands import Command, display_command
-from bzrlib.option import Option, RegistryOption
+from bzrlib.option import ListOption, Option, RegistryOption
from bzrlib.progress import DummyProgress, ProgressPhase
from bzrlib.trace import mutter, note, log_error, warning, is_quiet, info
@@ -2087,7 +2088,7 @@
# XXX: verbose currently does nothing
- _see_also = ['uncommit']
+ _see_also = ['bugs', 'uncommit']
takes_args = ['selected*']
takes_options = ['message', 'verbose',
Option('unchanged',
@@ -2099,6 +2100,9 @@
Option('strict',
help="refuse to commit if there are unknown "
"files in the working tree."),
+ ListOption('fixes', type=str,
+ help="mark a bug as being fixed by this "
+ "revision."),
Option('local',
help="perform a local only commit in a bound "
"branch. Such commits are not pushed to "
@@ -2108,8 +2112,30 @@
]
aliases = ['ci', 'checkin']
+ def _get_bug_fix_properties(self, fixes, branch):
+ properties = []
+ # Configure the properties for bug fixing attributes.
+ for fixed_bug in fixes:
+ tokens = fixed_bug.split(':')
+ if len(tokens) != 2:
+ raise errors.BzrCommandError(
+ "Invalid bug %s. Must be in the form of 'tag:id'. "
+ "Commit refused." % fixed_bug)
+ tag, bug_id = tokens
+ try:
+ bug_url = bugtracker.get_bug_url(tag, branch, bug_id)
+ except errors.UnknownBugTrackerAbbreviation:
+ raise errors.BzrCommandError(
+ 'Unrecognized bug %s. Commit refused.' % fixed_bug)
+ except errors.MalformedBugIdentifier:
+ raise errors.BzrCommandError(
+ "Invalid bug identifier for %s. Commit refused."
+ % fixed_bug)
+ properties.append('%s fixed' % bug_url)
+ return '\n'.join(properties)
+
def run(self, message=None, file=None, verbose=True, selected_list=None,
- unchanged=False, strict=False, local=False):
+ unchanged=False, strict=False, local=False, fixes=None):
from bzrlib.commit import (NullCommitReporter, ReportCommitToLog)
from bzrlib.errors import (PointlessCommit, ConflictsInTree,
StrictCommitFailed)
@@ -2121,6 +2147,9 @@
# TODO: do more checks that the commit will succeed before
# spending the user's valuable time typing a commit message.
+
+ properties = {}
+
tree, selected_list = tree_files(selected_list)
if selected_list == ['']:
# workaround - commit of root of tree should be exactly the same
@@ -2128,6 +2157,8 @@
# selected-file merge commit is not done yet
selected_list = []
+ properties['bugs'] = self._get_bug_fix_properties(fixes, tree.branch)
+
if local and not tree.branch.get_bound_location():
raise errors.LocalRequiresBoundBranch()
@@ -2149,7 +2180,7 @@
if my_message == "":
raise errors.BzrCommandError("empty commit message specified")
return my_message
-
+
if verbose:
reporter = ReportCommitToLog()
else:
@@ -2159,7 +2190,7 @@
tree.commit(message_callback=get_message,
specific_files=selected_list,
allow_pointless=unchanged, strict=strict, local=local,
- reporter=reporter)
+ reporter=reporter, revprops=properties)
except PointlessCommit:
# FIXME: This should really happen before the file is read in;
# perhaps prepare the commit; get the message; then actually commit
=== modified file 'bzrlib/errors.py'
--- a/bzrlib/errors.py 2007-04-23 00:28:58 +0000
+++ b/bzrlib/errors.py 2007-04-23 06:55:58 +0000
@@ -2087,10 +2087,28 @@
self.tag_name = tag_name
+class MalformedBugIdentifier(BzrError):
+
+ _fmt = "Did not understand bug identifier %(bug_id)s: %(reason)s"
+
+ def __init__(self, bug_id, reason):
+ self.bug_id = bug_id
+ self.reason = reason
+
+
+class UnknownBugTrackerAbbreviation(BzrError):
+
+ _fmt = ("Cannot find registered bug tracker called %(abbreviation)s "
+ "on %(branch)s")
+
+ def __init__(self, abbreviation, branch):
+ self.abbreviation = abbreviation
+ self.branch = branch
+
+
class UnexpectedSmartServerResponse(BzrError):
_fmt = "Could not understand response from smart server: %(response_tuple)r"
def __init__(self, response_tuple):
self.response_tuple = response_tuple
-
=== modified file 'bzrlib/help_topics.py'
--- a/bzrlib/help_topics.py 2007-04-23 02:58:30 +0000
+++ b/bzrlib/help_topics.py 2007-04-23 06:55:58 +0000
@@ -81,7 +81,7 @@
def _help_on_revisionspec(name):
- """"Write the summary help for all documented topics to outfile."""
+ """Write the summary help for all documented topics to outfile."""
import bzrlib.revisionspec
out = []
@@ -291,6 +291,10 @@
'Information on what a checkout is')
topic_registry.register('urlspec', _help_on_transport,
"Supported transport protocols")
+def get_bugs_topic(topic):
+ from bzrlib import bugtracker
+ return bugtracker.tracker_registry.help_topic(topic)
+topic_registry.register('bugs', get_bugs_topic, 'Bug tracker support')
class HelpTopicIndex(object):
=== modified file 'bzrlib/option.py'
--- a/bzrlib/option.py 2007-03-14 04:43:45 +0000
+++ b/bzrlib/option.py 2007-04-17 07:59:42 +0000
@@ -205,6 +205,36 @@
yield self.name, self.short_name(), argname, self.help
+class ListOption(Option):
+ """Option used to provide a list of values.
+
+ On the command line, arguments are specified by a repeated use of the
+ option. '-' is a special argument that resets the list. For example,
+ --foo=a --foo=b
+ sets the value of the 'foo' option to ['a', 'b'], and
+ --foo=a --foo=b --foo=- --foo=c
+ sets the value of the 'foo' option to ['c'].
+ """
+
+ def add_option(self, parser, short_name):
+ """Add this option to an Optparse parser."""
+ option_strings = ['--%s' % self.name]
+ if short_name is not None:
+ option_strings.append('-%s' % short_name)
+ parser.add_option(action='callback',
+ callback=self._optparse_callback,
+ type='string', metavar=self.argname.upper(),
+ help=self.help, default=[],
+ *option_strings)
+
+ def _optparse_callback(self, option, opt, value, parser):
+ values = getattr(parser.values, self.name)
+ if value == '-':
+ del values[:]
+ else:
+ values.append(self.type(value))
+
+
class RegistryOption(Option):
"""Option based on a registry
=== modified file 'bzrlib/tests/__init__.py'
--- a/bzrlib/tests/__init__.py 2007-04-23 03:41:48 +0000
+++ b/bzrlib/tests/__init__.py 2007-04-23 06:55:58 +0000
@@ -2154,6 +2154,7 @@
'bzrlib.tests.test_atomicfile',
'bzrlib.tests.test_bad_files',
'bzrlib.tests.test_branch',
+ 'bzrlib.tests.test_bugtracker',
'bzrlib.tests.test_bundle',
'bzrlib.tests.test_bzrdir',
'bzrlib.tests.test_cache_utf8',
=== modified file 'bzrlib/tests/blackbox/test_commit.py'
--- a/bzrlib/tests/blackbox/test_commit.py 2007-03-03 17:17:53 +0000
+++ b/bzrlib/tests/blackbox/test_commit.py 2007-04-17 07:59:42 +0000
@@ -358,3 +358,103 @@
# --no-strict overrides --strict
self.run_bzr('commit', '--strict', '-m', 'add b', '--no-strict',
working_dir='tree')
+
+ def test_fixes_bug_output(self):
+ """commit --fixes=lp:23452 succeeds without output."""
+ tree = self.make_branch_and_tree('tree')
+ self.build_tree(['tree/hello.txt'])
+ tree.add('hello.txt')
+ output, err = self.run_bzr(
+ 'commit', '-m', 'hello', '--fixes=lp:23452', 'tree/hello.txt')
+ self.assertEqual('', output)
+ self.assertEqual('added hello.txt\nCommitted revision 1.\n', err)
+
+ def test_fixes_bug_sets_property(self):
+ """commit --fixes=lp:234 sets the lp:234 revprop to 'fixed'."""
+ tree = self.make_branch_and_tree('tree')
+ self.build_tree(['tree/hello.txt'])
+ tree.add('hello.txt')
+ self.run_bzr(
+ 'commit', '-m', 'hello', '--fixes=lp:234', 'tree/hello.txt')
+
+ # Get the revision properties, ignoring the branch-nick property, which
+ # we don't care about for this test.
+ last_rev = tree.branch.repository.get_revision(tree.last_revision())
+ properties = dict(last_rev.properties)
+ del properties['branch-nick']
+
+ self.assertEqual({'bugs': 'https://launchpad.net/bugs/234 fixed'},
+ properties)
+
+ def test_fixes_multiple_bugs_sets_properties(self):
+ """--fixes can be used more than once to show that bugs are fixed."""
+ tree = self.make_branch_and_tree('tree')
+ self.build_tree(['tree/hello.txt'])
+ tree.add('hello.txt')
+ self.run_bzr(
+ 'commit', '-m', 'hello', '--fixes=lp:123', '--fixes=lp:235',
+ 'tree/hello.txt')
+
+ # Get the revision properties, ignoring the branch-nick property, which
+ # we don't care about for this test.
+ last_rev = tree.branch.repository.get_revision(tree.last_revision())
+ properties = dict(last_rev.properties)
+ del properties['branch-nick']
+
+ self.assertEqual(
+ {'bugs': 'https://launchpad.net/bugs/123 fixed\n'
+ 'https://launchpad.net/bugs/235 fixed'},
+ properties)
+
+ def test_fixes_bug_with_alternate_trackers(self):
+ """--fixes can be used on a properly configured branch to mark bug
+ fixes on multiple trackers.
+ """
+ tree = self.make_branch_and_tree('tree')
+ tree.branch.get_config().set_user_option(
+ 'trac_twisted_url', 'http://twistedmatrix.com/trac')
+ self.build_tree(['tree/hello.txt'])
+ tree.add('hello.txt')
+ self.run_bzr(
+ 'commit', '-m', 'hello', '--fixes=lp:123',
+ '--fixes=twisted:235', 'tree/')
+
+ # Get the revision properties, ignoring the branch-nick property, which
+ # we don't care about for this test.
+ last_rev = tree.branch.repository.get_revision(tree.last_revision())
+ properties = dict(last_rev.properties)
+ del properties['branch-nick']
+
+ self.assertEqual(
+ {'bugs': 'https://launchpad.net/bugs/123 fixed\n'
+ 'http://twistedmatrix.com/trac/ticket/235 fixed'},
+ properties)
+
+ def test_fixes_unknown_bug_prefix(self):
+ tree = self.make_branch_and_tree('tree')
+ self.build_tree(['tree/hello.txt'])
+ tree.add('hello.txt')
+ self.run_bzr_error(
+ ["Unrecognized bug %s. Commit refused." % 'xxx:123'],
+ 'commit', '-m', 'add b', '--fixes=xxx:123',
+ working_dir='tree')
+
+ def test_fixes_invalid_bug_number(self):
+ tree = self.make_branch_and_tree('tree')
+ self.build_tree(['tree/hello.txt'])
+ tree.add('hello.txt')
+ self.run_bzr_error(
+ ["Invalid bug identifier for %s. Commit refused." % 'lp:orange'],
+ 'commit', '-m', 'add b', '--fixes=lp:orange',
+ working_dir='tree')
+
+ def test_fixes_invalid_argument(self):
+ """Raise an appropriate error when the fixes argument isn't tag:id."""
+ tree = self.make_branch_and_tree('tree')
+ self.build_tree(['tree/hello.txt'])
+ tree.add('hello.txt')
+ self.run_bzr_error(
+ [r"Invalid bug orange. Must be in the form of 'tag:id'\. "
+ r"Commit refused\."],
+ 'commit', '-m', 'add b', '--fixes=orange',
+ working_dir='tree')
=== modified file 'bzrlib/tests/test_errors.py'
--- a/bzrlib/tests/test_errors.py 2007-04-23 00:28:58 +0000
+++ b/bzrlib/tests/test_errors.py 2007-04-23 06:55:58 +0000
@@ -244,6 +244,21 @@
host='ahost', port=444, msg='Unable to connect to ssh host',
orig_error='my_error')
+ def test_malformed_bug_identifier(self):
+ """Test the formatting of MalformedBugIdentifier."""
+ error = errors.MalformedBugIdentifier('bogus', 'reason for bogosity')
+ self.assertEqual(
+ "Did not understand bug identifier bogus: reason for bogosity",
+ str(error))
+
+ def test_unknown_bug_tracker_abbreviation(self):
+ """Test the formatting of UnknownBugTrackerAbbreviation."""
+ branch = self.make_branch('some_branch')
+ error = errors.UnknownBugTrackerAbbreviation('xxx', branch)
+ self.assertEqual(
+ "Cannot find registered bug tracker called xxx on %s" % branch,
+ str(error))
+
def test_unexpected_smart_server_response(self):
e = errors.UnexpectedSmartServerResponse(('not yes',))
self.assertEqual(
=== modified file 'bzrlib/tests/test_options.py'
--- a/bzrlib/tests/test_options.py 2007-03-14 04:43:45 +0000
+++ b/bzrlib/tests/test_options.py 2007-04-17 07:59:42 +0000
@@ -27,10 +27,12 @@
from bzrlib.tests import TestCase
from bzrlib.repofmt import knitrepo
+
def parse(options, args):
parser = option.get_optparser(dict((o.name, o) for o in options))
return parser.parse_args(args)
+
class OptionTests(TestCase):
"""Command-line option tests"""
@@ -38,16 +40,14 @@
"""Option parser"""
eq = self.assertEquals
eq(parse_args(cmd_commit(), ['--help']),
- ([], {'help': True}))
+ ([], {'fixes': [], 'help': True}))
eq(parse_args(cmd_commit(), ['--message=biter']),
- ([], {'message': 'biter'}))
- ## eq(parse_args(cmd_log(), '-r 500'.split()),
- ## ([], {'revision': RevisionSpec_int(500)}))
+ ([], {'fixes': [], 'message': 'biter'}))
def test_no_more_opts(self):
"""Terminated options"""
self.assertEquals(parse_args(cmd_commit(), ['--', '-file-with-dashes']),
- (['-file-with-dashes'], {}))
+ (['-file-with-dashes'], {'fixes': []}))
def test_option_help(self):
"""Options have help strings."""
@@ -112,7 +112,8 @@
def test_allow_dash(self):
"""Test that we can pass a plain '-' as an argument."""
- self.assertEqual((['-'], {}), parse_args(cmd_commit(), ['-']))
+ self.assertEqual(
+ (['-'], {'fixes': []}), parse_args(cmd_commit(), ['-']))
def parse(self, options, args):
parser = option.get_optparser(dict((o.name, o) for o in options))
@@ -231,11 +232,38 @@
('two', None, None, 'two help'),
])
-# >>> parse_args('log -r 500'.split())
-# (['log'], {'revision': [<RevisionSpec_int 500>]})
-# >>> parse_args('log -r500..600'.split())
-# (['log'], {'revision': [<RevisionSpec_int 500>, <RevisionSpec_int 600>]})
-# >>> parse_args('log -vr500..600'.split())
-# (['log'], {'verbose': True, 'revision': [<RevisionSpec_int 500>, <RevisionSpec_int 600>]})
-# >>> parse_args('log -rrevno:500..600'.split()) #the r takes an argument
-# (['log'], {'revision': [<RevisionSpec_revno revno:500>, <RevisionSpec_int 600>]})
+
+class TestListOptions(TestCase):
+ """Tests for ListOption, used to specify lists on the command-line."""
+
+ def parse(self, options, args):
+ parser = option.get_optparser(dict((o.name, o) for o in options))
+ return parser.parse_args(args)
+
+ def test_list_option(self):
+ options = [option.ListOption('hello', type=str)]
+ opts, args = self.parse(options, ['--hello=world', '--hello=sailor'])
+ self.assertEqual(['world', 'sailor'], opts.hello)
+
+ def test_list_option_no_arguments(self):
+ options = [option.ListOption('hello', type=str)]
+ opts, args = self.parse(options, [])
+ self.assertEqual([], opts.hello)
+
+ def test_list_option_with_int_type(self):
+ options = [option.ListOption('hello', type=int)]
+ opts, args = self.parse(options, ['--hello=2', '--hello=3'])
+ self.assertEqual([2, 3], opts.hello)
+
+ def test_list_option_with_int_type_can_be_reset(self):
+ options = [option.ListOption('hello', type=int)]
+ opts, args = self.parse(options, ['--hello=2', '--hello=3',
+ '--hello=-', '--hello=5'])
+ self.assertEqual([5], opts.hello)
+
+ def test_list_option_can_be_reset(self):
+ """Passing an option of '-' to a list option should reset the list."""
+ options = [option.ListOption('hello', type=str)]
+ opts, args = self.parse(
+ options, ['--hello=a', '--hello=b', '--hello=-', '--hello=c'])
+ self.assertEqual(['c'], opts.hello)
=== modified file 'doc/configuration.txt'
--- a/doc/configuration.txt 2007-03-02 12:40:45 +0000
+++ b/doc/configuration.txt 2007-04-23 01:30:35 +0000
@@ -139,7 +139,7 @@
The gnupg signature for revisions must be present and must be valid.
ignore
- Do not check gnupg signatures of revisions.
+ Do not check gnupg signatures of revisions.
check-available
(default) If gnupg signatures for revisions are present, check them.
@@ -171,7 +171,7 @@
false
This section only applies to the branch at this directory and not
- branches below it.
+ branches below it.
gpg_signing_command
-------------------
@@ -215,3 +215,34 @@
-----
If set to "True", the branch should act as a checkout, and push each commit to
the bound_location. This option is normally set by ``bind``/``unbind``.
+
+
+Bug Tracker Options
+===================
+
+These options can go into bazaar.conf, branch.conf or into a branch-specific
+configuration section in locations.conf.
+
+bugzilla_<tracker_abbreviation>_url
+-----------------------------------
+If present, the location of the Bugzilla bug tracker referred to by
+<tracker_abbreviation>. This option can then be used together with ``bzr commit
+--fixes`` to mark bugs in that tracker as being fixed by that commit. For
+example::
+
+ bugzilla_squid_url = http://www.squid-cache.org/bugs
+
+would allow ``bzr commit --fixes squid:1234`` to mark Squid's bug 1234 as
+fixed.
+
+trac_<tracker_abbrevation>_url
+------------------------------
+If present, the location of the Trac instance referred to by
+<tracker_abbreviation>. This option can then be used together with ``bzr commit
+--fixes`` to mark bugs in that tracker as being fixed by that commit. For
+example::
+
+ trac_twisted_url = http://www.twistedmatrix.com/trac
+
+would allow ``bzr commit --fixes twisted:1234`` to mark Twisted's bug 1234 as
+fixed.
More information about the bazaar-commits
mailing list