It seems people are interested in adding support for flatpaks into other software centers, and I thought I might be useful to explain how I did this in gnome-software. I’m lucky enough to have a plugin architecture to make all the flatpak code be self contained in one file, but that’s certainly not a requirement.
Flatpak generates AppStream metadata when you build desktop applications. This means it’s possible to use appstream-glib and a few tricks to just load all the enabled remotes into an existing system store. This makes searching the new applications using the (optionally stemmed) token cache trivial. Once per day gnome-software checks the age of the AppStream cache, and if required downloads a new copy using flatpak_installation_update_appstream_sync()
. As if by magic, appstream-glib notices the file modification/creation and updates the internal AsStore
with the new applications.
When listing the installed applications, a simple call to flatpak_installation_list_installed_refs()
returns us the list we need, on which we can easily set other flatpak-specific data like the runtime. This is matched against the AppStream data, which gives us a localized and beautiful application to display in the listview.
At this point we also call flatpak_installation_list_installed_refs_for_update()
and then do flatpak_installation_update()
with the NO_DEPLOY
flag set. This just downloads the data we need, and can be cancelled without anything bad happening. When populating the updates panel I can just call flatpak_installation_list_installed_refs()
again to find installed applications that have downloaded updates ready to apply without network access.
For the sources list I’m calling flatpak_installation_list_remotes() then ignoring any set as disabled or noenumerate. Most remotes have a name and title, and this makes the UI feature complete. When collecting information to show in the ui like the size we have the metadata already, but we also add the size of the runtime if it’s not already installed. This is the same idea as flatpak_installation_install()
, where we also install any required runtime when installing the main application. There is a slight impedance mismatch between the flatpak many-installed-versions and the AppStream only-one-version model, but it seems to work well enough in the current code. Flatpak splits the deployment into a runtime containing common libraries that can be shared between apps (for instance, GNOME 3.20 or KDE5) and the application itself, so the software center always needs to install the runtime for the application to launch successfully. This is something that is not enforced by the CLI tool. Rather than installing everything for each app, we can also install other so-called extensions. These are typically non-essential like the various translations and any debug information, but are not strictly limited to those things. libflatpak
automatically keeps the extensions up to date when updating, so gnome-software doesn’t have to do anything special at all.
Updating single applications is trivial with flatpak_installation_update()
and launching applications is just as easy with flatpak_installation_launch()
, although we only support launching the newest installed version of an application at the moment. Reading local bundles works well with flatpak_bundle_ref_new()
, although we do have to load the gzipped AppStream metadata and the icon ourselves. Reading a .flatpakrepo
file is slightly more work, but the data is in keyfile format and trivial to parse with GKeyFile
.
Overall I’ve found libflatpak
to be surprisingly easy to work with, requiring none of the kludges of all the different package-based systems I’ve worked on developing PackageKit. Full marks to Alex et al.