openSUSE Commits
Threads by month
- ----- 2024 -----
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
June 2024
- 2 participants
- 1219 discussions
Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package kdb for openSUSE:Factory checked in at 2024-06-07 15:04:55
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/kdb (Old)
and /work/SRC/openSUSE:Factory/.kdb.new.24587 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "kdb"
Fri Jun 7 15:04:55 2024 rev:16 rq:1179159 version:3.2.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/kdb/kdb.changes 2024-02-07 18:54:10.659221858 +0100
+++ /work/SRC/openSUSE:Factory/.kdb.new.24587/kdb.changes 2024-06-07 15:05:57.869450819 +0200
@@ -1,0 +2,5 @@
+Fri Jun 7 08:57:55 UTC 2024 - Christophe Marin <christophe(a)krop.fr>
+
+- Enforce c++-17 to fix build with icu 75
+
+-------------------------------------------------------------------
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ kdb.spec ++++++
--- /var/tmp/diff_new_pack.4Ib3In/_old 2024-06-07 15:05:58.605477632 +0200
+++ /var/tmp/diff_new_pack.4Ib3In/_new 2024-06-07 15:05:58.609477778 +0200
@@ -100,7 +100,7 @@
sed -i 's#/usr/bin/env python$#/usr/bin/python3#' tools/sdc.py
%build
-%cmake_kf5 -d build
+%cmake_kf5 -d build -- -DCMAKE_CXX_STANDARD=17
%cmake_build
1
0
Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package pgn-extract for openSUSE:Factory checked in at 2024-06-07 15:04:48
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/pgn-extract (Old)
and /work/SRC/openSUSE:Factory/.pgn-extract.new.24587 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "pgn-extract"
Fri Jun 7 15:04:48 2024 rev:7 rq:1179142 version:24.09
Changes:
--------
--- /work/SRC/openSUSE:Factory/pgn-extract/pgn-extract.changes 2024-02-29 21:52:13.442085638 +0100
+++ /work/SRC/openSUSE:Factory/.pgn-extract.new.24587/pgn-extract.changes 2024-06-07 15:05:48.937125417 +0200
@@ -1,0 +2,14 @@
+Wed Jun 5 05:59:23 UTC 2024 - Andrea Manzini <andrea.manzini(a)suse.com>
+
+- Update to 24.09
+ * For tag matches using <> in which all matches are negative,
+ the absence of that tag from a game will result in the game being retained.
+ * Bug fix for relational operators matching numeric tags.
+ Comparisons are now 'anded' rather than 'ored'.
+ * Bug fix affecting material matches for games with a FEN tag in which Black is to move.
+ * Added options --commented , --insufficient, --suppressmatched and -n stdout
+ * <> relational operator now available for non-numeric tag values.
+ * EloDiff pseudo-tag added for matching differences in Elo rating between opponents
+ * Detect wrong to-move status in FEN string when the other side is in check.
+
+-------------------------------------------------------------------
Old:
----
pgn-extract-22-11.tgz
New:
----
pgn-extract-24-09.tgz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ pgn-extract.spec ++++++
--- /var/tmp/diff_new_pack.FaBBCS/_old 2024-06-07 15:05:49.821157622 +0200
+++ /var/tmp/diff_new_pack.FaBBCS/_new 2024-06-07 15:05:49.821157622 +0200
@@ -1,7 +1,7 @@
#
# spec file for package pgn-extract
#
-# Copyright (c) 2022 SUSE LLC
+# Copyright (c) 2024 SUSE LLC
# Copyright (c) 2010 Packman Team <packman(a)links2linux.de>
#
# All modifications and additions to the file contributed by third parties
@@ -18,8 +18,8 @@
Name: pgn-extract
-Version: 22.11
-%define mver 22-11
+Version: 24.09
+%define mver 24-09
Release: 0
Summary: A CLI program for manipulating PGN files
License: GPL-3.0-or-later
++++++ pgn-extract-22-11.tgz -> pgn-extract-24-09.tgz ++++++
++++ 3378 lines of diff (skipped)
++++++ pgn-extract-no-buildtime.patch ++++++
--- /var/tmp/diff_new_pack.FaBBCS/_old 2024-06-07 15:05:49.993163888 +0200
+++ /var/tmp/diff_new_pack.FaBBCS/_new 2024-06-07 15:05:49.997164033 +0200
@@ -2,7 +2,7 @@
===================================================================
--- pgn-extract.orig/argsfile.c
+++ pgn-extract/argsfile.c
-@@ -277,8 +277,8 @@ usage_and_exit(void)
+@@ -280,8 +280,8 @@ usage_and_exit(void)
const char **data = help_data;
fprintf(GlobalState.logfile,
@@ -11,6 +11,6 @@
+ "pgn-extract %s: a Portable Game Notation (PGN) manipulator.\n",
+ CURRENT_VERSION);
fprintf(GlobalState.logfile,
- "Copyright (C) 1994-2022 David J. Barnes (d.j.barnes(a)kent.ac.uk)\n");
+ "Copyright (C) 1994-2024 David J. Barnes (d.j.barnes(a)kent.ac.uk)\n");
fprintf(GlobalState.logfile, "%s\n\n", URL);
++++++ pgn-extract-set_eco.pgn_path.patch ++++++
--- /var/tmp/diff_new_pack.FaBBCS/_old 2024-06-07 15:05:50.013164616 +0200
+++ /var/tmp/diff_new_pack.FaBBCS/_new 2024-06-07 15:05:50.017164762 +0200
@@ -15,7 +15,7 @@
===================================================================
--- pgn-extract.orig/help.html
+++ pgn-extract/help.html
-@@ -243,7 +243,7 @@ of this page before attempting to use pg
+@@ -248,7 +248,7 @@ of this page before attempting to use pg
<li>-D - don't output duplicate extracted game scores.
<li>-eECO_file - perform ECO classification of games. The optional
ECO_file should contain a PGN format list of ECO lines
@@ -24,7 +24,7 @@
<li>-E[123 etc.] - split output into separate files according to ECO.
<ul>
<li>E1 : Produce files from ECO letter, A.pgn, B.pgn, ...
-@@ -1627,7 +1627,7 @@ believe that this was put together by Ew
+@@ -1674,7 +1674,7 @@ believe that this was put together by Ew
others, to whom appropriate thanks is due. The -e flag requests
pgn-extract to add/replace ECO classifications in the games it outputs.
This is done by firstly reading a file of ECO lines in PGN format
1
0
Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-pytest-testinfra for openSUSE:Factory checked in at 2024-06-07 15:04:47
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-pytest-testinfra (Old)
and /work/SRC/openSUSE:Factory/.python-pytest-testinfra.new.24587 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pytest-testinfra"
Fri Jun 7 15:04:47 2024 rev:7 rq:1179143 version:10.1.1
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-pytest-testinfra/python-pytest-testinfra.changes 2024-03-17 22:15:30.595300508 +0100
+++ /work/SRC/openSUSE:Factory/.python-pytest-testinfra.new.24587/python-pytest-testinfra.changes 2024-06-07 15:05:46.945052846 +0200
@@ -1,0 +2,10 @@
+Fri Jun 7 07:02:49 UTC 2024 - Dirk Müller <dmueller(a)suse.com>
+
+- update to 10.1.1:
+ * [FIX] Add check for the existence of ssh control path
+ directory
+ * [FIX] Handle is_installed for rpm package when rpm database
+ is corrupted
+ * [FIX] Fix service.exists
+
+-------------------------------------------------------------------
Old:
----
pytest-testinfra-10.1.0.tar.gz
New:
----
pytest-testinfra-10.1.1.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-pytest-testinfra.spec ++++++
--- /var/tmp/diff_new_pack.6ntiLX/_old 2024-06-07 15:05:47.397069312 +0200
+++ /var/tmp/diff_new_pack.6ntiLX/_new 2024-06-07 15:05:47.397069312 +0200
@@ -18,7 +18,7 @@
%{?sle15_python_module_pythons}
Name: python-pytest-testinfra
-Version: 10.1.0
+Version: 10.1.1
Release: 0
Summary: Python module to test infrastructures
License: Apache-2.0
++++++ pytest-testinfra-10.1.0.tar.gz -> pytest-testinfra-10.1.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-testinfra-10.1.0/CHANGELOG.rst new/pytest-testinfra-10.1.1/CHANGELOG.rst
--- old/pytest-testinfra-10.1.0/CHANGELOG.rst 2024-02-15 06:02:21.000000000 +0100
+++ new/pytest-testinfra-10.1.1/CHANGELOG.rst 2024-05-26 18:28:54.000000000 +0200
@@ -2,6 +2,13 @@
Changelog
=========
+10.1.1
+======
+
+* [FIX] Add check for the existence of ssh control path directory
+* [FIX] Handle is_installed for rpm package when rpm database is corrupted
+* [FIX] Fix service.exists
+
10.1.0
======
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-testinfra-10.1.0/PKG-INFO new/pytest-testinfra-10.1.1/PKG-INFO
--- old/pytest-testinfra-10.1.0/PKG-INFO 2024-02-15 06:02:35.177928700 +0100
+++ new/pytest-testinfra-10.1.1/PKG-INFO 2024-05-26 18:48:26.822989700 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: pytest-testinfra
-Version: 10.1.0
+Version: 10.1.1
Summary: Test infrastructures
Home-page: https://github.com/pytest-dev/pytest-testinfra
Author: Philippe Pepiot
@@ -23,20 +23,15 @@
Classifier: Framework :: Pytest
Requires-Python: >=3.9
Description-Content-Type: text/x-rst
-License-File: LICENSE
-Requires-Dist: pytest>=6
Provides-Extra: ansible
-Requires-Dist: ansible; extra == "ansible"
Provides-Extra: docker
Provides-Extra: kubectl
Provides-Extra: local
Provides-Extra: lxc
Provides-Extra: paramiko
-Requires-Dist: paramiko; extra == "paramiko"
Provides-Extra: salt
-Requires-Dist: salt; extra == "salt"
Provides-Extra: winrm
-Requires-Dist: pywinrm; extra == "winrm"
+License-File: LICENSE
##################################
Testinfra test your infrastructure
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-testinfra-10.1.0/images/debian_bookworm/Dockerfile new/pytest-testinfra-10.1.1/images/debian_bookworm/Dockerfile
--- old/pytest-testinfra-10.1.0/images/debian_bookworm/Dockerfile 2024-02-15 06:02:21.000000000 +0100
+++ new/pytest-testinfra-10.1.1/images/debian_bookworm/Dockerfile 2024-05-26 17:58:19.000000000 +0200
@@ -66,7 +66,12 @@
RUN /v/bin/pip install 'requests==2.30.0'
# install salt
-RUN python3 -m pip install --break-system-packages --no-cache salt
+ARG _BUILD_DEPS="gcc g++ libc6-dev python3-dev"
+RUN apt update && apt install -y $_BUILD_DEPS && \
+ python3 -m pip install --break-system-packages --no-cache salt && \
+ apt -y purge $_BUILD_DEPS && \
+ apt -y autoremove --purge && \
+ rm -rf /var/lib/apt/lists/*
ENV LANG fr_FR.ISO-8859-15
ENV LANGUAGE fr_FR
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-testinfra-10.1.0/pytest_testinfra.egg-info/PKG-INFO new/pytest-testinfra-10.1.1/pytest_testinfra.egg-info/PKG-INFO
--- old/pytest-testinfra-10.1.0/pytest_testinfra.egg-info/PKG-INFO 2024-02-15 06:02:35.000000000 +0100
+++ new/pytest-testinfra-10.1.1/pytest_testinfra.egg-info/PKG-INFO 2024-05-26 18:48:26.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: pytest-testinfra
-Version: 10.1.0
+Version: 10.1.1
Summary: Test infrastructures
Home-page: https://github.com/pytest-dev/pytest-testinfra
Author: Philippe Pepiot
@@ -23,20 +23,15 @@
Classifier: Framework :: Pytest
Requires-Python: >=3.9
Description-Content-Type: text/x-rst
-License-File: LICENSE
-Requires-Dist: pytest>=6
Provides-Extra: ansible
-Requires-Dist: ansible; extra == "ansible"
Provides-Extra: docker
Provides-Extra: kubectl
Provides-Extra: local
Provides-Extra: lxc
Provides-Extra: paramiko
-Requires-Dist: paramiko; extra == "paramiko"
Provides-Extra: salt
-Requires-Dist: salt; extra == "salt"
Provides-Extra: winrm
-Requires-Dist: pywinrm; extra == "winrm"
+License-File: LICENSE
##################################
Testinfra test your infrastructure
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-testinfra-10.1.0/test/test_modules.py new/pytest-testinfra-10.1.1/test/test_modules.py
--- old/pytest-testinfra-10.1.0/test/test_modules.py 2024-02-15 06:02:21.000000000 +0100
+++ new/pytest-testinfra-10.1.1/test/test_modules.py 2024-05-26 18:27:41.000000000 +0200
@@ -59,6 +59,17 @@
assert python.version.startswith("3.11.")
+(a)pytest.mark.destructive
+(a)pytest.mark.testinfra_hosts("docker://rockylinux9")
+def test_rpmdb_corrupted(host):
+ host.check_output("dd if=/dev/zero of=/var/lib/rpm/rpmdb.sqlite bs=1024 count=1")
+ with pytest.raises(RuntimeError) as excinfo:
+ host.package("zsh").is_installed
+ assert (
+ "Could not check if RPM package 'zsh' is installed. error: sqlite failure:"
+ ) in str(excinfo.value)
+
+
@pytest.mark.testinfra_hosts("docker://rockylinux9")
def test_non_default_package_tool(host):
# Make non default pkg tool binary present
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-testinfra-10.1.0/testinfra/backend/ssh.py new/pytest-testinfra-10.1.1/testinfra/backend/ssh.py
--- old/pytest-testinfra-10.1.0/testinfra/backend/ssh.py 2024-02-15 06:02:21.000000000 +0100
+++ new/pytest-testinfra-10.1.1/testinfra/backend/ssh.py 2024-05-26 18:27:41.000000000 +0200
@@ -27,7 +27,7 @@
ssh_config: Optional[str] = None,
ssh_identity_file: Optional[str] = None,
timeout: int = 10,
- controlpath: str = "",
+ controlpath: Optional[str] = None,
controlpersist: int = 60,
ssh_extra_args: Optional[str] = None,
*args: Any,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-testinfra-10.1.0/testinfra/modules/package.py new/pytest-testinfra-10.1.1/testinfra/modules/package.py
--- old/pytest-testinfra-10.1.0/testinfra/modules/package.py 2024-02-15 06:02:21.000000000 +0100
+++ new/pytest-testinfra-10.1.1/testinfra/modules/package.py 2024-05-26 18:27:41.000000000 +0200
@@ -165,7 +165,15 @@
class RpmPackage(Package):
@property
def is_installed(self):
- return self.run_test("rpm -q %s", self.name).rc == 0
+ result = self.run_test("rpm -q --quiet %s 2>&1", self.name)
+ if result.succeeded:
+ return True
+ elif result.failed and result.stdout == "":
+ return False
+ else:
+ raise RuntimeError(
+ f"Could not check if RPM package '{self.name}' is installed. {result.stdout}"
+ )
@property
def version(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-testinfra-10.1.0/testinfra/modules/service.py new/pytest-testinfra-10.1.1/testinfra/modules/service.py
--- old/pytest-testinfra-10.1.0/testinfra/modules/service.py 2024-02-15 06:02:21.000000000 +0100
+++ new/pytest-testinfra-10.1.1/testinfra/modules/service.py 2024-05-26 17:58:19.000000000 +0200
@@ -176,7 +176,7 @@
@property
def exists(self):
- cmd = self.run_test('systemctl list-unit-files | grep -q"^%s"', self.name)
+ cmd = self.run_test('systemctl list-unit-files | grep -q "^%s"', self.name)
return cmd.rc == 0
@property
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-testinfra-10.1.0/testinfra/utils/ansible_runner.py new/pytest-testinfra-10.1.1/testinfra/utils/ansible_runner.py
--- old/pytest-testinfra-10.1.0/testinfra/utils/ansible_runner.py 2024-02-15 06:02:21.000000000 +0100
+++ new/pytest-testinfra-10.1.1/testinfra/utils/ansible_runner.py 2024-05-26 18:27:41.000000000 +0200
@@ -187,13 +187,18 @@
control_path = config.get("ssh_connection", "control_path", fallback="", raw=True)
if control_path:
- directory = config.get(
+ control_path_dir = config.get(
"persistent_connection", "control_path_dir", fallback="~/.ansible/cp"
)
- control_path = control_path % ({"directory": directory}) # noqa: S001
- # restore original "%%"
- control_path = control_path.replace("%", "%%")
- kwargs["controlpath"] = control_path
+ control_path_dir = os.path.expanduser(control_path_dir)
+ control_path_dir = os.path.normpath(control_path_dir)
+
+ if os.path.isdir(control_path_dir):
+ control_path = control_path % ( # noqa: S001
+ {"directory": control_path_dir}
+ )
+ control_path = control_path.replace("%", "%%") # restore original "%%"
+ kwargs["controlpath"] = control_path
spec = "{}://".format(connection)
1
0
Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package gamescope for openSUSE:Factory checked in at 2024-06-07 15:04:36
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/gamescope (Old)
and /work/SRC/openSUSE:Factory/.gamescope.new.24587 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "gamescope"
Fri Jun 7 15:04:36 2024 rev:14 rq:1179090 version:3.14.18
Changes:
--------
--- /work/SRC/openSUSE:Factory/gamescope/gamescope.changes 2024-05-10 12:06:41.880890402 +0200
+++ /work/SRC/openSUSE:Factory/.gamescope.new.24587/gamescope.changes 2024-06-07 15:05:34.240590025 +0200
@@ -1,0 +2,16 @@
+Wed Jun 05 18:57:26 UTC 2024 - opensuse(a)dstoecker.de
+
+- Update to version 3.14.18:
+ * wayland_backend: Fix fractional scale bug
+ * wayland_backend: Fix cursor position with display scaling
+ * main: hide disabled backends from user
+ * Fix `sdl2_backend=disabled`
+ * layer: Attempt at fixing CI
+ * steamcompmgr: Handle FIFO stuff for Wayland windows
+ * layer: Get working with native Wayland applications
+ * steamcompmgr: Hook up more common stuff to XDG code
+ * all: Refactor IBackendFb to be owned by CVulkanTexture
+ * steamcompmgr: Don't re-enable applyOutputColorMgmt when dumping screen buffer for screenshots
+- Drop libliftoff-fix-gcc14-calloc-transposed-args.patch
+
+-------------------------------------------------------------------
Old:
----
gamescope-3.14.13.tar.xz
libliftoff-fix-gcc14-calloc-transposed-args.patch
New:
----
gamescope-3.14.18.tar.xz
BETA DEBUG BEGIN:
Old: * steamcompmgr: Don't re-enable applyOutputColorMgmt when dumping screen buffer for screenshots
- Drop libliftoff-fix-gcc14-calloc-transposed-args.patch
BETA DEBUG END:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ gamescope.spec ++++++
--- /var/tmp/diff_new_pack.V0csKc/_old 2024-06-07 15:05:35.464634617 +0200
+++ /var/tmp/diff_new_pack.V0csKc/_new 2024-06-07 15:05:35.464634617 +0200
@@ -18,15 +18,13 @@
%bcond_without intree_libs
Name: gamescope
-Version: 3.14.13
+Version: 3.14.18
Release: 0
Summary: Micro-compositor optimized for running video games on Wayland
License: BSD-2-Clause
Group: Amusements/Games/Other
URL: https://github.com/Plagman/gamescope
Source: %{name}-%{version}.tar.xz
-# PATCH-FIX-UPSTREAM libliftoff-fix-gcc14-calloc-transposed-args.patch -- Fixes libliftoff build with gcc14
-Patch1: libliftoff-fix-gcc14-calloc-transposed-args.patch
BuildRequires: cmake
BuildRequires: gcc-c++
BuildRequires: glslang-devel
@@ -128,6 +126,7 @@
%license LICENSE
%doc README.md
%{_bindir}/%{name}
+%{_bindir}/%{name}stream
%{_libdir}/libVkLayer_FROG_gamescope_wsi_%{_arch}.so
%dir %{_datadir}/vulkan/implicit_layer.d/
%{_datadir}/vulkan/implicit_layer.d/VkLayer_FROG_gamescope_wsi.%{_arch}.json
++++++ gamescope-3.14.13.tar.xz -> gamescope-3.14.18.tar.xz ++++++
/work/SRC/openSUSE:Factory/gamescope/gamescope-3.14.13.tar.xz /work/SRC/openSUSE:Factory/.gamescope.new.24587/gamescope-3.14.18.tar.xz differ: char 15, line 1
1
0
Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package os-autoinst for openSUSE:Factory checked in at 2024-06-07 15:04:33
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/os-autoinst (Old)
and /work/SRC/openSUSE:Factory/.os-autoinst.new.24587 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "os-autoinst"
Fri Jun 7 15:04:33 2024 rev:437 rq:1179088 version:4.6.1717514179.6646558
Changes:
--------
--- /work/SRC/openSUSE:Factory/os-autoinst/os-autoinst.changes 2024-05-24 19:52:39.256830995 +0200
+++ /work/SRC/openSUSE:Factory/.os-autoinst.new.24587/os-autoinst.changes 2024-06-07 15:05:28.404377414 +0200
@@ -1,0 +2,10 @@
+Tue Jun 04 15:16:28 UTC 2024 - okurz(a)suse.com
+
+- Update to version 4.6.1717514179.6646558:
+ * Modernize perl code
+ * Update Perl::Tidy version to 20240511.0.0
+ * Update to Leap 15.6 in CI workflow
+ * Change workflow logic to assume default root user
+ * Update actions versions to latest release
+
+-------------------------------------------------------------------
Old:
----
os-autoinst-4.6.1716387241.58dd214.obscpio
New:
----
os-autoinst-4.6.1717514179.6646558.obscpio
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ os-autoinst-devel-test.spec ++++++
--- /var/tmp/diff_new_pack.YXN9Ug/_old 2024-06-07 15:05:29.960434101 +0200
+++ /var/tmp/diff_new_pack.YXN9Ug/_new 2024-06-07 15:05:29.964434246 +0200
@@ -18,7 +18,7 @@
%define short_name os-autoinst-devel
Name: %{short_name}-test
-Version: 4.6.1716387241.58dd214
+Version: 4.6.1717514179.6646558
Release: 0
Summary: Test package for %{short_name}
License: GPL-2.0-or-later
++++++ os-autoinst-openvswitch-test.spec ++++++
--- /var/tmp/diff_new_pack.YXN9Ug/_old 2024-06-07 15:05:29.992435267 +0200
+++ /var/tmp/diff_new_pack.YXN9Ug/_new 2024-06-07 15:05:29.992435267 +0200
@@ -19,7 +19,7 @@
%define name_ext -test
%define short_name os-autoinst-openvswitch
Name: %{short_name}%{?name_ext}
-Version: 4.6.1716387241.58dd214
+Version: 4.6.1717514179.6646558
Release: 0
Summary: test package for %{short_name}
License: GPL-2.0-or-later
++++++ os-autoinst-test.spec ++++++
--- /var/tmp/diff_new_pack.YXN9Ug/_old 2024-06-07 15:05:30.024436432 +0200
+++ /var/tmp/diff_new_pack.YXN9Ug/_new 2024-06-07 15:05:30.024436432 +0200
@@ -19,7 +19,7 @@
%define name_ext -test
%define short_name os-autoinst
Name: %{short_name}%{?name_ext}
-Version: 4.6.1716387241.58dd214
+Version: 4.6.1717514179.6646558
Release: 0
Summary: test package for os-autoinst
License: GPL-2.0-or-later
++++++ os-autoinst.spec ++++++
--- /var/tmp/diff_new_pack.YXN9Ug/_old 2024-06-07 15:05:30.052437452 +0200
+++ /var/tmp/diff_new_pack.YXN9Ug/_new 2024-06-07 15:05:30.056437598 +0200
@@ -17,7 +17,7 @@
Name: os-autoinst
-Version: 4.6.1716387241.58dd214
+Version: 4.6.1717514179.6646558
Release: 0
Summary: OS-level test automation
License: GPL-2.0-or-later
++++++ os-autoinst-4.6.1716387241.58dd214.obscpio -> os-autoinst-4.6.1717514179.6646558.obscpio ++++++
/work/SRC/openSUSE:Factory/os-autoinst/os-autoinst-4.6.1716387241.58dd214.obscpio /work/SRC/openSUSE:Factory/.os-autoinst.new.24587/os-autoinst-4.6.1717514179.6646558.obscpio differ: char 49, line 1
++++++ os-autoinst.obsinfo ++++++
--- /var/tmp/diff_new_pack.YXN9Ug/_old 2024-06-07 15:05:30.136440512 +0200
+++ /var/tmp/diff_new_pack.YXN9Ug/_new 2024-06-07 15:05:30.140440658 +0200
@@ -1,5 +1,5 @@
name: os-autoinst
-version: 4.6.1716387241.58dd214
-mtime: 1716387241
-commit: 58dd214af1e54dedd925dba15276b42662283b00
+version: 4.6.1717514179.6646558
+mtime: 1717514179
+commit: 664655866ebd886b2bb9163bcec0ca6b371cccc7
1
0
Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-pytools for openSUSE:Factory checked in at 2024-06-07 15:04:30
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-pytools (Old)
and /work/SRC/openSUSE:Factory/.python-pytools.new.24587 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pytools"
Fri Jun 7 15:04:30 2024 rev:19 rq:1179086 version:2024.1.4
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-pytools/python-pytools.changes 2024-04-29 08:58:32.128910890 +0200
+++ /work/SRC/openSUSE:Factory/.python-pytools.new.24587/python-pytools.changes 2024-06-07 15:04:59.475323534 +0200
@@ -1,0 +2,9 @@
+Thu Jun 6 20:03:37 UTC 2024 - Dirk Müller <dmueller(a)suse.com>
+
+- update to 2024.1.4:
+ * remove get_read_from_map_from_permutation,
+ get_write_to_map_from_permutation
+ * KeyBuilder: support function hashing
+ * PersistentDict: Use sqlite as backend storage v2
+
+-------------------------------------------------------------------
Old:
----
pytools-2024.1.2.tar.gz
New:
----
pytools-2024.1.4.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-pytools.spec ++++++
--- /var/tmp/diff_new_pack.lcfvdg/_old 2024-06-07 15:05:01.643402517 +0200
+++ /var/tmp/diff_new_pack.lcfvdg/_new 2024-06-07 15:05:01.643402517 +0200
@@ -18,7 +18,7 @@
%{?sle15_python_module_pythons}
Name: python-pytools
-Version: 2024.1.2
+Version: 2024.1.4
Release: 0
Summary: A collection of tools for Python
License: MIT
@@ -30,6 +30,7 @@
BuildRequires: %{python_module platformdirs >= 2.2.0}
BuildRequires: %{python_module pytest}
BuildRequires: %{python_module setuptools}
+BuildRequires: %{python_module sqlite3}
BuildRequires: %{python_module typing_extensions if %python-base < 3.11}
BuildRequires: %{python_module wheel}
BuildRequires: fdupes
++++++ pytools-2024.1.2.tar.gz -> pytools-2024.1.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytools-2024.1.2/PKG-INFO new/pytools-2024.1.4/PKG-INFO
--- old/pytools-2024.1.2/PKG-INFO 2024-04-24 16:58:13.700250000 +0200
+++ new/pytools-2024.1.4/PKG-INFO 2024-05-31 19:41:22.161351700 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: pytools
-Version: 2024.1.2
+Version: 2024.1.4
Summary: A collection of tools for Python
Home-page: http://pypi.python.org/pypi/pytools
Author: Andreas Kloeckner
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytools-2024.1.2/pytools/__init__.py new/pytools-2024.1.4/pytools/__init__.py
--- old/pytools-2024.1.2/pytools/__init__.py 2024-03-20 19:39:03.000000000 +0100
+++ new/pytools-2024.1.4/pytools/__init__.py 2024-05-30 19:19:07.000000000 +0200
@@ -189,6 +189,7 @@
----------------
.. autofunction:: strtobool
+.. autofunction:: to_identifier
Sequence utilities
------------------
@@ -448,7 +449,7 @@
return "{}({})".format(
self.__class__.__name__,
", ".join(f"{fld}={getattr(self, fld)!r}"
- for fld in self.__class__.fields
+ for fld in sorted(self.__class__.fields)
if hasattr(self, fld)))
def register_fields(self, new_fields):
@@ -1524,68 +1525,6 @@
# }}}
-# {{{ index mangling
-
-def get_read_from_map_from_permutation(original, permuted):
- """With a permutation given by *original* and *permuted*,
- generate a list *rfm* of indices such that
- ``permuted[i] == original[rfm[i]]``.
-
- Requires that the permutation can be inferred from
- *original* and *permuted*.
-
- .. doctest ::
-
- >>> for p1 in generate_permutations(list(range(5))):
- ... for p2 in generate_permutations(list(range(5))):
- ... rfm = get_read_from_map_from_permutation(p1, p2)
- ... p2a = [p1[rfm[i]] for i in range(len(p1))]
- ... assert p2 == p2a
- """
- from warnings import warn
- warn("get_read_from_map_from_permutation is deprecated and will be "
- "removed in 2019", DeprecationWarning, stacklevel=2)
-
- assert len(original) == len(permuted)
- where_in_original = {
- original[i]: i for i in range(len(original))}
- assert len(where_in_original) == len(original)
- return tuple(where_in_original[pi] for pi in permuted)
-
-
-def get_write_to_map_from_permutation(original, permuted):
- """With a permutation given by *original* and *permuted*,
- generate a list *wtm* of indices such that
- ``permuted[wtm[i]] == original[i]``.
-
- Requires that the permutation can be inferred from
- *original* and *permuted*.
-
- .. doctest ::
-
- >>> for p1 in generate_permutations(list(range(5))):
- ... for p2 in generate_permutations(list(range(5))):
- ... wtm = get_write_to_map_from_permutation(p1, p2)
- ... p2a = [0] * len(p2)
- ... for i, oi in enumerate(p1):
- ... p2a[wtm[i]] = oi
- ... assert p2 == p2a
- """
- from warnings import warn
- warn("get_write_to_map_from_permutation is deprecated and will be "
- "removed in 2019", DeprecationWarning, stacklevel=2)
-
- assert len(original) == len(permuted)
-
- where_in_permuted = {
- permuted[i]: i for i in range(len(permuted))}
-
- assert len(where_in_permuted) == len(permuted)
- return tuple(where_in_permuted[oi] for oi in original)
-
-# }}}
-
-
# {{{ graph algorithms
from pytools.graph import a_star as a_star_moved
@@ -2998,6 +2937,33 @@
# }}}
+
+# {{{ to_identifier
+
+def to_identifier(s: str) -> str:
+ """Convert a string to a valid Python identifier, by removing
+ non-alphanumeric, non-underscore characters, and prepending an underscore
+ if the string starts with a numeric character.
+
+ :param s: The string to convert to an identifier.
+
+ :returns: The converted string.
+ """
+ if s.isidentifier():
+ return s
+
+ s = "".join(c for c in s if c.isalnum() or c == "_")
+
+ if len(s) == 0:
+ return "_"
+
+ if s[0].isdigit():
+ s = "_" + s
+
+ return s
+
+# }}}
+
# {{{ unique
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytools-2024.1.2/pytools/persistent_dict.py new/pytools-2024.1.4/pytools/persistent_dict.py
--- old/pytools-2024.1.2/pytools/persistent_dict.py 2024-04-23 17:15:32.000000000 +0200
+++ new/pytools-2024.1.4/pytools/persistent_dict.py 2024-05-30 19:19:07.000000000 +0200
@@ -29,15 +29,17 @@
THE SOFTWARE.
"""
-import errno
+
import hashlib
import logging
import os
-import shutil
+import pickle
+import sqlite3
import sys
from dataclasses import fields as dc_fields, is_dataclass
from enum import Enum
-from typing import TYPE_CHECKING, Any, Generic, Mapping, Optional, Protocol, TypeVar
+from typing import (
+ TYPE_CHECKING, Any, Generator, Mapping, Optional, Protocol, Tuple, TypeVar)
if TYPE_CHECKING:
@@ -64,8 +66,6 @@
This module also provides a disk-backed dictionary that uses persistent hashing.
.. autoexception:: NoSuchEntryError
-.. autoexception:: NoSuchEntryInvalidKeyError
-.. autoexception:: NoSuchEntryInvalidContentsError
.. autoexception:: NoSuchEntryCollisionError
.. autoexception:: ReadOnlyEntryError
@@ -90,108 +90,6 @@
"""
-# {{{ cleanup managers
-
-class CleanupBase:
- pass
-
-
-class CleanupManager(CleanupBase):
- def __init__(self):
- self.cleanups = []
-
- def register(self, c):
- self.cleanups.insert(0, c)
-
- def clean_up(self):
- for c in self.cleanups:
- c.clean_up()
-
- def error_clean_up(self):
- for c in self.cleanups:
- c.error_clean_up()
-
-
-class LockManager(CleanupBase):
- def __init__(self, cleanup_m, lock_file, stacklevel=0):
- self.lock_file = lock_file
-
- attempts = 0
- while True:
- try:
- self.fd = os.open(self.lock_file,
- os.O_CREAT | os.O_WRONLY | os.O_EXCL)
- break
- except OSError:
- pass
-
- # This value was chosen based on the py-filelock package:
- # https://github.com/tox-dev/py-filelock/blob/a6c8fabc4192fa7a4ae19b1875ee842…
- wait_time_seconds = 0.05
-
- # Warn every 10 seconds if not able to acquire lock
- warn_attempts = int(10/wait_time_seconds)
-
- # Exit after 60 seconds if not able to acquire lock
- exit_attempts = int(60/wait_time_seconds)
-
- from time import sleep
- sleep(wait_time_seconds)
-
- attempts += 1
-
- if attempts % warn_attempts == 0:
- from warnings import warn
- warn("could not obtain lock -- "
- f"delete '{self.lock_file}' if necessary",
- stacklevel=1 + stacklevel)
-
- if attempts > exit_attempts:
- raise RuntimeError("waited more than one minute "
- f"on the lock file '{self.lock_file}' "
- "-- something is wrong")
-
- cleanup_m.register(self)
-
- def clean_up(self):
- os.close(self.fd)
- os.unlink(self.lock_file)
-
- def error_clean_up(self):
- pass
-
-
-class ItemDirManager(CleanupBase):
- def __init__(self, cleanup_m, path, delete_on_error):
- from os.path import isdir
-
- self.existed = isdir(path)
- self.path = path
- self.delete_on_error = delete_on_error
-
- cleanup_m.register(self)
-
- def reset(self):
- try:
- shutil.rmtree(self.path)
- except OSError as e:
- if e.errno != errno.ENOENT:
- raise
-
- def mkdir(self):
- from os import makedirs
- makedirs(self.path, exist_ok=True)
-
- def clean_up(self):
- pass
-
- def error_clean_up(self):
- if self.delete_on_error:
- self.reset()
-
-# }}}
-
-
# {{{ key generation
class Hash(Protocol):
@@ -402,7 +300,7 @@
key_hash.update(b"<None>")
@staticmethod
- def update_for_dtype(key_hash, key):
+ def update_for_dtype(key_hash: Hash, key: Any) -> None:
key_hash.update(key.str.encode("utf8"))
# Handling numpy >= 1.20, for which
@@ -410,11 +308,11 @@
# Introducing this method allows subclasses to specially handle all those
# dtypes.
@staticmethod
- def update_for_specific_dtype(key_hash, key):
+ def update_for_specific_dtype(key_hash: Hash, key: Any) -> None:
key_hash.update(key.str.encode("utf8"))
@staticmethod
- def update_for_numpy_scalar(key_hash: Hash, key) -> None:
+ def update_for_numpy_scalar(key_hash: Hash, key: Any) -> None:
import numpy as np
if hasattr(np, "complex256") and key.dtype == np.dtype("complex256"):
key_hash.update(repr(complex(key)).encode("utf8"))
@@ -430,7 +328,7 @@
self.rec(key_hash, fld.name)
self.rec(key_hash, getattr(key, fld.name, None))
- def update_for_attrs(self, key_hash: Hash, key) -> None:
+ def update_for_attrs(self, key_hash: Hash, key: Any) -> None:
self.rec(key_hash, f"{type(key).__qualname__}.{type(key).__name__}")
for fld in attrs.fields(key.__class__):
@@ -449,6 +347,43 @@
update_for_PMap = update_for_frozendict # noqa: N815
update_for_Map = update_for_frozendict # noqa: N815
+ # {{{ date, time, datetime, timezone
+
+ def update_for_date(self, key_hash: Hash, key: Any) -> None:
+ # 'date' has no timezone information; it is always naive
+ self.rec(key_hash, key.isoformat())
+
+ def update_for_time(self, key_hash: Hash, key: Any) -> None:
+ # 'time' should differentiate between naive and aware
+ import datetime
+
+ # Convert to datetime object
+ self.rec(key_hash, datetime.datetime.combine(datetime.date.min, key))
+ self.rec(key_hash, "<time>")
+
+ def update_for_datetime(self, key_hash: Hash, key: Any) -> None:
+ # 'datetime' should differentiate between naive and aware
+
+ # https://docs.python.org/3.11/library/datetime.html#determining-if-an-object…
+ if key.tzinfo is not None and key.tzinfo.utcoffset(key) is not None:
+ self.rec(key_hash, key.timestamp())
+ self.rec(key_hash, "<aware>")
+ else:
+ from datetime import timezone
+ self.rec(key_hash, key.replace(tzinfo=timezone.utc).timestamp())
+ self.rec(key_hash, "<naive>")
+
+ def update_for_timezone(self, key_hash: Hash, key: Any) -> None:
+ self.rec(key_hash, repr(key))
+
+ # }}}
+
+ def update_for_function(self, key_hash: Hash, key: Any) -> None:
+ self.rec(key_hash, key.__module__ + key.__qualname__)
+
+ if key.__closure__:
+ self.rec(key_hash, tuple(c.cell_contents for c in key.__closure__))
+
# }}}
# }}}
@@ -461,18 +396,6 @@
pass
-class NoSuchEntryInvalidKeyError(NoSuchEntryError):
- """Raised when an entry is not found in a :class:`PersistentDict` due to an
- invalid key file."""
- pass
-
-
-class NoSuchEntryInvalidContentsError(NoSuchEntryError):
- """Raised when an entry is not found in a :class:`PersistentDict` due to an
- invalid contents file."""
- pass
-
-
class NoSuchEntryCollisionError(NoSuchEntryError):
"""Raised when an entry is not found in a :class:`PersistentDict`, but it
contains an entry with the same hash key (hash collision)."""
@@ -490,15 +413,27 @@
pass
+def __getattr__(name: str) -> Any:
+ if name in ("NoSuchEntryInvalidKeyError",
+ "NoSuchEntryInvalidContentsError"):
+ from warnings import warn
+ warn(f"pytools.persistent_dict.{name} has been removed.")
+ return NoSuchEntryError
+
+ raise AttributeError(name)
+
+
K = TypeVar("K")
V = TypeVar("V")
-class _PersistentDictBase(Generic[K, V]):
+class _PersistentDictBase(Mapping[K, V]):
def __init__(self, identifier: str,
key_builder: Optional[KeyBuilder] = None,
- container_dir: Optional[str] = None) -> None:
+ container_dir: Optional[str] = None,
+ enable_wal: bool = False) -> None:
self.identifier = identifier
+ self.conn = None
if key_builder is None:
key_builder = KeyBuilder()
@@ -512,112 +447,126 @@
if sys.platform == "darwin" and os.getenv("XDG_CACHE_HOME") is not None:
# platformdirs does not handle XDG_CACHE_HOME on macOS
# https://github.com/platformdirs/platformdirs/issues/269
- cache_dir = join(os.getenv("XDG_CACHE_HOME"), "pytools")
+ container_dir = join(os.getenv("XDG_CACHE_HOME"), "pytools")
else:
- cache_dir = platformdirs.user_cache_dir("pytools", "pytools")
+ container_dir = platformdirs.user_cache_dir("pytools", "pytools")
- container_dir = join(
- cache_dir,
- "pdict-v4-{}-py{}".format(
- identifier,
- ".".join(str(i) for i in sys.version_info)))
+ self.filename = join(container_dir, f"pdict-v5-{identifier}"
+ + ".".join(str(i) for i in sys.version_info)
+ + ".sqlite")
self.container_dir = container_dir
-
self._make_container_dir()
- @staticmethod
- def _warn(msg: str, category: Any = UserWarning, stacklevel: int = 0) -> None:
- from warnings import warn
- warn(msg, category, stacklevel=1 + stacklevel)
-
- def store_if_not_present(self, key: K, value: V,
- _stacklevel: int = 0) -> None:
- """Store (*key*, *value*) if *key* is not already present."""
- self.store(key, value, _skip_if_present=True, _stacklevel=1 + _stacklevel)
-
- def store(self, key: K, value: V, _skip_if_present: bool = False,
- _stacklevel: int = 0) -> None:
- """Store (*key*, *value*) in the dictionary."""
- raise NotImplementedError()
-
- def fetch(self, key: K, _stacklevel: int = 0) -> V:
- """Return the value associated with *key* in the dictionary."""
- raise NotImplementedError()
-
- @staticmethod
- def _read(path: str) -> V:
- from pickle import load
- with open(path, "rb") as inf:
- return load(inf)
-
- @staticmethod
- def _write(path: str, value: V) -> None:
- from pickle import HIGHEST_PROTOCOL, dump
- with open(path, "wb") as outf:
- dump(value, outf, protocol=HIGHEST_PROTOCOL)
-
- def _item_dir(self, hexdigest_key: str) -> str:
- from os.path import join
-
- # Some file systems limit the number of directories in a directory.
- # For ext4, that limit appears to be 64K for example.
- # This doesn't solve that problem, but it makes it much less likely
-
- return join(self.container_dir,
- hexdigest_key[:3],
- hexdigest_key[3:6],
- hexdigest_key[6:])
-
- def _key_file(self, hexdigest_key: str) -> str:
- from os.path import join
- return join(self._item_dir(hexdigest_key), "key")
-
- def _contents_file(self, hexdigest_key: str) -> str:
- from os.path import join
- return join(self._item_dir(hexdigest_key), "contents")
-
- def _lock_file(self, hexdigest_key: str) -> str:
- from os.path import join
- return join(self.container_dir, str(hexdigest_key) + ".lock")
-
- def _make_container_dir(self) -> None:
- """Create the container directory to store the dictionary."""
- os.makedirs(self.container_dir, exist_ok=True)
+ # isolation_level=None: enable autocommit mode
+ # https://www.sqlite.org/lang_transaction.html#implicit_versus_explicit_trans…
+ self.conn = sqlite3.connect(self.filename, isolation_level=None)
+
+ self.conn.execute(
+ "CREATE TABLE IF NOT EXISTS dict "
+ "(keyhash TEXT NOT NULL PRIMARY KEY, key_value TEXT NOT NULL)"
+ )
+
+ # https://www.sqlite.org/wal.html
+ if enable_wal:
+ self.conn.execute("PRAGMA journal_mode = 'WAL'")
+
+ # Note: the following configuration values were taken from litedict:
+ # https://github.com/litements/litedict/blob/377603fa597453ffd9997186a493ed4f…
+ # They result in fast operations while maintaining database integrity
+ # even in the face of concurrent accesses and power loss.
+
+ # temp_store=2: use in-memory temp store
+ # https://www.sqlite.org/pragma.html#pragma_temp_store
+ self.conn.execute("PRAGMA temp_store = 2")
+
+ # https://www.sqlite.org/pragma.html#pragma_synchronous
+ self.conn.execute("PRAGMA synchronous = NORMAL")
+
+ # 64 MByte of cache
+ # https://www.sqlite.org/pragma.html#pragma_cache_size
+ self.conn.execute("PRAGMA cache_size = -64000")
+
+ def __del__(self) -> None:
+ if self.conn:
+ self.conn.close()
- def _collision_check(self, key: K, stored_key: K, _stacklevel: int) -> None:
+ def _collision_check(self, key: K, stored_key: K) -> None:
if stored_key != key:
# Key collision, oh well.
- self._warn(f"{self.identifier}: key collision in cache at "
+ from warnings import warn
+ warn(f"{self.identifier}: key collision in cache at "
f"'{self.container_dir}' -- these are sufficiently unlikely "
"that they're often indicative of a broken hash key "
"implementation (that is not considering some elements "
"relevant for equality comparison)",
- CollisionWarning,
- 1 + _stacklevel)
+ CollisionWarning
+ )
# This is here so we can step through equality comparison to
# see what is actually non-equal.
stored_key == key # pylint:disable=pointless-statement # noqa: B015
raise NoSuchEntryCollisionError(key)
+ def store_if_not_present(self, key: K, value: V) -> None:
+ """Store (*key*, *value*) if *key* is not already present."""
+ self.store(key, value, _skip_if_present=True)
+
+ def store(self, key: K, value: V, _skip_if_present: bool = False) -> None:
+ """Store (*key*, *value*) in the dictionary."""
+ raise NotImplementedError()
+
+ def fetch(self, key: K) -> V:
+ """Return the value associated with *key* in the dictionary."""
+ raise NotImplementedError()
+
+ def _make_container_dir(self) -> None:
+ """Create the container directory to store the dictionary."""
+ os.makedirs(self.container_dir, exist_ok=True)
+
def __getitem__(self, key: K) -> V:
"""Return the value associated with *key* in the dictionary."""
- return self.fetch(key, _stacklevel=1)
+ return self.fetch(key)
def __setitem__(self, key: K, value: V) -> None:
"""Store (*key*, *value*) in the dictionary."""
- self.store(key, value, _stacklevel=1)
+ self.store(key, value)
+
+ def __len__(self) -> int:
+ """Return the number of entries in the dictionary."""
+ return next(self.conn.execute("SELECT COUNT(*) FROM dict"))[0]
+
+ def __iter__(self) -> Generator[K, None, None]:
+ """Return an iterator over the keys in the dictionary."""
+ return self.keys()
+
+ def keys(self) -> Generator[K, None, None]:
+ """Return an iterator over the keys in the dictionary."""
+ for row in self.conn.execute("SELECT key_value FROM dict ORDER BY rowid"):
+ yield pickle.loads(row[0])[0]
+
+ def values(self) -> Generator[V, None, None]:
+ """Return an iterator over the values in the dictionary."""
+ for row in self.conn.execute("SELECT key_value FROM dict ORDER BY rowid"):
+ yield pickle.loads(row[0])[1]
+
+ def items(self) -> Generator[tuple[K, V], None, None]:
+ """Return an iterator over the items in the dictionary."""
+ for row in self.conn.execute("SELECT key_value FROM dict ORDER BY rowid"):
+ yield pickle.loads(row[0])
+
+ def nbytes(self) -> int:
+ """Return the size of the dictionary in bytes."""
+ return next(self.conn.execute("SELECT page_size * page_count FROM "
+ "pragma_page_size(), pragma_page_count()"))[0]
+
+ def __repr__(self) -> str:
+ """Return a string representation of the dictionary."""
+ return f"{type(self).__name__}({self.filename}, nitems={len(self)})"
def clear(self) -> None:
"""Remove all entries from the dictionary."""
- try:
- shutil.rmtree(self.container_dir)
- except OSError as e:
- if e.errno != errno.ENOENT:
- raise
-
- self._make_container_dir()
+ self.conn.execute("DELETE FROM dict")
class WriteOncePersistentDict(_PersistentDictBase[K, V]):
@@ -627,6 +576,13 @@
Compared with :class:`PersistentDict`, this class has faster
retrieval times because it uses an LRU cache to cache entries in memory.
+ .. note::
+
+ This class intentionally does not store all values with a certain
+ key, based on the assumption that key conflicts are highly unlikely,
+ and if they occur, almost always due to a bug in the hash key
+ generation code (:class:`KeyBuilder`).
+
.. automethod:: __init__
.. automethod:: __getitem__
.. automethod:: __setitem__
@@ -639,19 +595,23 @@
def __init__(self, identifier: str,
key_builder: Optional[KeyBuilder] = None,
container_dir: Optional[str] = None,
+ enable_wal: bool = False,
in_mem_cache_size: int = 256) -> None:
"""
- :arg identifier: a file-name-compatible string identifying this
+ :arg identifier: a filename-compatible string identifying this
dictionary
:arg key_builder: a subclass of :class:`KeyBuilder`
:arg container_dir: the directory in which to store this
dictionary. If ``None``, the default cache directory from
:func:`platformdirs.user_cache_dir` is used
+ :arg enable_wal: enable write-ahead logging (WAL) mode. This mode
+ is faster than the default rollback journal mode, but it is
+ not compatible with network filesystems.
:arg in_mem_cache_size: retain an in-memory cache of up to
*in_mem_cache_size* items (with an LRU replacement policy)
"""
- _PersistentDictBase.__init__(self, identifier, key_builder, container_dir)
- self._in_mem_cache_size = in_mem_cache_size
+ _PersistentDictBase.__init__(self, identifier, key_builder,
+ container_dir, enable_wal)
from functools import lru_cache
self._fetch = lru_cache(maxsize=in_mem_cache_size)(self._fetch)
@@ -661,129 +621,38 @@
.. versionadded:: 2023.1.1
"""
-
self._fetch.cache_clear()
- def _spin_until_removed(self, lock_file: str, stacklevel: int) -> None:
- from os.path import exists
-
- attempts = 0
- while exists(lock_file):
- from time import sleep
- sleep(1)
-
- attempts += 1
-
- if attempts > 10:
- self._warn(
- f"waiting until unlocked--delete '{lock_file}' if necessary",
- stacklevel=1 + stacklevel)
-
- if attempts > 3 * 60:
- raise RuntimeError("waited more than three minutes "
- f"on the lock file '{lock_file}'"
- "--something is wrong")
-
- def store(self, key: K, value: V, _skip_if_present: bool = False,
- _stacklevel: int = 0) -> None:
- hexdigest_key = self.key_builder(key)
-
- cleanup_m = CleanupManager()
- try:
- try:
- LockManager(cleanup_m, self._lock_file(hexdigest_key),
- 1 + _stacklevel)
- item_dir_m = ItemDirManager(
- cleanup_m, self._item_dir(hexdigest_key),
- delete_on_error=False)
-
- if item_dir_m.existed:
- if _skip_if_present:
- return
- raise ReadOnlyEntryError(key)
-
- item_dir_m.mkdir()
-
- key_path = self._key_file(hexdigest_key)
- value_path = self._contents_file(hexdigest_key)
-
- self._write(value_path, value)
- self._write(key_path, key)
-
- logger.debug("%s: disk cache store [key=%s]",
- self.identifier, hexdigest_key)
- except Exception:
- cleanup_m.error_clean_up()
- raise
- finally:
- cleanup_m.clean_up()
-
- def fetch(self, key: K, _stacklevel: int = 0) -> Any:
- hexdigest_key = self.key_builder(key)
-
- (stored_key, stored_value) = self._fetch(hexdigest_key, 1 + _stacklevel)
-
- self._collision_check(key, stored_key, 1 + _stacklevel)
-
- return stored_value
-
- def _fetch(self, hexdigest_key: str, # pylint:disable=method-hidden
- _stacklevel: int = 0) -> V:
- # This is separate from fetch() to allow for LRU caching
-
- # {{{ check path exists and is unlocked
-
- item_dir = self._item_dir(hexdigest_key)
-
- from os.path import isdir
- if not isdir(item_dir):
- logger.debug("%s: disk cache miss [key=%s]",
- self.identifier, hexdigest_key)
- raise NoSuchEntryError(hexdigest_key)
-
- lock_file = self._lock_file(hexdigest_key)
- self._spin_until_removed(lock_file, 1 + _stacklevel)
-
- # }}}
-
- key_file = self._key_file(hexdigest_key)
- contents_file = self._contents_file(hexdigest_key)
-
- # Note: Unlike PersistentDict, this doesn't autodelete invalid entires,
- # because that would lead to a race condition.
-
- # {{{ load key file and do equality check
+ def store(self, key: K, value: V, _skip_if_present: bool = False) -> None:
+ keyhash = self.key_builder(key)
+ v = pickle.dumps((key, value))
try:
- read_key = self._read(key_file)
- except Exception as e:
- self._warn(f"{type(self).__name__}({self.identifier}) "
- f"encountered an invalid key file for key {hexdigest_key}. "
- f"Remove the directory '{item_dir}' if necessary. "
- f"(caught: {type(e).__name__}: {e})",
- stacklevel=1 + _stacklevel)
- raise NoSuchEntryInvalidKeyError(hexdigest_key)
-
- # }}}
+ self.conn.execute("INSERT INTO dict VALUES (?, ?)", (keyhash, v))
+ except sqlite3.IntegrityError:
+ if not _skip_if_present:
+ raise ReadOnlyEntryError("WriteOncePersistentDict, "
+ "tried overwriting key")
+
+ def _fetch(self, keyhash: str) -> Tuple[K, V]: # pylint:disable=method-hidden
+ # This method is separate from fetch() to allow for LRU caching
+ c = self.conn.execute("SELECT key_value FROM dict WHERE keyhash=?",
+ (keyhash,))
+ row = c.fetchone()
+ if row is None:
+ raise KeyError
+ return pickle.loads(row[0])
- logger.debug("%s: disk cache hit [key=%s]",
- self.identifier, hexdigest_key)
-
- # {{{ load contents
+ def fetch(self, key: K) -> V:
+ keyhash = self.key_builder(key)
try:
- read_contents = self._read(contents_file)
- except Exception as e:
- self._warn(f"{type(self).__name__}({self.identifier}) "
- f"encountered an invalid contents file for key {hexdigest_key}. "
- f"Remove the directory '{item_dir}' if necessary."
- f"(caught: {type(e).__name__}: {e})",
- stacklevel=1 + _stacklevel)
- raise NoSuchEntryInvalidContentsError(hexdigest_key)
-
- # }}}
-
- return (read_key, read_contents)
+ stored_key, value = self._fetch(keyhash)
+ except KeyError:
+ raise NoSuchEntryError(key)
+ else:
+ self._collision_check(key, stored_key)
+ return value
def clear(self) -> None:
_PersistentDictBase.clear(self)
@@ -793,6 +662,13 @@
class PersistentDict(_PersistentDictBase[K, V]):
"""A concurrent disk-backed dictionary.
+ .. note::
+
+ This class intentionally does not store all values with a certain
+ key, based on the assumption that key conflicts are highly unlikely,
+ and if they occur, almost always due to a bug in the hash key
+ generation code (:class:`KeyBuilder`).
+
.. automethod:: __init__
.. automethod:: __getitem__
.. automethod:: __setitem__
@@ -806,161 +682,72 @@
def __init__(self,
identifier: str,
key_builder: Optional[KeyBuilder] = None,
- container_dir: Optional[str] = None) -> None:
+ container_dir: Optional[str] = None,
+ enable_wal: bool = False) -> None:
"""
- :arg identifier: a file-name-compatible string identifying this
+ :arg identifier: a filename-compatible string identifying this
dictionary
:arg key_builder: a subclass of :class:`KeyBuilder`
:arg container_dir: the directory in which to store this
dictionary. If ``None``, the default cache directory from
:func:`platformdirs.user_cache_dir` is used
+ :arg enable_wal: enable write-ahead logging (WAL) mode. This mode
+ is faster than the default rollback journal mode, but it is
+ not compatible with network filesystems.
"""
- _PersistentDictBase.__init__(self, identifier, key_builder, container_dir)
+ _PersistentDictBase.__init__(self, identifier, key_builder,
+ container_dir, enable_wal)
- def store(self, key: K, value: V, _skip_if_present: bool = False,
- _stacklevel: int = 0) -> None:
- hexdigest_key = self.key_builder(key)
+ def store(self, key: K, value: V, _skip_if_present: bool = False) -> None:
+ keyhash = self.key_builder(key)
+ v = pickle.dumps((key, value))
+
+ if _skip_if_present:
+ self.conn.execute("INSERT OR IGNORE INTO dict VALUES (?, ?)",
+ (keyhash, v))
+ else:
+ self.conn.execute("INSERT OR REPLACE INTO dict VALUES (?, ?)",
+ (keyhash, v))
- cleanup_m = CleanupManager()
- try:
- try:
- LockManager(cleanup_m, self._lock_file(hexdigest_key),
- 1 + _stacklevel)
- item_dir_m = ItemDirManager(
- cleanup_m, self._item_dir(hexdigest_key),
- delete_on_error=True)
-
- if item_dir_m.existed:
- if _skip_if_present:
- return
- item_dir_m.reset()
-
- item_dir_m.mkdir()
-
- key_path = self._key_file(hexdigest_key)
- value_path = self._contents_file(hexdigest_key)
-
- self._write(value_path, value)
- self._write(key_path, key)
-
- logger.debug("%s: cache store [key=%s]",
- self.identifier, hexdigest_key)
- except Exception:
- cleanup_m.error_clean_up()
- raise
- finally:
- cleanup_m.clean_up()
-
- def fetch(self, key: K, _stacklevel: int = 0) -> V:
- hexdigest_key = self.key_builder(key)
- item_dir = self._item_dir(hexdigest_key)
-
- from os.path import isdir
- if not isdir(item_dir):
- logger.debug("%s: cache miss [key=%s]",
- self.identifier, hexdigest_key)
+ def fetch(self, key: K) -> V:
+ keyhash = self.key_builder(key)
+
+ c = self.conn.execute("SELECT key_value FROM dict WHERE keyhash=?",
+ (keyhash,))
+ row = c.fetchone()
+ if row is None:
raise NoSuchEntryError(key)
- cleanup_m = CleanupManager()
- try:
- try:
- LockManager(cleanup_m, self._lock_file(hexdigest_key),
- 1 + _stacklevel)
- item_dir_m = ItemDirManager(
- cleanup_m, item_dir, delete_on_error=False)
-
- key_path = self._key_file(hexdigest_key)
- value_path = self._contents_file(hexdigest_key)
-
- # {{{ load key
-
- try:
- read_key = self._read(key_path)
- except Exception as e:
- item_dir_m.reset()
- self._warn(f"{type(self).__name__}({self.identifier}) "
- "encountered an invalid key file for key "
- f"{hexdigest_key}. Entry deleted."
- f"(caught: {type(e).__name__}: {e})",
- stacklevel=1 + _stacklevel)
- raise NoSuchEntryInvalidKeyError(key)
-
- self._collision_check(key, read_key, 1 + _stacklevel)
-
- # }}}
-
- logger.debug("%s: cache hit [key=%s]",
- self.identifier, hexdigest_key)
-
- # {{{ load value
-
- try:
- read_contents = self._read(value_path)
- except Exception as e:
- item_dir_m.reset()
- self._warn(f"{type(self).__name__}({self.identifier}) "
- "encountered an invalid contents file for key "
- f"{hexdigest_key}. Entry deleted."
- f"(caught: {type(e).__name__}: {e})",
- stacklevel=1 + _stacklevel)
- raise NoSuchEntryInvalidContentsError(key)
-
- return read_contents
-
- # }}}
-
- except Exception:
- cleanup_m.error_clean_up()
- raise
- finally:
- cleanup_m.clean_up()
+ stored_key, value = pickle.loads(row[0])
+ self._collision_check(key, stored_key)
+ return value
- def remove(self, key: K, _stacklevel: int = 0) -> None:
+ def remove(self, key: K) -> None:
"""Remove the entry associated with *key* from the dictionary."""
- hexdigest_key = self.key_builder(key)
+ keyhash = self.key_builder(key)
- item_dir = self._item_dir(hexdigest_key)
- from os.path import isdir
- if not isdir(item_dir):
- raise NoSuchEntryError(key)
+ self.conn.execute("BEGIN EXCLUSIVE TRANSACTION")
- cleanup_m = CleanupManager()
try:
- try:
- LockManager(cleanup_m, self._lock_file(hexdigest_key),
- 1 + _stacklevel)
- item_dir_m = ItemDirManager(
- cleanup_m, item_dir, delete_on_error=False)
- key_file = self._key_file(hexdigest_key)
-
- # {{{ load key
-
- try:
- read_key = self._read(key_file)
- except Exception as e:
- item_dir_m.reset()
- self._warn(f"{type(self).__name__}({self.identifier}) "
- "encountered an invalid key file for key "
- f"{hexdigest_key}. Entry deleted"
- f"(caught: {type(e).__name__}: {e})",
- stacklevel=1 + _stacklevel)
- raise NoSuchEntryInvalidKeyError(key)
-
- self._collision_check(key, read_key, 1 + _stacklevel)
-
- # }}}
-
- item_dir_m.reset()
-
- except Exception:
- cleanup_m.error_clean_up()
- raise
- finally:
- cleanup_m.clean_up()
+ # This is split into SELECT/DELETE to allow for a collision check
+ c = self.conn.execute("SELECT key_value FROM dict WHERE keyhash=?",
+ (keyhash,))
+ row = c.fetchone()
+ if row is None:
+ raise NoSuchEntryError(key)
+
+ stored_key, _value = pickle.loads(row[0])
+ self._collision_check(key, stored_key)
+
+ self.conn.execute("DELETE FROM dict WHERE keyhash=?", (keyhash,))
+ self.conn.execute("COMMIT")
+ except Exception as e:
+ self.conn.execute("ROLLBACK")
+ raise e
def __delitem__(self, key: K) -> None:
"""Remove the entry associated with *key* from the dictionary."""
- self.remove(key, _stacklevel=1)
+ self.remove(key)
# }}}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytools-2024.1.2/pytools/test/test_persistent_dict.py new/pytools-2024.1.4/pytools/test/test_persistent_dict.py
--- old/pytools-2024.1.2/pytools/test/test_persistent_dict.py 2024-04-23 17:15:32.000000000 +0200
+++ new/pytools-2024.1.4/pytools/test/test_persistent_dict.py 2024-05-30 19:19:07.000000000 +0200
@@ -169,6 +169,9 @@
del pdict[0]
with pytest.raises(NoSuchEntryError):
+ pdict.remove(0)
+
+ with pytest.raises(NoSuchEntryError):
pdict.fetch(0)
with pytest.raises(NoSuchEntryError):
@@ -598,6 +601,105 @@
!= keyb(MyAttrs("hi", 1))) # type: ignore[call-arg]
+def test_datetime_hashing() -> None:
+ keyb = KeyBuilder()
+
+ import datetime
+
+ # {{{ date
+ # No timezone info; date is always naive
+ assert (keyb(datetime.date(2020, 1, 1))
+ == keyb(datetime.date(2020, 1, 1))
+ == "9fb97d7faabc3603f3e334ca5eb1eb0fe0c92665e5611cb1b5aa77fa0f70f5e3")
+ assert keyb(datetime.date(2020, 1, 1)) != keyb(datetime.date(2020, 1, 2))
+
+ # }}}
+
+ # {{{ time
+
+ # Must distinguish between naive and aware time objects
+
+ # Naive time
+ assert (keyb(datetime.time(12, 0))
+ == keyb(datetime.time(12, 0))
+ == keyb(datetime.time(12, 0, 0))
+ == keyb(datetime.time(12, 0, 0, 0))
+ == "288ec82f6a00ac15968d4d257d4aca1089b863c61ef2ee200e64351238397705")
+ assert keyb(datetime.time(12, 0)) != keyb(datetime.time(12, 1))
+
+ # Aware time
+ t1 = datetime.time(12, 0, tzinfo=datetime.timezone.utc)
+ t2 = datetime.time(7, 0,
+ tzinfo=datetime.timezone(datetime.timedelta(hours=-5)))
+ t3 = datetime.time(7, 0,
+ tzinfo=datetime.timezone(datetime.timedelta(hours=-4)))
+
+ assert t1 == t2
+ assert (keyb(t1)
+ == keyb(t2)
+ == "3587427ca9d581779d532b397df206ddeadfcf4e38b1ee69c19174e8e1268cc4")
+
+ assert t1 != t3
+ assert keyb(t1) != keyb(t3)
+
+ # }}}
+
+ # {{{ datetime
+
+ # must distinguish between naive and aware datetime objects
+
+ # Aware datetime
+ dt1 = datetime.datetime(2020, 1, 1, 12, tzinfo=datetime.timezone.utc)
+ dt2 = datetime.datetime(2020, 1, 1, 7,
+ tzinfo=datetime.timezone(datetime.timedelta(hours=-5)))
+
+ assert dt1 == dt2
+ assert (keyb(dt1)
+ == keyb(dt2)
+ == "cd35722af47e42cb3bc81c389b87eb2e78ee8e20298bb1d8a193b30940d1c142")
+
+ dt3 = datetime.datetime(2020, 1, 1, 7,
+ tzinfo=datetime.timezone(datetime.timedelta(hours=-4)))
+
+ assert dt1 != dt3
+ assert keyb(dt1) != keyb(dt3)
+
+ # Naive datetime
+ dt4 = datetime.datetime(2020, 1, 1, 6) # matches dt1 'naively'
+ assert dt1 != dt4 # naive and aware datetime objects are never equal
+ assert keyb(dt1) != keyb(dt4)
+
+ assert (keyb(datetime.datetime(2020, 1, 1))
+ == keyb(datetime.datetime(2020, 1, 1))
+ == keyb(datetime.datetime(2020, 1, 1, 0, 0, 0, 0))
+ == "8f3b843d7b9176afd8e2ce97ebc19789098a1c7774c4ec00d4054ec954ce2b88"
+ )
+ assert keyb(datetime.datetime(2020, 1, 1)) != keyb(datetime.datetime(2020, 1, 2))
+ assert (keyb(datetime.datetime(2020, 1, 1))
+ != keyb(datetime.datetime(2020, 1, 1, tzinfo=datetime.timezone.utc)))
+
+ # }}}
+
+ # {{{ timezone
+
+ tz1 = datetime.timezone(datetime.timedelta(hours=-4))
+ tz2 = datetime.timezone(datetime.timedelta(hours=0))
+ tz3 = datetime.timezone.utc
+
+ assert tz1 != tz2
+ assert keyb(tz1) != keyb(tz2)
+
+ assert tz1 != tz3
+ assert keyb(tz1) != keyb(tz3)
+
+ assert tz2 == tz3
+ assert (keyb(tz2)
+ == keyb(tz3)
+ == "89bd615f32c1f209b0853b1fc7d06ddb6fda7f367a00a8621d60337d52cb8d10")
+
+ # }}}
+
+
def test_xdg_cache_home() -> None:
import os
xdg_dir = "tmpdir_pytools_xdg_test"
@@ -620,6 +722,172 @@
shutil.rmtree(xdg_dir)
+def test_speed():
+ import time
+
+ tmpdir = tempfile.mkdtemp()
+ pdict = WriteOncePersistentDict("pytools-test", container_dir=tmpdir)
+
+ start = time.time()
+ for i in range(10000):
+ pdict[i] = i
+ end = time.time()
+ print("persistent dict write time: ", end-start)
+
+ start = time.time()
+ for _ in range(5):
+ for i in range(10000):
+ pdict[i]
+ end = time.time()
+ print("persistent dict read time: ", end-start)
+
+ shutil.rmtree(tmpdir)
+
+
+def test_size():
+ try:
+ tmpdir = tempfile.mkdtemp()
+ pdict = PersistentDict("pytools-test", container_dir=tmpdir)
+
+ for i in range(10000):
+ pdict[f"foobarbazfoobbb{i}"] = i
+
+ size = pdict.nbytes()
+ print("sqlite size: ", size/1024/1024, " MByte")
+ assert 1*1024*1024 < size < 2*1024*1024
+ finally:
+ shutil.rmtree(tmpdir)
+
+
+def test_len():
+ try:
+ tmpdir = tempfile.mkdtemp()
+ pdict = PersistentDict("pytools-test", container_dir=tmpdir)
+
+ assert len(pdict) == 0
+
+ for i in range(10000):
+ pdict[i] = i
+
+ assert len(pdict) == 10000
+
+ pdict.clear()
+
+ assert len(pdict) == 0
+ finally:
+ shutil.rmtree(tmpdir)
+
+
+def test_repr():
+ try:
+ tmpdir = tempfile.mkdtemp()
+ pdict = PersistentDict("pytools-test", container_dir=tmpdir)
+
+ assert repr(pdict)[:15] == "PersistentDict("
+ finally:
+ shutil.rmtree(tmpdir)
+
+
+def test_keys_values_items():
+ try:
+ tmpdir = tempfile.mkdtemp()
+ pdict = PersistentDict("pytools-test", container_dir=tmpdir)
+
+ for i in range(10000):
+ pdict[i] = i
+
+ # This also tests deterministic iteration order
+ assert len(list(pdict.keys())) == 10000 == len(set(pdict.keys()))
+ assert list(pdict.keys()) == list(range(10000))
+ assert list(pdict.values()) == list(range(10000))
+ assert list(pdict.items()) == list(zip(list(pdict.keys()), range(10000)))
+
+ assert ([k for k in pdict.keys()] # noqa: C416
+ == list(pdict.keys())
+ == list(pdict)
+ == [k for k in pdict]) # noqa: C416
+
+ finally:
+ shutil.rmtree(tmpdir)
+
+
+def global_fun():
+ pass
+
+
+def global_fun2():
+ pass
+
+
+def test_hash_function() -> None:
+ keyb = KeyBuilder()
+
+ # {{{ global functions
+
+ assert keyb(global_fun) == keyb(global_fun) == \
+ "51b5980dd3a8aa13f6e83869e4a04c22973d7aaf96cb22899abdfdc55e15c9b2"
+ assert keyb(global_fun) != keyb(global_fun2)
+
+ # }}}
+
+ # {{{ closures
+
+ def get_fun(x):
+ def add_x(y):
+ return x + y
+ return add_x
+
+ f1 = get_fun(1)
+ f11 = get_fun(1)
+ f2 = get_fun(2)
+
+ fa = get_fun
+ fb = get_fun
+
+ assert fa == fb
+ assert keyb(fa) == keyb(fb)
+
+ assert f1 != f2
+ assert keyb(f1) != keyb(f2)
+
+ # FIXME: inconsistency!
+ assert f1 != f11
+ assert hash(f1) != hash(f11)
+ assert keyb(f1) == keyb(f11)
+
+ # }}}
+
+ # {{{ local functions
+
+ def local_fun():
+ pass
+
+ def local_fun2():
+ pass
+
+ assert keyb(local_fun) == keyb(local_fun) == \
+ "fc58f5b0130df821913c848749eb03f5dcd4da7a568c6130f1c0cfb96ed0d12d"
+ assert keyb(local_fun) != keyb(local_fun2)
+
+ # }}}
+
+ # {{{ methods
+
+ class C1:
+ def method(self):
+ pass
+
+ class C2:
+ def method(self):
+ pass
+
+ assert keyb(C1.method) == keyb(C1.method) == \
+ "3013eb424dac133a57bd70cb6084d2a2f349a247714efc508fe3b10b99b6f717"
+ assert keyb(C1.method) != keyb(C2.method)
+
+ # }}}
+
+
if __name__ == "__main__":
if len(sys.argv) > 1:
exec(sys.argv[1])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytools-2024.1.2/pytools/test/test_pytools.py new/pytools-2024.1.4/pytools/test/test_pytools.py
--- old/pytools-2024.1.2/pytools/test/test_pytools.py 2024-04-23 17:15:32.000000000 +0200
+++ new/pytools-2024.1.4/pytools/test/test_pytools.py 2024-05-21 19:51:19.000000000 +0200
@@ -26,6 +26,8 @@
import pytest
+from pytools import Record
+
logger = logging.getLogger(__name__)
from typing import FrozenSet
@@ -738,6 +740,23 @@
assert strtobool(None, False) is False
+def test_to_identifier() -> None:
+ from pytools import to_identifier
+
+ assert to_identifier("_a_123_") == "_a_123_"
+ assert to_identifier("a_123") == "a_123"
+ assert to_identifier("a 123") == "a123"
+ assert to_identifier("123") == "_123"
+ assert to_identifier("_123") == "_123"
+ assert to_identifier("123A") == "_123A"
+ assert to_identifier("") == "_"
+
+ assert not "a 123".isidentifier()
+ assert to_identifier("a 123").isidentifier()
+ assert to_identifier("123").isidentifier()
+ assert to_identifier("").isidentifier()
+
+
def test_typedump():
from pytools import typedump
assert typedump("") == "str"
@@ -783,6 +802,78 @@
assert next(unique([]), None) is None
+# This class must be defined globally to be picklable
+class SimpleRecord(Record):
+ pass
+
+
+def test_record():
+ r = SimpleRecord(c=3, b=2, a=1)
+
+ assert r.a == 1
+ assert r.b == 2
+ assert r.c == 3
+
+ # Fields are sorted alphabetically in records
+ assert str(r) == "SimpleRecord(a=1, b=2, c=3)"
+
+ # Unregistered fields are (silently) ignored for printing
+ r.f = 6
+ assert str(r) == "SimpleRecord(a=1, b=2, c=3)"
+
+ # Registered fields are printed
+ r.register_fields({"d", "e"})
+ assert str(r) == "SimpleRecord(a=1, b=2, c=3)"
+
+ r.d = 4
+ r.e = 5
+ assert str(r) == "SimpleRecord(a=1, b=2, c=3, d=4, e=5)"
+
+ with pytest.raises(AttributeError):
+ r.ff
+
+ # Test pickling
+ import pickle
+ r_pickled = pickle.loads(pickle.dumps(r))
+ assert r == r_pickled
+
+ # }}}
+
+ # {{{ __slots__, __dict__, __weakref__ handling
+
+ class RecordWithEmptySlots(Record):
+ __slots__ = []
+
+ assert hasattr(RecordWithEmptySlots(), "__slots__")
+ assert not hasattr(RecordWithEmptySlots(), "__dict__")
+ assert not hasattr(RecordWithEmptySlots(), "__weakref__")
+
+ class RecordWithUnsetSlots(Record):
+ pass
+
+ assert hasattr(RecordWithUnsetSlots(), "__slots__")
+ assert hasattr(RecordWithUnsetSlots(), "__dict__")
+ assert hasattr(RecordWithUnsetSlots(), "__weakref__")
+
+ from pytools import ImmutableRecord
+
+ class ImmutableRecordWithEmptySlots(ImmutableRecord):
+ __slots__ = []
+
+ assert hasattr(ImmutableRecordWithEmptySlots(), "__slots__")
+ assert hasattr(ImmutableRecordWithEmptySlots(), "__dict__")
+ assert hasattr(ImmutableRecordWithEmptySlots(), "__weakref__")
+
+ class ImmutableRecordWithUnsetSlots(ImmutableRecord):
+ pass
+
+ assert hasattr(ImmutableRecordWithUnsetSlots(), "__slots__")
+ assert hasattr(ImmutableRecordWithUnsetSlots(), "__dict__")
+ assert hasattr(ImmutableRecordWithUnsetSlots(), "__weakref__")
+
+ # }}}
+
+
if __name__ == "__main__":
if len(sys.argv) > 1:
exec(sys.argv[1])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytools-2024.1.2/pytools/version.py new/pytools-2024.1.4/pytools/version.py
--- old/pytools-2024.1.2/pytools/version.py 2024-04-24 16:57:12.000000000 +0200
+++ new/pytools-2024.1.4/pytools/version.py 2024-05-31 19:39:32.000000000 +0200
@@ -1,3 +1,3 @@
-VERSION = (2024, 1, 2)
+VERSION = (2024, 1, 4)
VERSION_STATUS = ""
VERSION_TEXT = ".".join(str(x) for x in VERSION) + VERSION_STATUS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytools-2024.1.2/pytools.egg-info/PKG-INFO new/pytools-2024.1.4/pytools.egg-info/PKG-INFO
--- old/pytools-2024.1.2/pytools.egg-info/PKG-INFO 2024-04-24 16:58:13.000000000 +0200
+++ new/pytools-2024.1.4/pytools.egg-info/PKG-INFO 2024-05-31 19:41:22.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: pytools
-Version: 2024.1.2
+Version: 2024.1.4
Summary: A collection of tools for Python
Home-page: http://pypi.python.org/pypi/pytools
Author: Andreas Kloeckner
1
0
Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-py3dns for openSUSE:Factory checked in at 2024-06-07 15:04:28
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-py3dns (Old)
and /work/SRC/openSUSE:Factory/.python-py3dns.new.24587 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-py3dns"
Fri Jun 7 15:04:28 2024 rev:5 rq:1179083 version:4.0.2
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-py3dns/python-py3dns.changes 2024-03-01 23:37:49.414271808 +0100
+++ /work/SRC/openSUSE:Factory/.python-py3dns.new.24587/python-py3dns.changes 2024-06-07 15:04:54.223132198 +0200
@@ -1,0 +2,7 @@
+Thu Jun 6 20:25:40 UTC 2024 - Dirk Müller <dmueller(a)suse.com>
+
+- update to 4.0.2:
+ * Update expected test results due to changed example.com IP
+ addresses.
+
+-------------------------------------------------------------------
Old:
----
py3dns-4.0.1.tar.gz
New:
----
py3dns-4.0.2.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-py3dns.spec ++++++
--- /var/tmp/diff_new_pack.t2A8E0/_old 2024-06-07 15:04:55.923194131 +0200
+++ /var/tmp/diff_new_pack.t2A8E0/_new 2024-06-07 15:04:55.951195150 +0200
@@ -17,7 +17,7 @@
Name: python-py3dns
-Version: 4.0.1
+Version: 4.0.2
Release: 0
Summary: Python module for DNS (Domain Name Service)
License: CNRI-Python
++++++ py3dns-4.0.1.tar.gz -> py3dns-4.0.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py3dns-4.0.1/CHANGES new/py3dns-4.0.2/CHANGES
--- old/py3dns-4.0.1/CHANGES 2024-02-25 15:54:28.064536000 +0100
+++ new/py3dns-4.0.2/CHANGES 2024-06-06 14:10:31.968456700 +0200
@@ -1,3 +1,6 @@
+4.0.2 Thu, Jun 6, 2024
+ * Update expected test results due to changed example.com IP addresses.
+
4.0.1 Sun, Feb 25, 2024
* Fix regex string in Base.py to be raw string to resolve SyntaxWarning for
invalid escape sequence with python3.12, thanks to Agathe Porte for fixing
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py3dns-4.0.1/DNS/__init__.py new/py3dns-4.0.2/DNS/__init__.py
--- old/py3dns-4.0.1/DNS/__init__.py 2024-02-25 15:56:46.498406200 +0100
+++ new/py3dns-4.0.2/DNS/__init__.py 2024-06-06 14:10:01.659978400 +0200
@@ -10,7 +10,7 @@
# __init__.py for DNS class.
-__version__ = '4.0.1'
+__version__ = '4.0.2'
try:
import ipaddress
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py3dns-4.0.1/DNS/tests/test_base.py new/py3dns-4.0.2/DNS/tests/test_base.py
--- old/py3dns-4.0.1/DNS/tests/test_base.py 2020-04-17 21:29:51.000000000 +0200
+++ new/py3dns-4.0.2/DNS/tests/test_base.py 2024-06-06 14:06:22.728525000 +0200
@@ -36,12 +36,12 @@
self.assertTrue(a_response.answers)
# is the result vaguely ipv4 like?
self.assertEqual(a_response.answers[0]['data'].count('.'), 3)
- self.assertEqual(a_response.answers[0]['data'],'93.184.216.34')
+ self.assertEqual(a_response.answers[0]['data'],'93.184.215.14')
# Default result type for .qry object is an ipaddress object
ad_response = dnsobj.qry(qtype='A', timeout=1)
self.assertTrue(ad_response.answers)
- self.assertEqual(ad_response.answers[0]['data'],ipaddress.IPv4Address('93.184.216.34'))
+ self.assertEqual(ad_response.answers[0]['data'],ipaddress.IPv4Address('93.184.215.14'))
ab_response = dnsobj.qry(qtype='A', resulttype='binary', timeout=1)
self.assertTrue(ab_response.answers)
@@ -49,11 +49,11 @@
self.assertEqual(len(ab_response.answers[0]['data']), 4)
for b in ab_response.answers[0]['data']:
assertIsByte(b)
- self.assertEqual(ab_response.answers[0]['data'],b']\xb8\xd8\"')
+ self.assertEqual(ab_response.answers[0]['data'],b']\xb8\xd7\x0e')
ai_response = dnsobj.qry(qtype='A', resulttype='integer', timeout=1)
self.assertTrue(ai_response.answers)
- self.assertEqual(ai_response.answers[0]['data'],1572395042)
+ self.assertEqual(ai_response.answers[0]['data'],1572394766)
def testDnsRequestAAAA(self):
@@ -63,12 +63,12 @@
self.assertTrue(aaaa_response.answers)
# does the result look like an ipv6 address?
self.assertTrue(':' in aaaa_response.answers[0]['data'])
- self.assertEqual(aaaa_response.answers[0]['data'],'2606:2800:220:1:248:1893:25c8:1946')
+ self.assertEqual(aaaa_response.answers[0]['data'],'2606:2800:21f:cb07:6820:80da:af6b:8b2c')
# default is returning ipaddress object
aaaad_response = dnsobj.qry(qtype='AAAA', timeout=1)
self.assertTrue(aaaad_response.answers)
- self.assertEqual(aaaad_response.answers[0]['data'],ipaddress.IPv6Address('2606:2800:220:1:248:1893:25c8:1946'))
+ self.assertEqual(aaaad_response.answers[0]['data'],ipaddress.IPv6Address('2606:2800:21f:cb07:6820:80da:af6b:8b2c'))
aaaab_response = dnsobj.qry(qtype='AAAA', resulttype='binary', timeout=1)
self.assertTrue(aaaab_response.answers)
@@ -76,11 +76,11 @@
self.assertEqual(len(aaaab_response.answers[0]['data']) , 16)
for b in aaaab_response.answers[0]['data']:
assertIsByte(b)
- self.assertEqual(aaaab_response.answers[0]['data'],b'&\x06(\x00\x02 \x00\x01\x02H\x18\x93%\xc8\x19F')
+ self.assertEqual(aaaab_response.answers[0]['data'],b'&\x06(\x00\x02\x1f\xcb\x07h \x80\xda\xafk\x8b,')
# IPv6 decimal
aaaai_response = dnsobj.qry(qtype='AAAA', resulttype='integer', timeout=1)
self.assertTrue(aaaai_response.answers)
- self.assertEqual(aaaai_response.answers[0]['data'], 50542628918019813867414319910101719366)
+ self.assertEqual(aaaai_response.answers[0]['data'], 50542628918019563700009922510424083244)
def testDnsRequestEmptyMX(self):
dnsobj = DNS.DnsRequest('mail.kitterman.org')
@@ -170,7 +170,7 @@
self.assertTrue(ad_response.answers)
# is the result vaguely ipv4 like?
self.assertEqual(ad_response.answers[0]['data'].count('.'), 3)
- self.assertEqual(ad_response.answers[0]['data'],'93.184.216.34')
+ self.assertEqual(ad_response.answers[0]['data'],'93.184.215.14')
def testDnsRequestAAAAD(self):
dnsob = DNS.DnsRequest('example.org')
@@ -182,7 +182,7 @@
self.assertEqual(len(aaaad_response.answers[0]['data']) , 16)
for b in aaaad_response.answers[0]['data']:
assertIsByte(b)
- self.assertEqual(aaaad_response.answers[0]['data'],b'&\x06(\x00\x02 \x00\x01\x02H\x18\x93%\xc8\x19F')
+ self.assertEqual(aaaad_response.answers[0]['data'],b'&\x06(\x00\x02\x1f\xcb\x07h \x80\xda\xafk\x8b,')
def testDnsRequestEmptyMXD(self):
dnsob = DNS.DnsRequest('mail.kitterman.org')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/py3dns-4.0.1/PKG-INFO new/py3dns-4.0.2/PKG-INFO
--- old/py3dns-4.0.1/PKG-INFO 1970-01-01 01:00:00.000000000 +0100
+++ new/py3dns-4.0.2/PKG-INFO 1970-01-01 01:00:00.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: py3dns
-Version: 4.0.1
+Version: 4.0.2
Summary: Python 3 DNS library
Keywords: DNS
Author-email: Anthony Baxter and others <py3dns-hackers(a)lists.launchpad.net>
1
0
Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-Pyphen for openSUSE:Factory checked in at 2024-06-07 15:04:21
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-Pyphen (Old)
and /work/SRC/openSUSE:Factory/.python-Pyphen.new.24587 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-Pyphen"
Fri Jun 7 15:04:21 2024 rev:7 rq:1179077 version:0.15.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-Pyphen/python-Pyphen.changes 2024-01-11 21:05:59.100343398 +0100
+++ /work/SRC/openSUSE:Factory/.python-Pyphen.new.24587/python-Pyphen.changes 2024-06-07 15:04:45.230804610 +0200
@@ -1,0 +2,10 @@
+Thu Jun 6 20:13:33 UTC 2024 - Dirk Müller <dmueller(a)suse.com>
+
+- update to 0.15.0:
+ * Support Python 3.12, drop Python 3.7 support.
+ * Add READMEs for dictionaries.
+ * Add Basque hyphenation dictionary.
+ * Update Catalan and Hungarian dictionaries.
+ * Use Ruff instead of Flake8 and isort.
+
+-------------------------------------------------------------------
Old:
----
0.14.0.tar.gz
New:
----
0.15.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-Pyphen.spec ++++++
--- /var/tmp/diff_new_pack.VRqNiJ/_old 2024-06-07 15:04:45.758823845 +0200
+++ /var/tmp/diff_new_pack.VRqNiJ/_new 2024-06-07 15:04:45.758823845 +0200
@@ -18,7 +18,7 @@
%{?sle15_python_module_pythons}
Name: python-Pyphen
-Version: 0.14.0
+Version: 0.15.0
Release: 0
Summary: Pure Python module to hyphenate text
License: GPL-2.0-or-later AND LGPL-2.1-or-later AND MPL-1.1
++++++ 0.14.0.tar.gz -> 0.15.0.tar.gz ++++++
++++ 12176 lines of diff (skipped)
1
0
Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package govulncheck for openSUSE:Factory checked in at 2024-06-07 15:04:19
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/govulncheck (Old)
and /work/SRC/openSUSE:Factory/.govulncheck.new.24587 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "govulncheck"
Fri Jun 7 15:04:19 2024 rev:8 rq:1179096 version:1.1.2
Changes:
--------
--- /work/SRC/openSUSE:Factory/govulncheck/govulncheck.changes 2024-05-24 19:51:56.255257967 +0200
+++ /work/SRC/openSUSE:Factory/.govulncheck.new.24587/govulncheck.changes 2024-06-07 15:04:42.978722566 +0200
@@ -1,0 +2,22 @@
+Thu Jun 06 20:41:57 UTC 2024 - Jeff Kowalczyk <jkowalczyk(a)suse.com>
+
+- Update to version 1.1.2:
+ * internal/osv: add review status
+ * vulncheck: update documentation for vex
+ * cmd/govulncheck/integration/stackrox-scanner: update expectations
+ * cmd/govulncheck/integration/k8s: update expectations
+ * internal/govulncheck: add more comments for emitted OSVs
+ * go.mod: update golang.org/x dependencies
+ * internal/scan: increase telemetry counter for show flag
+ * internal/scan: add format and scan level telemetry
+ * internal/cmd/govulncheck: remove unnecessary binary dependency
+ * cmd/govulncheck/integration: update go in integration tests
+ * internal/openvex: add hash for doc ID
+ * internal/openvex: add statements to handler
+ * internal/openvex: add handler
+ * all: remove test that runs govulncheck on govulncheck
+ * internal/sarif: fix a typo
+ * internal/scan: limit number of binary traces shown
+ * cmd/govulncheck: record scan mode telemetry
+
+-------------------------------------------------------------------
Old:
----
govulncheck-1.1.1.tar.gz
New:
----
govulncheck-1.1.2.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ govulncheck.spec ++++++
--- /var/tmp/diff_new_pack.LhdWvR/_old 2024-06-07 15:04:43.674747923 +0200
+++ /var/tmp/diff_new_pack.LhdWvR/_new 2024-06-07 15:04:43.674747923 +0200
@@ -17,7 +17,7 @@
Name: govulncheck
-Version: 1.1.1
+Version: 1.1.2
Release: 0
Summary: CLI tool to report known CVE vulnerabilities in Go source code and binaries
License: Apache-2.0 AND BSD-3-Clause
++++++ _service ++++++
--- /var/tmp/diff_new_pack.LhdWvR/_old 2024-06-07 15:04:43.710749234 +0200
+++ /var/tmp/diff_new_pack.LhdWvR/_new 2024-06-07 15:04:43.714749381 +0200
@@ -3,7 +3,7 @@
<param name="url">https://github.com/golang/vuln.git</param>
<param name="scm">git</param>
<param name="exclude">.git</param>
- <param name="revision">v1.1.1</param>
+ <param name="revision">v1.1.2</param>
<param name="versionformat">@PARENT_TAG@</param>
<param name="changesgenerate">enable</param>
<param name="versionrewrite-pattern">v(.*)</param>
++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.LhdWvR/_old 2024-06-07 15:04:43.734750109 +0200
+++ /var/tmp/diff_new_pack.LhdWvR/_new 2024-06-07 15:04:43.738750254 +0200
@@ -1,6 +1,6 @@
<servicedata>
<service name="tar_scm">
<param name="url">https://github.com/golang/vuln.git</param>
- <param name="changesrevision">486fd2384a39a632a0e5b003e1840d49d1db7e86</param></service></servicedata>
+ <param name="changesrevision">3740f5cb12a3f93b18dbe200c4bcb6256f8586e2</param></service></servicedata>
(No newline at EOF)
++++++ govulncheck-1.1.1.tar.gz -> govulncheck-1.1.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/govulncheck-1.1.1/all_test.go new/govulncheck-1.1.2/all_test.go
--- old/govulncheck-1.1.1/all_test.go 2024-05-21 23:23:08.000000000 +0200
+++ new/govulncheck-1.1.2/all_test.go 2024-06-06 16:46:51.000000000 +0200
@@ -9,8 +9,6 @@
import (
"bufio"
- "bytes"
- "context"
"errors"
"io/fs"
"os"
@@ -21,7 +19,6 @@
"golang.org/x/mod/modfile"
"golang.org/x/vuln/internal/testenv"
- "golang.org/x/vuln/scan"
)
// excluded contains the set of modules that x/vuln should not depend on.
@@ -55,33 +52,6 @@
}
}
-func TestGovulncheck(t *testing.T) {
- skipIfShort(t)
- testenv.NeedsGoBuild(t)
-
- var o string
- out := bytes.NewBufferString(o)
- ctx := context.Background()
-
- cmd := scan.Command(ctx, "./...")
- cmd.Stdout = out
- cmd.Stderr = out
- err := cmd.Start()
- if err == nil {
- err = cmd.Wait()
- }
-
- t.Logf("govulncheck finished with std out/err:\n%s", out.String())
- switch err := err.(type) {
- case nil:
- t.Log("govulncheck: no vulnerabilities detected")
- case interface{ ExitCode() int }:
- t.Errorf("govulncheck: unexpected exit code %d and error %v", err.ExitCode(), err)
- default:
- t.Errorf("govulncheck: abruptly failed with error %v", err)
- }
-}
-
func TestVet(t *testing.T) {
rungo(t, "vet", "-all", "./...")
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/govulncheck-1.1.1/cmd/govulncheck/doc.go new/govulncheck-1.1.2/cmd/govulncheck/doc.go
--- old/govulncheck-1.1.1/cmd/govulncheck/doc.go 2024-05-21 23:23:08.000000000 +0200
+++ new/govulncheck-1.1.2/cmd/govulncheck/doc.go 2024-06-06 16:46:51.000000000 +0200
@@ -67,12 +67,16 @@
format, following the specification at https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=sarif.
For more details, please see [golang.org/x/vuln/internal/sarif].
+Govulncheck supports the Vulnerability EXchange (VEX) output format, following
+the specification at https://github.com/openvex/spec.
+For more details, please see [golang.org/x/vuln/internal/openvex].
+
# Exit codes
Govulncheck exits successfully (exit code 0) if there are no vulnerabilities,
and exits unsuccessfully if there are. It also exits successfully if the
-'format -json' ('-json') or '-format sarif' is provided, regardless of the number
-of detected vulnerabilities.
+'format -json' ('-json'), '-format sarif', or '-format openvex' is provided,
+regardless of the number of detected vulnerabilities.
# Limitations
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/govulncheck-1.1.1/cmd/govulncheck/integration/Dockerfile new/govulncheck-1.1.2/cmd/govulncheck/integration/Dockerfile
--- old/govulncheck-1.1.1/cmd/govulncheck/integration/Dockerfile 2024-05-21 23:23:08.000000000 +0200
+++ new/govulncheck-1.1.2/cmd/govulncheck/integration/Dockerfile 2024-06-06 16:46:51.000000000 +0200
@@ -1,4 +1,4 @@
-FROM golang:1.20.3-alpine
+FROM golang:1.22.3-alpine
# This Dockerfile sets up an image for repeated integration testing.
# This assumes the build context, i.e., CWD is vuln/
@@ -12,6 +12,5 @@
RUN go install golang.org/x/vuln/cmd/govulncheck
# ---- Step 2: Build other test binaries ----
-RUN go install golang.org/dl/go1.18@latest
RUN go install golang.org/x/vuln/cmd/govulncheck/integration/k8s
RUN go install golang.org/x/vuln/cmd/govulncheck/integration/stackrox-scanner
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/govulncheck-1.1.1/cmd/govulncheck/integration/k8s/k8s.go new/govulncheck-1.1.2/cmd/govulncheck/integration/k8s/k8s.go
--- old/govulncheck-1.1.1/cmd/govulncheck/integration/k8s/k8s.go 2024-05-21 23:23:08.000000000 +0200
+++ new/govulncheck-1.1.2/cmd/govulncheck/integration/k8s/k8s.go 2024-06-06 16:46:51.000000000 +0200
@@ -23,18 +23,30 @@
out := os.Args[1]
want := map[string]bool{
- "github.com/containernetworking/cni/pkg/invoke": true,
- "github.com/evanphx/json-patch": true,
- "github.com/opencontainers/selinux/go-selinux": true,
- "github.com/prometheus/client_golang/prometheus/promhttp": true,
- "golang.org/x/crypto/cryptobyte": true,
- "golang.org/x/crypto/salsa20/salsa": true,
- "golang.org/x/crypto/ssh": true,
- "golang.org/x/net/http/httpguts": true,
- "golang.org/x/net/http2": true,
- "golang.org/x/net/http2/hpack": true,
- "golang.org/x/text/encoding/unicode": true,
- "google.golang.org/grpc": true,
+ "github.com/containerd/containerd/api/services/containers/v1": true,
+ "github.com/containerd/containerd/api/services/tasks/v1": true,
+ "github.com/containerd/containerd/api/services/version/v1": true,
+ "github.com/containerd/containerd/api/types": true,
+ "github.com/containerd/containerd/api/types/task": true,
+ "github.com/containerd/containerd/containers": true,
+ "github.com/containerd/containerd/dialer": true,
+ "github.com/containerd/containerd/errdefs": true,
+ "github.com/containerd/containerd/namespaces": true,
+ "github.com/containernetworking/cni/pkg/invoke": true,
+ "github.com/evanphx/json-patch": true,
+ "github.com/heketi/heketi/client/api/go-client": true,
+ "github.com/heketi/heketi/pkg/glusterfs/api": true,
+ "github.com/heketi/heketi/pkg/utils": true,
+ "github.com/opencontainers/selinux/go-selinux": true,
+ "github.com/prometheus/client_golang/prometheus/promhttp": true,
+ "golang.org/x/crypto/cryptobyte": true,
+ "golang.org/x/crypto/salsa20/salsa": true,
+ "golang.org/x/crypto/ssh": true,
+ "golang.org/x/net/http/httpguts": true,
+ "golang.org/x/net/http2": true,
+ "golang.org/x/net/http2/hpack": true,
+ "golang.org/x/text/encoding/unicode": true,
+ "google.golang.org/grpc": true,
}
if err := integration.CompareNonStdVulns(out, want); err != nil {
log.Fatal(err)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/govulncheck-1.1.1/cmd/govulncheck/integration/stackrox-scanner/scanner.go new/govulncheck-1.1.2/cmd/govulncheck/integration/stackrox-scanner/scanner.go
--- old/govulncheck-1.1.1/cmd/govulncheck/integration/stackrox-scanner/scanner.go 2024-05-21 23:23:08.000000000 +0200
+++ new/govulncheck-1.1.2/cmd/govulncheck/integration/stackrox-scanner/scanner.go 2024-06-06 16:46:51.000000000 +0200
@@ -28,6 +28,7 @@
"github.com/go-git/go-git/v5/plumbing/object": true,
"github.com/go-git/go-git/v5/storage/filesystem": true,
"github.com/go-git/go-git/v5/storage/filesystem/dotgit": true,
+ "github.com/mholt/archiver/v3": true,
"golang.org/x/crypto/ssh": true,
"golang.org/x/net/http2": true,
"golang.org/x/net/http2/hpack": true,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/govulncheck-1.1.1/cmd/govulncheck/main.go new/govulncheck-1.1.2/cmd/govulncheck/main.go
--- old/govulncheck-1.1.1/cmd/govulncheck/main.go 2024-05-21 23:23:08.000000000 +0200
+++ new/govulncheck-1.1.2/cmd/govulncheck/main.go 2024-06-06 16:46:51.000000000 +0200
@@ -9,10 +9,13 @@
"fmt"
"os"
+ "golang.org/x/telemetry"
"golang.org/x/vuln/scan"
)
func main() {
+ telemetry.Start(telemetry.Config{ReportCrashes: true})
+
ctx := context.Background()
cmd := scan.Command(ctx, os.Args[1:]...)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/govulncheck-1.1.1/cmd/govulncheck/testdata/common/config.json new/govulncheck-1.1.2/cmd/govulncheck/testdata/common/config.json
--- old/govulncheck-1.1.1/cmd/govulncheck/testdata/common/config.json 2024-05-21 23:23:08.000000000 +0200
+++ new/govulncheck-1.1.2/cmd/govulncheck/testdata/common/config.json 2024-06-06 16:46:51.000000000 +0200
@@ -35,6 +35,10 @@
{
"pattern": "\"go_version\": \"go[^\\s\"]*\"",
"replace": "\"go_version\": \"go1.18\""
+ },
+ {
+ "pattern": "\"timestamp\": (.*),",
+ "replace": "\"timestamp\": \"2024-01-01T00:00:00\","
}
]
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/govulncheck-1.1.1/cmd/govulncheck/testdata/common/testfiles/binary-call/binary_vex.ct new/govulncheck-1.1.2/cmd/govulncheck/testdata/common/testfiles/binary-call/binary_vex.ct
--- old/govulncheck-1.1.1/cmd/govulncheck/testdata/common/testfiles/binary-call/binary_vex.ct 1970-01-01 01:00:00.000000000 +0100
+++ new/govulncheck-1.1.2/cmd/govulncheck/testdata/common/testfiles/binary-call/binary_vex.ct 2024-06-06 16:46:51.000000000 +0200
@@ -0,0 +1,104 @@
+#####
+# Test basic binary scanning with vex output
+$ govulncheck -format openvex -mode binary ${common_vuln_binary}
+{
+ "@context": "https://openvex.dev/ns/v0.2.0",
+ "@id": "govulncheck/vex:b2e8274f24820051d79285827c4fe6e1912c99143a4693804b9a5c366ec5fb8d",
+ "author": "Unknown Author",
+ "timestamp": "2024-01-01T00:00:00",
+ "version": 1,
+ "tooling": "https://pkg.go.dev/golang.org/x/vuln/cmd/govulncheck",
+ "statements": [
+ {
+ "vulnerability": {
+ "@id": "https://pkg.go.dev/vuln/GO-2020-0015",
+ "name": "GO-2020-0015",
+ "description": "Infinite loop when decoding some inputs in golang.org/x/text",
+ "aliases": [
+ "CVE-2020-14040",
+ "GHSA-5rcv-m4m3-hfh7"
+ ]
+ },
+ "products": [
+ {
+ "@id": "Unknown Product"
+ }
+ ],
+ "status": "not_affected",
+ "justification": "vulnerable_code_not_present",
+ "impact_statement": "Govulncheck determined that the vulnerable code isn't called"
+ },
+ {
+ "vulnerability": {
+ "@id": "https://pkg.go.dev/vuln/GO-2021-0054",
+ "name": "GO-2021-0054",
+ "description": "Due to improper bounds checking, maliciously crafted JSON objects can cause an out-of-bounds panic. If parsing user input, this may be used as a denial of service vector.",
+ "aliases": [
+ "CVE-2020-36067",
+ "GHSA-p64j-r5f4-pwwx"
+ ]
+ },
+ "products": [
+ {
+ "@id": "Unknown Product"
+ }
+ ],
+ "status": "affected"
+ },
+ {
+ "vulnerability": {
+ "@id": "https://pkg.go.dev/vuln/GO-2021-0059",
+ "name": "GO-2021-0059",
+ "description": "Due to improper bounds checking, maliciously crafted JSON objects can cause an out-of-bounds panic. If parsing user input, this may be used as a denial of service vector.",
+ "aliases": [
+ "CVE-2020-35380",
+ "GHSA-w942-gw6m-p62c"
+ ]
+ },
+ "products": [
+ {
+ "@id": "Unknown Product"
+ }
+ ],
+ "status": "not_affected",
+ "justification": "vulnerable_code_not_present",
+ "impact_statement": "Govulncheck determined that the vulnerable code isn't called"
+ },
+ {
+ "vulnerability": {
+ "@id": "https://pkg.go.dev/vuln/GO-2021-0113",
+ "name": "GO-2021-0113",
+ "description": "Due to improper index calculation, an incorrectly formatted language tag can cause Parse to panic via an out of bounds read. If Parse is used to process untrusted user inputs, this may be used as a vector for a denial of service attack.",
+ "aliases": [
+ "CVE-2021-38561",
+ "GHSA-ppp9-7jff-5vj2"
+ ]
+ },
+ "products": [
+ {
+ "@id": "Unknown Product"
+ }
+ ],
+ "status": "affected"
+ },
+ {
+ "vulnerability": {
+ "@id": "https://pkg.go.dev/vuln/GO-2021-0265",
+ "name": "GO-2021-0265",
+ "description": "A maliciously crafted path can cause Get and other query functions to consume excessive amounts of CPU and time.",
+ "aliases": [
+ "CVE-2021-42248",
+ "CVE-2021-42836",
+ "GHSA-c9gm-7rfj-8w5h",
+ "GHSA-ppj4-34rq-v8j9"
+ ]
+ },
+ "products": [
+ {
+ "@id": "Unknown Product"
+ }
+ ],
+ "status": "affected"
+ }
+ ]
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/govulncheck-1.1.1/cmd/govulncheck/testdata/common/testfiles/source-call/source_call_vex.ct new/govulncheck-1.1.2/cmd/govulncheck/testdata/common/testfiles/source-call/source_call_vex.ct
--- old/govulncheck-1.1.1/cmd/govulncheck/testdata/common/testfiles/source-call/source_call_vex.ct 1970-01-01 01:00:00.000000000 +0100
+++ new/govulncheck-1.1.2/cmd/govulncheck/testdata/common/testfiles/source-call/source_call_vex.ct 2024-06-06 16:46:51.000000000 +0200
@@ -0,0 +1,104 @@
+#####
+# Test vex json output
+$ govulncheck -C ${moddir}/vuln -format openvex ./...
+{
+ "@context": "https://openvex.dev/ns/v0.2.0",
+ "@id": "govulncheck/vex:b2e8274f24820051d79285827c4fe6e1912c99143a4693804b9a5c366ec5fb8d",
+ "author": "Unknown Author",
+ "timestamp": "2024-01-01T00:00:00",
+ "version": 1,
+ "tooling": "https://pkg.go.dev/golang.org/x/vuln/cmd/govulncheck",
+ "statements": [
+ {
+ "vulnerability": {
+ "@id": "https://pkg.go.dev/vuln/GO-2020-0015",
+ "name": "GO-2020-0015",
+ "description": "Infinite loop when decoding some inputs in golang.org/x/text",
+ "aliases": [
+ "CVE-2020-14040",
+ "GHSA-5rcv-m4m3-hfh7"
+ ]
+ },
+ "products": [
+ {
+ "@id": "Unknown Product"
+ }
+ ],
+ "status": "not_affected",
+ "justification": "vulnerable_code_not_present",
+ "impact_statement": "Govulncheck determined that the vulnerable code isn't called"
+ },
+ {
+ "vulnerability": {
+ "@id": "https://pkg.go.dev/vuln/GO-2021-0054",
+ "name": "GO-2021-0054",
+ "description": "Due to improper bounds checking, maliciously crafted JSON objects can cause an out-of-bounds panic. If parsing user input, this may be used as a denial of service vector.",
+ "aliases": [
+ "CVE-2020-36067",
+ "GHSA-p64j-r5f4-pwwx"
+ ]
+ },
+ "products": [
+ {
+ "@id": "Unknown Product"
+ }
+ ],
+ "status": "affected"
+ },
+ {
+ "vulnerability": {
+ "@id": "https://pkg.go.dev/vuln/GO-2021-0059",
+ "name": "GO-2021-0059",
+ "description": "Due to improper bounds checking, maliciously crafted JSON objects can cause an out-of-bounds panic. If parsing user input, this may be used as a denial of service vector.",
+ "aliases": [
+ "CVE-2020-35380",
+ "GHSA-w942-gw6m-p62c"
+ ]
+ },
+ "products": [
+ {
+ "@id": "Unknown Product"
+ }
+ ],
+ "status": "not_affected",
+ "justification": "vulnerable_code_not_present",
+ "impact_statement": "Govulncheck determined that the vulnerable code isn't called"
+ },
+ {
+ "vulnerability": {
+ "@id": "https://pkg.go.dev/vuln/GO-2021-0113",
+ "name": "GO-2021-0113",
+ "description": "Due to improper index calculation, an incorrectly formatted language tag can cause Parse to panic via an out of bounds read. If Parse is used to process untrusted user inputs, this may be used as a vector for a denial of service attack.",
+ "aliases": [
+ "CVE-2021-38561",
+ "GHSA-ppp9-7jff-5vj2"
+ ]
+ },
+ "products": [
+ {
+ "@id": "Unknown Product"
+ }
+ ],
+ "status": "affected"
+ },
+ {
+ "vulnerability": {
+ "@id": "https://pkg.go.dev/vuln/GO-2021-0265",
+ "name": "GO-2021-0265",
+ "description": "A maliciously crafted path can cause Get and other query functions to consume excessive amounts of CPU and time.",
+ "aliases": [
+ "CVE-2021-42248",
+ "CVE-2021-42836",
+ "GHSA-c9gm-7rfj-8w5h",
+ "GHSA-ppj4-34rq-v8j9"
+ ]
+ },
+ "products": [
+ {
+ "@id": "Unknown Product"
+ }
+ ],
+ "status": "affected"
+ }
+ ]
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/govulncheck-1.1.1/cmd/govulncheck/testdata/common/testfiles/usage/usage.ct new/govulncheck-1.1.2/cmd/govulncheck/testdata/common/testfiles/usage/usage.ct
--- old/govulncheck-1.1.1/cmd/govulncheck/testdata/common/testfiles/usage/usage.ct 2024-05-21 23:23:08.000000000 +0200
+++ new/govulncheck-1.1.2/cmd/govulncheck/testdata/common/testfiles/usage/usage.ct 2024-06-06 16:46:51.000000000 +0200
@@ -14,7 +14,7 @@
vulnerability database url (default "https://vuln.go.dev")
-format value
specify format output
- The supported values are 'text', 'json', and 'sarif' (default 'text')
+ The supported values are 'text', 'json', 'sarif', and 'openvex' (default 'text')
-json
output JSON (Go compatible legacy flag, see format flag)
-mode value
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/govulncheck-1.1.1/cmd/govulncheck/testdata/strip/testfiles/binary/strip.ct new/govulncheck-1.1.2/cmd/govulncheck/testdata/strip/testfiles/binary/strip.ct
--- old/govulncheck-1.1.1/cmd/govulncheck/testdata/strip/testfiles/binary/strip.ct 2024-05-21 23:23:08.000000000 +0200
+++ new/govulncheck-1.1.2/cmd/govulncheck/testdata/strip/testfiles/binary/strip.ct 2024-06-06 16:46:51.000000000 +0200
@@ -13,10 +13,12 @@
Found in: golang.org/x/text@v0.3.0
Fixed in: golang.org/x/text@v0.3.7
Vulnerable symbols found:
- #1: language.MatchStrings
- #2: language.MustParse
- #3: language.Parse
- #4: language.ParseAcceptLanguage
+ #1: language.Compose
+ #2: language.Make
+ #3: language.MatchStrings
+ #4: language.MustParse
+ #5: language.Parse
+ Use '-show traces' to see the other 7 found symbols
Vulnerability #2: GO-2020-0015
Infinite loop when decoding some inputs in golang.org/x/text
@@ -31,5 +33,63 @@
Your code is affected by 2 vulnerabilities from 1 module.
This scan found no other vulnerabilities in packages you import or modules you
+require.
+Use '-show verbose' for more details.
+
+# The same as above but with '-show traces'.
+$ govulncheck -mode=binary -show traces ${strip_vuln_binary} --> FAIL 3
+=== Symbol Results ===
+
+Vulnerability #1: GO-2021-0113
+ Due to improper index calculation, an incorrectly formatted language tag can
+ cause Parse to panic via an out of bounds read. If Parse is used to process
+ untrusted user inputs, this may be used as a vector for a denial of service
+ attack.
+ More info: https://pkg.go.dev/vuln/GO-2021-0113
+ Module: golang.org/x/text
+ Found in: golang.org/x/text@v0.3.0
+ Fixed in: golang.org/x/text@v0.3.7
+ Vulnerable symbols found:
+ #1: for function golang.org/x/text/language.Compose
+ golang.org/x/text/language.Compose
+ #2: for function golang.org/x/text/language.Make
+ golang.org/x/text/language.Make
+ #3: for function golang.org/x/text/language.MatchStrings
+ golang.org/x/text/language.MatchStrings
+ #4: for function golang.org/x/text/language.MustParse
+ golang.org/x/text/language.MustParse
+ #5: for function golang.org/x/text/language.Parse
+ golang.org/x/text/language.Parse
+ #6: for function golang.org/x/text/language.ParseAcceptLanguage
+ golang.org/x/text/language.ParseAcceptLanguage
+ #7: for function golang.org/x/text/language.Tag.Base
+ golang.org/x/text/language.Tag.Base
+ #8: for function golang.org/x/text/language.Tag.Extension
+ golang.org/x/text/language.Tag.Extension
+ #9: for function golang.org/x/text/language.Tag.IsRoot
+ golang.org/x/text/language.Tag.IsRoot
+ #10: for function golang.org/x/text/language.Tag.Parent
+ golang.org/x/text/language.Tag.Parent
+ #11: for function golang.org/x/text/language.Tag.Region
+ golang.org/x/text/language.Tag.Region
+ #12: for function golang.org/x/text/language.Tag.String
+ golang.org/x/text/language.Tag.String
+
+Vulnerability #2: GO-2020-0015
+ Infinite loop when decoding some inputs in golang.org/x/text
+ More info: https://pkg.go.dev/vuln/GO-2020-0015
+ Module: golang.org/x/text
+ Found in: golang.org/x/text@v0.3.0
+ Fixed in: golang.org/x/text@v0.3.3
+ Vulnerable symbols found:
+ #1: for function golang.org/x/text/transform.String
+ golang.org/x/text/transform.String
+ #2: for function golang.org/x/text/encoding/unicode.bomOverride.Transform
+ golang.org/x/text/encoding/unicode.bomOverride.Transform
+ #3: for function golang.org/x/text/encoding/unicode.utf16Decoder.Transform
+ golang.org/x/text/encoding/unicode.utf16Decoder.Transform
+
+Your code is affected by 2 vulnerabilities from 1 module.
+This scan found no other vulnerabilities in packages you import or modules you
require.
Use '-show verbose' for more details.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/govulncheck-1.1.1/cmd/govulncheck/testdata/strip/vulndb-v1/ID/GO-2021-0113.json new/govulncheck-1.1.2/cmd/govulncheck/testdata/strip/vulndb-v1/ID/GO-2021-0113.json
--- old/govulncheck-1.1.1/cmd/govulncheck/testdata/strip/vulndb-v1/ID/GO-2021-0113.json 2024-05-21 23:23:08.000000000 +0200
+++ new/govulncheck-1.1.2/cmd/govulncheck/testdata/strip/vulndb-v1/ID/GO-2021-0113.json 2024-06-06 16:46:51.000000000 +0200
@@ -1 +1 @@
-{"schema_version":"1.3.1","id":"GO-2021-0113","modified":"2023-04-03T15:57:51Z","published":"2021-10-06T17:51:21Z","aliases":["CVE-2021-38561","GHSA-ppp9-7jff-5vj2"],"details":"Due to improper index calculation, an incorrectly formatted language tag can cause Parse to panic via an out of bounds read. If Parse is used to process untrusted user inputs, this may be used as a vector for a denial of service attack.","affected":[{"package":{"name":"golang.org/x/text","ecosystem":"Go"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"0.3.7"}]}],"ecosystem_specific":{"imports":[{"path":"golang.org/x/text/language","symbols":["MatchStrings","MustParse","Parse","ParseAcceptLanguage"]}]}}],"references":[{"type":"FIX","url":"https://go.dev/cl/340830"},{"type":"FIX","url":"https://go.googlesource.com/text/+/383b2e75a7a4198c42f8f87833eefb772868a56f"}],"credits":[{"name":"Guido Vranken"}],"database_specific":{"url":"https://pkg.go.dev/vuln/GO-2021-0113"}}
\ No newline at end of file
+{"schema_version":"1.3.1","id":"GO-2021-0113","modified":"2023-04-03T15:57:51Z","published":"2021-10-06T17:51:21Z","aliases":["CVE-2021-38561","GHSA-ppp9-7jff-5vj2"],"details":"Due to improper index calculation, an incorrectly formatted language tag can cause Parse to panic via an out of bounds read. If Parse is used to process untrusted user inputs, this may be used as a vector for a denial of service attack.","affected":[{"package":{"name":"golang.org/x/text","ecosystem":"Go"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"0.3.7"}]}],"ecosystem_specific":{"imports":[{"path":"golang.org/x/text/language","symbols":["MatchStrings","MustParse","Parse","ParseAcceptLanguage","Compose","Make","Tag.Base","Tag.Extension","Tag.IsRoot","Tag.Parent","Tag.Region","Tag.String"]}]}}],"references":[{"type":"FIX","url":"https://go.dev/cl/340830"},{"type":"FIX","url":"https://go.googlesource.com/text/+/383b2e75a7a4198c42f8f87833eefb772868a56f"}],"credits":[{"name":"Guido Vranken"
}],"database_specific":{"url":"https://pkg.go.dev/vuln/GO-2021-0113"}}
Binary files old/govulncheck-1.1.1/cmd/govulncheck/testdata/strip/vulndb-v1/ID/GO-2021-0113.json.gz and new/govulncheck-1.1.2/cmd/govulncheck/testdata/strip/vulndb-v1/ID/GO-2021-0113.json.gz differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/govulncheck-1.1.1/go.mod new/govulncheck-1.1.2/go.mod
--- old/govulncheck-1.1.1/go.mod 2024-05-21 23:23:08.000000000 +0200
+++ new/govulncheck-1.1.2/go.mod 2024-06-06 16:46:51.000000000 +0200
@@ -5,9 +5,13 @@
require (
github.com/google/go-cmdtest v0.4.1-0.20220921163831-55ab3332a786
github.com/google/go-cmp v0.6.0
- golang.org/x/mod v0.17.0
+ golang.org/x/mod v0.18.0
golang.org/x/sync v0.7.0
- golang.org/x/tools v0.21.1-0.20240514024235-59d9797072e7
+ golang.org/x/telemetry v0.0.0-20240522233618-39ace7a40ae7
+ golang.org/x/tools v0.22.0
)
-require github.com/google/renameio v0.1.0 // indirect
+require (
+ github.com/google/renameio v0.1.0 // indirect
+ golang.org/x/sys v0.21.0 // indirect
+)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/govulncheck-1.1.1/go.sum new/govulncheck-1.1.2/go.sum
--- old/govulncheck-1.1.1/go.sum 2024-05-21 23:23:08.000000000 +0200
+++ new/govulncheck-1.1.2/go.sum 2024-06-06 16:46:51.000000000 +0200
@@ -5,9 +5,13 @@
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
-golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
-golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
+golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
+golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
-golang.org/x/tools v0.21.1-0.20240514024235-59d9797072e7 h1:DnP3aRQn/r68glNGB8/7+3iE77jA+YZZCxpfIXx2MdA=
-golang.org/x/tools v0.21.1-0.20240514024235-59d9797072e7/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
+golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
+golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/telemetry v0.0.0-20240522233618-39ace7a40ae7 h1:FemxDzfMUcK2f3YY4H+05K9CDzbSVr2+q/JKN45pey0=
+golang.org/x/telemetry v0.0.0-20240522233618-39ace7a40ae7/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0=
+golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
+golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/govulncheck-1.1.1/internal/govulncheck/govulncheck.go new/govulncheck-1.1.2/internal/govulncheck/govulncheck.go
--- old/govulncheck-1.1.1/internal/govulncheck/govulncheck.go 2024-05-21 23:23:08.000000000 +0200
+++ new/govulncheck-1.1.2/internal/govulncheck/govulncheck.go 2024-06-06 16:46:51.000000000 +0200
@@ -37,10 +37,15 @@
// Message is an entry in the output stream. It will always have exactly one
// field filled in.
type Message struct {
- Config *Config `json:"config,omitempty"`
- Progress *Progress `json:"progress,omitempty"`
- OSV *osv.Entry `json:"osv,omitempty"`
- Finding *Finding `json:"finding,omitempty"`
+ Config *Config `json:"config,omitempty"`
+ Progress *Progress `json:"progress,omitempty"`
+ // OSV is emitted for every vulnerability in the current database
+ // that applies to user modules regardless of their version. If a
+ // module is being used at a vulnerable version, the corresponding
+ // OSV will be referenced in Findings depending on the type of usage
+ // and the desired scan level.
+ OSV *osv.Entry `json:"osv,omitempty"`
+ Finding *Finding `json:"finding,omitempty"`
}
// Config must occur as the first message of a stream and informs the client
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/govulncheck-1.1.1/internal/openvex/handler.go new/govulncheck-1.1.2/internal/openvex/handler.go
--- old/govulncheck-1.1.1/internal/openvex/handler.go 1970-01-01 01:00:00.000000000 +0100
+++ new/govulncheck-1.1.2/internal/openvex/handler.go 2024-06-06 16:46:51.000000000 +0200
@@ -0,0 +1,183 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package openvex
+
+import (
+ "crypto/sha256"
+ "encoding/json"
+ "fmt"
+ "io"
+ "slices"
+ "time"
+
+ "golang.org/x/vuln/internal/govulncheck"
+ "golang.org/x/vuln/internal/osv"
+)
+
+type findingLevel int
+
+const (
+ invalid findingLevel = iota
+ required
+ imported
+ called
+)
+
+type handler struct {
+ w io.Writer
+ cfg *govulncheck.Config
+ osvs map[string]*osv.Entry
+ levels map[string]findingLevel
+}
+
+func NewHandler(w io.Writer) *handler {
+ return &handler{
+ w: w,
+ osvs: make(map[string]*osv.Entry),
+ levels: make(map[string]findingLevel),
+ }
+}
+
+func (h *handler) Config(cfg *govulncheck.Config) error {
+ h.cfg = cfg
+ return nil
+}
+
+func (h *handler) Progress(progress *govulncheck.Progress) error {
+ return nil
+}
+
+func (h *handler) OSV(e *osv.Entry) error {
+ h.osvs[e.ID] = e
+ return nil
+}
+
+// foundAtLevel returns the level at which a specific finding is present in the
+// scanned product.
+func foundAtLevel(f *govulncheck.Finding) findingLevel {
+ frame := f.Trace[0]
+ if frame.Function != "" {
+ return called
+ }
+ if frame.Package != "" {
+ return imported
+ }
+ return required
+}
+
+func (h *handler) Finding(f *govulncheck.Finding) error {
+ fLevel := foundAtLevel(f)
+ if fLevel > h.levels[f.OSV] {
+ h.levels[f.OSV] = fLevel
+ }
+ return nil
+}
+
+// Flush is used to print the vex json to w.
+// This is needed as vex is not streamed.
+func (h *handler) Flush() error {
+ doc := toVex(h)
+ out, err := json.MarshalIndent(doc, "", " ")
+ if err != nil {
+ return err
+ }
+ _, err = h.w.Write(out)
+ return err
+}
+
+func toVex(h *handler) Document {
+ doc := Document{
+ Context: ContextURI,
+ Author: DefaultAuthor,
+ Timestamp: time.Now().UTC(),
+ Version: 1,
+ Tooling: Tooling,
+ Statements: statements(h),
+ }
+
+ id := hashVex(doc)
+ doc.ID = "govulncheck/vex:" + id
+ return doc
+}
+
+// statements combines all OSVs found by govulncheck and generates the list of
+// vex statements with the proper affected level and justification to match the
+// openVex specification.
+func statements(h *handler) []Statement {
+ var scanLevel findingLevel
+ switch h.cfg.ScanLevel {
+ case govulncheck.ScanLevelModule:
+ scanLevel = required
+ case govulncheck.ScanLevelPackage:
+ scanLevel = imported
+ case govulncheck.ScanLevelSymbol:
+ scanLevel = called
+ }
+
+ var statements []Statement
+ for id, osv := range h.osvs {
+ description := osv.Summary
+ if description == "" {
+ description = osv.Details
+ }
+ s := Statement{
+ Vulnerability: Vulnerability{
+ ID: fmt.Sprintf("https://pkg.go.dev/vuln/%s", id),
+ Name: id,
+ Description: description,
+ Aliases: osv.Aliases,
+ },
+ Products: []Product{
+ {
+ ID: DefaultPID,
+ },
+ },
+ }
+
+ if h.levels[id] >= scanLevel {
+ s.Status = StatusAffected
+ } else {
+ s.Status = StatusNotAffected
+ s.ImpactStatement = Impact
+ s.Justification = JustificationNotPresent
+ // We only reach this case if running in symbol mode
+ if h.levels[id] == imported {
+ s.Justification = JustificationNotExecuted
+ }
+ }
+ statements = append(statements, s)
+ }
+
+ slices.SortFunc(statements, func(a, b Statement) int {
+ if a.Vulnerability.ID > b.Vulnerability.ID {
+ return 1
+ }
+ if a.Vulnerability.ID < b.Vulnerability.ID {
+ return -1
+ }
+ // this should never happen in practice, since statements are being
+ // populated from a map with the vulnerability IDs as keys
+ return 0
+ })
+ return statements
+}
+
+func hashVex(doc Document) string {
+ // json.Marshal should never error here (because of the structure of Document).
+ // If an error does occur, it won't be a jsonerror, but instead a panic
+ d := Document{
+ Context: doc.Context,
+ ID: doc.ID,
+ Author: doc.Author,
+ Version: doc.Version,
+ Tooling: doc.Tooling,
+ Statements: doc.Statements,
+ }
+ out, err := json.Marshal(d)
+ if err != nil {
+ panic(err)
+ }
+ return fmt.Sprintf("%x", sha256.Sum256(out))
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/govulncheck-1.1.1/internal/openvex/handler_test.go new/govulncheck-1.1.2/internal/openvex/handler_test.go
--- old/govulncheck-1.1.1/internal/openvex/handler_test.go 1970-01-01 01:00:00.000000000 +0100
+++ new/govulncheck-1.1.2/internal/openvex/handler_test.go 2024-06-06 16:46:51.000000000 +0200
@@ -0,0 +1,70 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package openvex
+
+import (
+ "testing"
+
+ "golang.org/x/vuln/internal/govulncheck"
+)
+
+func TestFinding(t *testing.T) {
+ const id1 = "ID1"
+ tests := []struct {
+ name string
+ id string
+ findings []*govulncheck.Finding
+ want findingLevel
+ }{
+ {
+ name: "multiple",
+ id: id1,
+ findings: []*govulncheck.Finding{
+ {
+ OSV: id1,
+ Trace: []*govulncheck.Frame{
+ {
+ Module: "mod",
+ Package: "pkg",
+ },
+ },
+ },
+ {
+ OSV: id1,
+ Trace: []*govulncheck.Frame{
+ {
+ Module: "mod",
+ Package: "pkg",
+ Function: "func",
+ },
+ },
+ },
+ {
+ OSV: id1,
+ Trace: []*govulncheck.Frame{
+ {
+ Module: "mod",
+ },
+ },
+ },
+ },
+ want: called,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ h := NewHandler(nil)
+ for _, f := range tt.findings {
+ if err := h.Finding(f); err != nil {
+ t.Errorf("handler.Finding() error = %v", err)
+ }
+ }
+ got := h.levels[tt.id]
+ if got != tt.want {
+ t.Errorf("want %v; got %v", tt.want, got)
+ }
+ })
+ }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/govulncheck-1.1.1/internal/openvex/vex.go new/govulncheck-1.1.2/internal/openvex/vex.go
--- old/govulncheck-1.1.1/internal/openvex/vex.go 2024-05-21 23:23:08.000000000 +0200
+++ new/govulncheck-1.1.2/internal/openvex/vex.go 2024-06-06 16:46:51.000000000 +0200
@@ -7,6 +7,9 @@
//
// These types match the OpenVEX standard. See https://github.com/openvex for
// more information on VEX and OpenVEX.
+//
+// This is intended to be the minimimal amount of information required to output
+// a complete VEX document according to the specification.
package openvex
import "time"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/govulncheck-1.1.1/internal/osv/osv.go new/govulncheck-1.1.2/internal/osv/osv.go
--- old/govulncheck-1.1.1/internal/osv/osv.go 2024-05-21 23:23:08.000000000 +0200
+++ new/govulncheck-1.1.2/internal/osv/osv.go 2024-06-06 16:46:51.000000000 +0200
@@ -235,4 +235,6 @@
// The URL of the Go advisory for this vulnerability, of the form
// "https://pkg.go.dev/GO-YYYY-XXXX".
URL string `json:"url,omitempty"`
+ // The review status of this report (UNREVIEWED or REVIEWED).
+ ReviewStatus ReviewStatus `json:"review_status,omitempty"`
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/govulncheck-1.1.1/internal/osv/review_status.go new/govulncheck-1.1.2/internal/osv/review_status.go
--- old/govulncheck-1.1.1/internal/osv/review_status.go 1970-01-01 01:00:00.000000000 +0100
+++ new/govulncheck-1.1.2/internal/osv/review_status.go 2024-06-06 16:46:51.000000000 +0200
@@ -0,0 +1,67 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package osv
+
+import (
+ "encoding/json"
+ "fmt"
+)
+
+type ReviewStatus int
+
+const (
+ ReviewStatusUnknown ReviewStatus = iota
+ ReviewStatusUnreviewed
+ ReviewStatusReviewed
+)
+
+var statusStrs = []string{
+ ReviewStatusUnknown: "",
+ ReviewStatusUnreviewed: "UNREVIEWED",
+ ReviewStatusReviewed: "REVIEWED",
+}
+
+func (r ReviewStatus) String() string {
+ if !r.IsValid() {
+ return fmt.Sprintf("INVALID(%d)", r)
+ }
+ return statusStrs[r]
+}
+
+func ReviewStatusValues() []string {
+ return statusStrs[1:]
+}
+
+func (r ReviewStatus) IsValid() bool {
+ return int(r) >= 0 && int(r) < len(statusStrs)
+}
+
+func ToReviewStatus(s string) (ReviewStatus, bool) {
+ for stat, str := range statusStrs {
+ if s == str {
+ return ReviewStatus(stat), true
+ }
+ }
+ return 0, false
+}
+
+func (r ReviewStatus) MarshalJSON() ([]byte, error) {
+ if !r.IsValid() {
+ return nil, fmt.Errorf("MarshalJSON: unrecognized review status: %d", r)
+ }
+ return json.Marshal(r.String())
+}
+
+func (r *ReviewStatus) UnmarshalJSON(b []byte) error {
+ var s string
+ if err := json.Unmarshal(b, &s); err != nil {
+ return err
+ }
+ if rs, ok := ToReviewStatus(s); ok {
+ *r = rs
+ return nil
+ }
+ return fmt.Errorf("UnmarshalJSON: unrecognized review status: %s", s)
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/govulncheck-1.1.1/internal/sarif/sarif.go new/govulncheck-1.1.2/internal/sarif/sarif.go
--- old/govulncheck-1.1.1/internal/sarif/sarif.go 2024-05-21 23:23:08.000000000 +0200
+++ new/govulncheck-1.1.2/internal/sarif/sarif.go 2024-06-06 16:46:51.000000000 +0200
@@ -39,7 +39,7 @@
// Properties field of a Tool.Driver is a govulncheck.Config used for the
// invocation of govulncheck producing the Results. Properties field of
// a Rule contains information on CVE and GHSA aliases for the corresponding
-// rule OSV. Clients can use this information to, say, supress and filter
+// rule OSV. Clients can use this information to, say, suppress and filter
// vulnerabilities.
//
// Please see the definition of types below for more information.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/govulncheck-1.1.1/internal/scan/flags.go new/govulncheck-1.1.2/internal/scan/flags.go
--- old/govulncheck-1.1.1/internal/scan/flags.go 2024-05-21 23:23:08.000000000 +0200
+++ new/govulncheck-1.1.2/internal/scan/flags.go 2024-06-06 16:46:51.000000000 +0200
@@ -42,7 +42,7 @@
flags.Var(&modeFlag, "mode", "supports 'source', 'binary', and 'extract' (default 'source')")
flags.Var(&cfg.tags, "tags", "comma-separated `list` of build tags")
flags.Var(&cfg.show, "show", "enable display of additional information specified by the comma separated `list`\nThe supported values are 'traces','color', 'version', and 'verbose'")
- flags.Var(&cfg.format, "format", "specify format output\nThe supported values are 'text', 'json', and 'sarif' (default 'text')")
+ flags.Var(&cfg.format, "format", "specify format output\nThe supported values are 'text', 'json', 'sarif', and 'openvex' (default 'text')")
flags.BoolVar(&version, "version", false, "print the version information")
flags.Var(&scanFlag, "scan", "set the scanning level desired, one of 'module', 'package', or 'symbol' (default 'symbol')")
@@ -236,16 +236,18 @@
type FormatFlag string
const (
- formatUnset = ""
- formatJSON = "json"
- formatText = "text"
- formatSarif = "sarif"
+ formatUnset = ""
+ formatJSON = "json"
+ formatText = "text"
+ formatSarif = "sarif"
+ formatOpenVEX = "openvex"
)
var supportedFormats = map[string]bool{
- formatJSON: true,
- formatText: true,
- formatSarif: true,
+ formatJSON: true,
+ formatText: true,
+ formatSarif: true,
+ formatOpenVEX: true,
}
func (f *FormatFlag) Get() interface{} { return *f }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/govulncheck-1.1.1/internal/scan/run.go new/govulncheck-1.1.2/internal/scan/run.go
--- old/govulncheck-1.1.1/internal/scan/run.go 2024-05-21 23:23:08.000000000 +0200
+++ new/govulncheck-1.1.2/internal/scan/run.go 2024-06-06 16:46:51.000000000 +0200
@@ -15,8 +15,10 @@
"strings"
"time"
+ "golang.org/x/telemetry/counter"
"golang.org/x/vuln/internal/client"
"golang.org/x/vuln/internal/govulncheck"
+ "golang.org/x/vuln/internal/openvex"
"golang.org/x/vuln/internal/sarif"
)
@@ -41,6 +43,8 @@
handler = govulncheck.NewJSONHandler(stdout)
case formatSarif:
handler = sarif.NewHandler(stdout)
+ case formatOpenVEX:
+ handler = openvex.NewHandler(stdout)
default:
th := NewTextHandler(stdout)
cfg.show.Update(th)
@@ -51,6 +55,8 @@
return err
}
+ incTelemetryFlagCounters(cfg)
+
switch cfg.ScanMode {
case govulncheck.ScanModeSource:
dir := filepath.FromSlash(cfg.dir)
@@ -133,6 +139,19 @@
cfg.ScannerVersion = buf.String()
}
+func incTelemetryFlagCounters(cfg *config) {
+ counter.Inc(fmt.Sprintf("govulncheck/mode:%s", cfg.ScanMode))
+ counter.Inc(fmt.Sprintf("govulncheck/scan:%s", cfg.ScanLevel))
+ counter.Inc(fmt.Sprintf("govulncheck/format:%s", cfg.format))
+
+ if len(cfg.show) == 0 {
+ counter.Inc("govulncheck/show:none")
+ }
+ for _, s := range cfg.show {
+ counter.Inc(fmt.Sprintf("govulncheck/show:%s", s))
+ }
+}
+
func Flush(h govulncheck.Handler) error {
if th, ok := h.(interface{ Flush() error }); ok {
return th.Flush()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/govulncheck-1.1.1/internal/scan/text.go new/govulncheck-1.1.2/internal/scan/text.go
--- old/govulncheck-1.1.1/internal/scan/text.go 2024-05-21 23:23:08.000000000 +0200
+++ new/govulncheck-1.1.2/internal/scan/text.go 2024-06-06 16:46:51.000000000 +0200
@@ -297,23 +297,37 @@
return symbol(traces[i].Trace[0], true) < symbol(traces[j].Trace[0], true)
})
- first := true
- count := 1
- for _, entry := range traces {
- if entry.Compact == "" {
- continue // skip package and module level traces
+ // compacts are finding summaries with compact traces
+ // suitable for non-verbose textual output. Currently,
+ // only traces produced by symbol analysis.
+ var compacts []*findingSummary
+ for _, t := range traces {
+ if t.Compact != "" {
+ compacts = append(compacts, t)
}
- if first {
+ }
+
+ // binLimit is a limit on the number of binary traces
+ // to show. Traces for binaries are less interesting
+ // as users cannot act on them and they can hence
+ // spam users.
+ const binLimit = 5
+ for i, entry := range compacts {
+ if i == 0 {
if h.scanMode == govulncheck.ScanModeBinary {
h.style(keyStyle, " Vulnerable symbols found:\n")
} else {
h.style(keyStyle, " Example traces found:\n")
}
}
- first = false
- h.print(" #", count, ": ")
- count++
+ // skip showing all symbols in binary mode unless '-show traces' is on.
+ if h.scanMode == govulncheck.ScanModeBinary && (i+1) > binLimit && !h.showTraces {
+ h.print(" Use '-show traces' to see the other ", len(compacts)-binLimit, " found symbols\n")
+ break
+ }
+
+ h.print(" #", i+1, ": ")
if !h.showTraces {
h.print(entry.Compact, "\n")
} else {
++++++ vendor.tar.gz ++++++
++++ 35094 lines of diff (skipped)
1
0
Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-pyvips for openSUSE:Factory checked in at 2024-06-07 15:04:21
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-pyvips (Old)
and /work/SRC/openSUSE:Factory/.python-pyvips.new.24587 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pyvips"
Fri Jun 7 15:04:21 2024 rev:4 rq:1179076 version:2.2.3
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-pyvips/python-pyvips.changes 2024-01-06 18:41:07.733455756 +0100
+++ /work/SRC/openSUSE:Factory/.python-pyvips.new.24587/python-pyvips.changes 2024-06-07 15:04:44.298770656 +0200
@@ -1,0 +2,10 @@
+Thu Jun 6 20:11:27 UTC 2024 - Dirk Müller <dmueller(a)suse.com>
+
+- update to 2.2.3:
+ * Fix -Wincompatible-function-pointer-types warning on Clang
+ * Fix flake8 warnings
+ * new_from_source keeps a ref to the source
+ * improve generation of enums.py
+ * Ensure compatibility with a single shared libvips library
+
+-------------------------------------------------------------------
Old:
----
pyvips-2.2.2.tar.gz
New:
----
pyvips-2.2.3.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-pyvips.spec ++++++
--- /var/tmp/diff_new_pack.oo4vQr/_old 2024-06-07 15:04:44.842790474 +0200
+++ /var/tmp/diff_new_pack.oo4vQr/_new 2024-06-07 15:04:44.846790620 +0200
@@ -18,7 +18,7 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
Name: python-pyvips
-Version: 2.2.2
+Version: 2.2.3
Release: 0
Summary: Python bindings for VIPS image processing library
License: MIT
++++++ pyvips-2.2.2.tar.gz -> pyvips-2.2.3.tar.gz ++++++
++++ 1901 lines of diff (skipped)
1
0