Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-python-jenkins for openSUSE:Factory checked in at 2023-04-17 17:41:20 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-python-jenkins (Old) and /work/SRC/openSUSE:Factory/.python-python-jenkins.new.2023 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-python-jenkins" Mon Apr 17 17:41:20 2023 rev:13 rq:1079857 version:1.8.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-python-jenkins/python-python-jenkins.changes 2022-05-04 15:11:26.472193464 +0200 +++ /work/SRC/openSUSE:Factory/.python-python-jenkins.new.2023/python-python-jenkins.changes 2023-04-17 17:41:26.986274308 +0200 @@ -1,0 +2,11 @@ +Mon Apr 17 08:05:56 UTC 2023 - Steve Kowalik <steven.kowa...@suse.com> + +- Update to 1.8.0: + * Add retrieval of stages of artifacts + * Switch links to opendev.org + * Allow build number to be a string + * Use fullname in get_job_info_regex +- Add patch use-parts-of-legacy-version.patch: + * Use underpining parts of LegacyVersion pre-removal. + +------------------------------------------------------------------- Old: ---- python-jenkins-1.7.0.tar.gz New: ---- python-jenkins-1.8.0.tar.gz use-parts-of-legacy-version.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-python-jenkins.spec ++++++ --- /var/tmp/diff_new_pack.FuQzQJ/_old 2023-04-17 17:41:27.522277440 +0200 +++ /var/tmp/diff_new_pack.FuQzQJ/_new 2023-04-17 17:41:27.530277487 +0200 @@ -1,7 +1,7 @@ # # spec file for package python-python-jenkins # -# Copyright (c) 2022 SUSE LLC +# Copyright (c) 2023 SUSE LLC # Copyright (c) 2014 Thomas Bechtold <thomasbecht...@jpberlin.de> # # All modifications and additions to the file contributed by third parties @@ -17,30 +17,34 @@ # -%{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-python-jenkins -Version: 1.7.0 +Version: 1.8.0 Release: 0 Summary: Python bindings for the remote Jenkins API License: BSD-3-Clause -Group: Development/Languages/Python URL: https://opendev.org/jjb/python-jenkins Source: https://files.pythonhosted.org/packages/source/p/python-jenkins/python-jenkins-%{version}.tar.gz # https://bugs.launchpad.net/python-jenkins/+bug/1971524 Patch0: python-python-jenkins-no-mock.patch +# PATCH-FIX-OPENSUSE Upstream are arguing about version parsing, use the +# underlying parts of LegacyVersion from packaging pre-removal +Patch1: use-parts-of-legacy-version.patch BuildRequires: %{python_module cmd2} BuildRequires: %{python_module multi_key_dict} BuildRequires: %{python_module pbr >= 0.8.2} +BuildRequires: %{python_module pip} BuildRequires: %{python_module requests-mock >= 1.4} BuildRequires: %{python_module requests} BuildRequires: %{python_module testscenarios} +BuildRequires: %{python_module wheel} +BuildRequires: fdupes BuildRequires: openssl-devel BuildRequires: pkgconfig BuildRequires: python-rpm-macros BuildRequires: pkgconfig(krb5-gssapi) Requires: python-multi_key_dict +Requires: python-pbr Requires: python-requests -Requires: python-setuptools Requires: python-six >= 1.3.0 Provides: python-jenkins = %{version} Obsoletes: python-jenkins < %{version} @@ -57,18 +61,22 @@ %prep %autosetup -p1 -n python-jenkins-%{version} +sed -i '1{\@^#!%{_bindir}/env python@d}' jenkins/__init__.py + %build -%python_build +%pyproject_wheel %install -%python_install +%pyproject_install +%python_expand %fdupes %{buildroot}%{$python_sitelib} %check -%pyunittest tests/*.py +%pyunittest discover -v tests %files %{python_files} %license COPYING %doc README.rst -%{python_sitelib}/* +%{python_sitelib}/jenkins +%{python_sitelib}/python_jenkins-%{version}*-info %changelog ++++++ python-jenkins-1.7.0.tar.gz -> python-jenkins-1.8.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-jenkins-1.7.0/.zuul.yaml new/python-jenkins-1.8.0/.zuul.yaml --- old/python-jenkins-1.7.0/.zuul.yaml 2020-03-04 04:06:09.000000000 +0100 +++ new/python-jenkins-1.8.0/.zuul.yaml 2023-03-24 15:50:48.000000000 +0100 @@ -18,8 +18,6 @@ jobs: - openstack-tox-linters - openstack-tox-py27 - - openstack-tox-pypy: - nodeset: ubuntu-bionic - jjb-tox-cross-jenkins-job-builder gate: jobs: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-jenkins-1.7.0/AUTHORS new/python-jenkins-1.8.0/AUTHORS --- old/python-jenkins-1.7.0/AUTHORS 2020-03-04 04:07:27.000000000 +0100 +++ new/python-jenkins-1.8.0/AUTHORS 2023-03-24 15:51:12.000000000 +0100 @@ -26,6 +26,7 @@ Emilien Macchi <emil...@redhat.com> Frank Lichtenheld <frank.lichtenh...@sophos.com> Guido Günther <a...@sigxcpu.org> +Guillaume DeMengin <gdemen...@gmail.com> JP Sullivan <jonps...@cisco.com> James E. Blair <cor...@gnu.org> James E. Blair <jebl...@hp.com> @@ -38,8 +39,10 @@ Jeremy Stanley <fu...@yuggoth.org> Jerome Hourquebie <jhour...@cisco.com> Jerry Zhao <xyzje...@gmail.com> +Jim Wisniewski <wis...@gmail.com> Jonathan Perret <jonat...@ut7.fr> K Jonathan Harker <jhar...@suse.com> +Kazuhiro Suzuki <ksauzz...@gmail.com> Ken Conley k...@willowgarage.com <> Ken Dreyer <ktdre...@ktdreyer.com> Ken Rumer <kenru...@gmail.com> @@ -49,7 +52,9 @@ Lukas Vacek <lucas.va...@gmail.com> Marc Abramowitz <m...@marc-abramowitz.com> Marc Abramowitz <ma...@surveymonkey.com> +Marcin CieÅlak <sa...@saper.info> Marcos Diez <mar...@unitron.com.br> +Michael Still <mi...@stillhq.com> Monty Taylor <mord...@inaugust.com> Nickolas Pohilets <pohil...@gmail.com> OndÅej Nový <ondrej.n...@firma.seznam.cz> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-jenkins-1.7.0/ChangeLog new/python-jenkins-1.8.0/ChangeLog --- old/python-jenkins-1.7.0/ChangeLog 2020-03-04 04:07:27.000000000 +0100 +++ new/python-jenkins-1.8.0/ChangeLog 2023-03-24 15:51:12.000000000 +0100 @@ -1,6 +1,21 @@ CHANGES ======= +1.8.0 +----- + +* Fix CI tests +* Handle new master naming in Jenkins post v2.307 +* Use fullname in get\_job\_info\_regex + +1.8.0.0a0 +--------- + +* Allow build number to be a string +* Switch links for contributors to opendev.org or launchpad +* Add retrieval of stages and artifacts +* Blacklist stestr 3.0.0 and drop pypy + 1.7.0 ----- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-jenkins-1.7.0/PKG-INFO new/python-jenkins-1.8.0/PKG-INFO --- old/python-jenkins-1.7.0/PKG-INFO 2020-03-04 04:07:28.000000000 +0100 +++ new/python-jenkins-1.8.0/PKG-INFO 2023-03-24 15:51:12.177868000 +0100 @@ -1,13 +1,14 @@ Metadata-Version: 1.2 Name: python-jenkins -Version: 1.7.0 +Version: 1.8.0 Summary: Python bindings for the remote Jenkins API -Home-page: http://git.openstack.org/cgit/openstack/python-jenkins +Home-page: https://opendev.org/jjb/python-jenkins Author: Ken Conley Author-email: k...@willowgarage.com -Maintainer: OpenStack Infrastructure Team -Maintainer-email: openst...@lists.launchpad.net +Maintainer: Python-Jenkins Developers +Maintainer-email: python-jenkins-develop...@lists.launchpad.net License: BSD +Project-URL: Documentation, https://python-jenkins.readthedocs.io/ Description: README ====== @@ -56,15 +57,15 @@ Repository: - * https://git.openstack.org/cgit/openstack/python-jenkins + * https://opendev.org/jjb/python-jenkins Cloning: - * git clone https://git.openstack.org/openstack/python-jenkins + * git clone https://opendev.org/jjb/python-jenkins Patches are submitted via Gerrit at: - * https://review.openstack.org/ + * https://review.opendev.org/#/q/project:jjb/python-jenkins Please do not submit GitHub pull requests, they will be automatically closed. @@ -73,7 +74,7 @@ More details on how you can contribute is available on our wiki at: - * http://docs.openstack.org/infra/manual/developers.html + * https://docs.opendev.org/opendev/infra-manual/latest/developers.html Writing a patch --------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-jenkins-1.7.0/README.rst new/python-jenkins-1.8.0/README.rst --- old/python-jenkins-1.7.0/README.rst 2020-03-04 04:06:09.000000000 +0100 +++ new/python-jenkins-1.8.0/README.rst 2023-03-24 15:50:48.000000000 +0100 @@ -46,15 +46,15 @@ Repository: -* https://git.openstack.org/cgit/openstack/python-jenkins +* https://opendev.org/jjb/python-jenkins Cloning: -* git clone https://git.openstack.org/openstack/python-jenkins +* git clone https://opendev.org/jjb/python-jenkins Patches are submitted via Gerrit at: -* https://review.openstack.org/ +* https://review.opendev.org/#/q/project:jjb/python-jenkins Please do not submit GitHub pull requests, they will be automatically closed. @@ -63,7 +63,7 @@ More details on how you can contribute is available on our wiki at: -* http://docs.openstack.org/infra/manual/developers.html +* https://docs.opendev.org/opendev/infra-manual/latest/developers.html Writing a patch --------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-jenkins-1.7.0/bindep.txt new/python-jenkins-1.8.0/bindep.txt --- old/python-jenkins-1.7.0/bindep.txt 2020-03-04 04:06:09.000000000 +0100 +++ new/python-jenkins-1.8.0/bindep.txt 2023-03-24 15:50:48.000000000 +0100 @@ -4,7 +4,6 @@ gcc [platform:rpm] pypy [test] pypy-dev [test] -python-dev [platform:dpkg] python-devel [platform:rpm] python3-dev [platform:dpkg] python3-devel [platform:fedora] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-jenkins-1.7.0/jenkins/__init__.py new/python-jenkins-1.8.0/jenkins/__init__.py --- old/python-jenkins-1.7.0/jenkins/__init__.py 2020-03-04 04:06:09.000000000 +0100 +++ new/python-jenkins-1.8.0/jenkins/__init__.py 2023-03-24 15:50:48.000000000 +0100 @@ -117,12 +117,14 @@ BUILD_JOB = '%(folder_url)sjob/%(short_name)s/build' STOP_BUILD = '%(folder_url)sjob/%(short_name)s/%(number)s/stop' BUILD_WITH_PARAMS_JOB = '%(folder_url)sjob/%(short_name)s/buildWithParameters' -BUILD_INFO = '%(folder_url)sjob/%(short_name)s/%(number)d/api/json?depth=%(depth)s' -BUILD_CONSOLE_OUTPUT = '%(folder_url)sjob/%(short_name)s/%(number)d/consoleText' -BUILD_ENV_VARS = '%(folder_url)sjob/%(short_name)s/%(number)d/injectedEnvVars/api/json' + \ +BUILD_INFO = '%(folder_url)sjob/%(short_name)s/%(number)s/api/json?depth=%(depth)s' +BUILD_CONSOLE_OUTPUT = '%(folder_url)sjob/%(short_name)s/%(number)s/consoleText' +BUILD_ENV_VARS = '%(folder_url)sjob/%(short_name)s/%(number)s/injectedEnvVars/api/json' + \ '?depth=%(depth)s' -BUILD_TEST_REPORT = '%(folder_url)sjob/%(short_name)s/%(number)d/testReport/api/json' + \ +BUILD_TEST_REPORT = '%(folder_url)sjob/%(short_name)s/%(number)s/testReport/api/json' + \ '?depth=%(depth)s' +BUILD_ARTIFACT = '%(folder_url)sjob/%(short_name)s/%(number)s/artifact/%(artifact)s' +BUILD_STAGES = '%(folder_url)sjob/%(short_name)s/%(number)s/wfapi/describe/' DELETE_BUILD = '%(folder_url)sjob/%(short_name)s/%(number)s/doDelete' WIPEOUT_JOB_WORKSPACE = '%(folder_url)sjob/%(short_name)s/doWipeOutWorkspace' NODE_LIST = 'computer/api/json?depth=%(depth)s' @@ -350,7 +352,8 @@ def _get_encoded_params(self, params): for k, v in params.items(): if k in ["name", "msg", "short_name", "from_short_name", - "to_short_name", "folder_url", "from_folder_url", "to_folder_url"]: + "to_short_name", "folder_url", "from_folder_url", "to_folder_url", + "artifact"]: params[k] = quote(v.encode('utf8')) return params @@ -495,7 +498,7 @@ folder_depth_per_request=folder_depth_per_request) for job in jobs: if re.search(pattern, job['name']): - result.append(self.get_job_info(job['name'], depth=depth)) + result.append(self.get_job_info(job['fullname'], depth=depth)) return result @@ -630,7 +633,7 @@ '''Get build information dictionary. :param name: Job name, ``str`` - :param number: Build number, ``int`` + :param number: Build number, ``str`` (also accepts ``int``) :param depth: JSON depth, ``int`` :returns: dictionary of build information, ``dict`` @@ -651,22 +654,20 @@ if response: return json.loads(response) else: - raise JenkinsException('job[%s] number[%d] does not exist' + raise JenkinsException('job[%s] number[%s] does not exist' % (name, number)) except (req_exc.HTTPError, NotFoundException): - raise JenkinsException('job[%s] number[%d] does not exist' + raise JenkinsException('job[%s] number[%s] does not exist' % (name, number)) except ValueError: - raise JenkinsException( - 'Could not parse JSON info for job[%s] number[%d]' - % (name, number) - ) + raise JenkinsException('Could not parse JSON info for job[%s] number[%s]' + % (name, number)) def get_build_env_vars(self, name, number, depth=0): '''Get build environment variables. :param name: Job name, ``str`` - :param number: Build number, ``int`` + :param number: Build number, ``str`` (also accepts ``int``) :param depth: JSON depth, ``int`` :returns: dictionary of build env vars, ``dict`` or None for workflow jobs, or if InjectEnvVars plugin not installed @@ -678,12 +679,12 @@ if response: return json.loads(response) else: - raise JenkinsException('job[%s] number[%d] does not exist' % (name, number)) + raise JenkinsException('job[%s] number[%s] does not exist' % (name, number)) except req_exc.HTTPError: - raise JenkinsException('job[%s] number[%d] does not exist' % (name, number)) + raise JenkinsException('job[%s] number[%s] does not exist' % (name, number)) except ValueError: raise JenkinsException( - 'Could not parse JSON info for job[%s] number[%d]' % (name, number)) + 'Could not parse JSON info for job[%s] number[%s]' % (name, number)) except NotFoundException: # This can happen on workflow jobs, or if InjectEnvVars plugin not installed return None @@ -692,7 +693,7 @@ '''Get test results report. :param name: Job name, ``str`` - :param number: Build number, ``int`` + :param number: Build number, ``str`` (also accepts ``int``) :returns: dictionary of test report results, ``dict`` or None if there is no Test Report ''' folder_url, short_name = self._get_job_folder(name) @@ -702,16 +703,69 @@ if response: return json.loads(response) else: - raise JenkinsException('job[%s] number[%d] does not exist' % (name, number)) + raise JenkinsException('job[%s] number[%s] does not exist' % (name, number)) except req_exc.HTTPError: - raise JenkinsException('job[%s] number[%d] does not exist' % (name, number)) + raise JenkinsException('job[%s] number[%s] does not exist' % (name, number)) except ValueError: raise JenkinsException( - 'Could not parse JSON info for job[%s] number[%d]' % (name, number)) + 'Could not parse JSON info for job[%s] number[%s]' % (name, number)) except NotFoundException: # This can happen if the test report wasn't generated for any reason return None + def get_build_artifact(self, name, number, artifact): + """Get artifacts from job + + :param name: Job name, ``str`` + :param number: Build number, ``str`` (also accepts ``int``) + :param artifact: Artifact relative path, ``str`` + :returns: artifact to download, ``dict`` + """ + folder_url, short_name = self._get_job_folder(name) + + try: + response = self.jenkins_open(requests.Request( + 'GET', self._build_url(BUILD_ARTIFACT, locals()))) + + if response: + return json.loads(response) + else: + raise JenkinsException('job[%s] number[%s] does not exist' % (name, number)) + except requests.exceptions.HTTPError: + raise JenkinsException('job[%s] number[%s] does not exist' % (name, number)) + except ValueError: + raise JenkinsException( + 'Could not parse JSON info for job[%s] number[%s]' % (name, number)) + except NotFoundException: + # This can happen if the artifact is not found + return None + + def get_build_stages(self, name, number): + """Get stages info from job + + :param name: Job name, ``str`` + :param number: Build number, ``str`` (also accepts ``int``) + :returns: dictionary of stages in the job, ``dict`` + """ + folder_url, short_name = self._get_job_folder(name) + + try: + response = self.jenkins_open(requests.Request( + 'GET', self._build_url(BUILD_STAGES, locals()))) + + if response: + return json.loads(response) + else: + raise JenkinsException('job[%s] number[%s] does not exist' % (name, number)) + except requests.exceptions.HTTPError: + raise JenkinsException('job[%s] number[%s] does not exist' % (name, number)) + except ValueError: + raise JenkinsException( + 'Could not parse JSON info for job[%s] number[%s]' % (name, number)) + except NotFoundException: + # This can happen if this isn't a stages/pipeline job + return None + def get_queue_info(self): ''':returns: list of job dictionaries, ``[dict]`` @@ -1445,7 +1499,7 @@ for node in nodes: # the name returned is not the name to lookup when # dealing with master :/ - if node['name'] == 'master': + if node['name'] in ['master', 'Built-In Node']: node_name = '(master)' else: node_name = node['name'] @@ -1500,6 +1554,9 @@ :param depth: JSON depth, ``int`` :returns: Dictionary of node info, ``dict`` ''' + if name == 'Built-In Node': + name = '(master)' + try: response = self.jenkins_open(requests.Request( 'GET', self._build_url(NODE_INFO, locals()) @@ -1651,7 +1708,7 @@ '''Get build console text. :param name: Job name, ``str`` - :param number: Build number, ``int`` + :param number: Build number, ``str`` (also accepts ``int``) :returns: Build console output, ``str`` ''' folder_url, short_name = self._get_job_folder(name) @@ -1662,10 +1719,10 @@ if response: return response else: - raise JenkinsException('job[%s] number[%d] does not exist' + raise JenkinsException('job[%s] number[%s] does not exist' % (name, number)) except (req_exc.HTTPError, NotFoundException): - raise JenkinsException('job[%s] number[%d] does not exist' + raise JenkinsException('job[%s] number[%s] does not exist' % (name, number)) def _get_job_folder(self, name): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-jenkins-1.7.0/python_jenkins.egg-info/PKG-INFO new/python-jenkins-1.8.0/python_jenkins.egg-info/PKG-INFO --- old/python-jenkins-1.7.0/python_jenkins.egg-info/PKG-INFO 2020-03-04 04:07:27.000000000 +0100 +++ new/python-jenkins-1.8.0/python_jenkins.egg-info/PKG-INFO 2023-03-24 15:51:12.000000000 +0100 @@ -1,13 +1,14 @@ Metadata-Version: 1.2 Name: python-jenkins -Version: 1.7.0 +Version: 1.8.0 Summary: Python bindings for the remote Jenkins API -Home-page: http://git.openstack.org/cgit/openstack/python-jenkins +Home-page: https://opendev.org/jjb/python-jenkins Author: Ken Conley Author-email: k...@willowgarage.com -Maintainer: OpenStack Infrastructure Team -Maintainer-email: openst...@lists.launchpad.net +Maintainer: Python-Jenkins Developers +Maintainer-email: python-jenkins-develop...@lists.launchpad.net License: BSD +Project-URL: Documentation, https://python-jenkins.readthedocs.io/ Description: README ====== @@ -56,15 +57,15 @@ Repository: - * https://git.openstack.org/cgit/openstack/python-jenkins + * https://opendev.org/jjb/python-jenkins Cloning: - * git clone https://git.openstack.org/openstack/python-jenkins + * git clone https://opendev.org/jjb/python-jenkins Patches are submitted via Gerrit at: - * https://review.openstack.org/ + * https://review.opendev.org/#/q/project:jjb/python-jenkins Please do not submit GitHub pull requests, they will be automatically closed. @@ -73,7 +74,7 @@ More details on how you can contribute is available on our wiki at: - * http://docs.openstack.org/infra/manual/developers.html + * https://docs.opendev.org/opendev/infra-manual/latest/developers.html Writing a patch --------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-jenkins-1.7.0/python_jenkins.egg-info/pbr.json new/python-jenkins-1.8.0/python_jenkins.egg-info/pbr.json --- old/python-jenkins-1.7.0/python_jenkins.egg-info/pbr.json 2020-03-04 04:07:27.000000000 +0100 +++ new/python-jenkins-1.8.0/python_jenkins.egg-info/pbr.json 2023-03-24 15:51:12.000000000 +0100 @@ -1 +1 @@ -{"git_version": "9e66e45", "is_release": true} \ No newline at end of file +{"git_version": "70dc3e4", "is_release": true} \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-jenkins-1.7.0/python_jenkins.egg-info/requires.txt new/python-jenkins-1.8.0/python_jenkins.egg-info/requires.txt --- old/python-jenkins-1.7.0/python_jenkins.egg-info/requires.txt 2020-03-04 04:07:27.000000000 +0100 +++ new/python-jenkins-1.8.0/python_jenkins.egg-info/requires.txt 2023-03-24 15:51:12.000000000 +0100 @@ -1,4 +1,5 @@ -six>=1.3.0 -pbr>=0.8.2 multi_key_dict +pbr>=0.8.2 requests +setuptools<66 +six>=1.3.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-jenkins-1.7.0/requirements.txt new/python-jenkins-1.8.0/requirements.txt --- old/python-jenkins-1.7.0/requirements.txt 2020-03-04 04:06:09.000000000 +0100 +++ new/python-jenkins-1.8.0/requirements.txt 2023-03-24 15:50:48.000000000 +0100 @@ -1,3 +1,5 @@ +# Setuptools removed support for PEP 440 non-conforming versions +setuptools<66 six>=1.3.0 pbr>=0.8.2 multi_key_dict diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-jenkins-1.7.0/setup.cfg new/python-jenkins-1.8.0/setup.cfg --- old/python-jenkins-1.7.0/setup.cfg 2020-03-04 04:07:28.000000000 +0100 +++ new/python-jenkins-1.8.0/setup.cfg 2023-03-24 15:51:12.177868000 +0100 @@ -3,11 +3,13 @@ author = Ken Conley author_email = k...@willowgarage.com summary = Python bindings for the remote Jenkins API -maintainer = OpenStack Infrastructure Team -maintainer_email = openst...@lists.launchpad.net +maintainer = Python-Jenkins Developers +maintainer_email = python-jenkins-develop...@lists.launchpad.net description-file = README.rst license = BSD -home-page = http://git.openstack.org/cgit/openstack/python-jenkins +home-page = https://opendev.org/jjb/python-jenkins +project-urls = + Documentation = https://python-jenkins.readthedocs.io/ classifier = Topic :: Utilities Intended Audience :: Developers diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-jenkins-1.7.0/test-requirements.txt new/python-jenkins-1.8.0/test-requirements.txt --- old/python-jenkins-1.7.0/test-requirements.txt 2020-03-04 04:06:09.000000000 +0100 +++ new/python-jenkins-1.8.0/test-requirements.txt 2023-03-24 15:50:48.000000000 +0100 @@ -5,10 +5,11 @@ unittest2 python-subunit requests-mock>=1.4.0 -requests-kerberos +requests-kerberos<=0.12.0;python_version<'3.6' +requests-kerberos;python_version>='3.6' sphinx>=1.6.0,<2.0.0;python_version=='2.7' # BSD sphinx>=1.6.0;python_version>='3.4' # BSD -stestr>=2.0.0 +stestr>=2.0.0,!=3.0.0 testscenarios testtools pre-commit diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-jenkins-1.7.0/tests/jobs/test_info.py new/python-jenkins-1.8.0/tests/jobs/test_info.py --- old/python-jenkins-1.7.0/tests/jobs/test_info.py 2020-03-04 04:06:09.000000000 +0100 +++ new/python-jenkins-1.8.0/tests/jobs/test_info.py 2023-03-24 15:50:48.000000000 +0100 @@ -110,22 +110,36 @@ @patch.object(jenkins.Jenkins, 'jenkins_open') def test_regex(self, jenkins_mock): + parent_job = { + u'name': u'nested-parent-job', + u'jobs': [{u'name': u'nested-child-job'}], + } jobs = [ {u'name': u'my-job-1'}, {u'name': u'my-job-2'}, {u'name': u'your-job-1'}, {u'name': u'Your-Job-1'}, {u'name': u'my-project-1'}, + parent_job, ] job_info_to_return = {u'jobs': jobs} - jenkins_mock.return_value = json.dumps(job_info_to_return) + + def mock_jenkins_open(req, **kwargs): + return json.dumps(parent_job if parent_job['name'] in req.url else job_info_to_return) + jenkins_mock.side_effect = mock_jenkins_open self.assertEqual(len(self.j.get_job_info_regex('her-job')), 0) self.assertEqual(len(self.j.get_job_info_regex('my-job-1')), 1) self.assertEqual(len(self.j.get_job_info_regex('my-job')), 2) - self.assertEqual(len(self.j.get_job_info_regex('job')), 3) + self.assertEqual(len(self.j.get_job_info_regex('job')), 4) + self.assertEqual(len(self.j.get_job_info_regex('job', folder_depth=1)), 5) self.assertEqual(len(self.j.get_job_info_regex('project')), 1) self.assertEqual(len(self.j.get_job_info_regex('[Yy]our-[Jj]ob-1')), 2) + self.assertEqual(len(self.j.get_job_info_regex('nested-.*-job')), 1) + self.assertEqual(len(self.j.get_job_info_regex('nested-.*-job', folder_depth=1)), 2) + self.assertEqual(len(self.j.get_job_info_regex('parent')), 1) + self.assertEqual(len(self.j.get_job_info_regex('child')), 0) + self.assertEqual(len(self.j.get_job_info_regex('child', folder_depth=1)), 1) self._check_requests(jenkins_mock.call_args_list) @patch.object(jenkins.Jenkins, 'jenkins_open') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-jenkins-1.7.0/tests/test_build.py new/python-jenkins-1.8.0/tests/test_build.py --- old/python-jenkins-1.7.0/tests/test_build.py 2020-03-04 04:06:09.000000000 +0100 +++ new/python-jenkins-1.8.0/tests/test_build.py 2023-03-24 15:50:48.000000000 +0100 @@ -14,7 +14,7 @@ def test_simple(self, jenkins_mock): jenkins_mock.return_value = "build console output..." - build_info = self.j.get_build_console_output(u'Test Job', number=52) + build_info = self.j.get_build_console_output(u'Test Job', number='52') self.assertEqual(build_info, jenkins_mock.return_value) self.assertEqual( @@ -26,7 +26,7 @@ def test_in_folder(self, jenkins_mock): jenkins_mock.return_value = "build console output..." - build_info = self.j.get_build_console_output(u'a Folder/Test Job', number=52) + build_info = self.j.get_build_console_output(u'a Folder/Test Job', number='52') self.assertEqual(build_info, jenkins_mock.return_value) self.assertEqual( @@ -35,10 +35,23 @@ self._check_requests(jenkins_mock.call_args_list) @patch.object(jenkins.Jenkins, 'jenkins_open') + def test_matrix(self, jenkins_mock): + jenkins_mock.return_value = "build console output..." + + build_info = self.j.get_build_console_output(u'a Folder/Test Job', number='52/label=matrix') + + self.assertEqual(build_info, jenkins_mock.return_value) + self.assertEqual( + jenkins_mock.call_args[0][0].url, + self.make_url('job/a%20Folder/job/Test%20Job/52/label=matrix/consoleText')) + self._check_requests(jenkins_mock.call_args_list) + + @patch.object(jenkins.Jenkins, 'jenkins_open') def test_return_none(self, jenkins_mock): jenkins_mock.return_value = None with self.assertRaises(jenkins.JenkinsException) as context_manager: + # Test with a number for a printing case, to ensure it works self.j.get_build_console_output(u'TestJob', number=52) self.assertEqual( str(context_manager.exception), @@ -50,17 +63,28 @@ jenkins_mock.return_value = None with self.assertRaises(jenkins.JenkinsException) as context_manager: - self.j.get_build_console_output(u'A Folder/TestJob', number=52) + self.j.get_build_console_output(u'A Folder/TestJob', number='52') self.assertEqual( str(context_manager.exception), 'job[A Folder/TestJob] number[52] does not exist') self._check_requests(jenkins_mock.call_args_list) @patch.object(jenkins.Jenkins, 'jenkins_open') + def test_matrix_return_none(self, jenkins_mock): + jenkins_mock.return_value = None + + with self.assertRaises(jenkins.JenkinsException) as context_manager: + self.j.get_build_console_output(u'A Folder/TestJob', number='52/label=matrix') + self.assertEqual( + str(context_manager.exception), + 'job[A Folder/TestJob] number[52/label=matrix] does not exist') + self._check_requests(jenkins_mock.call_args_list) + + @patch.object(jenkins.Jenkins, 'jenkins_open') def test_return_invalid_json(self, jenkins_mock): jenkins_mock.return_value = 'Invalid JSON' - console_output = self.j.get_build_console_output(u'TestJob', number=52) + console_output = self.j.get_build_console_output(u'TestJob', number='52') self.assertEqual(console_output, jenkins_mock.return_value) @patch('jenkins.requests.Session.send') @@ -71,7 +95,7 @@ ]) with self.assertRaises(jenkins.JenkinsException) as context_manager: - self.j.get_build_console_output(u'TestJob', number=52) + self.j.get_build_console_output(u'TestJob', number='52') self.assertEqual( session_send_mock.call_args_list[1][0][0].url, self.make_url('job/TestJob/52/consoleText')) @@ -87,6 +111,7 @@ ]) with self.assertRaises(jenkins.JenkinsException) as context_manager: + # Test with a number for a printing case, to ensure it works self.j.get_build_console_output(u'a Folder/TestJob', number=52) self.assertEqual( session_send_mock.call_args_list[1][0][0].url, @@ -108,7 +133,7 @@ } jenkins_mock.return_value = json.dumps(build_info_to_return) - build_info = self.j.get_build_info(u'Test Job', number=52) + build_info = self.j.get_build_info(u'Test Job', number='52') self.assertEqual(build_info, build_info_to_return) self.assertEqual( @@ -126,7 +151,7 @@ } jenkins_mock.return_value = json.dumps(build_info_to_return) - build_info = self.j.get_build_info(u'a Folder/Test Job', number=52) + build_info = self.j.get_build_info(u'a Folder/Test Job', number='52') self.assertEqual(build_info, build_info_to_return) self.assertEqual( @@ -135,11 +160,29 @@ self._check_requests(jenkins_mock.call_args_list) @patch.object(jenkins.Jenkins, 'jenkins_open') + def test_matrix(self, jenkins_mock): + build_info_to_return = { + u'building': False, + u'msg': u'test', + u'revision': 66, + u'user': u'unknown' + } + jenkins_mock.return_value = json.dumps(build_info_to_return) + + build_info = self.j.get_build_info(u'a Folder/Test Job', number='52/label=matrix') + + self.assertEqual(build_info, build_info_to_return) + self.assertEqual( + jenkins_mock.call_args[0][0].url, + self.make_url('job/a%20Folder/job/Test%20Job/52/label=matrix/api/json?depth=0')) + self._check_requests(jenkins_mock.call_args_list) + + @patch.object(jenkins.Jenkins, 'jenkins_open') def test_return_none(self, jenkins_mock): jenkins_mock.return_value = None with self.assertRaises(jenkins.JenkinsException) as context_manager: - self.j.get_build_info(u'TestJob', number=52) + self.j.get_build_info(u'TestJob', number='52') self.assertEqual( str(context_manager.exception), 'job[TestJob] number[52] does not exist') @@ -150,6 +193,7 @@ jenkins_mock.return_value = 'Invalid JSON' with self.assertRaises(jenkins.JenkinsException) as context_manager: + # Test with a number for a printing case, to ensure it works self.j.get_build_info(u'TestJob', number=52) self.assertEqual( str(context_manager.exception), @@ -164,7 +208,7 @@ ]) with self.assertRaises(jenkins.JenkinsException) as context_manager: - self.j.get_build_info(u'TestJob', number=52) + self.j.get_build_info(u'TestJob', number='52') self.assertEqual( str(context_manager.exception), 'job[TestJob] number[52] does not exist') @@ -177,7 +221,7 @@ ]) with self.assertRaises(jenkins.JenkinsException) as context_manager: - self.j.get_build_info(u'a Folder/TestJob', number=52) + self.j.get_build_info(u'a Folder/TestJob', number='52') self.assertEqual( str(context_manager.exception), 'job[a Folder/TestJob] number[52] does not exist') @@ -187,7 +231,7 @@ @patch.object(jenkins.Jenkins, 'jenkins_open') def test_simple(self, jenkins_mock): - self.j.stop_build(u'Test Job', number=52) + self.j.stop_build(u'Test Job', number='52') self.assertEqual( jenkins_mock.call_args[0][0].url, @@ -197,7 +241,7 @@ @patch.object(jenkins.Jenkins, 'jenkins_open') def test_in_folder(self, jenkins_mock): - self.j.stop_build(u'a Folder/Test Job', number=52) + self.j.stop_build(u'a Folder/Test Job', number='52') self.assertEqual( jenkins_mock.call_args[0][0].url, @@ -209,7 +253,7 @@ @patch.object(jenkins.Jenkins, 'jenkins_open') def test_simple(self, jenkins_mock): - self.j.delete_build(u'Test Job', number=52) + self.j.delete_build(u'Test Job', number='52') self.assertEqual( jenkins_mock.call_args[0][0].url, @@ -219,7 +263,7 @@ @patch.object(jenkins.Jenkins, 'jenkins_open') def test_in_folder(self, jenkins_mock): - self.j.delete_build(u'a Folder/Test Job', number=52) + self.j.delete_build(u'a Folder/Test Job', number='52') self.assertEqual( jenkins_mock.call_args[0][0].url, @@ -496,7 +540,7 @@ @patch.object(jenkins.Jenkins, 'jenkins_open') def test_simple(self, jenkins_mock): jenkins_mock.return_value = '{}' - ret = self.j.get_build_env_vars(u'Test Job', number=52, depth=1) + ret = self.j.get_build_env_vars(u'Test Job', number='52', depth=1) self.assertEqual(ret, json.loads(jenkins_mock.return_value)) self.assertEqual( jenkins_mock.call_args[0][0].url, @@ -506,6 +550,7 @@ @patch.object(jenkins.Jenkins, 'jenkins_open') def test_in_folder(self, jenkins_mock): jenkins_mock.return_value = '{}' + # Test with a number to ensure it works as well as string ret = self.j.get_build_env_vars(u'a Folder/Test Job', number=52, depth=1) self.assertEqual(ret, json.loads(jenkins_mock.return_value)) self.assertEqual( @@ -513,13 +558,24 @@ self.make_url('job/a%20Folder/job/Test%20Job/52/injectedEnvVars/api/json?depth=1')) self._check_requests(jenkins_mock.call_args_list) + @patch.object(jenkins.Jenkins, 'jenkins_open') + def test_matrix(self, jenkins_mock): + jenkins_mock.return_value = '{}' + ret = self.j.get_build_env_vars(u'a Folder/Test Job', number='52/index=matrix', depth=1) + self.assertEqual(ret, json.loads(jenkins_mock.return_value)) + self.assertEqual( + jenkins_mock.call_args[0][0].url, + self.make_url( + 'job/a%20Folder/job/Test%20Job/52/index=matrix/injectedEnvVars/api/json?depth=1')) + self._check_requests(jenkins_mock.call_args_list) + @patch('jenkins.requests.Session.send', autospec=True) def test_return_none(self, session_send_mock): session_send_mock.side_effect = iter([ build_response_mock(404, reason="Not Found"), # crumb build_response_mock(404, reason="Not Found"), # request ]) - ret = self.j.get_build_env_vars(u'TestJob', number=52) + ret = self.j.get_build_env_vars(u'TestJob', number='52') self.assertIsNone(ret) @patch.object(jenkins.Jenkins, 'jenkins_open') @@ -527,7 +583,7 @@ jenkins_mock.return_value = None with self.assertRaises(jenkins.JenkinsException) as context_manager: - self.j.get_build_env_vars(u'TestJob', number=52) + self.j.get_build_env_vars(u'TestJob', number='52') self.assertEqual( str(context_manager.exception), 'job[TestJob] number[52] does not exist') @@ -538,7 +594,7 @@ jenkins_mock.return_value = 'Invalid JSON' with self.assertRaises(jenkins.JenkinsException) as context_manager: - self.j.get_build_env_vars(u'TestJob', number=52) + self.j.get_build_env_vars(u'TestJob', number='52') self.assertEqual( str(context_manager.exception), 'Could not parse JSON info for job[TestJob] number[52]') @@ -552,6 +608,7 @@ ]) with self.assertRaises(jenkins.JenkinsException) as context_manager: + # Test with a number for a printing case, to ensure it works self.j.get_build_env_vars(u'TestJob', number=52) self.assertEqual( str(context_manager.exception), @@ -565,7 +622,7 @@ ]) with self.assertRaises(jenkins.JenkinsException) as context_manager: - self.j.get_build_env_vars(u'a Folder/TestJob', number=52) + self.j.get_build_env_vars(u'a Folder/TestJob', number='52') self.assertEqual( str(context_manager.exception), 'Error in request. Possibly authentication failed [401]: Not Authorised') @@ -576,7 +633,7 @@ @patch.object(jenkins.Jenkins, 'jenkins_open') def test_simple(self, jenkins_mock): jenkins_mock.return_value = '{}' - ret = self.j.get_build_test_report(u'Test Job', number=52, depth=1) + ret = self.j.get_build_test_report(u'Test Job', number='52', depth=1) self.assertEqual(ret, json.loads(jenkins_mock.return_value)) self.assertEqual( jenkins_mock.call_args[0][0].url, @@ -586,6 +643,7 @@ @patch.object(jenkins.Jenkins, 'jenkins_open') def test_in_folder(self, jenkins_mock): jenkins_mock.return_value = '{}' + # Test with a number to ensure it works as well as string ret = self.j.get_build_test_report(u'a Folder/Test Job', number=52, depth=1) self.assertEqual(ret, json.loads(jenkins_mock.return_value)) self.assertEqual( @@ -593,13 +651,24 @@ self.make_url('job/a%20Folder/job/Test%20Job/52/testReport/api/json?depth=1')) self._check_requests(jenkins_mock.call_args_list) + @patch.object(jenkins.Jenkins, 'jenkins_open') + def test_matrix(self, jenkins_mock): + jenkins_mock.return_value = '{}' + ret = self.j.get_build_test_report(u'a Folder/Test Job', number='52/index=matrix', depth=1) + self.assertEqual(ret, json.loads(jenkins_mock.return_value)) + self.assertEqual( + jenkins_mock.call_args[0][0].url, + self.make_url( + 'job/a%20Folder/job/Test%20Job/52/index=matrix/testReport/api/json?depth=1')) + self._check_requests(jenkins_mock.call_args_list) + @patch('jenkins.requests.Session.send', autospec=True) def test_return_none(self, session_send_mock): session_send_mock.side_effect = iter([ build_response_mock(404, reason="Not Found"), # crumb build_response_mock(404, reason="Not Found"), # request ]) - ret = self.j.get_build_test_report(u'TestJob', number=52) + ret = self.j.get_build_test_report(u'TestJob', number='52') self.assertIsNone(ret) @patch.object(jenkins.Jenkins, 'jenkins_open') @@ -607,7 +676,7 @@ jenkins_mock.return_value = None with self.assertRaises(jenkins.JenkinsException) as context_manager: - self.j.get_build_test_report(u'TestJob', number=52) + self.j.get_build_test_report(u'TestJob', number='52') self.assertEqual( str(context_manager.exception), 'job[TestJob] number[52] does not exist') @@ -618,7 +687,7 @@ jenkins_mock.return_value = 'Invalid JSON' with self.assertRaises(jenkins.JenkinsException) as context_manager: - self.j.get_build_test_report(u'TestJob', number=52) + self.j.get_build_test_report(u'TestJob', number='52') self.assertEqual( str(context_manager.exception), 'Could not parse JSON info for job[TestJob] number[52]') @@ -632,7 +701,7 @@ ]) with self.assertRaises(jenkins.JenkinsException) as context_manager: - self.j.get_build_test_report(u'TestJob', number=52) + self.j.get_build_test_report(u'TestJob', number='52') self.assertEqual( str(context_manager.exception), 'Error in request. Possibly authentication failed [401]: Not Authorised') @@ -645,7 +714,190 @@ ]) with self.assertRaises(jenkins.JenkinsException) as context_manager: + # Test with a number for a printing case, to ensure it works self.j.get_build_test_report(u'a Folder/TestJob', number=52) self.assertEqual( str(context_manager.exception), 'Error in request. Possibly authentication failed [401]: Not Authorised') + + +class JenkinsBuildArtifactUrlTest(JenkinsTestBase): + + @patch.object(jenkins.Jenkins, 'jenkins_open') + def test_simple(self, jenkins_mock): + jenkins_mock.return_value = '{}' + ret = self.j.get_build_artifact(u'Test Job', number='52', artifact="filename") + self.assertEqual(ret, json.loads(jenkins_mock.return_value)) + self.assertEqual( + jenkins_mock.call_args[0][0].url, + self.make_url('job/Test%20Job/52/artifact/filename')) + self._check_requests(jenkins_mock.call_args_list) + + @patch.object(jenkins.Jenkins, 'jenkins_open') + def test_in_folder(self, jenkins_mock): + jenkins_mock.return_value = '{}' + ret = self.j.get_build_artifact(u'a Folder/Test Job', number='52', artifact="file name") + self.assertEqual(ret, json.loads(jenkins_mock.return_value)) + self.assertEqual( + jenkins_mock.call_args[0][0].url, + self.make_url('job/a%20Folder/job/Test%20Job/52/artifact/file%20name')) + self._check_requests(jenkins_mock.call_args_list) + + @patch.object(jenkins.Jenkins, 'jenkins_open') + def test_matrix(self, jenkins_mock): + jenkins_mock.return_value = '{}' + ret = self.j.get_build_artifact(u'a Folder/Test Job', number='52/index=matrix', + artifact="file name") + self.assertEqual(ret, json.loads(jenkins_mock.return_value)) + self.assertEqual( + jenkins_mock.call_args[0][0].url, + self.make_url('job/a%20Folder/job/Test%20Job/52/index=matrix/artifact/file%20name')) + self._check_requests(jenkins_mock.call_args_list) + + @patch('jenkins.requests.Session.send', autospec=True) + def test_return_none(self, session_send_mock): + session_send_mock.side_effect = iter([ + build_response_mock(404, reason="Not Found"), # crumb + build_response_mock(404, reason="Not Found"), # request + ]) + ret = self.j.get_build_artifact(u'TestJob', number='52', artifact="filename") + self.assertIsNone(ret) + + @patch.object(jenkins.Jenkins, 'jenkins_open') + def test_open_return_none(self, jenkins_mock): + jenkins_mock.return_value = None + + with self.assertRaises(jenkins.JenkinsException) as context_manager: + self.j.get_build_artifact(u'TestJob', number='52', artifact="filename") + self.assertEqual( + str(context_manager.exception), + 'job[TestJob] number[52] does not exist') + self._check_requests(jenkins_mock.call_args_list) + + @patch.object(jenkins.Jenkins, 'jenkins_open') + def test_return_invalid_json(self, jenkins_mock): + jenkins_mock.return_value = 'Invalid JSON' + + with self.assertRaises(jenkins.JenkinsException) as context_manager: + self.j.get_build_artifact(u'TestJob', number='52', artifact="filename") + self.assertEqual( + str(context_manager.exception), + 'Could not parse JSON info for job[TestJob] number[52]') + self._check_requests(jenkins_mock.call_args_list) + + @patch('jenkins.requests.Session.send', autospec=True) + def test_raise_HTTPError(self, session_send_mock): + session_send_mock.side_effect = iter([ + build_response_mock(401, reason="Not Authorised"), # crumb + build_response_mock(401, reason="Not Authorised"), # request + ]) + + with self.assertRaises(jenkins.JenkinsException) as context_manager: + self.j.get_build_artifact(u'TestJob', number='52', artifact="filename") + self.assertEqual( + str(context_manager.exception), + 'Error in request. Possibly authentication failed [401]: Not Authorised') + + @patch('jenkins.requests.Session.send', autospec=True) + def test_in_folder_raise_HTTPError(self, session_send_mock): + session_send_mock.side_effect = iter([ + build_response_mock(401, reason="Not Authorised"), # crumb + build_response_mock(401, reason="Not Authorised"), # request + ]) + + with self.assertRaises(jenkins.JenkinsException) as context_manager: + self.j.get_build_artifact(u'a Folder/TestJob', number='52', artifact="filename") + self.assertEqual( + str(context_manager.exception), + 'Error in request. Possibly authentication failed [401]: Not Authorised') + + +class JenkinsBuildStagesUrlTest(JenkinsTestBase): + + @patch.object(jenkins.Jenkins, 'jenkins_open') + def test_simple(self, jenkins_mock): + jenkins_mock.return_value = '{}' + ret = self.j.get_build_stages(u'Test Job', number='52') + self.assertEqual(ret, json.loads(jenkins_mock.return_value)) + self.assertEqual( + jenkins_mock.call_args[0][0].url, + self.make_url('job/Test%20Job/52/wfapi/describe/')) + self._check_requests(jenkins_mock.call_args_list) + + @patch.object(jenkins.Jenkins, 'jenkins_open') + def test_matrix(self, jenkins_mock): + jenkins_mock.return_value = '{}' + ret = self.j.get_build_stages(u'a Folder/Test Job', number='52/index=matrix') + self.assertEqual(ret, json.loads(jenkins_mock.return_value)) + self.assertEqual( + jenkins_mock.call_args[0][0].url, + self.make_url('job/a%20Folder/job/Test%20Job/52/index=matrix/wfapi/describe/')) + self._check_requests(jenkins_mock.call_args_list) + + @patch.object(jenkins.Jenkins, 'jenkins_open') + def test_in_folder(self, jenkins_mock): + jenkins_mock.return_value = '{}' + ret = self.j.get_build_stages(u'a Folder/Test Job', number='52') + self.assertEqual(ret, json.loads(jenkins_mock.return_value)) + self.assertEqual( + jenkins_mock.call_args[0][0].url, + self.make_url('job/a%20Folder/job/Test%20Job/52/wfapi/describe/')) + self._check_requests(jenkins_mock.call_args_list) + + @patch('jenkins.requests.Session.send', autospec=True) + def test_return_none(self, session_send_mock): + session_send_mock.side_effect = iter([ + build_response_mock(404, reason="Not Found"), # crumb + build_response_mock(404, reason="Not Found"), # request + ]) + ret = self.j.get_build_stages(u'TestJob', number='52') + self.assertIsNone(ret) + + @patch.object(jenkins.Jenkins, 'jenkins_open') + def test_open_return_none(self, jenkins_mock): + jenkins_mock.return_value = None + + with self.assertRaises(jenkins.JenkinsException) as context_manager: + # Test with a number for a printing case, to ensure it works + self.j.get_build_stages(u'TestJob', number=52) + self.assertEqual( + str(context_manager.exception), + 'job[TestJob] number[52] does not exist') + self._check_requests(jenkins_mock.call_args_list) + + @patch.object(jenkins.Jenkins, 'jenkins_open') + def test_return_invalid_json(self, jenkins_mock): + jenkins_mock.return_value = 'Invalid JSON' + + with self.assertRaises(jenkins.JenkinsException) as context_manager: + self.j.get_build_stages(u'TestJob', number='52') + self.assertEqual( + str(context_manager.exception), + 'Could not parse JSON info for job[TestJob] number[52]') + self._check_requests(jenkins_mock.call_args_list) + + @patch('jenkins.requests.Session.send', autospec=True) + def test_raise_HTTPError(self, session_send_mock): + session_send_mock.side_effect = iter([ + build_response_mock(401, reason="Not Authorised"), # crumb + build_response_mock(401, reason="Not Authorised"), # request + ]) + + with self.assertRaises(jenkins.JenkinsException) as context_manager: + self.j.get_build_stages(u'TestJob', number='52') + self.assertEqual( + str(context_manager.exception), + 'Error in request. Possibly authentication failed [401]: Not Authorised') + + @patch('jenkins.requests.Session.send', autospec=True) + def test_in_folder_raise_HTTPError(self, session_send_mock): + session_send_mock.side_effect = iter([ + build_response_mock(401, reason="Not Authorised"), # crumb + build_response_mock(401, reason="Not Authorised"), # request + ]) + + with self.assertRaises(jenkins.JenkinsException) as context_manager: + self.j.get_build_stages(u'a Folder/TestJob', number='52') + self.assertEqual( + str(context_manager.exception), + 'Error in request. Possibly authentication failed [401]: Not Authorised') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-jenkins-1.7.0/tox.ini new/python-jenkins-1.8.0/tox.ini --- old/python-jenkins-1.7.0/tox.ini 2020-03-04 04:06:09.000000000 +0100 +++ new/python-jenkins-1.8.0/tox.ini 2023-03-24 15:50:48.000000000 +0100 @@ -1,7 +1,7 @@ [tox] minversion = 2.0 skipsdist = True -envlist = py{34,27,35,36}, linters, pypy +envlist = py{34,27,35,36}, linters [testenv] setenv = @@ -9,12 +9,13 @@ VIRTUAL_ENV={envdir} usedevelop = True install_command = pip install {opts} {packages} -deps = -r{toxinidir}/test-requirements.txt +deps = -r{toxinidir}/requirements.txt + -r{toxinidir}/test-requirements.txt commands = - find . -type f -name "*.pyc" -delete - find . -type d -name "__pycache__" -delete stestr run --slowest {posargs} -whitelist_externals = +allowlist_externals = bash find @@ -25,7 +26,7 @@ commands = bash -c "if [ -d {toxinidir}/../jenkins-job-builder ]; then \ pip install -q -U -e 'git+file://{toxinidir}/../jenkins-job-builder#egg=jenkins-job-builder' ; else \ - pip install -q -U -e 'git+https://git.openstack.org/openstack-infra/jenkins-job-builder@master#egg=jenkins-job-builder' ; fi " + pip install -q -U -e 'https://opendev.org/jjb/python-jenkins@master#egg=jenkins-job-builder' ; fi " stestr run --slowest {posargs} [testenv:cover] ++++++ python-python-jenkins-no-mock.patch ++++++ --- /var/tmp/diff_new_pack.FuQzQJ/_old 2023-04-17 17:41:27.686278399 +0200 +++ /var/tmp/diff_new_pack.FuQzQJ/_new 2023-04-17 17:41:27.690278422 +0200 @@ -1,17 +1,79 @@ -diff -upr python-jenkins-1.7.0.orig/tests/base.py python-jenkins-1.7.0/tests/base.py ---- python-jenkins-1.7.0.orig/tests/base.py 2022-05-03 14:48:58.234141501 +0200 -+++ python-jenkins-1.7.0/tests/base.py 2022-05-03 14:48:58.242141551 +0200 -@@ -1,6 +1,6 @@ +--- + test-requirements.txt | 2 -- + tests/base.py | 7 ++----- + tests/helper.py | 2 +- + tests/jobs/test_assert.py | 2 +- + tests/jobs/test_build.py | 2 +- + tests/jobs/test_config.py | 2 +- + tests/jobs/test_copy.py | 2 +- + tests/jobs/test_count.py | 2 +- + tests/jobs/test_create.py | 2 +- + tests/jobs/test_debug.py | 2 +- + tests/jobs/test_delete.py | 2 +- + tests/jobs/test_disable.py | 2 +- + tests/jobs/test_enable.py | 2 +- + tests/jobs/test_get.py | 2 +- + tests/jobs/test_getall.py | 2 +- + tests/jobs/test_info.py | 2 +- + tests/jobs/test_name.py | 2 +- + tests/jobs/test_reconfig.py | 2 +- + tests/jobs/test_rename.py | 2 +- + tests/jobs/test_set_next_build_number.py | 2 +- + tests/test_build.py | 2 +- + tests/test_check_jenkinsfile_syntax.py | 2 +- + tests/test_credential.py | 2 +- + tests/test_info.py | 2 +- + tests/test_jenkins.py | 2 +- + tests/test_job_folder.py | 2 +- + tests/test_node.py | 2 +- + tests/test_plugins.py | 2 +- + tests/test_promotion.py | 2 +- + tests/test_queue.py | 2 +- + tests/test_quiet_down.py | 2 +- + tests/test_script.py | 2 +- + tests/test_version.py | 2 +- + tests/test_view.py | 2 +- + tests/test_whoami.py | 2 +- + 35 files changed, 35 insertions(+), 40 deletions(-) + +Index: python-jenkins-1.8.0/test-requirements.txt +=================================================================== +--- python-jenkins-1.8.0.orig/test-requirements.txt ++++ python-jenkins-1.8.0/test-requirements.txt +@@ -1,8 +1,6 @@ + cmd2!=0.8.3,<0.9.0;python_version<'3.0' # MIT + cmd2!=0.8.3;python_version>='3.0' # MIT + coverage>=3.6 +-mock +-unittest2 + python-subunit + requests-mock>=1.4.0 + requests-kerberos<=0.12.0;python_version<'3.6' +Index: python-jenkins-1.8.0/tests/base.py +=================================================================== +--- python-jenkins-1.8.0.orig/tests/base.py ++++ python-jenkins-1.8.0/tests/base.py +@@ -1,14 +1,11 @@ import sys -import mock +from unittest import mock ++import unittest from testscenarios import TestWithScenarios import jenkins -diff -upr python-jenkins-1.7.0.orig/tests/helper.py python-jenkins-1.7.0/tests/helper.py ---- python-jenkins-1.7.0.orig/tests/helper.py 2022-05-03 14:48:58.234141501 +0200 -+++ python-jenkins-1.7.0/tests/helper.py 2022-05-03 14:48:58.242141551 +0200 + +-if sys.version_info < (2, 7): +- import unittest2 as unittest +-else: +- import unittest + + + class JenkinsTestBase(TestWithScenarios, unittest.TestCase): +Index: python-jenkins-1.8.0/tests/helper.py +=================================================================== +--- python-jenkins-1.8.0.orig/tests/helper.py ++++ python-jenkins-1.8.0/tests/helper.py @@ -4,7 +4,7 @@ from multiprocessing import Process from multiprocessing import Queue import traceback @@ -21,9 +83,10 @@ import requests from six.moves import socketserver -diff -upr python-jenkins-1.7.0.orig/tests/jobs/test_assert.py python-jenkins-1.7.0/tests/jobs/test_assert.py ---- python-jenkins-1.7.0.orig/tests/jobs/test_assert.py 2022-05-03 14:48:58.238141526 +0200 -+++ python-jenkins-1.7.0/tests/jobs/test_assert.py 2022-05-03 14:48:58.246141576 +0200 +Index: python-jenkins-1.8.0/tests/jobs/test_assert.py +=================================================================== +--- python-jenkins-1.8.0.orig/tests/jobs/test_assert.py ++++ python-jenkins-1.8.0/tests/jobs/test_assert.py @@ -1,5 +1,5 @@ import json -from mock import patch @@ -31,9 +94,10 @@ import jenkins from tests.jobs.base import JenkinsJobsTestBase -diff -upr python-jenkins-1.7.0.orig/tests/jobs/test_build.py python-jenkins-1.7.0/tests/jobs/test_build.py ---- python-jenkins-1.7.0.orig/tests/jobs/test_build.py 2022-05-03 14:48:58.238141526 +0200 -+++ python-jenkins-1.7.0/tests/jobs/test_build.py 2022-05-03 14:48:58.246141576 +0200 +Index: python-jenkins-1.8.0/tests/jobs/test_build.py +=================================================================== +--- python-jenkins-1.8.0.orig/tests/jobs/test_build.py ++++ python-jenkins-1.8.0/tests/jobs/test_build.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from mock import patch @@ -41,18 +105,20 @@ import jenkins from six.moves.urllib.parse import quote -diff -upr python-jenkins-1.7.0.orig/tests/jobs/test_config.py python-jenkins-1.7.0/tests/jobs/test_config.py ---- python-jenkins-1.7.0.orig/tests/jobs/test_config.py 2022-05-03 14:48:58.238141526 +0200 -+++ python-jenkins-1.7.0/tests/jobs/test_config.py 2022-05-03 14:48:58.246141576 +0200 +Index: python-jenkins-1.8.0/tests/jobs/test_config.py +=================================================================== +--- python-jenkins-1.8.0.orig/tests/jobs/test_config.py ++++ python-jenkins-1.8.0/tests/jobs/test_config.py @@ -1,4 +1,4 @@ -from mock import patch +from unittest.mock import patch import jenkins from tests.jobs.base import JenkinsJobsTestBase -diff -upr python-jenkins-1.7.0.orig/tests/jobs/test_copy.py python-jenkins-1.7.0/tests/jobs/test_copy.py ---- python-jenkins-1.7.0.orig/tests/jobs/test_copy.py 2022-05-03 14:48:58.238141526 +0200 -+++ python-jenkins-1.7.0/tests/jobs/test_copy.py 2022-05-03 14:48:58.246141576 +0200 +Index: python-jenkins-1.8.0/tests/jobs/test_copy.py +=================================================================== +--- python-jenkins-1.8.0.orig/tests/jobs/test_copy.py ++++ python-jenkins-1.8.0/tests/jobs/test_copy.py @@ -1,5 +1,5 @@ import json -from mock import patch @@ -60,9 +126,10 @@ import jenkins from tests.jobs.base import JenkinsJobsTestBase -diff -upr python-jenkins-1.7.0.orig/tests/jobs/test_count.py python-jenkins-1.7.0/tests/jobs/test_count.py ---- python-jenkins-1.7.0.orig/tests/jobs/test_count.py 2022-05-03 14:48:58.238141526 +0200 -+++ python-jenkins-1.7.0/tests/jobs/test_count.py 2022-05-03 14:48:58.246141576 +0200 +Index: python-jenkins-1.8.0/tests/jobs/test_count.py +=================================================================== +--- python-jenkins-1.8.0.orig/tests/jobs/test_count.py ++++ python-jenkins-1.8.0/tests/jobs/test_count.py @@ -1,5 +1,5 @@ import json -from mock import patch @@ -70,9 +137,10 @@ import jenkins from tests.jobs.base import JenkinsJobsTestBase -diff -upr python-jenkins-1.7.0.orig/tests/jobs/test_create.py python-jenkins-1.7.0/tests/jobs/test_create.py ---- python-jenkins-1.7.0.orig/tests/jobs/test_create.py 2022-05-03 14:48:58.238141526 +0200 -+++ python-jenkins-1.7.0/tests/jobs/test_create.py 2022-05-03 14:48:58.246141576 +0200 +Index: python-jenkins-1.8.0/tests/jobs/test_create.py +=================================================================== +--- python-jenkins-1.8.0.orig/tests/jobs/test_create.py ++++ python-jenkins-1.8.0/tests/jobs/test_create.py @@ -1,5 +1,5 @@ import json -from mock import patch @@ -80,9 +148,10 @@ import jenkins from tests.jobs.base import JenkinsJobsTestBase -diff -upr python-jenkins-1.7.0.orig/tests/jobs/test_debug.py python-jenkins-1.7.0/tests/jobs/test_debug.py ---- python-jenkins-1.7.0.orig/tests/jobs/test_debug.py 2022-05-03 14:48:58.238141526 +0200 -+++ python-jenkins-1.7.0/tests/jobs/test_debug.py 2022-05-03 14:48:58.246141576 +0200 +Index: python-jenkins-1.8.0/tests/jobs/test_debug.py +=================================================================== +--- python-jenkins-1.8.0.orig/tests/jobs/test_debug.py ++++ python-jenkins-1.8.0/tests/jobs/test_debug.py @@ -1,5 +1,5 @@ import json -from mock import patch @@ -90,9 +159,10 @@ import jenkins from tests.jobs.base import JenkinsJobsTestBase -diff -upr python-jenkins-1.7.0.orig/tests/jobs/test_delete.py python-jenkins-1.7.0/tests/jobs/test_delete.py ---- python-jenkins-1.7.0.orig/tests/jobs/test_delete.py 2022-05-03 14:48:58.238141526 +0200 -+++ python-jenkins-1.7.0/tests/jobs/test_delete.py 2022-05-03 14:48:58.246141576 +0200 +Index: python-jenkins-1.8.0/tests/jobs/test_delete.py +=================================================================== +--- python-jenkins-1.8.0.orig/tests/jobs/test_delete.py ++++ python-jenkins-1.8.0/tests/jobs/test_delete.py @@ -1,5 +1,5 @@ import json -from mock import patch @@ -100,9 +170,10 @@ import jenkins from tests.jobs.base import JenkinsJobsTestBase -diff -upr python-jenkins-1.7.0.orig/tests/jobs/test_disable.py python-jenkins-1.7.0/tests/jobs/test_disable.py ---- python-jenkins-1.7.0.orig/tests/jobs/test_disable.py 2022-05-03 14:48:58.238141526 +0200 -+++ python-jenkins-1.7.0/tests/jobs/test_disable.py 2022-05-03 14:48:58.246141576 +0200 +Index: python-jenkins-1.8.0/tests/jobs/test_disable.py +=================================================================== +--- python-jenkins-1.8.0.orig/tests/jobs/test_disable.py ++++ python-jenkins-1.8.0/tests/jobs/test_disable.py @@ -1,5 +1,5 @@ import json -from mock import patch @@ -110,9 +181,10 @@ import jenkins from tests.jobs.base import JenkinsJobsTestBase -diff -upr python-jenkins-1.7.0.orig/tests/jobs/test_enable.py python-jenkins-1.7.0/tests/jobs/test_enable.py ---- python-jenkins-1.7.0.orig/tests/jobs/test_enable.py 2022-05-03 14:48:58.238141526 +0200 -+++ python-jenkins-1.7.0/tests/jobs/test_enable.py 2022-05-03 14:48:58.246141576 +0200 +Index: python-jenkins-1.8.0/tests/jobs/test_enable.py +=================================================================== +--- python-jenkins-1.8.0.orig/tests/jobs/test_enable.py ++++ python-jenkins-1.8.0/tests/jobs/test_enable.py @@ -1,5 +1,5 @@ import json -from mock import patch @@ -120,29 +192,32 @@ import jenkins from tests.jobs.base import JenkinsJobsTestBase -diff -upr python-jenkins-1.7.0.orig/tests/jobs/test_getall.py python-jenkins-1.7.0/tests/jobs/test_getall.py ---- python-jenkins-1.7.0.orig/tests/jobs/test_getall.py 2022-05-03 14:48:58.238141526 +0200 -+++ python-jenkins-1.7.0/tests/jobs/test_getall.py 2022-05-03 14:48:58.246141576 +0200 +Index: python-jenkins-1.8.0/tests/jobs/test_get.py +=================================================================== +--- python-jenkins-1.8.0.orig/tests/jobs/test_get.py ++++ python-jenkins-1.8.0/tests/jobs/test_get.py @@ -1,5 +1,5 @@ import json -from mock import patch +from unittest.mock import patch import jenkins - from tests.jobs.base import JenkinsGetJobsTestBase -diff -upr python-jenkins-1.7.0.orig/tests/jobs/test_get.py python-jenkins-1.7.0/tests/jobs/test_get.py ---- python-jenkins-1.7.0.orig/tests/jobs/test_get.py 2022-05-03 14:48:58.238141526 +0200 -+++ python-jenkins-1.7.0/tests/jobs/test_get.py 2022-05-03 14:48:58.246141576 +0200 + from tests.helper import build_response_mock +Index: python-jenkins-1.8.0/tests/jobs/test_getall.py +=================================================================== +--- python-jenkins-1.8.0.orig/tests/jobs/test_getall.py ++++ python-jenkins-1.8.0/tests/jobs/test_getall.py @@ -1,5 +1,5 @@ import json -from mock import patch +from unittest.mock import patch import jenkins - from tests.helper import build_response_mock -diff -upr python-jenkins-1.7.0.orig/tests/jobs/test_info.py python-jenkins-1.7.0/tests/jobs/test_info.py ---- python-jenkins-1.7.0.orig/tests/jobs/test_info.py 2022-05-03 14:48:58.238141526 +0200 -+++ python-jenkins-1.7.0/tests/jobs/test_info.py 2022-05-03 14:48:58.246141576 +0200 + from tests.jobs.base import JenkinsGetJobsTestBase +Index: python-jenkins-1.8.0/tests/jobs/test_info.py +=================================================================== +--- python-jenkins-1.8.0.orig/tests/jobs/test_info.py ++++ python-jenkins-1.8.0/tests/jobs/test_info.py @@ -1,5 +1,5 @@ import json -from mock import patch @@ -150,9 +225,10 @@ import jenkins from tests.helper import build_response_mock -diff -upr python-jenkins-1.7.0.orig/tests/jobs/test_name.py python-jenkins-1.7.0/tests/jobs/test_name.py ---- python-jenkins-1.7.0.orig/tests/jobs/test_name.py 2022-05-03 14:48:58.238141526 +0200 -+++ python-jenkins-1.7.0/tests/jobs/test_name.py 2022-05-03 14:48:58.246141576 +0200 +Index: python-jenkins-1.8.0/tests/jobs/test_name.py +=================================================================== +--- python-jenkins-1.8.0.orig/tests/jobs/test_name.py ++++ python-jenkins-1.8.0/tests/jobs/test_name.py @@ -1,5 +1,5 @@ import json -from mock import patch @@ -160,9 +236,10 @@ import jenkins from tests.jobs.base import JenkinsJobsTestBase -diff -upr python-jenkins-1.7.0.orig/tests/jobs/test_reconfig.py python-jenkins-1.7.0/tests/jobs/test_reconfig.py ---- python-jenkins-1.7.0.orig/tests/jobs/test_reconfig.py 2022-05-03 14:48:58.238141526 +0200 -+++ python-jenkins-1.7.0/tests/jobs/test_reconfig.py 2022-05-03 14:48:58.246141576 +0200 +Index: python-jenkins-1.8.0/tests/jobs/test_reconfig.py +=================================================================== +--- python-jenkins-1.8.0.orig/tests/jobs/test_reconfig.py ++++ python-jenkins-1.8.0/tests/jobs/test_reconfig.py @@ -1,5 +1,5 @@ import json -from mock import patch @@ -170,9 +247,10 @@ import jenkins from tests.jobs.base import JenkinsJobsTestBase -diff -upr python-jenkins-1.7.0.orig/tests/jobs/test_rename.py python-jenkins-1.7.0/tests/jobs/test_rename.py ---- python-jenkins-1.7.0.orig/tests/jobs/test_rename.py 2022-05-03 14:48:58.238141526 +0200 -+++ python-jenkins-1.7.0/tests/jobs/test_rename.py 2022-05-03 14:48:58.246141576 +0200 +Index: python-jenkins-1.8.0/tests/jobs/test_rename.py +=================================================================== +--- python-jenkins-1.8.0.orig/tests/jobs/test_rename.py ++++ python-jenkins-1.8.0/tests/jobs/test_rename.py @@ -1,5 +1,5 @@ import json -from mock import patch @@ -180,18 +258,20 @@ import jenkins from tests.jobs.base import JenkinsJobsTestBase -diff -upr python-jenkins-1.7.0.orig/tests/jobs/test_set_next_build_number.py python-jenkins-1.7.0/tests/jobs/test_set_next_build_number.py ---- python-jenkins-1.7.0.orig/tests/jobs/test_set_next_build_number.py 2022-05-03 14:48:58.238141526 +0200 -+++ python-jenkins-1.7.0/tests/jobs/test_set_next_build_number.py 2022-05-03 14:48:58.246141576 +0200 +Index: python-jenkins-1.8.0/tests/jobs/test_set_next_build_number.py +=================================================================== +--- python-jenkins-1.8.0.orig/tests/jobs/test_set_next_build_number.py ++++ python-jenkins-1.8.0/tests/jobs/test_set_next_build_number.py @@ -1,4 +1,4 @@ -from mock import patch +from unittest.mock import patch import jenkins from tests.jobs.base import JenkinsJobsTestBase -diff -upr python-jenkins-1.7.0.orig/tests/test_build.py python-jenkins-1.7.0/tests/test_build.py ---- python-jenkins-1.7.0.orig/tests/test_build.py 2022-05-03 14:48:58.234141501 +0200 -+++ python-jenkins-1.7.0/tests/test_build.py 2022-05-03 14:48:58.242141551 +0200 +Index: python-jenkins-1.8.0/tests/test_build.py +=================================================================== +--- python-jenkins-1.8.0.orig/tests/test_build.py ++++ python-jenkins-1.8.0/tests/test_build.py @@ -1,7 +1,7 @@ import json @@ -201,18 +281,20 @@ import jenkins from tests.base import JenkinsTestBase -diff -upr python-jenkins-1.7.0.orig/tests/test_check_jenkinsfile_syntax.py python-jenkins-1.7.0/tests/test_check_jenkinsfile_syntax.py ---- python-jenkins-1.7.0.orig/tests/test_check_jenkinsfile_syntax.py 2022-05-03 14:48:58.234141501 +0200 -+++ python-jenkins-1.7.0/tests/test_check_jenkinsfile_syntax.py 2022-05-03 14:48:58.246141576 +0200 +Index: python-jenkins-1.8.0/tests/test_check_jenkinsfile_syntax.py +=================================================================== +--- python-jenkins-1.8.0.orig/tests/test_check_jenkinsfile_syntax.py ++++ python-jenkins-1.8.0/tests/test_check_jenkinsfile_syntax.py @@ -1,4 +1,4 @@ -from mock import patch +from unittest.mock import patch from tests.base import JenkinsTestBase from tests.helper import build_response_mock -diff -upr python-jenkins-1.7.0.orig/tests/test_credential.py python-jenkins-1.7.0/tests/test_credential.py ---- python-jenkins-1.7.0.orig/tests/test_credential.py 2022-05-03 14:48:58.234141501 +0200 -+++ python-jenkins-1.7.0/tests/test_credential.py 2022-05-03 14:48:58.242141551 +0200 +Index: python-jenkins-1.8.0/tests/test_credential.py +=================================================================== +--- python-jenkins-1.8.0.orig/tests/test_credential.py ++++ python-jenkins-1.8.0/tests/test_credential.py @@ -1,5 +1,5 @@ import json -from mock import patch @@ -220,9 +302,10 @@ import jenkins from tests.base import JenkinsTestBase -diff -upr python-jenkins-1.7.0.orig/tests/test_info.py python-jenkins-1.7.0/tests/test_info.py ---- python-jenkins-1.7.0.orig/tests/test_info.py 2022-05-03 14:48:58.238141526 +0200 -+++ python-jenkins-1.7.0/tests/test_info.py 2022-05-03 14:48:58.246141576 +0200 +Index: python-jenkins-1.8.0/tests/test_info.py +=================================================================== +--- python-jenkins-1.8.0.orig/tests/test_info.py ++++ python-jenkins-1.8.0/tests/test_info.py @@ -1,5 +1,5 @@ import json -from mock import patch @@ -230,9 +313,10 @@ import jenkins from tests.base import JenkinsTestBase -diff -upr python-jenkins-1.7.0.orig/tests/test_jenkins.py python-jenkins-1.7.0/tests/test_jenkins.py ---- python-jenkins-1.7.0.orig/tests/test_jenkins.py 2022-05-03 14:48:58.234141501 +0200 -+++ python-jenkins-1.7.0/tests/test_jenkins.py 2022-05-03 14:48:58.246141576 +0200 +Index: python-jenkins-1.8.0/tests/test_jenkins.py +=================================================================== +--- python-jenkins-1.8.0.orig/tests/test_jenkins.py ++++ python-jenkins-1.8.0/tests/test_jenkins.py @@ -1,7 +1,7 @@ import json import socket @@ -242,18 +326,20 @@ import six from tests.base import JenkinsTestBase -diff -upr python-jenkins-1.7.0.orig/tests/test_job_folder.py python-jenkins-1.7.0/tests/test_job_folder.py ---- python-jenkins-1.7.0.orig/tests/test_job_folder.py 2022-05-03 14:48:58.234141501 +0200 -+++ python-jenkins-1.7.0/tests/test_job_folder.py 2022-05-03 14:48:58.242141551 +0200 +Index: python-jenkins-1.8.0/tests/test_job_folder.py +=================================================================== +--- python-jenkins-1.8.0.orig/tests/test_job_folder.py ++++ python-jenkins-1.8.0/tests/test_job_folder.py @@ -1,4 +1,4 @@ -from mock import patch +from unittest.mock import patch import jenkins from tests.base import JenkinsTestBase -diff -upr python-jenkins-1.7.0.orig/tests/test_node.py python-jenkins-1.7.0/tests/test_node.py ---- python-jenkins-1.7.0.orig/tests/test_node.py 2022-05-03 14:48:58.234141501 +0200 -+++ python-jenkins-1.7.0/tests/test_node.py 2022-05-03 14:48:58.242141551 +0200 +Index: python-jenkins-1.8.0/tests/test_node.py +=================================================================== +--- python-jenkins-1.8.0.orig/tests/test_node.py ++++ python-jenkins-1.8.0/tests/test_node.py @@ -1,5 +1,5 @@ import json -from mock import patch @@ -261,9 +347,10 @@ import jenkins import requests_mock -diff -upr python-jenkins-1.7.0.orig/tests/test_plugins.py python-jenkins-1.7.0/tests/test_plugins.py ---- python-jenkins-1.7.0.orig/tests/test_plugins.py 2022-05-03 14:48:58.234141501 +0200 -+++ python-jenkins-1.7.0/tests/test_plugins.py 2022-05-03 14:48:58.242141551 +0200 +Index: python-jenkins-1.8.0/tests/test_plugins.py +=================================================================== +--- python-jenkins-1.8.0.orig/tests/test_plugins.py ++++ python-jenkins-1.8.0/tests/test_plugins.py @@ -32,7 +32,7 @@ @@ -273,9 +360,10 @@ from testscenarios.scenarios import multiply_scenarios import jenkins -diff -upr python-jenkins-1.7.0.orig/tests/test_promotion.py python-jenkins-1.7.0/tests/test_promotion.py ---- python-jenkins-1.7.0.orig/tests/test_promotion.py 2022-05-03 14:48:58.234141501 +0200 -+++ python-jenkins-1.7.0/tests/test_promotion.py 2022-05-03 14:48:58.242141551 +0200 +Index: python-jenkins-1.8.0/tests/test_promotion.py +=================================================================== +--- python-jenkins-1.8.0.orig/tests/test_promotion.py ++++ python-jenkins-1.8.0/tests/test_promotion.py @@ -1,5 +1,5 @@ import json -from mock import patch @@ -283,9 +371,10 @@ import jenkins from tests.base import JenkinsTestBase -diff -upr python-jenkins-1.7.0.orig/tests/test_queue.py python-jenkins-1.7.0/tests/test_queue.py ---- python-jenkins-1.7.0.orig/tests/test_queue.py 2022-05-03 14:48:58.234141501 +0200 -+++ python-jenkins-1.7.0/tests/test_queue.py 2022-05-03 14:48:58.246141576 +0200 +Index: python-jenkins-1.8.0/tests/test_queue.py +=================================================================== +--- python-jenkins-1.8.0.orig/tests/test_queue.py ++++ python-jenkins-1.8.0/tests/test_queue.py @@ -1,5 +1,5 @@ import json -from mock import patch @@ -293,9 +382,10 @@ import jenkins from tests.base import JenkinsTestBase -diff -upr python-jenkins-1.7.0.orig/tests/test_quiet_down.py python-jenkins-1.7.0/tests/test_quiet_down.py ---- python-jenkins-1.7.0.orig/tests/test_quiet_down.py 2022-05-03 14:48:58.238141526 +0200 -+++ python-jenkins-1.7.0/tests/test_quiet_down.py 2022-05-03 14:48:58.246141576 +0200 +Index: python-jenkins-1.8.0/tests/test_quiet_down.py +=================================================================== +--- python-jenkins-1.8.0.orig/tests/test_quiet_down.py ++++ python-jenkins-1.8.0/tests/test_quiet_down.py @@ -1,5 +1,5 @@ import json -from mock import patch @@ -303,27 +393,30 @@ import jenkins from tests.base import JenkinsTestBase -diff -upr python-jenkins-1.7.0.orig/tests/test_script.py python-jenkins-1.7.0/tests/test_script.py ---- python-jenkins-1.7.0.orig/tests/test_script.py 2022-05-03 14:48:58.234141501 +0200 -+++ python-jenkins-1.7.0/tests/test_script.py 2022-05-03 14:48:58.242141551 +0200 +Index: python-jenkins-1.8.0/tests/test_script.py +=================================================================== +--- python-jenkins-1.8.0.orig/tests/test_script.py ++++ python-jenkins-1.8.0/tests/test_script.py @@ -1,4 +1,4 @@ -from mock import patch +from unittest.mock import patch import jenkins from tests.base import JenkinsTestBase -diff -upr python-jenkins-1.7.0.orig/tests/test_version.py python-jenkins-1.7.0/tests/test_version.py ---- python-jenkins-1.7.0.orig/tests/test_version.py 2022-05-03 14:48:58.234141501 +0200 -+++ python-jenkins-1.7.0/tests/test_version.py 2022-05-03 14:48:58.246141576 +0200 +Index: python-jenkins-1.8.0/tests/test_version.py +=================================================================== +--- python-jenkins-1.8.0.orig/tests/test_version.py ++++ python-jenkins-1.8.0/tests/test_version.py @@ -1,4 +1,4 @@ -from mock import patch +from unittest.mock import patch import jenkins from tests.base import JenkinsTestBase -diff -upr python-jenkins-1.7.0.orig/tests/test_view.py python-jenkins-1.7.0/tests/test_view.py ---- python-jenkins-1.7.0.orig/tests/test_view.py 2022-05-03 14:48:58.238141526 +0200 -+++ python-jenkins-1.7.0/tests/test_view.py 2022-05-03 14:48:58.246141576 +0200 +Index: python-jenkins-1.8.0/tests/test_view.py +=================================================================== +--- python-jenkins-1.8.0.orig/tests/test_view.py ++++ python-jenkins-1.8.0/tests/test_view.py @@ -1,5 +1,5 @@ import json -from mock import patch @@ -331,9 +424,10 @@ import jenkins from tests.base import JenkinsTestBase -diff -upr python-jenkins-1.7.0.orig/tests/test_whoami.py python-jenkins-1.7.0/tests/test_whoami.py ---- python-jenkins-1.7.0.orig/tests/test_whoami.py 2022-05-03 14:48:58.234141501 +0200 -+++ python-jenkins-1.7.0/tests/test_whoami.py 2022-05-03 14:48:58.242141551 +0200 +Index: python-jenkins-1.8.0/tests/test_whoami.py +=================================================================== +--- python-jenkins-1.8.0.orig/tests/test_whoami.py ++++ python-jenkins-1.8.0/tests/test_whoami.py @@ -1,5 +1,5 @@ import json -from mock import patch ++++++ use-parts-of-legacy-version.patch ++++++ Index: python-jenkins-1.8.0/jenkins/plugins.py =================================================================== --- python-jenkins-1.8.0.orig/jenkins/plugins.py +++ python-jenkins-1.8.0/jenkins/plugins.py @@ -41,8 +41,7 @@ import operator import re - -import pkg_resources +from typing import Iterator, Tuple class Plugin(dict): @@ -67,6 +66,63 @@ class Plugin(dict): super(Plugin, self).__setitem__(key, value) +# Portion of code from packaging module, dual licensed under the terms of +# the Apache License, Version 2.0, and the BSD License. +_legacy_version_component_re = re.compile(r"(\d+ | [a-z]+ | \.| -)", re.VERBOSE) + +_legacy_version_replacement_map = { + "pre": "c", + "preview": "c", + "-": "final-", + "rc": "c", + "dev": "@", +} + + +def _parse_version_parts(s: str) -> Iterator[str]: + for part in _legacy_version_component_re.split(s): + part = _legacy_version_replacement_map.get(part, part) + + if not part or part == ".": + continue + + if part[:1] in "0123456789": + # pad for numeric comparison + yield part.zfill(8) + else: + yield "*" + part + + # ensure that alpha/beta/candidate are before final + yield "*final" + + +def _legacy_cmpkey(version: str) -> Tuple[int, Tuple[str, ...]]: + + # We hardcode an epoch of -1 here. A PEP 440 version can only have a epoch + # greater than or equal to 0. This will effectively put the LegacyVersion, + # which uses the defacto standard originally implemented by setuptools, + # as before all PEP 440 versions. + epoch = -1 + + # This scheme is taken from pkg_resources.parse_version setuptools prior to + # it's adoption of the packaging library. + parts: List[str] = [] + for part in _parse_version_parts(version.lower()): + if part.startswith("*"): + # remove "-" before a prerelease tag + if part < "*final": + while parts and parts[-1] == "*final-": + parts.pop() + + # remove trailing zeros from each series of numeric parts + while parts and parts[-1] == "00000000": + parts.pop() + + parts.append(part) + + return epoch, tuple(parts) + + class PluginVersion(str): '''Class providing comparison capabilities for plugin versions.''' @@ -76,15 +132,14 @@ class PluginVersion(str): '''Parse plugin version and store it for comparison.''' self._version = version - self.parsed_version = pkg_resources.parse_version( - self.__convert_version(version)) + self.parsed_version = _legacy_cmpkey(self.__convert_version(version)) def __convert_version(self, version): return self._VERSION_RE.sub(r'\g<1>.preview', str(version)) def __compare(self, op, version): - return op(self.parsed_version, pkg_resources.parse_version( - self.__convert_version(version))) + return op(self.parsed_version, + _legacy_cmpkey(self.__convert_version(version))) def __le__(self, version): return self.__compare(operator.le, version) Index: python-jenkins-1.8.0/requirements.txt =================================================================== --- python-jenkins-1.8.0.orig/requirements.txt +++ python-jenkins-1.8.0/requirements.txt @@ -1,5 +1,3 @@ -# Setuptools removed support for PEP 440 non-conforming versions -setuptools<66 six>=1.3.0 pbr>=0.8.2 multi_key_dict