upload version 1.2.0 to PyPi
by Jeremy Audet
Hi all,
Can python-bugzilla version 1.2.0 be uploaded to PyPi? I see that it was
released on the 8th, and it is now the 13th. Please CC me in any responses
to this email, as I'm not subscribed to this email list.
Thanks for your time,
—Jeremy "Ichimonji10" Audet
8 years, 11 months
ANNOUNCE: python-bugzilla 1.2.0 released
by Cole Robinson
I'm happy to announce a new release of python-bugzilla, version 1.2.0.
python-bugzilla is a library and commandline tool for interacting with
a bugzilla instance, including querying, modifying, and creating bug reports.
The release can be downloaded from:
https://fedorahosted.org/released/python-bugzilla/python-bugzilla-1.2.0.t...
This release includes:
- Add bugzilla new/query/modify --field flag (Arun Babu Neelicattu)
- API support for ExternalBugs (Arun Babu Neelicattu, Brian Bouterse)
- Add new/modify --alias support (Adam Williamson)
- Bugzilla.logged_in now returns live state (Arun Babu Neelicattu)
- Fix getbugs API with latest Bugzilla releases
Thanks to everyone who has contributed to this release through testing,
bug reporting, submitting patches, and otherwise sending in feedback!
Thanks,
Cole
8 years, 11 months
[PATCH] Special-case bugzilla.mozilla.org
by Dustin Mitchell
---
bugzilla/__init__.py | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/bugzilla/__init__.py b/bugzilla/__init__.py
index 138bd3b..52f77bc 100644
--- a/bugzilla/__init__.py
+++ b/bugzilla/__init__.py
@@ -41,18 +41,21 @@ def _getBugzillaClassForURL(url, sslverify):
rhbz = False
bzversion = ''
c = None
if "bugzilla.redhat.com" in url:
log.info("Using RHBugzilla for URL containing bugzilla.redhat.com")
return RHBugzilla
if "bugzilla.novell.com" in url:
- log.info("Using NovellBugzilla for URL containing novell.com")
+ log.info("Using NovellBugzilla for URL containing bugzilla.novell.com")
return NovellBugzilla
+ if "bugzilla.mozilla.org" in url:
+ log.info("Using Bugzilla42 for URL containing bugzilla.mozilla.org")
+ return Bugzilla42
# Check for a Red Hat extension
try:
log.debug("Checking for Red Hat Bugzilla extension")
extensions = s.Bugzilla.extensions()
if extensions.get('extensions', {}).get('RedHat', False):
rhbz = True
except Fault:
--
2.0.5
8 years, 11 months
[PATCH] Expands ExternalTracker field support
by Brian Bouterse
From: Brian Bouterse <bmbouter(a)gmail.com>
---
HACKING | 17 +++--
bugzilla/rhbugzilla.py | 164 ++++++++++++++++++++++++++++++++++++++-----------
tests/rw_functional.py | 110 ++++++++++++++++++++++++++-------
3 files changed, 223 insertions(+), 68 deletions(-)
diff --git a/HACKING b/HACKING
index f597a97..c2015c0 100644
--- a/HACKING
+++ b/HACKING
@@ -26,17 +26,20 @@ Once you have already activated an environment, you can use the following.
# Basic unit test suite
python setup.py test
-# Functional tests
+# Read-Only Functional tests
There are more comprehensive tests that are disabled by default. Readonly
functional tests that run against several public bugzilla instances. No
login account is required:
python setup.py test --ro-functional
-And read/write functional tests. These currently run against the test
-bugzilla instance at partner-bugzilla.redhat.com, and requires a valid
-login there:
+# Read/Write Functional Tests.
+Before running rw-functional tests, make sure you have logged into bugzilla
+using. These currently run against the test bugzilla instance at
+partner-bugzilla.redhat.com, and requires a valid login there:
+
+ bugzilla-cli --bugzilla=partner-bugzilla.redhat.com --user=$USER login
python setup.py test --rw-functional
# Testing across python versions
@@ -46,12 +49,6 @@ To test all supported python versions, run tox using any of the following.
tox -- --ro-functional
tox -- --rw-functional
-Note: Before running rw-functional tests, make sure you have logged into
-bugzilla using:
- python bugzilla-cli \
- --bugzilla=partner-bugzilla.redhat.com \
- --user=$USER login
-
3. pylint and pep8
------------------
diff --git a/bugzilla/rhbugzilla.py b/bugzilla/rhbugzilla.py
index 0903ff2..7300296 100644
--- a/bugzilla/rhbugzilla.py
+++ b/bugzilla/rhbugzilla.py
@@ -133,7 +133,10 @@ class RHBugzilla(_parent):
return vals
- def add_external_tracker(self, bug_ids, type_desc, external_id):
+ def add_external_tracker(self, bug_ids, ext_bz_bug_id, ext_type_id=None,
+ ext_type_description=None, ext_type_url=None,
+ ext_status=None, ext_description=None,
+ ext_priority=None):
"""
Wrapper method to allow adding of external tracking bugs using the
ExternalBugs::WebService::add_external_bug method.
@@ -141,23 +144,87 @@ class RHBugzilla(_parent):
This is documented at
https://bugzilla.redhat.com/docs/en/html/api/extensions/ExternalBugs/lib/...
- bug_ids: A single bug id or list if bug ids to add the tracker to.
- type_desc: The external tracker description as used by Bugzilla. This
- value maps to the ext_type_description parameter of the XMLRPC
- method.
- external_id: The id as used by the external tracker. This value maps to
- the ext_bz_bug_id parameter of the XMLRPC method.
+ bug_ids: A single bug id or list of bug ids to have external trackers
+ added.
+ ext_bz_bug_id: The external bug id (ie: the bug number in the
+ external tracker).
+ ext_type_id: The external tracker id as used by Bugzilla.
+ ext_type_description: The external tracker description as used by
+ Bugzilla.
+ ext_type_url: The external tracker url as used by Bugzilla.
+ ext_status: The status of the external bug.
+ ext_description: The description of the external bug.
+ ext_priority: The priority of the external bug.
"""
- kwargs = {
+ param_dict = {'ext_bz_bug_id': ext_bz_bug_id}
+ if ext_type_id is not None:
+ param_dict['ext_type_id'] = ext_type_id
+ if ext_type_description is not None:
+ param_dict['ext_type_description'] = ext_type_description
+ if ext_type_url is not None:
+ param_dict['ext_type_url'] = ext_type_url
+ if ext_status is not None:
+ param_dict['ext_status'] = ext_status
+ if ext_description is not None:
+ param_dict['ext_description'] = ext_description
+ if ext_priority is not None:
+ param_dict['ext_priority'] = ext_priority
+ params = {
'bug_ids': self._listify(bug_ids),
- 'external_bugs': [{
- 'ext_type_description': type_desc,
- 'ext_bz_bug_id': external_id,
- }],
+ 'external_bugs': [param_dict],
}
- return self._proxy.ExternalBugs.add_external_bug(kwargs)
+ return self._proxy.ExternalBugs.add_external_bug(params)
- def remove_external_tracker(self, bug_ids, type_desc, external_ids):
+ def update_external_tracker(self, ids=None, ext_type_id=None,
+ ext_type_description=None, ext_type_url=None,
+ ext_bz_bug_id=None, bug_ids=None,
+ ext_status=None, ext_description=None,
+ ext_priority=None):
+ """
+ Wrapper method to allow adding of external tracking bugs using the
+ ExternalBugs::WebService::update_external_bug method.
+
+ This is documented at
+ https://bugzilla.redhat.com/docs/en/html/api/extensions/ExternalBugs/lib/...
+
+ ids: A single external tracker bug id or list of external tracker bug
+ ids.
+ ext_type_id: The external tracker id as used by Bugzilla.
+ ext_type_description: The external tracker description as used by
+ Bugzilla.
+ ext_type_url: The external tracker url as used by Bugzilla.
+ ext_bz_bug_id: A single external bug id or list of external bug ids
+ (ie: the bug number in the external tracker).
+ bug_ids: A single bug id or list of bug ids to have external tracker
+ info updated.
+ ext_status: The status of the external bug.
+ ext_description: The description of the external bug.
+ ext_priority: The priority of the external bug.
+ """
+ params = {}
+ if ids is not None:
+ params['ids'] = self._listify(ids)
+ if ext_type_id is not None:
+ params['ext_type_id'] = ext_type_id
+ if ext_type_description is not None:
+ params['ext_type_description'] = ext_type_description
+ if ext_type_url is not None:
+ params['ext_type_url'] = ext_type_url
+ if ext_bz_bug_id is not None:
+ params['ext_bz_bug_id'] = self._listify(ext_bz_bug_id)
+ if bug_ids is not None:
+ params['bug_ids'] = self._listify(bug_ids)
+ if ext_status is not None:
+ params['ext_status'] = ext_status
+ if ext_description is not None:
+ params['ext_description'] = ext_description
+ if ext_priority is not None:
+ params['ext_priority'] = ext_priority
+ return self._proxy.ExternalBugs.update_external_bug(params)
+
+ def remove_external_tracker(self, ids=None, ext_type_id=None,
+ ext_type_description=None, ext_type_url=None,
+ ext_bz_bug_id=None, bug_ids=None):
"""
Wrapper method to allow removal of external tracking bugs using the
ExternalBugs::WebService::remove_external_bug method.
@@ -165,20 +232,31 @@ class RHBugzilla(_parent):
This is documented at
https://bugzilla.redhat.com/docs/en/html/api/extensions/ExternalBugs/lib/...
- bug_ids: A single bug id or list if bug ids to remove the tracker from.
- type_desc: The external tracker description as used by Bugzilla. This
- value maps to the ext_type_description parameter of the XMLRPC
- method.
- external_ids: The id or list of ids as used by the external tracker.
- This value maps to the ext_bz_bug_id parameter of the XMLRPC
- method.
+ ids: A single external tracker bug id or list of external tracker bug
+ ids.
+ ext_type_id: The external tracker id as used by Bugzilla.
+ ext_type_description: The external tracker description as used by
+ Bugzilla.
+ ext_type_url: The external tracker url as used by Bugzilla.
+ ext_bz_bug_id: A single external bug id or list of external bug ids
+ (ie: the bug number in the external tracker).
+ bug_ids: A single bug id or list of bug ids to have external tracker
+ info updated.
"""
- kwargs = {
- 'bug_ids': self._listify(bug_ids),
- 'ext_type_description': type_desc,
- 'ext_bz_bug_id': self._listify(external_ids),
- }
- return self._proxy.ExternalBugs.remove_external_bug(kwargs)
+ params = {}
+ if ids is not None:
+ params['ids'] = self._listify(ids)
+ if ext_type_id is not None:
+ params['ext_type_id'] = ext_type_id
+ if ext_type_description is not None:
+ params['ext_type_description'] = ext_type_description
+ if ext_type_url is not None:
+ params['ext_type_url'] = ext_type_url
+ if ext_bz_bug_id is not None:
+ params['ext_bz_bug_id'] = self._listify(ext_bz_bug_id)
+ if bug_ids is not None:
+ params['bug_ids'] = self._listify(bug_ids)
+ return self._proxy.ExternalBugs.remove_external_bug(params)
#################
@@ -285,29 +363,41 @@ class RHBugzilla(_parent):
bug['groups'] = tmp
def build_external_tracker_boolean_query(
- self, type_desc=None, external_id=None):
+ self, ext_type_description=None, ext_type_url=None,
+ ext_bz_bug_id=None, ext_status=None):
"""
Helper method to build a boolean query to find bugs that contain an
- external tracker with the 'type_desc' and 'external_id' combination.
+ external tracker.
All parameters that are None will be ignored when building the query.
- type_desc: The external tracker description as used by Bugzilla. This
- value maps to the external_bugzilla.description field.
- external_ids: The id as used by the external tracker. This value maps
- to the ext_bz_bug_map.ext_bz_bug_id field.
+ ext_type_description: The external tracker description as used by
+ Bugzilla.
+ ext_type_url: The external tracker url as used by Bugzilla.
+ ext_bz_bug_id: The external bug id (ie: the bug number in the
+ external tracker).
+ ext_status: The status of the external bug.
"""
parts = []
- if type_desc is not None:
+ if ext_type_description is not None:
+ parts.append(
+ 'external_bugzilla.description-equals-{0:s}'.format(
+ ext_type_description))
+
+ if ext_type_url is not None:
parts.append(
- 'external_bugzilla.description-equals-{0:s}'.format(type_desc))
+ 'external_bugzilla.url-equals-{0:s}'.format(ext_type_url))
- if external_id is not None:
- id_str = str(external_id)
+ if ext_bz_bug_id is not None:
+ id_str = str(ext_bz_bug_id)
parts.append(
'ext_bz_bug_map.ext_bz_bug_id-equals-{0:s}'.format(id_str))
+ if ext_status is not None:
+ parts.append(
+ 'ext_bz_bug_map.ext_status-equals-{0:s}'.format(ext_status))
+
return ' & '.join(parts)
def build_query(self, **kwargs):
diff --git a/tests/rw_functional.py b/tests/rw_functional.py
index fd89613..480835a 100644
--- a/tests/rw_functional.py
+++ b/tests/rw_functional.py
@@ -773,35 +773,103 @@ class RHPartnerTest(BaseTest):
bug.refresh()
self.assertEqual(bug.sub_components, {})
- def _test14ExternalTrackersQuery(self, bz, ext_type_desc, ext_bug_id):
- boolean_query = bz.build_external_tracker_boolean_query(
- ext_type_desc, ext_bug_id)
- query = bz.build_query(
- boolean_query=boolean_query, include_fields=['id'])
- return [bug.bug_id for bug in bz.query(query)]
+ def _deleteAllExistingExternalTrackers(self, bugid):
+ bz = self.bzclass(url=self.url, cookiefile=cf, tokenfile=tf)
+ ids = [bug['id'] for bug in bz.getbug(bugid).external_bugs]
+ if ids != []:
+ bz.remove_external_tracker(ids=ids)
def test14ExternalTrackersQuery(self):
bz = self.bzclass(url=self.url, cookiefile=cf, tokenfile=tf)
- ext_type_desc = "FreeDesktop.org"
- ext_bug_id = 64714
+ bugid = 461686
+ ext_bug_id = 1234659
- # Closed RH Bugzilla bug with external tracker
- bugid = 973374
- assert bugid in \
- self._test14ExternalTrackersQuery(bz, ext_type_desc, ext_bug_id)
+ # Delete any existing external trackers to get to a known state
+ self._deleteAllExistingExternalTrackers(bugid)
+
+ # test adding tracker
+ kwargs = {
+ 'ext_type_url': 'http://bugzilla.mozilla.org',
+ 'ext_type_description': 'Mozilla Foundation',
+ 'ext_status': 'Original Status',
+ }
- def test14ExternalTrackersAddRemove(self):
+ # Add a tracker that we can query for
+ bz.add_external_tracker(bugid, ext_bug_id, **kwargs)
+
+ kwargs['ext_bz_bug_id'] = ext_bug_id
+
+ boolean_query = bz.build_external_tracker_boolean_query(
+ ext_bz_bug_id=ext_bug_id)
+ query_results = bz.query(bz.build_query(boolean_query=boolean_query))
+ if len(query_results) != 1:
+ raise AssertionError(
+ 'external tracker query by bug id should return 1 result.')
+ for key, value in kwargs.iteritems():
+ assert kwargs[key] == value
+
+ boolean_query = bz.build_external_tracker_boolean_query(
+ ext_type_description=kwargs['ext_type_description'])
+ query_results = bz.query(bz.build_query(boolean_query=boolean_query))
+ assert bugid in [qr.id for qr in query_results]
+
+ boolean_query = bz.build_external_tracker_boolean_query(
+ ext_status=kwargs['ext_status'])
+ query_results = bz.query(bz.build_query(boolean_query=boolean_query))
+ if len(query_results) != 1:
+ raise AssertionError(
+ 'external tracker query by status should return 1 result.')
+ for key, value in kwargs.iteritems():
+ assert kwargs[key] == value
+
+ boolean_query = bz.build_external_tracker_boolean_query(
+ ext_type_url=kwargs['ext_type_url'])
+ query_results = bz.query(bz.build_query(boolean_query=boolean_query))
+ assert bugid in [qr.id for qr in query_results]
+
+ def test14ExternalTrackersAddUpdateRemoveQuery(self):
bz = self.bzclass(url=self.url, cookiefile=cf, tokenfile=tf)
- ext_type_desc = "Mozilla Foundation"
- ext_bug_id = 380489
bugid = 461686
+ ext_bug_id = 380489
+
+ # Delete any existing external trackers to get to a known state
+ self._deleteAllExistingExternalTrackers(bugid)
# test adding tracker
- bz.add_external_tracker(bugid, ext_type_desc, ext_bug_id)
- assert bugid in \
- self._test14ExternalTrackersQuery(bz, ext_type_desc, ext_bug_id)
+ kwargs = {
+ 'ext_type_id': 6,
+ 'ext_type_url': 'http://bugzilla.mozilla.org',
+ 'ext_type_description': 'Mozilla Foundation',
+ 'ext_status': 'Original Status',
+ 'ext_description': 'the description',
+ 'ext_priority': 'the priority'
+ }
+ bz.add_external_tracker(bugid, ext_bug_id, **kwargs)
+ added_bug = bz.getbug(bugid).external_bugs[0]
+ assert added_bug['type']['id'] == kwargs['ext_type_id']
+ assert added_bug['type']['url'] == kwargs['ext_type_url']
+ assert added_bug['type']['description'] == kwargs['ext_type_description']
+ assert added_bug['ext_status'] == kwargs['ext_status']
+ assert added_bug['ext_description'] == kwargs['ext_description']
+ assert added_bug['ext_priority'] == kwargs['ext_priority']
+
+ # test updating status, description, and priority by id
+ kwargs = {
+ 'ids': bz.getbug(bugid).external_bugs[0]['id'],
+ 'ext_status': 'New Status',
+ 'ext_description': 'New Description',
+ 'ext_priority': 'New Priority'
+ }
+ bz.update_external_tracker(**kwargs)
+ updated_bug = bz.getbug(bugid).external_bugs[0]
+ assert updated_bug['ext_bz_bug_id'] == str(ext_bug_id)
+ assert updated_bug['ext_status'] == kwargs['ext_status']
+ assert updated_bug['ext_description'] == kwargs['ext_description']
+ assert updated_bug['ext_priority'] == kwargs['ext_priority']
# test removing tracker
- bz.remove_external_tracker(bugid, ext_type_desc, ext_bug_id)
- assert bugid not in \
- self._test14ExternalTrackersQuery(bz, ext_type_desc, ext_bug_id)
+ ids = [bug['id'] for bug in bz.getbug(bugid).external_bugs]
+ assert len(ids) == 1
+ bz.remove_external_tracker(ids=ids)
+ ids = [bug['id'] for bug in bz.getbug(bugid).external_bugs]
+ assert len(ids) == 0
--
1.9.3
8 years, 12 months
Expanding Support for ExternalBugs
by Brian Bouterse
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
I'm using the ExternalBugs support in python-bugzilla from checkout. I
can create and remove entries so that is good. Mainly I'm using the
limited support from [0] which is a great start, but I need to set
more of the attributes described here [1].
Specifically I want to do two things:
1) Adjust the signature of add_external_bug and remove_external_bug to
use keyword args to support all fields
2) Add a new update_external_bug method which accepts kwargs similar
to how add and remove do
I think I see how to do it for my own purposes. My question is how
could I contribute a patch back to be included in future
python-bugzilla releases? I couldn't find any documented process, so
how do I contribute back?
[0]:
https://git.fedorahosted.org/cgit/python-bugzilla.git/commit/?id=8edea7ec...
[1]:
https://bugzilla.redhat.com/docs/en/html/api/extensions/ExternalBugs/lib/...
- -Brian
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
iQEcBAEBAgAGBQJU/19MAAoJEK48cdELyEfyf2oH/RpvWhch+ISSmzzNRj2NGQM7
ce97AYl2mv3tI03fXGajdYNgg8SQjARlVLGcONL3TIljQyAIDb7qluSZkqn26wx/
85PH4VamugOmtFRi0u/DQK1IoG4Okud3+l+gDNpSZShyDmGMSp8/M6OGJ5kh/ToR
dyY3Tn9YXnk+mkZqpKp3/homSARSpHMdTdjC+rqhAULV8XzA49YyJhrj32cIeYcb
KpK4ugnjV2GBAtl1m5q5aX4l6fDQ+pqTP+wws1ZrYVje3/5b68fsQYrMhM6bQAY4
/p3QoM7DBWP8jJeQxhDxqsIYI7VGNo6/pd9JTy3WcxZg29liq9tkRbCYxOYHK28=
=Wrvf
-----END PGP SIGNATURE-----
8 years, 12 months