From 9cfc8d8d0c94be3eceb1f0505de1e6520370d746 Mon Sep 17 00:00:00 2001 From: Michal Konečný Date: Sep 24 2023 04:43:04 +0000 Subject: [PATCH 1/12] Update test environment to F38 Update test containers to F38 for both pip and rpms. Signed-off-by: Michal Konečný --- diff --git a/dev/containers/base-fedora-pip-py3 b/dev/containers/base-fedora-pip-py3 index 9433227..9ec6037 100644 --- a/dev/containers/base-fedora-pip-py3 +++ b/dev/containers/base-fedora-pip-py3 @@ -1,4 +1,4 @@ -FROM quay.io/fedora/fedora:36-x86_64 +FROM quay.io/fedora/fedora:38-x86_64 LABEL org.opencontainers.image.authors="pagure community" LABEL org.opencontainers.image.url="https://pagure.io/pagure" diff --git a/dev/containers/base-fedora-rpms-py3 b/dev/containers/base-fedora-rpms-py3 index b50036d..5d10f3d 100644 --- a/dev/containers/base-fedora-rpms-py3 +++ b/dev/containers/base-fedora-rpms-py3 @@ -1,4 +1,4 @@ -FROM quay.io/fedora/fedora:36-x86_64 +FROM quay.io/fedora/fedora:38-x86_64 LABEL org.opencontainers.image.authors="pagure community" LABEL org.opencontainers.image.url="https://pagure.io/pagure" @@ -19,7 +19,7 @@ RUN dnf -y --enablerepo=updates-testing install \ python3-flake8 \ python3-pytest-xdist \ python3-flask-oidc \ - python3-cchardet \ + python3-chardet \ python3-fedora-messaging \ python3-pip \ redis \ diff --git a/dev/containers/fedora-pip-py3 b/dev/containers/fedora-pip-py3 index 58cc29d..cc181f6 100644 --- a/dev/containers/fedora-pip-py3 +++ b/dev/containers/fedora-pip-py3 @@ -1,4 +1,4 @@ -FROM quay.io/fedora/fedora:36-x86_64 +FROM quay.io/fedora/fedora:38-x86_64 ARG repo=https://pagure.io/pagure.git ARG branch=master diff --git a/dev/containers/fedora-rpms-py3 b/dev/containers/fedora-rpms-py3 index a6da18e..0b96267 100644 --- a/dev/containers/fedora-rpms-py3 +++ b/dev/containers/fedora-rpms-py3 @@ -1,4 +1,4 @@ -FROM quay.io/fedora/fedora:36-x86_64 +FROM quay.io/fedora/fedora:38-x86_64 ARG repo=https://pagure.io/pagure.git ARG branch=master @@ -17,7 +17,7 @@ RUN dnf -y --enablerepo=updates-testing install \ python3-isort \ python3-pytest-xdist \ python3-flask-oidc \ - python3-cchardet \ + python3-chardet \ python3-fedora-messaging \ python3-pip \ redis \ diff --git a/dev/containers/tox_py3.sh b/dev/containers/tox_py3.sh index 6dc5b73..9e079ea 100644 --- a/dev/containers/tox_py3.sh +++ b/dev/containers/tox_py3.sh @@ -23,4 +23,4 @@ git --no-pager log -2 fi export LANG="en_US.UTF-8" -tox -v -e "${PYVER:-py38}" -- ${TESTCASE:-tests/} \ No newline at end of file +tox -v -e "${PYVER:-py38}" -- ${TESTCASE:-tests/} diff --git a/pagure/lib/git.py b/pagure/lib/git.py index 293d172..ab66675 100644 --- a/pagure/lib/git.py +++ b/pagure/lib/git.py @@ -86,7 +86,7 @@ def commit_to_patch( # First commit in the repo diff = commit.tree.diff_to_tree(swap=True) - if diff.patch is None: + if not diff.patch: continue if find_similar and diff: diff --git a/pagure/lib/query.py b/pagure/lib/query.py index a7a03ce..3a862ef 100644 --- a/pagure/lib/query.py +++ b/pagure/lib/query.py @@ -4422,11 +4422,17 @@ def text2markdown(text, extended=True, readme=False): # Install our markdown modifications extensions.append("pagure.pfmarkdown") + extensions_configs = { + "markdown.extensions.codehilite": {"guess_lang": False}, + } + if md_version > (3, 0, 0): + extensions_configs["markdown.extensions.tables"] = { + "use_align_attribute": True + } + md_processor = markdown.Markdown( extensions=extensions, - extension_configs={ - "markdown.extensions.codehilite": {"guess_lang": False} - }, + extension_configs=extensions_configs, output_format="xhtml5", ) diff --git a/pagure/pfmarkdown.py b/pagure/pfmarkdown.py index 4f2a3e2..5cf8baa 100644 --- a/pagure/pfmarkdown.py +++ b/pagure/pfmarkdown.py @@ -31,6 +31,7 @@ import markdown.preprocessors import markdown.util import pygit2 import six +import xml.etree.ElementTree as etree import pagure.lib.query from pagure.config import config as pagure_config @@ -100,7 +101,7 @@ class MentionPattern(markdown.inlinepatterns.Pattern): if not user: return text - element = markdown.util.etree.Element("a") + element = etree.Element("a") base_url = pagure_config["APP_URL"] if base_url.endswith("/"): base_url = base_url[:-1] @@ -338,7 +339,7 @@ class StrikeThroughPattern(markdown.inlinepatterns.Pattern): text = markdown.util.AtomicString(m.group(2)) - element = markdown.util.etree.Element("del") + element = etree.Element("del") element.text = text return element @@ -359,7 +360,7 @@ class AutolinkPattern2(markdown.inlinepatterns.Pattern): url = url[1:] if url.endswith(">"): url = url[:-1] - el = markdown.util.etree.Element("a") + el = etree.Element("a") el.set("href", self.unescape(url)) el.text = markdown.util.AtomicString(url) return el @@ -376,11 +377,11 @@ class ImagePatternLazyLoad(ImagePattern): el = out # Add a noscript tag with the untouched img tag - noscript = markdown.util.etree.Element("noscript") + noscript = etree.Element("noscript") noscript.append(el) # Modify the origina img tag - img = markdown.util.etree.Element("img") + img = etree.Element("img") img.set("data-src", el.get("src")) img.set("src", "") img.set("alt", el.get("alt")) @@ -388,7 +389,7 @@ class ImagePatternLazyLoad(ImagePattern): # Create a global span in which we add both the new img tag and the # noscript one - outel = markdown.util.etree.Element("span") + outel = etree.Element("span") outel.append(img) outel.append(noscript) @@ -607,7 +608,7 @@ def _obj_anchor_tag(user, namespace, repo, obj, text): else: title = obj.title - element = markdown.util.etree.Element("a") + element = etree.Element("a") element.set("href", url) element.set("title", title) element.text = text diff --git a/requirements.txt b/requirements.txt index 38b6351..5ffaa59 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,38 +1,38 @@ # Used for when working from a virtualenv. # Use this file by running "$ pip install -r requirements.txt" -alembic <= 1.8.1 +alembic <= 1.9.3 arrow <= 1.2.3 bcrypt <= 3.2.2 binaryornot == 0.4.4 bleach <= 5.0.1 blinker <= 1.5 -celery <= 5.2.6 -chardet <= 4.0.0 -cryptography <= 36.0.0 -docutils <= 0.17.1 +celery <= 5.3.1 +chardet <= 5.1.0 +cryptography <= 37.0.2 +docutils <= 0.19.0 # required for backward compatibility email_validator -flask <= 2.2.2 -flask-wtf <= 1.0.0 +flask <= 2.2.3 +flask-wtf <= 1.1.1 kitchen == 1.2.6 -markdown <= 3.3.7 +markdown <= 3.4.1 munch <= 2.5.0 -Pillow <= 9.2.0 +Pillow <= 9.4.0 psutil <= 5.9.2 -pygit2 >= 0.26.0, <=1.8.0 +pygit2 >= 0.26.0, <=1.12.0 python3-openid <= 3.2.0 python-openid-cla == 1.2 python-openid-teams == 1.1 -redis <= 3.5.3 -requests <= 2.28.1 +redis <= 4.3.4 +requests <= 2.28.2 six <= 1.16.0 # required for backward compatibility setuptools -sqlalchemy >= 0.8, <=1.4.46 +sqlalchemy >= 0.8, <=1.4.48 straight.plugin == 1.5.0 whitenoise <= 6.2.0 wtforms <= 3.0.1 diff --git a/tests/test_pagure_flask_internal.py b/tests/test_pagure_flask_internal.py index eae24a5..e47f1ce 100644 --- a/tests/test_pagure_flask_internal.py +++ b/tests/test_pagure_flask_internal.py @@ -1999,6 +1999,10 @@ class PagureFlaskInternaltests(tests.Modeltests): self.assertTrue( js_data2 in [ + { + "results": "GitError(\"reference 'refs/heads/master' not found\")" + }, + {"results": "reference 'refs/heads/master' not found"}, {"results": "reference 'refs/heads/master' not found"}, {"results": "Reference 'refs/heads/master' not found"}, ] @@ -2141,6 +2145,9 @@ class PagureFlaskInternaltests(tests.Modeltests): self.assertTrue( js_data2 in [ + { + "results": "GitError(\"reference 'refs/heads/master' not found\")" + }, {"results": "reference 'refs/heads/master' not found"}, {"results": "Reference 'refs/heads/master' not found"}, ] diff --git a/tests/test_pagure_flask_ui_issues.py b/tests/test_pagure_flask_ui_issues.py index 6d763cf..bd57542 100644 --- a/tests/test_pagure_flask_ui_issues.py +++ b/tests/test_pagure_flask_ui_issues.py @@ -1315,8 +1315,7 @@ class PagureFlaskIssuestests(tests.Modeltests): output_text, ) self.assertIn( - '' - "Log in\n to comment on this ticket.", + '' - "Log in\n to comment on this ticket.", + '' - "Log in\n to comment on this ticket.", + '\n', output_text, ) - self.assertTrue( - '' - "Log in\n to comment on this ticket." in output_text - ) + self.assertIn('' - "Log in\n to comment on this ticket." - in output.get_data(as_text=True) + '' - "Log in\n to comment on this ticket.", + '' - "Log in\n to comment on this ticket." - in output.get_data(as_text=True) + '' - "Log in\n to comment on this ticket.", + '\n', output_text, ) - self.assertTrue( - '' - "Log in\n to comment on this ticket." in output_text - ) + self.assertTrue(' Date: Sep 24 2023 04:43:04 +0000 Subject: [PATCH 2/12] Drop the dependency on python-trololio (in favor of asyncio) On Fedora 38, using python 3.11 'trololio' is broken and no updates have been made to it for almost 10 years. Time to use 'raw' asyncio. Details trololio feature two issues. 1) Trololio depend on deprecated `imp` module: ``` >>> from imp import find_module, load_module :1: DeprecationWarning: the imp module is deprecated in favour of importlib and slated for removal in Python 3.12; see the module's documentation for alternative uses ``` 2) Trololio's embedded asyncio module fails. So trololio methods are never defined. For example: ``` $ cat trolo-smoke.py from trololio import asyncio, coroutine @coroutine def coro(): yield From(asyncio.sleep(1)) $ python trolo-smoke.py AttributeError: module 'trololio.asyncio' has no attribute 'coroutine'. Did you mean: 'coroutines'? ``` The same issue can be seen in the `pagure-ev` logs ``` pagure_stream_server.py[192893]: File "/usr/libexec/pagure-ev/pagure_stream_server.py", line 140, in pagure_stream_server.py[192893]: @asyncio.coroutine pagure_stream_server.py[192893]: ^^^^^^^^^^^^^^^^^ pagure_stream_server.py[192893]: AttributeError: module 'asyncio' has no attribute 'coroutine'. Did you mean: 'coroutines'? ``` --- diff --git a/doc/install_pagure_ci.rst b/doc/install_pagure_ci.rst index 3b9ae78..68f7538 100644 --- a/doc/install_pagure_ci.rst +++ b/doc/install_pagure_ci.rst @@ -22,7 +22,6 @@ Configure your system python-jenkins python-redis - python-trololio .. note:: We ship a systemd unit file for pagure_ci but we welcome patches for scripts for other init systems. diff --git a/doc/install_pagure_ev.rst b/doc/install_pagure_ev.rst index 614f312..db6f78f 100644 --- a/doc/install_pagure_ev.rst +++ b/doc/install_pagure_ev.rst @@ -16,7 +16,6 @@ The eventsource server is easy to set-up. :: python-redis - python-trololio .. note:: We ship a systemd unit file for pagure_milter but we welcome patches for scripts for other init systems. diff --git a/doc/install_pagure_loadjson.rst b/doc/install_pagure_loadjson.rst index 4b13f06..407b672 100644 --- a/doc/install_pagure_loadjson.rst +++ b/doc/install_pagure_loadjson.rst @@ -14,7 +14,6 @@ Configure your system :: python-redis - python-trololio .. note:: We ship a systemd unit file for pagure_loadjson but we welcome patches for scripts for other init systems. diff --git a/doc/install_pagure_logcom.rst b/doc/install_pagure_logcom.rst index f92e0b3..4512dc4 100644 --- a/doc/install_pagure_logcom.rst +++ b/doc/install_pagure_logcom.rst @@ -14,7 +14,6 @@ Configure your system :: python-redis - python-trololio .. note:: We ship a systemd unit file for pagure_logcom but we welcome patches for scripts for other init systems. diff --git a/doc/install_pagure_webhooks.rst b/doc/install_pagure_webhooks.rst index 9aff374..9800817 100644 --- a/doc/install_pagure_webhooks.rst +++ b/doc/install_pagure_webhooks.rst @@ -17,7 +17,6 @@ Configure your system :: python-redis - python-trololio .. note:: We ship a systemd unit file for pagure_webhook but we welcome patches for scripts for other init systems. diff --git a/files/pagure.spec b/files/pagure.spec index d11614a..ce3c833 100644 --- a/files/pagure.spec +++ b/files/pagure.spec @@ -148,7 +148,6 @@ This is useful for example to allow commenting on a ticket by email. Summary: EventSource server for pagure BuildArch: noarch Requires: %{name} = %{version}-%{release} -Requires: python%{python_pkgversion}-trololio %{?systemd_requires} %description ev Pagure comes with an eventsource server allowing live update of the pages diff --git a/pagure-ev/pagure_stream_server.py b/pagure-ev/pagure_stream_server.py index 6908ea7..907fd45 100644 --- a/pagure-ev/pagure_stream_server.py +++ b/pagure-ev/pagure_stream_server.py @@ -26,7 +26,7 @@ import os import redis -import trololio +import asyncio from six.moves.urllib.parse import urlparse @@ -137,14 +137,12 @@ def get_obj_from_path(path): return getfunc(repo, objid) -@trololio.coroutine -def handle_client(client_reader, client_writer): +async def handle_client(client_reader, client_writer): data = None while True: # give client a chance to respond, timeout after 10 seconds - line = yield trololio.From( - trololio.asyncio.wait_for(client_reader.readline(), timeout=10.0) - ) + line = await asyncio.wait_for(client_reader.readline(), timeout=10.0) + if not line.decode().strip(): break line = line.decode().rstrip() @@ -204,16 +202,16 @@ def handle_client(client_reader, client_writer): client_writer.write(("event: ping\n\n").encode()) oncall = 0 oncall += 1 - yield trololio.From(client_writer.drain()) - yield trololio.From(trololio.asyncio.sleep(1)) + await client_writer.drain() + await asyncio.sleep(1) else: log.info("Sending %s", msg["data"]) client_writer.write(("data: %s\n\n" % msg["data"]).encode()) - yield trololio.From(client_writer.drain()) + await client_writer.drain() except OSError: log.info("Client closed connection") - except trololio.ConnectionResetError as err: + except ConnectionResetError as err: log.exception("ERROR: ConnectionResetError in handle_client") except Exception as err: log.exception("ERROR: Exception in handle_client") @@ -225,8 +223,7 @@ def handle_client(client_reader, client_writer): client_writer.close() -@trololio.coroutine -def stats(client_reader, client_writer): +async def stats(client_reader, client_writer): try: log.info("Clients: %s", SERVER.active_count) @@ -234,9 +231,9 @@ def stats(client_reader, client_writer): ("HTTP/1.0 200 OK\n" "Cache: nocache\n\n").encode() ) client_writer.write(("data: %s\n\n" % SERVER.active_count).encode()) - yield trololio.From(client_writer.drain()) + await client_writer.drain() - except trololio.ConnectionResetError as err: + except ConnectionResetError as err: log.info(err) finally: client_writer.close() @@ -248,8 +245,8 @@ def main(): _get_session() try: - loop = trololio.asyncio.get_event_loop() - coro = trololio.asyncio.start_server( + loop = asyncio.get_event_loop() + coro = asyncio.start_server( handle_client, host=None, port=pagure.config.config["EVENTSOURCE_PORT"], @@ -259,7 +256,7 @@ def main(): "Serving server at {}".format(SERVER.sockets[0].getsockname()) ) if pagure.config.config.get("EV_STATS_PORT"): - stats_coro = trololio.asyncio.start_server( + stats_coro = asyncio.start_server( stats, host=None, port=pagure.config.config.get("EV_STATS_PORT"), @@ -273,7 +270,7 @@ def main(): loop.run_forever() except KeyboardInterrupt: pass - except trololio.ConnectionResetError as err: + except ConnectionResetError as err: log.exception("ERROR: ConnectionResetError in main") except Exception: log.exception("ERROR: Exception in main") diff --git a/requirements-ev.txt b/requirements-ev.txt index e704325..e69de29 100644 --- a/requirements-ev.txt +++ b/requirements-ev.txt @@ -1 +0,0 @@ -trololio == 1.0 diff --git a/requirements-testing.txt b/requirements-testing.txt index 547e862..33a5f2c 100644 --- a/requirements-testing.txt +++ b/requirements-testing.txt @@ -18,7 +18,6 @@ pytest-cov <= 4.0.0 pytest-xdist <= 2.5.0 python-fedora == 1.1.1 -trololio == 1.0 # Seems that mock doesn't list this one funcsigs <= 1.0.2 From dc20ba1e5b1d27b1e6e7b8e25d5209906e98f207 Mon Sep 17 00:00:00 2001 From: Klaus Koder Date: Sep 24 2023 04:54:32 +0000 Subject: [PATCH 3/12] Replace deprecated imp with importlib `imp` is deprecated since version 3.4, will be removed in version 3.12: The `imp` module is deprecated in favor of `importlib`. Only one direct instance `tests/__init__.py` and one unused indirect instance in `straight.plugin` version 1.5, imported from `./pagure/lib/plugins.py`. The python module `straight.plugin.loaders` import `imp.find_module`, but it is not used. So can be removed: ``` /usr/lib/python3.11/site-packages/straight/plugin/loaders.py: - from imp import find_module + #from imp import find_module ``` Should probably be upstreamed. --- diff --git a/tests/__init__.py b/tests/__init__.py index 598ebf5..b3b7156 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -10,7 +10,7 @@ from __future__ import unicode_literals, absolute_import -import imp +import importlib as imp import json import logging import os From 6b3eaeeeb9edca55d30f5e774d58e150ae5dce52 Mon Sep 17 00:00:00 2001 From: Klaus Koder Date: Sep 24 2023 05:12:26 +0000 Subject: [PATCH 4/12] Update rpm-spec file and python requirements.txt Changed the requirements.txt max-versions to that from @zlopez PR 5396. RPM can be build and installed fc38. Update the the rpm-spec file: - remove _python_bytecompile_extra. - bump version to 5.13.4, one more than the currently released version from 2021. - add pagure_authorized_keys_worker.service - remove spurious %endif Corrected parameters to call of celery in runworker.py. Explicitly specify `python3-sqlalchemy1.3` in Fedora requirements. Add missing packages to `fedora-requirements.txt` to allow running `pagure` in a clean `mock` shell: ``` mock --enable-network -r fedora-38-x86_64 --shell \ -- mkdir -p pagure/{repos,docs,forks,tickets,requests,remotes} mock --enable-network -r fedora-38-x86_64 --shell \ -- cd pagure/ \; python3 createdb.py \; python3 runserver.py ``` centos8 can't run (`-r centos-stream+epel-8-x86_64') crashes with puff of `jinja2` messages. --- diff --git a/files/pagure.spec b/files/pagure.spec index ce3c833..28810b9 100644 --- a/files/pagure.spec +++ b/files/pagure.spec @@ -4,12 +4,9 @@ %global __python %{__python3} %global python_pkgversion %{python3_pkgversion} -# For now, to keep behavior consistent -%global _python_bytecompile_extra 1 - Name: pagure -Version: 5.13.2 +Version: 5.13.4 Release: 1%{?dist} Summary: A git-centered forge @@ -69,6 +66,26 @@ Requires: python%{python_pkgversion}-wtforms %{?systemd_requires} +%if 0%{?fedora} || 0%{?rhel} >= 8 +# We want to use cchardet whenever it's available +Recommends: python3-cchardet + +# If using PostgreSQL, the correct driver should be installed +Recommends: ((python3-psycopg2 or python3-pg8000) if postgresql-server) + +# If using MariaDB/MySQL, the correct driver should be installed +Recommends: ((python3-mysqlclient or python3-PyMySQL) if mysql-server) + +# If using Apache web server, the correct configuration should be installed +Recommends: (%{name}-web-apache-httpd if httpd) + +# If using Nginx web server, the correct configuration should be installed +Recommends: (%{name}-web-nginx if nginx) +%endif + +# We use the git tools for some actions due to deficiencies in libgit2 and pygit2 +Requires: git-core + # No dependency of the app per se, but required to make it working. Requires: gitolite3 @@ -86,7 +103,6 @@ BuildArch: noarch Requires: %{name} = %{version}-%{release} Requires: httpd-filesystem Requires: python%{python_pkgversion}-mod_wsgi -%endif %description web-apache-httpd This package provides the configuration files for deploying a Pagure server using the Apache HTTPD server. @@ -272,6 +288,10 @@ mkdir -p $RPM_BUILD_ROOT/%{_unitdir} install -p -m 644 files/pagure_worker.service \ $RPM_BUILD_ROOT/%{_unitdir}/pagure_worker.service +# Install the systemd file for the authorized_keys worker +install -p -m 644 files/pagure_authorized_keys_worker.service \ + $RPM_BUILD_ROOT/%{_unitdir}/pagure_authorized_keys_worker.service + # Install the systemd file for the gitolite worker install -p -m 644 files/pagure_gitolite_worker.service \ $RPM_BUILD_ROOT/%{_unitdir}/pagure_gitolite_worker.service @@ -363,13 +383,16 @@ for runnerhook in $runnerhooks; do ln -sf hookrunner $RPM_BUILD_ROOT/%{python_sitelib}/pagure/hooks/files/$runnerhook done +%if 0%{?fedora} || 0%{?rhel} >= 8 # Byte compile everything not in sitelib %py_byte_compile %{__python} %{buildroot}%{_datadir}/pagure/ %py_byte_compile %{__python} %{buildroot}%{_libexecdir}/pagure/ %py_byte_compile %{__python} %{buildroot}%{_libexecdir}/pagure-ev/ +%endif %post %systemd_post pagure_worker.service +%systemd_post pagure_authorized_keys_worker.service %systemd_post pagure_gitolite_worker.service %systemd_post pagure_api_key_expire_mail.timer %systemd_post pagure_mirror_project_in.timer @@ -393,6 +416,7 @@ done %preun %systemd_preun pagure_worker.service +%systemd_preun pagure_authorized_keys_worker.service %systemd_preun pagure_gitolite_worker.service %systemd_preun pagure_api_key_expire_mail.timer %systemd_preun pagure_mirror_project_in.timer @@ -416,6 +440,7 @@ done %postun %systemd_postun_with_restart pagure_worker.service +%systemd_postun_with_restart pagure_authorized_keys_worker.service %systemd_postun_with_restart pagure_gitolite_worker.service %systemd_postun pagure_api_key_expire_mail.timer %systemd_postun pagure_mirror_project_in.timer @@ -456,6 +481,7 @@ done %{python_sitelib}/pagure*.egg-info %{_bindir}/pagure-admin %{_unitdir}/pagure_worker.service +%{_unitdir}/pagure_authorized_keys_worker.service %{_unitdir}/pagure_gitolite_worker.service %{_unitdir}/pagure_api_key_expire_mail.service %{_unitdir}/pagure_api_key_expire_mail.timer diff --git a/pagure/__init__.py b/pagure/__init__.py index 823f4ae..86f6f95 100644 --- a/pagure/__init__.py +++ b/pagure/__init__.py @@ -11,4 +11,4 @@ from __future__ import absolute_import, unicode_literals __api_version__ = "0.31" -__version__ = "5.13.2" +__version__ = "5.13.4" diff --git a/requirements-fedora.txt b/requirements-fedora.txt index 26ac243..3724ab9 100644 --- a/requirements-fedora.txt +++ b/requirements-fedora.txt @@ -19,6 +19,10 @@ python3-openid-teams python3-psutil python3-pygit2 python3-redis -python3-sqlalchemy +python3-sqlalchemy1.3 python3-straight-plugin python3-wtforms +python3-whitenoise +python3-celery +python3-pillow +python3-email-validator diff --git a/requirements.txt b/requirements.txt index 5ffaa59..5e905b9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,7 +10,7 @@ celery <= 5.3.1 chardet <= 5.1.0 cryptography <= 37.0.2 docutils <= 0.19.0 - +enum34;python_version<"3.4" # required for backward compatibility email_validator @@ -22,7 +22,8 @@ munch <= 2.5.0 Pillow <= 9.4.0 psutil <= 5.9.2 pygit2 >= 0.26.0, <=1.12.0 -python3-openid <= 3.2.0 +python-openid;python_version<="2.7" +python3-openid;python_version>="3.0" python-openid-cla == 1.2 python-openid-teams == 1.1 redis <= 4.3.4 @@ -32,7 +33,7 @@ six <= 1.16.0 # required for backward compatibility setuptools -sqlalchemy >= 0.8, <=1.4.48 +sqlalchemy >= 0.8, <= 1.3.24 straight.plugin == 1.5.0 whitenoise <= 6.2.0 wtforms <= 3.0.1 @@ -48,3 +49,7 @@ wtforms <= 3.0.1 # Required only for the `fas` and `openid` authentication backends # python-fedora == 1.1.1 + +# pagure-ci +cryptography +python-jenkins diff --git a/runworker.py b/runworker.py index ffe94c7..9c55eaa 100755 --- a/runworker.py +++ b/runworker.py @@ -53,7 +53,7 @@ if args.config: config = os.path.join(here, config) env["PAGURE_CONFIG"] = config -cmd = [sys.executable, "-m", "celery", "-A", "worker", args.tasks] +cmd = [sys.executable, "-m", "celery", "-A", args.tasks, "worker"] if args.queue: cmd.extend(["-Q", args.queue]) From f4f5f55d5a778c3992bdc51144c71061299b5e0f Mon Sep 17 00:00:00 2001 From: Klaus Koder Date: Oct 02 2023 09:21:17 +0000 Subject: [PATCH 5/12] Fix Celery related exception in get_key_for_task @wombelix : celery introduce strict error handling of an empty key with https://github.com/celery/celery/commit/726b664840b6a1fcea9225b254a393e665363ad0 and is part of celery releases since 5.3.0. This causes a large amount of errors like this one in the unit tests. Tracked down to the decorator function `@pagure_task` in `pagure/lib/task_utils.py`, this can be solved by passing `self.task_id` to `update_state`. At this point, there is no task running and therefore no id assigned to `self.request.id` yet. By passing `self`, the request id will be added right after the task was started as part of the `update_state` call. All `task_id` related errors are gone in the unit tests after this change. --- diff --git a/pagure/lib/tasks_utils.py b/pagure/lib/tasks_utils.py index f65d7eb..9214b1e 100644 --- a/pagure/lib/tasks_utils.py +++ b/pagure/lib/tasks_utils.py @@ -28,7 +28,7 @@ def pagure_task(function): """Decorated function, actually does the work.""" if self is not None: try: - self.update_state(state="RUNNING") + self.update_state(self=self, state="RUNNING") except TypeError: pass session = pagure.lib.model_base.create_session(pagure_config["DB_URL"]) From 927e0514e95f4a9af58746bdea9a7d71f9a273eb Mon Sep 17 00:00:00 2001 From: Klaus Koder Date: Oct 02 2023 09:21:17 +0000 Subject: [PATCH 6/12] Fix self.assert(Not)Equals() DeprecationWarning For example: tests/test_pagure_utils.py::PagureUtilsTests::test_lookup_deploykey_non_existent_key pagure/tests/test_pagure_utils.py:75: DeprecationWarning: Please use assertEqual instead. self.assertEquals(res, None) --- diff --git a/tests/test_pagure_flask_api_project.py b/tests/test_pagure_flask_api_project.py index 2227dc6..9cef058 100644 --- a/tests/test_pagure_flask_api_project.py +++ b/tests/test_pagure_flask_api_project.py @@ -3482,7 +3482,7 @@ class PagureFlaskApiProjectModifyAclTests(tests.Modeltests): tests.create_tokens_acl(self.session, "aaabbbcccddd", "modify_project") project = pagure.lib.query._get_project(self.session, "test") - self.assertEquals( + self.assertEqual( project.access_users, {"admin": [], "collaborator": [], "commit": [], "ticket": []}, ) @@ -3746,7 +3746,7 @@ class PagureFlaskApiProjectModifyAclTests(tests.Modeltests): headers = {"Authorization": "token aaabbbcccddd"} project = pagure.lib.query._get_project(self.session, "test") - self.assertEquals( + self.assertEqual( project.access_users, {"admin": [], "collaborator": [], "commit": [], "ticket": []}, ) @@ -3795,7 +3795,7 @@ class PagureFlaskApiProjectModifyAclTests(tests.Modeltests): # Ensure `foo` was properly added: project = pagure.lib.query._get_project(self.session, "test") user_foo = pagure.lib.query.search_user(self.session, username="foo") - self.assertEquals( + self.assertEqual( project.access_users, { "admin": [], @@ -3877,7 +3877,7 @@ class PagureFlaskApiProjectModifyAclTests(tests.Modeltests): # Ensure `foo` was properly removed self.session = pagure.lib.query.create_session(self.dbpath) project = pagure.lib.query._get_project(self.session, "test") - self.assertEquals( + self.assertEqual( project.access_users, {"admin": [], "collaborator": [], "commit": [], "ticket": []}, ) @@ -3891,7 +3891,7 @@ class PagureFlaskApiProjectModifyAclTests(tests.Modeltests): # Ensure `foo` was properly added: project = pagure.lib.query._get_project(self.session, "test") user_foo = pagure.lib.query.search_user(self.session, username="foo") - self.assertEquals( + self.assertEqual( project.access_users, { "admin": [], @@ -3958,7 +3958,7 @@ class PagureFlaskApiProjectModifyAclTests(tests.Modeltests): # Ensure `foo` was properly removed self.session = pagure.lib.query.create_session(self.dbpath) project = pagure.lib.query._get_project(self.session, "test") - self.assertEquals( + self.assertEqual( project.access_users, {"admin": [], "collaborator": [], "commit": [], "ticket": []}, ) @@ -4039,15 +4039,15 @@ class PagureFlaskApiProjectModifyAclTests(tests.Modeltests): # Ensure `baz` was properly added self.session = pagure.lib.query.create_session(self.dbpath) project = pagure.lib.query._get_project(self.session, "test") - self.assertEquals( + self.assertEqual( project.access_users, {"admin": [], "collaborator": [], "commit": [], "ticket": []}, ) - self.assertNotEquals( + self.assertNotEqual( project.access_groups, {"admin": [], "collaborator": [], "commit": [], "ticket": []}, ) - self.assertEquals(len(project.access_groups["ticket"]), 1) + self.assertEqual(len(project.access_groups["ticket"]), 1) # Remove the group from the project data = {"user_type": "group", "name": "baz", "acl": None} @@ -4106,11 +4106,11 @@ class PagureFlaskApiProjectModifyAclTests(tests.Modeltests): # Ensure `baz` was properly removed self.session = pagure.lib.query.create_session(self.dbpath) project = pagure.lib.query._get_project(self.session, "test") - self.assertEquals( + self.assertEqual( project.access_users, {"admin": [], "collaborator": [], "commit": [], "ticket": []}, ) - self.assertEquals( + self.assertEqual( project.access_groups, {"admin": [], "collaborator": [], "commit": [], "ticket": []}, ) @@ -4191,11 +4191,11 @@ class PagureFlaskApiProjectModifyAclTests(tests.Modeltests): # Ensure `baz` was properly removed self.session = pagure.lib.query.create_session(self.dbpath) project = pagure.lib.query._get_project(self.session, "test") - self.assertEquals( + self.assertEqual( project.access_users, {"admin": [], "collaborator": [], "commit": [], "ticket": []}, ) - self.assertEquals( + self.assertEqual( project.access_groups, {"admin": [], "collaborator": [], "commit": [], "ticket": []}, ) @@ -4214,7 +4214,7 @@ class PagureFlaskApiProjectOptionsTests(tests.Modeltests): tests.create_tokens_acl(self.session, "aaabbbcccddd", "modify_project") project = pagure.lib.query._get_project(self.session, "test") - self.assertEquals( + self.assertEqual( project.access_users, {"admin": [], "collaborator": [], "commit": [], "ticket": []}, ) diff --git a/tests/test_pagure_flask_ui_repo.py b/tests/test_pagure_flask_ui_repo.py index 9603726..055830f 100644 --- a/tests/test_pagure_flask_ui_repo.py +++ b/tests/test_pagure_flask_ui_repo.py @@ -5450,8 +5450,8 @@ index 0000000..fb7093d tests.add_readme_git_repo(os.path.join(self.path, "repos", "test.git")) user = pagure.lib.query.search_user(self.session, username="pingou") - self.assertEquals(len(user.emails), 2) - self.assertEquals(user.default_email, "bar@pingou.com") + self.assertEqual(len(user.emails), 2) + self.assertEqual(user.default_email, "bar@pingou.com") user = tests.FakeUser(username="pingou") with tests.user_set(self.app.application, user): diff --git a/tests/test_pagure_flask_ui_roadmap.py b/tests/test_pagure_flask_ui_roadmap.py index f7eaa3b..9c8b4a4 100644 --- a/tests/test_pagure_flask_ui_roadmap.py +++ b/tests/test_pagure_flask_ui_roadmap.py @@ -662,7 +662,7 @@ class PagureFlaskRoadmaptests(tests.Modeltests): output_text, ) self.assertIn('', output_text) - self.assertEquals( + self.assertEqual( output_text.count(''), 1 ) diff --git a/tests/test_pagure_utils.py b/tests/test_pagure_utils.py index e39b694..71595be 100644 --- a/tests/test_pagure_utils.py +++ b/tests/test_pagure_utils.py @@ -60,23 +60,23 @@ class PagureUtilsTests(tests.SimplePagureTest): """Test lookup_deploykey with a non-deploykey username.""" project = pagure.lib.query._get_project(self.session, "test") res = pagure.utils.lookup_deploykey(project, "pingou") - self.assertEquals(res, None) + self.assertEqual(res, None) def test_lookup_deploykey_different_project(self): """Test lookup_deploykey with a username for another project.""" project = pagure.lib.query._get_project(self.session, "test2") res = pagure.utils.lookup_deploykey(project, "deploykey_test_1") - self.assertEquals(res, None) + self.assertEqual(res, None) def test_lookup_deploykey_non_existent_key(self): """Test lookup_deploykey with a non-existing deploykey.""" project = pagure.lib.query._get_project(self.session, "test") res = pagure.utils.lookup_deploykey(project, "deploykey_test_2") - self.assertEquals(res, None) + self.assertEqual(res, None) def test_lookup_deploykey(self): """Test lookup_deploykey with a correct username.""" project = pagure.lib.query._get_project(self.session, "test") res = pagure.utils.lookup_deploykey(project, "deploykey_test_1") - self.assertNotEquals(res, None) + self.assertNotEqual(res, None) self.assertFalse(res.pushaccess) From 94d5a07be0d0d6829dd1dabe8a8337d312ea8551 Mon Sep 17 00:00:00 2001 From: Klaus Koder Date: Oct 02 2023 09:21:17 +0000 Subject: [PATCH 7/12] Fix warning jinga2.escape DeprecationWarning For example ./pagure/ui/filters.py:580: DeprecationWarning: 'jinja2.escape' is deprecated and will be removed in Jinja 3.1. Import 'markupsafe.escape' instead. output = escape(author.name) --- diff --git a/pagure/doc_utils.py b/pagure/doc_utils.py index 9f3b5b2..3fb9d81 100644 --- a/pagure/doc_utils.py +++ b/pagure/doc_utils.py @@ -19,9 +19,9 @@ import docutils.core import docutils.examples try: - from jinja2 import escape -except ImportError: from markupsafe import escape +except ImportError: + from jinja2 import escape import kitchen.text.converters as ktc from markupsafe import Markup diff --git a/pagure/ui/filters.py b/pagure/ui/filters.py index 40cc276..0618bd0 100644 --- a/pagure/ui/filters.py +++ b/pagure/ui/filters.py @@ -27,9 +27,9 @@ import pygit2 import six try: - from jinja2 import escape -except ImportError: from markupsafe import escape +except ImportError: + from jinja2 import escape from six.moves.urllib.parse import parse_qsl, urlparse import pagure.exceptions From 52e097c558f836d5b8acdb7b6b0a4ac420cd7a15 Mon Sep 17 00:00:00 2001 From: Klaus Koder Date: Oct 02 2023 09:21:17 +0000 Subject: [PATCH 8/12] Fix create_remote() DeprecationWarning /usr/lib64/python3.11/site-packages/pygit2/repository.py:223: DeprecationWarning: Use repo.remotes.create(..) warnings.warn("Use repo.remotes.create(..)", DeprecationWarning) --- diff --git a/pagure/lib/git.py b/pagure/lib/git.py index ab66675..22b2585 100644 --- a/pagure/lib/git.py +++ b/pagure/lib/git.py @@ -1703,7 +1703,7 @@ def merge_pull_request(session, request, username, domerge=True): _log.info( " Adding remote: %s pointing to: %s", reponame, repopath ) - remote = new_repo.create_remote(reponame, repopath) + remote = new_repo.remotes.create(reponame, repopath) # Fetch the commits remote.fetch() @@ -2003,7 +2003,7 @@ def rebase_pull_request(session, request, username): _log.info( " Adding remote: %s pointing to: %s", upstream, upstream_path ) - remote = new_repo.create_remote(upstream, upstream_path) + remote = new_repo.remotes.create(upstream, upstream_path) # Fetch the commits remote.fetch() diff --git a/pagure/lib/tasks.py b/pagure/lib/tasks.py index 59000ad..9738035 100644 --- a/pagure/lib/tasks.py +++ b/pagure/lib/tasks.py @@ -655,7 +655,7 @@ def move_to_repospanner(self, session, name, namespace, user, region): continue repourl, _ = project.repospanner_repo_info(repotype, region) repo_obj = pagure.lib.repo.PagureRepo(repopath) - repo_obj.create_remote("repospanner_push", repourl) + repo_obj.remotes.create("repospanner_push", repourl) command = [ "git", diff --git a/tests/__init__.py b/tests/__init__.py index b3b7156..6479fd0 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1195,7 +1195,7 @@ def add_pull_request_git_repo( # Add the main project as remote repo upstream_path = os.path.join(folder, "repos", repo.path) - remote = clone_repo.create_remote("upstream", upstream_path) + remote = clone_repo.remotes.create("upstream", upstream_path) remote.fetch() # Edit the sources file again diff --git a/tests/test_pagure_flask_docs.py b/tests/test_pagure_flask_docs.py index 0752d3d..b828681 100644 --- a/tests/test_pagure_flask_docs.py +++ b/tests/test_pagure_flask_docs.py @@ -85,7 +85,7 @@ class PagureFlaskDocstests(tests.SimplePagureTest): ) # Push the changes to the bare repo - remote = repo.create_remote( + remote = repo.remotes.create( "origin", os.path.join(self.path, "repos", "docs", "test.git") ) diff --git a/tests/test_pagure_flask_ui_fork.py b/tests/test_pagure_flask_ui_fork.py index 8d33263..1630128 100644 --- a/tests/test_pagure_flask_ui_fork.py +++ b/tests/test_pagure_flask_ui_fork.py @@ -5440,7 +5440,7 @@ More information PagureRepo.push(ori_remote, refname) # Push to the fork repo - remote = clone_repo.create_remote("pingou_fork", gitrepo2) + remote = clone_repo.remotes.create("pingou_fork", gitrepo2) PagureRepo.push(remote, refname) # Add 1 commits to the fork repo diff --git a/tests/test_pagure_lib_git_diff_pr.py b/tests/test_pagure_lib_git_diff_pr.py index b677338..bda38cc 100644 --- a/tests/test_pagure_lib_git_diff_pr.py +++ b/tests/test_pagure_lib_git_diff_pr.py @@ -125,7 +125,7 @@ class PagureFlaskForkPrtests(tests.Modeltests): PagureRepo.push(ori_remote, refname) # Push to the fork repo - remote = clone_repo.create_remote("pingou_fork", gitrepo2) + remote = clone_repo.remotes.create("pingou_fork", gitrepo2) PagureRepo.push(remote, refname) # Do another 3 commits to the main repo From 59b344f5c3bb60c573a847d313e44cd4bb69859d Mon Sep 17 00:00:00 2001 From: Klaus Koder Date: Oct 02 2023 09:21:17 +0000 Subject: [PATCH 9/12] test_style: AssertionError These style *errors* are pretty annoing. IMHO the enforced format does not make code "better". I tried hard to satisfy flake/black and use less than 9 lines to express the original 2 lines (see pagure/ui/groups.py,app.py) that they complained about. ``` would reformat pagure/api/project.py would reformat pagure/ui/groups.py would reformat pagure/ui/oidc_login.py would reformat pagure/ui/app.py ``` --- diff --git a/pagure/api/project.py b/pagure/api/project.py index 6201daf..33d0b6f 100644 --- a/pagure/api/project.py +++ b/pagure/api/project.py @@ -1451,7 +1451,10 @@ def api_new_project(): 404, error_code=APIERROR.ENEWPROJECTDISABLED ) - if pagure_config["PAGURE_AUTH"] == 'oidc' and flask.g.fas_user.can_create is False: + if ( + pagure_config["PAGURE_AUTH"] == "oidc" + and flask.g.fas_user.can_create is False + ): raise pagure.exceptions.APIError( 403, error_code=APIERROR.ENEWPROJECTFORBIDDEN ) diff --git a/pagure/default_config.py b/pagure/default_config.py index d6cb960..615293b 100644 --- a/pagure/default_config.py +++ b/pagure/default_config.py @@ -65,7 +65,8 @@ ENABLE_NEW_PROJECTS = True # When using OIDC auth, users must be in this OIDC group to create new projects RESTRICT_CREATE_BY_OIDC_GROUP = None -# When using OIDC auth, users must be a member of RESTRICT_NEW_PROJECTS_BY_OIDC_GROUP and in total +# When using OIDC auth, users must be a member of +# RESTRICT_NEW_PROJECTS_BY_OIDC_GROUP and in total # this many groups to create new projects RESTRICT_CREATE_BY_OIDC_GROUP_COUNT = 0 diff --git a/pagure/ui/app.py b/pagure/ui/app.py index e6eba74..f351a23 100644 --- a/pagure/ui/app.py +++ b/pagure/ui/app.py @@ -1053,10 +1053,16 @@ def new_project(): description="Creation of new project is not allowed on this \ pagure instance", ) - - if pagure_config["PAGURE_AUTH"] == 'oidc' and flask.g.fas_user.can_create is False: - flask.abort(403,description="You are not allowed to create new projects on this instance") + if ( + pagure_config["PAGURE_AUTH"] == "oidc" + and flask.g.fas_user.can_create is False + ): + flask.abort( + 403, + description="You are not allowed to create new projects on \ + this instance", + ) namespaces = pagure_config["ALLOWED_PREFIX"][:] if user: diff --git a/pagure/ui/groups.py b/pagure/ui/groups.py index c089ec7..861f955 100644 --- a/pagure/ui/groups.py +++ b/pagure/ui/groups.py @@ -354,8 +354,15 @@ def add_group(): if not pagure_config.get("ENABLE_GROUP_MNGT", False): flask.abort(404) - if pagure_config["PAGURE_AUTH"] == 'oidc' and flask.g.fas_user.can_create is False: - flask.abort(403,description="You are not allowed to create new groups on this instance") + if ( + pagure_config["PAGURE_AUTH"] == "oidc" + and flask.g.fas_user.can_create is False + ): + flask.abort( + 403, + description="You are not allowed to create new \ + groups on this instance", + ) user = pagure.lib.query.search_user( flask.g.session, username=flask.g.fas_user.username diff --git a/pagure/ui/oidc_login.py b/pagure/ui/oidc_login.py index f3f37d2..431dad9 100644 --- a/pagure/ui/oidc_login.py +++ b/pagure/ui/oidc_login.py @@ -60,12 +60,17 @@ def fas_user_from_oidc(): pass oidc_group = pagure_config.get("RESTRICT_CREATE_BY_OIDC_GROUP", None) - oidc_group_count = pagure_config.get("RESTRICT_CREATE_BY_OIDC_GROUP_COUNT", 0) + oidc_group_count = pagure_config.get( + "RESTRICT_CREATE_BY_OIDC_GROUP_COUNT", 0 + ) can_create = True if oidc_group: if oidc_group not in info.get(groups_key, []): can_create = False - elif (oidc_group_count != 0) and (len(info.get(groups_key, [])) < oidc_group_count): + elif ( + oidc_group_count != 0 + and len(info.get(groups_key, [])) < oidc_group_count + ): can_create = False # Create the user object From 209063f3f5f114f8f39b24148ab2ba0524bd3eca Mon Sep 17 00:00:00 2001 From: Klaus Koder Date: Oct 02 2023 09:21:17 +0000 Subject: [PATCH 10/12] Fix AssertionError in test_api_error_codes Ryan Lerch introduced a new APIERROR enum in commit 02a5830dc, but forgot to update the test case: tests/test_pagure_flask_api.py Which fails with E AssertionError: 47 != 46 --- diff --git a/tests/test_pagure_flask_api.py b/tests/test_pagure_flask_api.py index 50f5223..fd3005e 100644 --- a/tests/test_pagure_flask_api.py +++ b/tests/test_pagure_flask_api.py @@ -176,7 +176,7 @@ class PagureFlaskApitests(tests.SimplePagureTest): output = self.app.get("/api/0/-/error_codes") self.assertEqual(output.status_code, 200) data = json.loads(output.get_data(as_text=True)) - self.assertEqual(len(data), 46) + self.assertEqual(len(data), 47) self.assertEqual( sorted(data.keys()), sorted( @@ -196,6 +196,7 @@ class PagureFlaskApitests(tests.SimplePagureTest): "EISSUENOTALLOWED", "EMODIFYPROJECTNOTALLOWED", "ENEWPROJECTDISABLED", + "ENEWPROJECTFORBIDDEN", "ENOCODE", "ENOCOMMENT", "ENOCOMMIT", From 18ad315fcaf7704aeb65b766c9b19c23c022059e Mon Sep 17 00:00:00 2001 From: Klaus Koder Date: Oct 02 2023 09:24:22 +0000 Subject: [PATCH 11/12] Fix "empty git" test cases Fix failing tests test_get_stats_commits_empty_git test_get_stats_commits_trend_empty_git Error caused by unhandled exception thrown by `pygit2 peel`. ``` Task pagure.lib.tasks.commits_history_stats[] raised unexpected: ExceptionWithTraceback() [] File "pagure/lib/tasks.py", line 1047, in commits_history_stats repo_obj.head.peel().oid.hex, pygit2.GIT_SORT_NONE ``` All `test_pagure_flask_internal` test pass: ``` $ pytest tests/test_pagure_flask_internal.py platform linux -- Python 3.11.2, pytest-7.2.2, pluggy-1.0.0 rootdir: /tmp/pagure plugins: anyio-3.5.0 collected 42 items tests/test_pagure_flask_internal.py [100%] 42 passed [] ``` --- diff --git a/pagure/lib/tasks.py b/pagure/lib/tasks.py index 9738035..481508d 100644 --- a/pagure/lib/tasks.py +++ b/pagure/lib/tasks.py @@ -962,13 +962,15 @@ def commits_author_stats(self, session, repopath): raise ValueError("Git repository not found.") repo_obj = pygit2.Repository(repopath) + try: + objids = repo_obj.head.peel().oid.hex + except pygit2.GitError as err: + return err stats = collections.defaultdict(int) number_of_commits = 0 authors_email = set() - for commit in repo_obj.walk( - repo_obj.head.peel().oid.hex, pygit2.GIT_SORT_NONE - ): + for commit in repo_obj.walk(objids, pygit2.GIT_SORT_NONE): # For each commit record how many times each combination of name and # e-mail appears in the git history. number_of_commits += 1 @@ -1025,11 +1027,13 @@ def commits_history_stats(self, session, repopath): raise ValueError("Git repository not found.") repo_obj = pygit2.Repository(repopath) + try: + objids = repo_obj.head.peel().oid.hex + except pygit2.GitError as err: + return err dates = collections.defaultdict(int) - for commit in repo_obj.walk( - repo_obj.head.peel().oid.hex, pygit2.GIT_SORT_NONE - ): + for commit in repo_obj.walk(objids, pygit2.GIT_SORT_NONE): delta = ( datetime.datetime.utcnow() - arrow.get(commit.commit_time).naive ) diff --git a/tests/test_pagure_flask_internal.py b/tests/test_pagure_flask_internal.py index e47f1ce..afaf0cb 100644 --- a/tests/test_pagure_flask_internal.py +++ b/tests/test_pagure_flask_internal.py @@ -2003,7 +2003,6 @@ class PagureFlaskInternaltests(tests.Modeltests): "results": "GitError(\"reference 'refs/heads/master' not found\")" }, {"results": "reference 'refs/heads/master' not found"}, - {"results": "reference 'refs/heads/master' not found"}, {"results": "Reference 'refs/heads/master' not found"}, ] ) From 8a7f37020ba0a9303a85d7e2d342e183770603ea Mon Sep 17 00:00:00 2001 From: Klaus Koder Date: Oct 03 2023 09:16:20 +0000 Subject: [PATCH 12/12] Fix PagureHooksPagureHooktests failure when system wide config exist When a pagure configuration file exist, for example, under `/etc/pagure/pagure.cfg` and the `APP_URL` key in that file is different from `http://localhost.localdomain/` then this test-case will fail (intermediately?). The root cause seem to be that `pagure_hook.py` keep a local version of the configuration from the time when the file was loaded, long time before the test-case create its configuration file. ``` pagure_config = pagure.config.reload_config() ``` The test case generate the configuration in `tests.setUp()`. A the timing looks like this: ``` $ pytest tests/ -k test_generate_revision_change_log_full_url_fork Using configuration file `/etc/pagure/pagure.cfg` tests/test_pagure_hooks_pagure_hook.py Detailed log of new commits: [...] ``` That looks a bit inefficient, notice how the local version of `pagure_config` inside `pagure_hook` is loaded from `/etc/pagure/pagure.cfg` even before the test case have been chosen. I can think of 3 ways to fix the issue. 1) Replace `"http://localhost.localdomain/"` with `mock.ANY`. 2) Pull the value of `pagure_config["APP_URL"]` from `pagure_hook` and use that in the test. 3) Fix the value of `pagure_config["APP_URL"]` using `mock.patch`. Here version 3. --- diff --git a/tests/test_pagure_hooks_pagure_hook.py b/tests/test_pagure_hooks_pagure_hook.py index 5123efa..162ecda 100644 --- a/tests/test_pagure_hooks_pagure_hook.py +++ b/tests/test_pagure_hooks_pagure_hook.py @@ -93,6 +93,10 @@ class PagureHooksPagureHooktests(tests.SimplePagureTest): # Add a README to the git repo - First commit tests.add_readme_git_repo(self.folder) + @mock.patch.dict( + "pagure.hooks.pagure_hook.pagure_config", + {"APP_URL": "http://localhost.localdomain/"}, + ) @mock.patch("pagure.hooks.pagure_hook.fixes_relation") def test_generate_revision_change_log_short_url(self, fixes_relation): """Test generate_revision_change_log when the comment contains @@ -125,6 +129,10 @@ class PagureHooksPagureHooktests(tests.SimplePagureTest): "http://localhost.localdomain/", ) + @mock.patch.dict( + "pagure.hooks.pagure_hook.pagure_config", + {"APP_URL": "http://localhost.localdomain/"}, + ) @mock.patch("pagure.hooks.pagure_hook.fixes_relation") def test_generate_revision_change_log_full_url(self, fixes_relation): """Test generate_revision_change_log when the comment contains @@ -161,6 +169,10 @@ class PagureHooksPagureHooktests(tests.SimplePagureTest): "http://localhost.localdomain/", ) + @mock.patch.dict( + "pagure.hooks.pagure_hook.pagure_config", + {"APP_URL": "http://localhost.localdomain/"}, + ) @mock.patch("pagure.hooks.pagure_hook.fixes_relation") def test_generate_revision_change_log_full_url_fork(self, fixes_relation): """Test generate_revision_change_log when the comment contains