Hello community,
here is the log from the commit of package python-osc-tiny for
openSUSE:Leap:15.2 checked in at 2020-03-29 14:56:31
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Leap:15.2/python-osc-tiny (Old)
and /work/SRC/openSUSE:Leap:15.2/.python-osc-tiny.new.3160 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-osc-tiny"
Sun Mar 29 14:56:31 2020 rev:2 rq:789311 version:0.2.2
Changes:
--------
--- /work/SRC/openSUSE:Leap:15.2/python-osc-tiny/python-osc-tiny.changes
2020-02-16 18:29:30.262755189 +0100
+++
/work/SRC/openSUSE:Leap:15.2/.python-osc-tiny.new.3160/python-osc-tiny.changes
2020-03-29 14:56:32.239197390 +0200
@@ -1,0 +2,9 @@
+Fri Mar 27 13:45:55 UTC 2020 - [email protected]
+
+- version update to 0.2.2
+ * Added the `issues` extension
+ * Give (read only) access to issues and issue trackers known to BuildService
+ * Set version to 0.2.2
+ * Dirty hacks for Python2 compatibility
+
+-------------------------------------------------------------------
Old:
----
osc-tiny-0.2.1.tar.gz
New:
----
osc-tiny-0.2.2.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-osc-tiny.spec ++++++
--- /var/tmp/diff_new_pack.GYiO2A/_old 2020-03-29 14:56:33.495198369 +0200
+++ /var/tmp/diff_new_pack.GYiO2A/_new 2020-03-29 14:56:33.539198403 +0200
@@ -18,7 +18,7 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
Name: python-osc-tiny
-Version: 0.2.1
+Version: 0.2.2
Release: 0
Summary: Client API for openSUSE BuildService
License: MIT
@@ -27,6 +27,7 @@
Source:
https://files.pythonhosted.org/packages/source/o/osc-tiny/osc-tiny-%{version}.tar.gz
BuildRequires: %{python_module devel}
BuildRequires: %{python_module lxml}
+BuildRequires: %{python_module pytest}
BuildRequires: %{python_module python-dateutil}
BuildRequires: %{python_module pytz}
BuildRequires: %{python_module requests}
@@ -41,11 +42,11 @@
Requires: python-python-dateutil
Requires: python-pytz
Requires: python-requests
+Requires: python-responses
Requires: python-six
BuildArch: noarch
%ifpython2
Requires: python-mock
-Requires: python-unittest2
%endif
%python_subpackages
@@ -66,7 +67,7 @@
%python_build
%check
-%python_exec -m unittest discover -v
+%pytest
%install
%python_install
++++++ osc-tiny-0.2.1.tar.gz -> osc-tiny-0.2.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/osc-tiny-0.2.1/PKG-INFO new/osc-tiny-0.2.2/PKG-INFO
--- old/osc-tiny-0.2.1/PKG-INFO 2020-01-10 09:32:27.000000000 +0100
+++ new/osc-tiny-0.2.2/PKG-INFO 2020-02-04 09:22:19.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: osc-tiny
-Version: 0.2.1
+Version: 0.2.2
Summary: Client API for openSUSE BuildService
Home-page: http://github.com/crazyscientist/osc-tiny
Author: Andreas Hasenkopf
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/osc-tiny-0.2.1/osc_tiny.egg-info/PKG-INFO
new/osc-tiny-0.2.2/osc_tiny.egg-info/PKG-INFO
--- old/osc-tiny-0.2.1/osc_tiny.egg-info/PKG-INFO 2020-01-10
09:32:27.000000000 +0100
+++ new/osc-tiny-0.2.2/osc_tiny.egg-info/PKG-INFO 2020-02-04
09:22:19.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: osc-tiny
-Version: 0.2.1
+Version: 0.2.2
Summary: Client API for openSUSE BuildService
Home-page: http://github.com/crazyscientist/osc-tiny
Author: Andreas Hasenkopf
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/osc-tiny-0.2.1/osc_tiny.egg-info/SOURCES.txt
new/osc-tiny-0.2.2/osc_tiny.egg-info/SOURCES.txt
--- old/osc-tiny-0.2.1/osc_tiny.egg-info/SOURCES.txt 2020-01-10
09:32:27.000000000 +0100
+++ new/osc-tiny-0.2.2/osc_tiny.egg-info/SOURCES.txt 2020-02-04
09:22:19.000000000 +0100
@@ -17,6 +17,7 @@
osctiny/extensions/bs_requests.py
osctiny/extensions/buildresults.py
osctiny/extensions/comments.py
+osctiny/extensions/issues.py
osctiny/extensions/packages.py
osctiny/extensions/projects.py
osctiny/extensions/search.py
@@ -28,6 +29,7 @@
osctiny/tests/test_cache.py
osctiny/tests/test_comments.py
osctiny/tests/test_datadir.py
+osctiny/tests/test_issues.py
osctiny/tests/test_packages.py
osctiny/tests/test_projects.py
osctiny/tests/test_requests.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/osc-tiny-0.2.1/osctiny/__init__.py
new/osc-tiny-0.2.2/osctiny/__init__.py
--- old/osc-tiny-0.2.1/osctiny/__init__.py 2020-01-10 09:32:12.000000000
+0100
+++ new/osc-tiny-0.2.2/osctiny/__init__.py 2020-02-04 09:21:59.000000000
+0100
@@ -6,4 +6,4 @@
__all__ = ['Osc', 'bs_requests', 'buildresults', 'comments', 'packages',
'projects', 'search', 'users']
-__version__ = "0.2.1"
+__version__ = "0.2.2"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/osc-tiny-0.2.1/osctiny/extensions/issues.py
new/osc-tiny-0.2.2/osctiny/extensions/issues.py
--- old/osc-tiny-0.2.1/osctiny/extensions/issues.py 1970-01-01
01:00:00.000000000 +0100
+++ new/osc-tiny-0.2.2/osctiny/extensions/issues.py 2020-02-04
09:21:59.000000000 +0100
@@ -0,0 +1,89 @@
+"""
+Issues extension
+------------------
+"""
+from __future__ import unicode_literals
+import os
+
+from six.moves.urllib.parse import urljoin
+from six import text_type
+
+from ..utils.base import ExtensionBase
+
+try:
+ from functools import lru_cache
+except ImportError:
+ # Whoever had the grandiose idea to backport this to Python2?
+ # pylint: disable=unused-argument, missing-function-docstring
+ def lru_cache(*args, **kwargs):
+ def wrapper(fun):
+ return fun
+
+ return wrapper
+
+
+class Issue(ExtensionBase):
+ """
+ The BuildService issue(-tracker) API is accessible through this object.
+
+ .. versionadded:: 0.2.2
+ """
+ base_path = "/issue_trackers/"
+
+ @staticmethod
+ def _validate(value):
+ return text_type(value)
+
+ @lru_cache(maxsize=1)
+ def get_trackers(self):
+ """
+ Get all issue trackers with data
+ """
+ response = self.osc.request(
+ url=urljoin(self.osc.url, self.base_path),
+ method="GET",
+ )
+ return self.osc.get_objectified_xml(response)
+
+ def get_tracker(self, name):
+ """
+ Get information on one issue tracker
+
+ :param str name: issue tracker name
+ :return: Objectified XML element
+ :rtype: lxml.objectify.ObjectifiedElement
+ """
+ response = self.osc.request(
+ url=urljoin(self.osc.url, os.path.join(self.base_path, name)),
+ method="GET",
+ )
+ return self.osc.get_objectified_xml(response)
+
+ def get(self, tracker, name, force_update=None):
+ """
+ Get details for an issue
+
+ :param str tracker: issue tracker name
+ :param str name: issue name
+ :param force_update: If ``True``, BuildService will update the issue
+ details internally prior to returning the response
+ :return: Objectified XML element
+ :rtype: lxml.objectify.ObjectifiedElement
+ """
+ tracker, name = [self._validate(x) for x in [tracker, name]]
+ trackers = self.get_trackers()
+ can_get_details = trackers.xpath(
+ "issue-tracker/name[text()='{}']/../enable-fetch".format(tracker))
+
+ response = self.osc.request(
+ url=urljoin(self.osc.url,
+ os.path.join(self.base_path, tracker, "issues", name)),
+ method="GET",
+ params={'force_update': force_update}
+ )
+
+ if not force_update and can_get_details and all(can_get_details):
+ if not getattr(getattr(response, "summary", None), "text", None):
+ return self.get(tracker, name, force_update=True)
+
+ return self.osc.get_objectified_xml(response)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/osc-tiny-0.2.1/osctiny/extensions/search.py
new/osc-tiny-0.2.2/osctiny/extensions/search.py
--- old/osc-tiny-0.2.1/osctiny/extensions/search.py 2020-01-10
09:32:12.000000000 +0100
+++ new/osc-tiny-0.2.2/osctiny/extensions/search.py 2020-02-04
09:21:59.000000000 +0100
@@ -26,7 +26,16 @@
.. code:: python
- Osc.search.request("starts-with(@name,'SUSE:Maintenance')")
+ Osc.search.project("starts-with(@name,'SUSE:Maintenance')")
+
+ .. note:: Pagination
+
+ Search results can be paginated using ``limit`` and ``offset``,
e.g.
+
+ .. code:: python
+
+ Osc.search.project("starts-with(@name,'SUSE:Maintenance')",
+ limit=10, offset=30)
:param path: object type / relative URL
:param xpath: XPath expression to filter results
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/osc-tiny-0.2.1/osctiny/osc.py
new/osc-tiny-0.2.2/osctiny/osc.py
--- old/osc-tiny-0.2.1/osctiny/osc.py 2020-01-10 09:32:12.000000000 +0100
+++ new/osc-tiny-0.2.2/osctiny/osc.py 2020-02-04 09:21:59.000000000 +0100
@@ -19,6 +19,7 @@
from .extensions.buildresults import Build
from .extensions.comments import Comment
+from .extensions.issues import Issue
from .extensions.packages import Package
from .extensions.projects import Project
from .extensions.bs_requests import Request as BsRequest
@@ -79,6 +80,9 @@
.. versionadded:: 0.1.8
The ``comments`` extension
+ .. versionadded:: 0.2.2
+ The `issues`` extension
+
.. _SSL Cert Verification:
http://docs.python-requests.org/en/master/user/advanced/
#ssl-cert-verification
@@ -107,6 +111,7 @@
self.build = Build(osc_obj=self)
self.comments = Comment(osc_obj=self)
self.groups = Group(osc_obj=self)
+ self.issues = Issue(osc_obj=self)
self.packages = Package(osc_obj=self)
self.projects = Project(osc_obj=self)
self.requests = BsRequest(osc_obj=self)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/osc-tiny-0.2.1/osctiny/tests/base.py
new/osc-tiny-0.2.2/osctiny/tests/base.py
--- old/osc-tiny-0.2.1/osctiny/tests/base.py 2020-01-10 09:32:12.000000000
+0100
+++ new/osc-tiny-0.2.2/osctiny/tests/base.py 2020-02-04 09:21:59.000000000
+0100
@@ -8,7 +8,7 @@
from io import IOBase
import responses
-from six.moves.urllib_parse import parse_qs
+from six.moves.urllib_parse import parse_qs, urlparse
from osctiny import Osc
@@ -42,6 +42,8 @@
if hasattr(body, "decode"):
body = body.decode('utf-8')
params = parse_qs(body) if body else {}
+ parsed = urlparse(request.url)
+ params.update(parse_qs(parsed.query))
headers = {
"Cache-Control": "max-age=0, private, must-revalidate",
"Connection": "Keep-Alive",
@@ -65,6 +67,8 @@
username="foobar",
password="helloworld",
)
+ cls.osc.default_connection_retries = 0
+ cls.osc.default_retry_timeout = 0
@staticmethod
def mock_request(**kwargs):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/osc-tiny-0.2.1/osctiny/tests/test_issues.py
new/osc-tiny-0.2.2/osctiny/tests/test_issues.py
--- old/osc-tiny-0.2.1/osctiny/tests/test_issues.py 1970-01-01
01:00:00.000000000 +0100
+++ new/osc-tiny-0.2.2/osctiny/tests/test_issues.py 2020-02-04
09:21:59.000000000 +0100
@@ -0,0 +1,152 @@
+# -*- coding: utf8 -*-
+from __future__ import unicode_literals
+import re
+from sys import version_info
+
+from lxml.objectify import ObjectifiedElement
+from requests.exceptions import HTTPError
+import responses
+
+from .base import OscTest, CallbackFactory
+
+
+class TestIssue(OscTest):
+ def setUp(self):
+ super(TestIssue, self).setUpClass()
+
+ def callback(headers, params, request):
+ status, body = 200, """
+ <issue-trackers>
+ <issue-tracker>
+ <name>boost</name>
+ <kind>trac</kind>
+ <description>Boost Trac</description>
+ <url>https://svn.boost.org/trac/boost/</url>
+
<show-url>https://svn.boost.org/trac/boost/ticket/@@@</show-url>
+ <regex>boost#(\d+)</regex>
+ <label>boost#@@@</label>
+ <enable-fetch>false</enable-fetch>
+ </issue-tracker>
+ <issue-tracker>
+ <name>bco</name>
+ <kind>bugzilla</kind>
+ <description>Clutter Project Bugzilla</description>
+ <url>http://bugzilla.clutter-project.org/</url>
+
<show-url>http://bugzilla.clutter-project.org/show_bug.cgi?id=@@@</show-url>
+ <regex>bco#(\d+)</regex>
+ <label>bco#@@@</label>
+ <enable-fetch>false</enable-fetch>
+ </issue-tracker>
+ <issue-tracker>
+ <name>bnc</name>
+ <kind>bugzilla</kind>
+ <description>SUSE Bugzilla</description>
+ <url>https://apibugzilla.novell.com/</url>
+
<show-url>https://bugzilla.suse.com/show_bug.cgi?id=@@@</show-url>
+ <regex>(?:bnc|BNC|bsc|BSC|boo|BOO)\s*[#:]\s*(\d+)</regex>
+ <label>bsc#@@@</label>
+ <enable-fetch>true</enable-fetch>
+ </issue-tracker>
+ </issue-trackers>"""
+ return status, headers, body
+
+ self.mock_request(
+ method=responses.GET,
+ url=re.compile(self.osc.url + '/issue_trackers/?$'),
+ callback=CallbackFactory(callback)
+ )
+
+ @responses.activate
+ def test_get_trackers(self):
+ response = self.osc.issues.get_trackers()
+ self.assertTrue(isinstance(response, ObjectifiedElement))
+ self.assertEqual(response.countchildren(), 3)
+ self.assertEqual(
+ {x.text for x in response.xpath("issue-tracker/name")},
+ {'boost', 'bco', 'bnc'}
+ )
+
+ @responses.activate
+ def test_get_tracker(self):
+ def callback(headers, params, request):
+ if re.search("bnc/?$", request.url):
+ status, body = 200, """
+ <issue-tracker>
+ <name>bnc</name>
+ <kind>bugzilla</kind>
+ <description>SUSE Bugzilla</description>
+ <url>https://apibugzilla.novell.com/</url>
+
<show-url>https://bugzilla.suse.com/show_bug.cgi?id=@@@</show-url>
+ <regex>(?:bnc|BNC|bsc|BSC|boo|BOO)\s*[#:]\s*(\d+)</regex>
+ <label>bsc#@@@</label>
+ <enable-fetch>true</enable-fetch>
+ </issue-tracker>"""
+ else:
+ status, body = 404, """
+ <status code="not_found">
+ <summary>Unable to find issue tracker 'bnc2'</summary>
+ </status>"""
+ return status, headers, body
+
+ self.mock_request(
+ method=responses.GET,
+ url=re.compile(self.osc.url + r'/issue_trackers/[^/]+/?$'),
+ callback=CallbackFactory(callback)
+ )
+
+ with self.subTest("Valid tracker"):
+ response = self.osc.issues.get_tracker("bnc")
+ self.assertEqual(response.name.text, "bnc")
+
+ with self.subTest("Invalid tracker"):
+ self.assertRaises(HTTPError, self.osc.issues.get_tracker, "nemo")
+
+ @responses.activate
+ def test_get(self):
+ def callback(headers, params, request):
+ if params.get("force_update", ["0"]) == ["1"]:
+ status, body = 200, u"""
+ <issue>
+ <created_at>2020-01-04 14:12:00 UTC</created_at>
+ <name>1160086</name>
+ <tracker>bnc</tracker>
+ <label>bsc#1160086</label>
+ <url>https://bugzilla.suse.com/show_bug.cgi?id=1160086</url>
+ <state>OPEN</state>
+ <summary>føø bar</summary>
+ <owner>
+ <login>nemo</login>
+ <email>[email protected]</email>
+ <realname>Caþtæn Nemo</realname>
+ </owner>
+ </issue>"""
+ else:
+ status, body = 200, """
+ <issue>
+ <created_at>2020-01-04 14:12:00 UTC</created_at>
+ <name>1160086</name>
+ <tracker>bnc</tracker>
+ <label>bsc#1160086</label>
+ <url>https://bugzilla.suse.com/show_bug.cgi?id=1160086</url>
+ </issue>"""
+ return status, headers, body
+
+ self.mock_request(
+ method=responses.GET,
+ url=re.compile(self.osc.url +
+ r'/issue_trackers/bnc/issues/1160086/?.*'),
+ callback=CallbackFactory(callback)
+ )
+
+ with self.subTest("Manual force update"):
+ response = self.osc.issues.get("bnc", 1160086, True)
+ self.assertTrue(hasattr(response, "summary"))
+ self.assertEqual(len(responses.calls), 2)
+
+ with self.subTest("Manual force update"):
+ response = self.osc.issues.get("bnc", 1160086, False)
+ self.assertTrue(hasattr(response, "summary"))
+ # to whom it may concern: `responses.calls` does not get reset
+ # between sub-tests
+ self.assertEqual(len(responses.calls),
+ 6 if version_info.major < 3 else 4)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/osc-tiny-0.2.1/setup.py new/osc-tiny-0.2.2/setup.py
--- old/osc-tiny-0.2.1/setup.py 2020-01-10 09:32:12.000000000 +0100
+++ new/osc-tiny-0.2.2/setup.py 2020-02-04 09:21:59.000000000 +0100
@@ -22,7 +22,7 @@
setup(
name='osc-tiny',
- version='0.2.1',
+ version='0.2.2',
description='Client API for openSUSE BuildService',
long_description=long_description,
long_description_content_type="text/markdown",