|
44 | 44 | import libdnf5.common |
45 | 45 | import libdnf5.conf |
46 | 46 | import libdnf5.rpm |
| 47 | + import rpm |
47 | 48 | except ImportError as exc: |
48 | 49 | raise MissingBackendError(str(exc)) from None |
49 | 50 |
|
@@ -944,15 +945,74 @@ def backend(self) -> BackendMod: |
944 | 945 | return t.cast(BackendMod, sys.modules[__name__]) |
945 | 946 |
|
946 | 947 |
|
| 948 | +def _dnf_getreleasever() -> str: # pragma: no cover |
| 949 | + # This is taken from dnf and slightly modified to fit fedrq's code style standards. |
| 950 | + # |
| 951 | + # SPDX-License-Identifier: GPL-2.0-or-later |
| 952 | + # Copyright (C) 2012-2015 Red Hat, Inc. |
| 953 | + DISTROVERPKG = ( |
| 954 | + "system-release(releasever)", |
| 955 | + "system-release", |
| 956 | + "distribution-release(releasever)", |
| 957 | + "distribution-release", |
| 958 | + "redhat-release", |
| 959 | + "suse-release", |
| 960 | + ) |
| 961 | + ts = rpm.TransactionSet("/") |
| 962 | + ts.setVSFlags(~(rpm._RPMVSF_NOSIGNATURES | rpm._RPMVSF_NODIGESTS)) |
| 963 | + for distroverpkg in map(lambda p: p.encode("utf-8"), DISTROVERPKG): |
| 964 | + idx = ts.dbMatch("provides", distroverpkg) |
| 965 | + if not len(idx): |
| 966 | + continue |
| 967 | + try: |
| 968 | + hdr = next(idx) |
| 969 | + except StopIteration: |
| 970 | + raise RuntimeError( |
| 971 | + "Error: rpmdb failed to list provides. Try: rpm --rebuilddb" |
| 972 | + ) from None |
| 973 | + releasever = hdr["version"] |
| 974 | + try: |
| 975 | + try: |
| 976 | + # header returns bytes -> look for bytes |
| 977 | + # it may fail because rpm returns a decoded string since 10 Apr 2019 |
| 978 | + off = hdr[rpm.RPMTAG_PROVIDENAME].index(distroverpkg) |
| 979 | + except ValueError: |
| 980 | + # header returns a string -> look for a string |
| 981 | + off = hdr[rpm.RPMTAG_PROVIDENAME].index(distroverpkg.decode("utf8")) |
| 982 | + flag = hdr[rpm.RPMTAG_PROVIDEFLAGS][off] |
| 983 | + ver = hdr[rpm.RPMTAG_PROVIDEVERSION][off] |
| 984 | + if ( |
| 985 | + flag == rpm.RPMSENSE_EQUAL |
| 986 | + and ver |
| 987 | + and hdr["name"] not in (distroverpkg, distroverpkg.decode("utf8")) |
| 988 | + ): |
| 989 | + # override the package version |
| 990 | + releasever = ver |
| 991 | + except (ValueError, KeyError, IndexError): |
| 992 | + pass |
| 993 | + if isinstance(releasever, bytes): |
| 994 | + releasever = releasever.decode("utf-8") |
| 995 | + return releasever |
| 996 | + return "" |
| 997 | + |
| 998 | + |
947 | 999 | @functools.cache |
948 | 1000 | def get_releasever() -> str: |
949 | 1001 | """ |
950 | 1002 | Return the system releasever |
951 | 1003 | """ |
| 1004 | + # Use our copy of dnf4's code for now. |
| 1005 | + # For some reason, `detect_release` from libdnf5 is broken in some libdnf5 |
| 1006 | + # versions and returns an empty string instead of the correct value. |
| 1007 | + # Plus, having to create a Base object just for this is expensive. |
| 1008 | + # See also the discussion in https://github.com/rpm-software-management/dnf5/pull/1804. |
| 1009 | + # libdnf5 is considering breaking this API. |
| 1010 | + return _dnf_getreleasever() |
| 1011 | + |
952 | 1012 | # libdnf5 >= 5.0.10 |
953 | 1013 | # https://github.com/rpm-software-management/dnf5/pull/448 |
954 | | - base = libdnf5.base.Base() |
955 | | - return libdnf5.conf.Vars.detect_release(base.get_weak_ptr(), "/").get() |
| 1014 | + # base = libdnf5.base.Base() |
| 1015 | + # return libdnf5.conf.Vars.detect_release(base.get_weak_ptr(), "/").get() |
956 | 1016 |
|
957 | 1017 |
|
958 | 1018 | def get_changelogs(package: Package) -> Iterator[ChangelogEntry]: |
|
0 commit comments