commit: 4983d96b6e800fa5006a8ba43097569c469ed19e Author: Matt Turner <mattst88 <AT> gentoo <DOT> org> AuthorDate: Thu Dec 12 01:50:58 2024 +0000 Commit: Matt Turner <mattst88 <AT> gentoo <DOT> org> CommitDate: Thu Dec 12 01:55:43 2024 +0000 URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=4983d96b
dev-libs/libei: Add patch to fix test failure Closes: https://bugs.gentoo.org/937846 Signed-off-by: Matt Turner <mattst88 <AT> gentoo.org> ...1.3.0-scanner-switch-to-using-dataclasses.patch | 417 +++++++++++++++++++++ dev-libs/libei/libei-1.3.0-r1.ebuild | 101 +++++ 2 files changed, 518 insertions(+) diff --git a/dev-libs/libei/files/1.3.0-scanner-switch-to-using-dataclasses.patch b/dev-libs/libei/files/1.3.0-scanner-switch-to-using-dataclasses.patch new file mode 100644 index 000000000000..08d192f52a5d --- /dev/null +++ b/dev-libs/libei/files/1.3.0-scanner-switch-to-using-dataclasses.patch @@ -0,0 +1,417 @@ +From dbc06510a115241fcfd07de49c0b991cad633721 Mon Sep 17 00:00:00 2001 +From: Peter Hutterer <[email protected]> +Date: Wed, 11 Sep 2024 10:50:26 +1000 +Subject: [PATCH] scanner: switch to using dataclasses + +This drops one dependency that we're not fully using anyway. Except for +the per-attribute validators that can be done in __post_init() we're not +using attrs for anything that dataclasses cannot do. +--- + .gitlab-ci.yml | 9 ++- + .gitlab-ci/ci.template | 1 + + .gitlab-ci/config.yml | 4 +- + proto/ei-scanner | 164 ++++++++++++++++++++--------------------- + proto/meson.build | 2 +- + 5 files changed, 90 insertions(+), 90 deletions(-) + +diff --git ./.gitlab-ci.yml ./.gitlab-ci.yml +index 1e5d956..caeedfa 100644 +--- ./.gitlab-ci.yml ++++ ./.gitlab-ci.yml +@@ -40,9 +40,9 @@ variables: + # See the documentation here: # + # https://wayland.freedesktop.org/libinput/doc/latest/building_libinput.html # + ############################################################################### +- FEDORA_PACKAGES: 'git diffutils gcc gcc-c++ pkgconf-pkg-config systemd-devel libxkbcommon-devel libxml2 doxygen python3-attrs python3-pytest python3-dbusmock python3-jinja2 python3-pip python3-pyyaml golang libabigail ' ++ FEDORA_PACKAGES: 'git diffutils gcc gcc-c++ pkgconf-pkg-config systemd-devel libxkbcommon-devel libxml2 doxygen python3-pytest python3-dbusmock python3-jinja2 python3-pip python3-pyyaml golang libabigail ' + FEDORA_PIP_PACKAGES: 'meson ninja structlog strenum ' +- DEBIAN_PACKAGES: 'git gcc g++ pkg-config libsystemd-dev libxkbcommon-dev libxml2 doxygen python3-attr python3-pytest python3-dbusmock python3-jinja2 python3-pip python3-yaml ' ++ DEBIAN_PACKAGES: 'git gcc g++ pkg-config libsystemd-dev libxkbcommon-dev libxml2 doxygen python3-pytest python3-dbusmock python3-jinja2 python3-pip python3-yaml ' + DEBIAN_PIP_PACKAGES: 'meson ninja structlog strenum ' + ############################ end of package lists ############################# + +@@ -50,8 +50,8 @@ variables: + # changing these will force rebuilding the associated image + # Note: these tags have no meaning and are not tied to a particular + # libinput version +- FEDORA_TAG: '2024-07-24.3' +- DEBIAN_TAG: '2024-07-24.3' ++ FEDORA_TAG: '2024-09-11.0' ++ DEBIAN_TAG: '2024-09-11.0' + + FDO_UPSTREAM_REPO: libinput/libei + +@@ -285,6 +285,7 @@ abicheck@fedora:40: + meson compile -C _build + meson install -C _build + popd ++ - pip install attrs + script: + - git remote add upstream$CI_JOB_ID https://gitlab.freedesktop.org/$FDO_UPSTREAM_REPO + - git fetch --tags upstream$CI_JOB_ID +diff --git ./.gitlab-ci/ci.template ./.gitlab-ci/ci.template +index 0c8aeb2..7e7cad5 100644 +--- ./.gitlab-ci/ci.template ++++ ./.gitlab-ci/ci.template +@@ -285,6 +285,7 @@ abicheck@{{distro.name}}:{{version}}: + meson compile -C _build + meson install -C _build + popd ++ - pip install attrs + script: + - git remote add upstream$CI_JOB_ID https://gitlab.freedesktop.org/$FDO_UPSTREAM_REPO + - git fetch --tags upstream$CI_JOB_ID +diff --git ./.gitlab-ci/config.yml ./.gitlab-ci/config.yml +index d89d0fd..42db0bc 100644 +--- ./.gitlab-ci/config.yml ++++ ./.gitlab-ci/config.yml +@@ -3,7 +3,7 @@ + # + + # We're happy to rebuild all containers when one changes. +-.default_tag: &default_tag '2024-07-24.3' ++.default_tag: &default_tag '2024-09-11.0' + + last_abi_break: abe85e051e7029bfd2e7913ab980a9e0042b6d0d + minimum_meson_version: 0.57.0 +@@ -24,7 +24,6 @@ distributions: + - libxkbcommon-devel + - libxml2 + - doxygen +- - python3-attrs + - python3-pytest + - python3-dbusmock + - python3-jinja2 +@@ -51,7 +50,6 @@ distributions: + - libxkbcommon-dev + - libxml2 + - doxygen +- - python3-attr + - python3-pytest + - python3-dbusmock + - python3-jinja2 +diff --git ./proto/ei-scanner ./proto/ei-scanner +index 11edb85..d23fea7 100755 +--- ./proto/ei-scanner ++++ ./proto/ei-scanner +@@ -20,9 +20,9 @@ appear in the XML file. + from typing import Any, Dict, List, Optional, Tuple, Union + from pathlib import Path + from textwrap import dedent ++from dataclasses import dataclass, field + + import argparse +-import attr + import jinja2 + import jinja2.environment + import os +@@ -55,48 +55,54 @@ def snake2camel(s: str) -> str: + return s.replace("_", " ").title().replace(" ", "") + + [email protected] ++@dataclass + class Description: +- summary: str = attr.ib(default="") +- text: str = attr.ib(default="") ++ summary: str = "" ++ text: str = "" + + [email protected] ++@dataclass + class Argument: + """ + Argument to a request or a reply + """ + +- name: str = attr.ib() +- protocol_type: str = attr.ib() +- summary: str = attr.ib() +- enum: Optional["Enum"] = attr.ib() +- interface: Optional["Interface"] = attr.ib() +- interface_arg: Optional["Argument"] = attr.ib(default=None) ++ name: str ++ protocol_type: str ++ summary: str ++ enum: Optional["Enum"] ++ interface: Optional["Interface"] ++ interface_arg: Optional["Argument"] = None + """ + For an argument with "interface_arg", this field points to the argument that + contains the interface name. + """ +- interface_arg_for: Optional["Argument"] = attr.ib(default=None) ++ interface_arg_for: Optional["Argument"] = None + """ + For an argument referenced by another argument through "interface_name", this field + points to the other argument that references this argument. + """ +- version_arg: Optional["Argument"] = attr.ib(default=None) ++ version_arg: Optional["Argument"] = None + """ + For an argument with type "new_id", this field points to the argument that + contains the version for this new object. + """ +- version_arg_for: Optional["Argument"] = attr.ib(default=None) ++ version_arg_for: Optional["Argument"] = None + """ + For an argument referenced by another argument of type "new_id", this field + points to the other argument that references this argument. + """ +- allow_null: bool = attr.ib(default=False) ++ allow_null: bool = False + """ + For an argument of type string, specify if the argument may be NULL. + """ + ++ def __post_init(self): ++ if self.protocol_type is None or self.protocol_type not in PROTOCOL_TYPES: ++ raise ValueError(f"Failed to parse protocol_type {self.protocol_type}") ++ if self.interface is not None and self.signature not in ["n", "o"]: ++ raise ValueError("Interface may only be set for object types") ++ + @property + def signature(self) -> str: + """ +@@ -104,11 +110,6 @@ class Argument: + """ + return PROTOCOL_TYPES[self.protocol_type] + +- @interface.validator # type: ignore +- def _validate_interface(self, attribute, value): +- if value is not None and self.signature not in ["n", "o"]: +- raise ValueError("Interface may only be set for object types") +- + @property + def as_c_arg(self) -> str: + return f"{self.c_type} {self.name}" +@@ -127,12 +128,6 @@ class Argument: + "new_id": "new_id_t", + }[self.protocol_type] + +- @protocol_type.validator # type: ignore +- def _validate_protocol_type(self, attribute, value): +- assert ( +- value is not None and value in PROTOCOL_TYPES +- ), f"Failed to parse protocol_type {value}" +- + @classmethod + def create( + cls, +@@ -153,26 +148,25 @@ class Argument: + ) + + [email protected] ++@dataclass + class Message: + """ + Parent class for a wire message (Request or Event). + """ + +- name: str = attr.ib() +- since: int = attr.ib() +- opcode: int = attr.ib() +- interface: "Interface" = attr.ib() +- description: Optional[Description] = attr.ib(default=None) +- is_destructor: bool = attr.ib(default=False) +- context_type: Optional[str] = attr.ib(default=None) ++ name: str ++ since: int ++ opcode: int ++ interface: "Interface" ++ description: Optional[Description] = None ++ is_destructor: bool = False ++ context_type: Optional[str] = None + +- arguments: List[Argument] = attr.ib(init=False, factory=list) ++ arguments: List[Argument] = field(init=False, default_factory=list) + +- @context_type.validator # type: ignore +- def _context_type_validate(self, attr, value): +- if value not in [None, "sender", "receiver"]: +- raise ValueError(f"Invalid context type {value}") ++ def __post_init(self): ++ if self.context_type not in [None, "sender", "receiver"]: ++ raise ValueError(f"Invalid context type {self.context_type}") + + def add_argument(self, arg: Argument) -> None: + if arg.name in [a.name for a in self.arguments]: +@@ -198,7 +192,7 @@ class Message: + return None + + [email protected] ++@dataclass + class Request(Message): + @classmethod + def create( +@@ -225,7 +219,7 @@ class Request(Message): + return f"{self.interface.name}_request_{self.name}" + + [email protected] ++@dataclass + class Event(Message): + @classmethod + def create( +@@ -252,17 +246,17 @@ class Event(Message): + return f"{self.interface.name}_event_{self.name}" + + [email protected] ++@dataclass + class Entry: + """ + An enum entry + """ + +- name: str = attr.ib() +- value: int = attr.ib() +- enum: "Enum" = attr.ib() +- summary: str = attr.ib() +- since: int = attr.ib() ++ name: str ++ value: int ++ enum: "Enum" ++ summary: str ++ since: int + + @classmethod + def create( +@@ -278,15 +272,15 @@ class Entry: + return f"{self.enum.fqdn}_{self.name}" + + [email protected] ++@dataclass + class Enum: +- name: str = attr.ib() +- since: int = attr.ib() +- interface: "Interface" = attr.ib() +- is_bitfield: bool = attr.ib(default=False) +- description: Optional[Description] = attr.ib(default=None) ++ name: str ++ since: int ++ interface: "Interface" ++ is_bitfield: bool = False ++ description: Optional[Description] = None + +- entries: List[Entry] = attr.ib(init=False, factory=list) ++ entries: List[Entry] = field(init=False, default_factory=list) + + @classmethod + def create( +@@ -329,16 +323,20 @@ class Enum: + return snake2camel(self.name) + + [email protected] ++@dataclass + class Interface: +- protocol_name: str = attr.ib() # name as in the XML, e.g. ei_pointer +- version: int = attr.ib() +- requests: List[Request] = attr.ib(init=False, factory=list) +- events: List[Event] = attr.ib(init=False, factory=list) +- enums: List[Enum] = attr.ib(init=False, factory=list) ++ protocol_name: str # name as in the XML, e.g. ei_pointer ++ version: int ++ requests: List[Request] = field(init=False, default_factory=list) ++ events: List[Event] = field(init=False, default_factory=list) ++ enums: List[Enum] = field(init=False, default_factory=list) ++ ++ mode: str ++ description: Optional[Description] = None + +- mode: str = attr.ib(validator=attr.validators.in_(["ei", "eis", "brei"])) +- description: Optional[Description] = attr.ib(default=None) ++ def __post_init(self): ++ if self.mode not in ["ei", "eis", "brei"]: ++ raise ValueError(f"Invalid mode {self.mode}") + + @property + def name(self) -> str: +@@ -444,11 +442,11 @@ class Interface: + return cls(protocol_name=protocol_name, version=version, mode=mode) + + [email protected] ++@dataclass + class XmlError(Exception): +- line: int = attr.ib() +- column: int = attr.ib() +- message: str = attr.ib() ++ line: int ++ column: int ++ message: str + + def __str__(self) -> str: + return f"line {self.line}:{self.column}: {self.message}" +@@ -458,32 +456,34 @@ class XmlError(Exception): + return cls(line=location[0], column=location[1], message=message) + + [email protected] ++@dataclass + class Copyright: +- text: str = attr.ib(default="") +- is_complete: bool = attr.ib(init=False, default=False) ++ text: str = "" ++ is_complete: bool = field(init=False, default=False) + + [email protected] ++@dataclass + class Protocol: +- copyright: Optional[str] = attr.ib(default=None) +- interfaces: List[Interface] = attr.ib(factory=list) ++ copyright: Optional[str] = None ++ interfaces: List[Interface] = field(default_factory=list) + + [email protected] ++@dataclass + class ProtocolParser(xml.sax.handler.ContentHandler): +- component: str = attr.ib() +- interfaces: List[Interface] = attr.ib(factory=list) +- copyright: Optional[Copyright] = attr.ib(init=False, default=None) ++ component: str ++ interfaces: List[Interface] = field(default_factory=list) ++ copyright: Optional[Copyright] = field(init=False, default=None) + +- current_interface: Optional[Interface] = attr.ib(init=False, default=None) +- current_message: Optional[Union[Message, Enum]] = attr.ib(init=False, default=None) +- current_description: Optional[Description] = attr.ib(init=False, default=None) ++ current_interface: Optional[Interface] = field(init=False, default=None) ++ current_message: Optional[Union[Message, Enum]] = field(init=False, default=None) ++ current_description: Optional[Description] = field(init=False, default=None) + # A dict of arg name to interface_arg name mappings +- current_interface_arg_names: Dict[str, str] = attr.ib(init=False, default=attr.Factory(dict)) # type: ignore +- current_new_id_arg: Optional[Argument] = attr.ib(init=False, default=None) ++ current_interface_arg_names: Dict[str, str] = field( ++ init=False, default_factory=dict ++ ) ++ current_new_id_arg: Optional[Argument] = field(init=False, default=None) + +- _run_counter: int = attr.ib(init=False, default=0, repr=False) ++ _run_counter: int = field(init=False, default=0, repr=False) + + @property + def location(self) -> Tuple[int, int]: +diff --git ./proto/meson.build ./proto/meson.build +index 95e9d07..db01a8b 100644 +--- ./proto/meson.build ++++ ./proto/meson.build +@@ -13,7 +13,7 @@ if xmllint.found() + endif + + pymod = import('python') +-required_python_modules = ['attr', 'jinja2'] ++required_python_modules = ['jinja2'] + python = pymod.find_installation('python3', modules: required_python_modules) + if python.language_version().version_compare('<3.9') + error('Python 3.9 or later required') +-- +2.45.2 + diff --git a/dev-libs/libei/libei-1.3.0-r1.ebuild b/dev-libs/libei/libei-1.3.0-r1.ebuild new file mode 100644 index 000000000000..3c5bc8f5dcf1 --- /dev/null +++ b/dev-libs/libei/libei-1.3.0-r1.ebuild @@ -0,0 +1,101 @@ +# Copyright 2023-2024 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=8 + +PYTHON_COMPAT=( python3_{10..13} ) +inherit meson python-any-r1 + +DESCRIPTION="Library for Emulated Input, primarily aimed at the Wayland stack" +HOMEPAGE="https://gitlab.freedesktop.org/libinput/libei" +SRC_URI="https://gitlab.freedesktop.org/libinput/${PN}/-/archive/${PV}/${P}.tar.bz2" +MUNIT_COMMIT="fbbdf1467eb0d04a6ee465def2e529e4c87f2118" +SRC_URI+=" https://github.com/nemequ/munit/archive/${MUNIT_COMMIT}.tar.gz -> munit-${MUNIT_COMMIT}.tar.gz" + +LICENSE="MIT" +SLOT="0" +KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~loong ~ppc ~ppc64 ~riscv ~s390 ~sparc ~x86" +IUSE="elogind systemd test" +RESTRICT="!test? ( test )" + +RDEPEND=" + >=dev-libs/libevdev-1.9.902 + || ( + systemd? ( >=sys-apps/systemd-237 ) + elogind? ( >=sys-auth/elogind-237 ) + sys-libs/basu + ) +" +DEPEND="${RDEPEND}" +BDEPEND=" + virtual/pkgconfig + $(python_gen_any_dep ' + dev-python/jinja2[${PYTHON_USEDEP}] + ') + test? ( + $(python_gen_any_dep ' + dev-python/pytest[${PYTHON_USEDEP}] + dev-python/python-dbusmock[${PYTHON_USEDEP}] + dev-python/pyyaml[${PYTHON_USEDEP}] + dev-python/structlog[${PYTHON_USEDEP}] + ') + ) +" + +PATCHES=( + "${FILESDIR}"/1.3.0-skip-protocol-test.patch + "${FILESDIR}"/1.3.0-scanner-switch-to-using-dataclasses.patch +) + +python_check_deps() { + if use test; then + python_has_version \ + "dev-python/pytest[${PYTHON_USEDEP}]" \ + "dev-python/python-dbusmock[${PYTHON_USEDEP}]" \ + "dev-python/pyyaml[${PYTHON_USEDEP}]" \ + "dev-python/structlog[${PYTHON_USEDEP}]" \ + || return 1 + fi + python_has_version \ + "dev-python/jinja2[${PYTHON_USEDEP}]" \ + || return 1 +} + +src_unpack() { + if [[ -n ${A} ]]; then + unpack ${A} + mv "${WORKDIR}"/munit-${MUNIT_COMMIT} "${WORKDIR}"/${P}/subprojects/munit || die + rm "${WORKDIR}"/${P}/subprojects/munit.wrap || die + fi +} + +src_prepare() { + default + + sed -i -e 's:^valgrind = .*:valgrind = disabler():g' test/meson.build || die +} + +src_configure() { + local emesonargs=( + -Ddocumentation="" + -Dliboeffis=enabled + $(meson_feature test tests) + ) + if use systemd; then + emesonargs+=(-Dsd-bus-provider=libsystemd) + elif use elogind; then + emesonargs+=(-Dsd-bus-provider=libelogind) + else + emesonargs+=(-Dsd-bus-provider=basu) + fi + meson_src_configure +} + +src_install() { + meson_src_install + + # munit subproject is installed but not wanted + if use test; then + rm "${ED}"/usr/lib*/libmunit.so || die + fi +}
