Portage
Using the Portage Python API
The Python API is installed with Portage itself. There is very little documentation on its interface, but an introduction can be found here, and an extended (and terse) reference can be found here.
Here's a brief example of its use:
import portage
# Use portage.db[portage.root] to access the database. "vartree" contains the
# list of installed packages and "porttree" contains every ebuild.
# See: https://www.funtoo.org/Portage_API
installed_packages = portage.db[portage.root]["vartree"].dbapi
# List all "catpkg-version" or "category/package-version" atoms in the tree.
print("\n".join(installed_packages.cpv_all()))
This can be used for performing various queries on the database. While this is
very cool, I generally prefer to use equery
, simply because its options are
well documented.
Querying the Database for Package Metadata
When I took my machine from testing to stable, I needed to generate a list of
all packages currently in testing so that I could add them to
package.accept_keywords
. I stole this query from this blogpost.
equery list --installed -F '<=$cpv $mask2' '*' | \
grep \~ | sudo tee /etc/portage/package.keywords/testing
I test to make sure that this has produced no changes by checking emerge:
$ emerge --ask --update --newuse --deep --pretend --with-bdeps=y @world
These are the packages that would be merged, in order:
Calculating dependencies... done!
Dependency resolution took 8.12 s (backtrack: 0/20).
Cleaning /etc/portage/package.*
From Unused Keywords
Over time, these directories gather keywords that no longer serve a function.
Use eix-test-obsolete
to look for all kinds of obsoletion. Since this
command produces a lot of output, I've attempted to document the sections it
produces below:
Non-matching Entries
Non-matching entries in /etc/portage/package.{accept_keywords,use}:
=dev-libs/hyprland-protocols-0.2 **
These packages cannot be found in the tree, either in portage or in any
enabled overlays. These may also show up under Installed packages with a
version not in the database (or masked)
if there are other versions in the
tree. Resolving these requires more than just changing files in
/etc/portage
, since it may also require updating packages to new versions or
removing packages entirely.
Redundant Entries
Redundant in /etc/portage/package.{,accept_}keywords:
... considered as REDUNDANT_IF_DOUBLE
[I] sys-devel/clang (17.0.6(17/17)@12/09/23 18.1.5(18/18.1)@05/05/24): C language family frontend for LLVM
These entires are redundant because one or more overlapping entries specify
the same behavior for portage. In this case, I have two versions of clang
installed, and two entries in /etc/portage/package.accept_keywords
:
<=sys-devel/clang-17.0.6 ~arm64
<=sys-devel/clang-18.1.5 ~arm64
It should be obvious from here that the first entry is made redundant by the second entry, so the first entry can be removed.
REDUNDANT_IF_WEAKER
... considered as REDUNDANT_IF_WEAKER
[I] app-misc/brightnessctl [2] (0.5.1@04/26/23): A program to read and control device brightness
In this case, package.accept_keywords
contains this entry:
=app-misc/brightnessctl-0.5.1 **
As you may recall from the relevant Gentoo wiki page, the special **
keyword means the package is always visible, regardless of architecture or
testing status. This was likely necessary at a time when the package was in
testing and didn't have your architecture listed in its keywords. However,
the package has since gained a keyword.
$ equery meta '=app-misc/brightnessctl-0.5.1'
* app-misc/brightnessctl [guru]
Maintainer: myrvogna@electrosphe.re (Octiabrina Terrien-Puig)
Upstream: Remote-ID: https://github.com/Hummer12007/brightnessctl
(github)
Homepage: https://github.com/Hummer12007/brightnessctl
Location: /var/db/repos/guru/app-misc/brightnessctl
Keywords: 0.5.1:0: ~amd64 ~arm64
License: MIT
This entry is now weaker than it needs to be, and can be modified.
REDUNDANT_IF_STRANGE
... considered as REDUNDANT_IF_STRANGE
[N] app-office/libreoffice (7.6.4.1{gpkg:2}): A full office productivity suite
This is an odd one. In this case, package.accept_keywords
contained:
app-office/libreoffice -~arm64
But I had just changed /etc/portage/make.conf
to list
ACCEPT_KEYWORDS="arm64"
, so this entry serves no purpose and can be
removed.
In some cases, you might need to add an arch keyword for a different arch if
eix-test-obsolete
continues to complain. For example, I recently added this
line to silence a warning about conan
. The package listed no keywords for
arm64
(my arch), but was stable in amd64
.
<=dev-util/conan-2.7.1 amd64
REDUNDANT_IF_NO_CHANGE
... considered as REDUNDANT_IF_NO_CHANGE
[I] app-crypt/gnupg (2.4.5@03/09/24): The GNU Privacy Guard, a GPL OpenPGP implementation
In this case, /etc/portage/package.accept_keywords
contained:
<=app-crypt/gnupg-2.4.5 ~arm64
However, ACCEPT_KEYWORDS="arm64"
and the metadata for the package lists
arm64
as well as ~arm64
:
$ equery meta '=app-crypt/gnupg-2.4.5'
* app-crypt/gnupg [gentoo]
Maintainer: base-system@gentoo.org (Gentoo Base System)
Upstream: Remote-ID: cpe:/a:gnupg:gnupg (cpe)
Homepage: https://gnupg.org/
Location: /var/db/repos/gentoo/app-crypt/gnupg
Keywords: 2.4.5:0: amd64 arm arm64 ppc ppc64 sparc x86 ~alpha
~amd64-linux ~arm64-macos ~hppa ~ia64 ~loong ~m68k
~mips ~ppc-macos ~riscv ~s390 ~x64-macos ~x64-solaris
~x86-linux
License: GPL-3+
So in this case, this entry can be removed entirely.
Not Installed Packages
If there are a lot of these, make sure that the database is up to date (run
eix update
). In the past, I had forgotten to do this recently, and it took
the number from 260 down to 43.
Not installed but in /etc/portage/package.{,accept_}keywords:
[N] media-sound/id3v2 ((*)0.1.12-r1): Command line editor for id3v2 tags
Found 11 matches
These ones are obvious. The package isn't installed, but we are accepting keywords for them.
Pulled Versions of Installed Packages
Installed packages with a version not in the database (or masked):
[?] dev-cpp/sdbus-c++ (1.4.0(0/1)@11/29/23 -> ??): High-level C++ D-Bus library
These packages are installed, but the versions that are installed can't be found in the database. For example:
$ eix sdbus-c++
[?] dev-cpp/sdbus-c++
Available versions: ~*1.4.0-r1(0/1)^t {doc +elogind systemd test tools}
Installed versions: 1.4.0(0/1)^t(07:08:07 11/29/23)(systemd -doc -elogind -test -tools)
Homepage: https://github.com/Kistler-Group/sdbus-cpp
Description: High-level C++ D-Bus library
If the first field is [U]
, explicitly emerge
ing the stated version should
resolve the issue. For example:
[U] dev-python/python-lsp-server (1.11.0@06/14/24 -> 1.12.0^t): Python Language Server for the Language Server Protocol
Finally, if a package doesn't list a keyword, open a bug to request it.