diff --git a/.gitignore b/.gitignore
index 020f529..dad4e7d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,3 @@
-flatpak-runtime.dependencies
+out/*
+cache/*
+report.html
diff --git a/Makefile b/Makefile
index 5834fc7..3cc5282 100644
--- a/Makefile
+++ b/Makefile
@@ -1,12 +1,24 @@
-all:
- @echo "Usage: make [update-modulemd|runtime-local]"
-
-update-modulemd:
- flatpak-module create-modulemd \
- --template flatpak-runtime.in.yaml \
- --package-list flatpak-runtime-packages.yaml \
- --dependency-tree flatpak-runtime.dependencies \
- -o flatpak-runtime.yaml
-
-runtime-local:
- flatpak-module create-flatpak --runtime --info flatpak.json --module 'flatpak-runtime:f26'
+PACKAGE_LISTS = \
+ out/freedesktop-Platform.packages \
+ out/freedesktop-Sdk.packages \
+ out/gnome-Platform.packages \
+ out/gnome-Sdk.packages
+
+FILE_LISTS = \
+ $(patsubst %.packages,%.files,$(PACKAGE_LISTS))
+
+all: report.html
+
+report.html: $(PACKAGE_LISTS) generate-report.py report-template.html
+ ./generate-report.py
+
+$(FILE_LISTS): %.files: generate-files.sh list-files.py
+ ./generate-files.sh $@
+
+%.packages: %.files resolve-files.py
+ ./resolve-files.py $<
+
+clean:
+ rm -f out/*
+
+.PHONY: clean
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..f7f6053
--- /dev/null
+++ b/README.md
@@ -0,0 +1,86 @@
+This git repository holds documentation, data and scripts related to
+maintaining Fedora modules for the desktop and for Flatpak runtimes
+for Fedora.
+
+Fedora Desktop Modules Plan
+===========================
+
+The plan is to have the following modules, in addition to a large number
+of application modules:
+
+**X11-base** - (already exists, name is perhaps not ideal). Holds the
+core graphics stack - X, wayland libraries, mesa.
+
+**desktop-runtime** - this module corresponds roughly to
+org.gnome.Platform/org.gnome.SDK, but possibly with the addition of
+Qt and other libraries frequently used by Linux workstation users.
+
+**desktop** - this module contains the core GNOME desktop, but not desktop
+applications.
+
+**flatpak-runtime** - this is a small module that depends on
+desktop-runtime, and adds Flatpak-specific stuff, and in particular
+has a `buildroot` profile that install macros for relocation to `/app`. If you
+build-requires this module, your package will be relocated to `/app`. Build
+time modules like `autotools` are also *required* by this module so that they
+can be included into the SDK flatpaks, while they are only *buildrequired*
+by the `desktop-runtime` module.
+
+The dependency graph looks something like:
+
+```
+flatpak-runtime ┐
+desktop ────────┤
+ └ desktop-runtime ┐
+ ├ X11-base
+ └ fonts ───────┐
+ └ Platform
+```
+
+The`flatpak-runtime module will have profiles corresponding to different
+generated runtimes:
+
+**runtime-base**: `org.fedoraproject.BasePlatform`. This is a smaller
+runtime corresponding to `org.freedesktop.Platform`, and should
+contain packages that we think could be supported over multiple
+years. (Possibly the name should be something like runtime-stable
+instead, but stable is a loaded word.)
+
+**sdk-base**: `org.fedoraproject.BaseSdk` - SDK corresponding to
+`org.fedoraproject.BasePlatform`. The goal is that most
+flatpak-builder manifests that build against `org.freedesktop.Sdk` can
+be built against this instead, though can't be a formal promise,
+because org.freedesktop.Platform contains some amount of stray
+binaries and libraries that we need to eliminate. (It contains, for
+example, a binary of the Python `idle` IDE that doesn't work. Pulling
+`idle` into our runtime via `python2-tools` would pull in
+`python2-tkinter` and `tk`.)
+
+**runtime**: org.fedoraproject.Platform - the runtime that Fedora
+Flatpaks uses, roughly corresponding to `org.gnome.Platform`. It may
+contain less stable libraries than `org.fedoraproject.BasePlatform`.
+
+**sdk**: the SDK corresponding to the ``org.fedoraproject.Platform`.
+The goal is that most flatpak-builder manifests that build against
+`org.gnome.Sdk` can be built against this instead.
+
+Usage of this module
+====================
+
+*Prequisites*: you need to have the following "upstream" runtimes installed:
+
+* `org.freedesktop.Platform/x86_64/1.6`
+* `org.freedesktop.Sdk/x86_64/1.6`
+* `org.gnome.platform/x86_64/3.26`
+* `org.gnome.Sdk/x86_64/3.26`
+
+These will be used as sources to resolve hypthetical package sets that we
+can compare to the package sets of the desktop modules.
+
+You also need `python3-jinja2 python3-dnf` and possibly a few other Python
+packages installed.
+
+*Report generation*: run `make`. The first run will download f27 data
+into the user-specific DNF cache and also generate a big index of all files
+in Fedora. Subsequent runs are faster. Then open `report.html` in your
+browser.
diff --git a/f26-flatpak-runtime.packages b/f26-flatpak-runtime.packages
new file mode 100644
index 0000000..538ff24
--- /dev/null
+++ b/f26-flatpak-runtime.packages
@@ -0,0 +1,204 @@
+abattis-cantarell-fonts
+acl
+adwaita-cursor-theme
+adwaita-gtk2-theme
+adwaita-icon-theme
+at-spi2-atk
+at-spi2-core
+atk
+audit-libs
+avahi-libs
+basesystem
+bash
+bzip2-libs
+ca-certificates
+cairo
+cairo-gobject
+chkconfig
+colord-libs
+coreutils
+coreutils-common
+cracklib
+crypto-policies
+cryptsetup-libs
+cups-libs
+dbus
+dbus-libs
+device-mapper
+device-mapper-libs
+elfutils-default-yama-scope
+elfutils-libelf
+elfutils-libs
+emacs-filesystem
+enchant
+expat
+fedora-modular-release
+fedora-modular-repos
+filesystem
+flatpak-runtime-config
+fontconfig
+fontpackages-filesystem
+freetype
+gawk
+gdbm
+gdk-pixbuf2
+gdk-pixbuf2-modules
+glib-networking
+glib2
+glibc
+glibc-all-langpacks
+glibc-common
+gmp
+gnome-desktop3
+gnome-themes-standard
+gnutls
+gobject-introspection
+graphite2
+grep
+gsettings-desktop-schemas
+gtk-update-icon-cache
+gtk2
+gtk3
+gvfs-client
+gzip
+harfbuzz
+hicolor-icon-theme
+hunspell
+hunspell-en-GB
+hunspell-en-US
+hwdata
+info
+iptables-libs
+jasper-libs
+jbigkit-libs
+json-glib
+keyutils-libs
+kmod-libs
+krb5-libs
+lcms2
+libX11
+libX11-common
+libXau
+libXcomposite
+libXcursor
+libXdamage
+libXext
+libXfixes
+libXft
+libXi
+libXinerama
+libXrandr
+libXrender
+libXtst
+libXxf86vm
+libacl
+libappstream-glib
+libarchive
+libattr
+libblkid
+libcap
+libcap-ng
+libcom_err
+libcroco
+libcrypt
+libdatrie
+libdb
+libdrm
+libepoxy
+libfdisk
+libffi
+libgcab1
+libgcc
+libgcrypt
+libglvnd
+libglvnd-egl
+libglvnd-glx
+libgpg-error
+libgusb
+libidn
+libidn2
+libjpeg-turbo
+libmodman
+libmount
+libnotify
+libpcap
+libpciaccess
+libpng
+libproxy
+libpwquality
+librsvg2
+libseccomp
+libselinux
+libsemanage
+libsepol
+libsigsegv
+libsmartcols
+libsoup
+libstdc++
+libstemmer
+libtasn1
+libthai
+libtiff
+libunistring
+libusbx
+libutempter
+libuuid
+libverto
+libwayland-client
+libwayland-cursor
+libwayland-server
+libxcb
+libxkbcommon
+libxml2
+libxshmfence
+lz4-libs
+lzo
+mesa-libEGL
+mesa-libGL
+mesa-libgbm
+mesa-libglapi
+mesa-libwayland-egl
+mpfr
+ncurses
+ncurses-base
+ncurses-libs
+nettle
+openssl-libs
+p11-kit
+p11-kit-trust
+pam
+pango
+pcre
+pixman
+popt
+python3
+python3-appdirs
+python3-cairo
+python3-gobject
+python3-gobject-base
+python3-libs
+python3-packaging
+python3-pip
+python3-pyparsing
+python3-setuptools
+python3-six
+qrencode-libs
+readline
+rest
+sed
+setup
+shadow-utils
+shared-mime-info
+sqlite-libs
+system-python
+system-python-libs
+systemd
+systemd-libs
+systemd-pam
+tzdata
+ustr
+util-linux
+xkeyboard-config
+xz-libs
+zenity
+zlib
diff --git a/f27-live.packages b/f27-live.packages
new file mode 100644
index 0000000..0d2f5ef
--- /dev/null
+++ b/f27-live.packages
@@ -0,0 +1,1561 @@
+aajohan-comfortaa-fonts
+abattis-cantarell-fonts
+abrt
+abrt-addon-ccpp
+abrt-addon-coredump-helper
+abrt-addon-kerneloops
+abrt-addon-pstoreoops
+abrt-addon-vmcore
+abrt-addon-xorg
+abrt-cli
+abrt-dbus
+abrt-desktop
+abrt-gui
+abrt-gui-libs
+abrt-java-connector
+abrt-libs
+abrt-plugin-bodhi
+abrt-retrace-client
+abrt-tui
+accountsservice
+accountsservice-libs
+acl
+adcli
+adobe-source-han-sans-cn-fonts
+adobe-source-han-sans-tw-fonts
+adobe-source-han-serif-cn-fonts
+adobe-source-han-serif-tw-fonts
+adwaita-cursor-theme
+adwaita-gtk2-theme
+adwaita-icon-theme
+adwaita-qt4
+adwaita-qt5
+alsa-lib
+alsa-plugins-pulseaudio
+alsa-ucm
+alsa-utils
+anaconda
+anaconda-core
+anaconda-gui
+anaconda-tui
+anaconda-user-help
+anaconda-widgets
+appstream-data
+apr
+apr-util
+argyllcms
+atk
+atkmm
+atmel-firmware
+at-spi2-atk
+at-spi2-core
+attr
+audit
+audit-libs
+audit-libs-python3
+augeas-libs
+authconfig
+autocorr-en
+avahi
+avahi-glib
+avahi-libs
+b43-fwcutter
+b43-openfwwf
+baobab
+basesystem
+bash
+bash-completion
+bc
+bcache-tools
+bind99-libs
+bind99-license
+bind-libs
+bind-libs-lite
+bind-license
+bind-utils
+blivet-gui-runtime
+bluez
+bluez-cups
+bluez-libs
+bluez-obexd
+boost-date-time
+boost-filesystem
+boost-iostreams
+boost-system
+brasero-libs
+bridge-utils
+brlapi
+brltty
+btrfs-progs
+bubblewrap
+bzip2
+bzip2-libs
+ca-certificates
+cairo
+cairo-gobject
+cairomm
+c-ares
+caribou
+caribou-gtk2-module
+caribou-gtk3-module
+cdparanoia-libs
+celt051
+checkpolicy
+cheese
+cheese-libs
+chkconfig
+chrony
+cifs-utils
+cldr-emoji-annotation
+clucene-contribs-lib
+clucene-core
+clutter
+clutter-gst2
+clutter-gst3
+clutter-gtk
+cogl
+colord
+colord-gtk
+colord-libs
+color-filesystem
+compat-openssl10
+comps-extras
+control-center
+control-center-filesystem
+copy-jdk-configs
+coreutils
+coreutils-common
+corosync
+corosynclib
+cpio
+cracklib
+cracklib-dicts
+crda
+createrepo_c
+createrepo_c-libs
+cronie
+cronie-anacron
+crontabs
+crypto-policies
+cryptsetup
+cryptsetup-libs
+cups
+cups-client
+cups-filesystem
+cups-filters
+cups-filters-libs
+cups-libs
+cups-pk-helper
+curl
+cyrus-sasl
+cyrus-sasl-gssapi
+cyrus-sasl-lib
+cyrus-sasl-plain
+dbus
+dbus-glib
+dbus-libs
+dbusmenu-qt
+dbus-x11
+dbxtool
+dconf
+dejavu-fonts-common
+dejavu-sans-fonts
+dejavu-sans-mono-fonts
+dejavu-serif-fonts
+deltarpm
+desktop-backgrounds-gnome
+desktop-file-utils
+device-mapper
+device-mapper-event
+device-mapper-event-libs
+device-mapper-libs
+device-mapper-multipath
+device-mapper-multipath-libs
+device-mapper-persistent-data
+dhcp-client
+dhcp-common
+dhcp-libs
+diffutils
+djvulibre-libs
+dleyna-connector-dbus
+dleyna-core
+dleyna-server
+dmidecode
+dmraid
+dmraid-events
+dnf
+dnf-conf
+dnf-plugins-core
+dnf-yum
+dnsmasq
+dos2unix
+dosfstools
+dotconf
+dracut
+dracut-config-rescue
+dracut-live
+dracut-network
+drpm
+e2fsprogs
+e2fsprogs-libs
+ebtables
+edk2-ovmf
+efibootmgr
+efivar
+efivar-libs
+elfutils
+elfutils-default-yama-scope
+elfutils-libelf
+elfutils-libs
+emacs-filesystem
+enca
+enchant
+eog
+epiphany-runtime
+espeak
+ethtool
+evince
+evince-djvu
+evince-libs
+evince-nautilus
+evolution
+evolution-data-server
+evolution-data-server-langpacks
+evolution-ews
+evolution-ews-langpacks
+evolution-help
+evolution-langpacks
+exempi
+exiv2
+exiv2-libs
+expat
+f27-backgrounds-base
+f27-backgrounds-gnome
+fcoe-utils
+fedora-bookmarks
+fedora-logos
+fedora-logos-httpd
+fedora-productimg-workstation
+fedora-release
+fedora-release-workstation
+fedora-repos
+fedora-repos-rawhide
+fedora-user-agent-chrome
+fedora-workstation-backgrounds
+file
+file-libs
+file-roller
+file-roller-nautilus
+filesystem
+findutils
+fipscheck
+fipscheck-lib
+firefox
+firewalld
+firewalld-filesystem
+flac-libs
+flatpak
+flatpak-libs
+folks
+fontconfig
+fontpackages-filesystem
+foomatic
+foomatic-db
+foomatic-db-filesystem
+foomatic-db-ppds
+fpaste
+fprintd
+fprintd-pam
+freetype
+frei0r-plugins
+fros
+fros-gnome
+fuse
+fuse-common
+fuse-libs
+fwupd
+fwupdate-efi
+fwupdate-libs
+fwupd-labels
+gavl
+gawk
+gc
+GConf2
+gcr
+gd
+gdb-headless
+gdbm
+gdisk
+gdk-pixbuf2
+gdk-pixbuf2-modules
+gdm
+gdouros-symbola-fonts
+gedit
+genisoimage
+geoclue2
+geoclue2-libs
+geocode-glib
+GeoIP
+GeoIP-GeoLite-data
+gettext
+gettext-libs
+gfbgraph
+ghostscript
+ghostscript-core
+ghostscript-fonts
+ghostscript-x11
+giflib
+git
+git-core
+git-core-doc
+gjs
+glade-libs
+glib2
+glibc
+glibc-all-langpacks
+glibc-common
+glibc-langpack-en
+glibmm24
+glib-networking
+glusterfs
+glusterfs-api
+glusterfs-cli
+glusterfs-client-xlators
+glusterfs-fuse
+glusterfs-libs
+glx-utils
+gmime30
+gmp
+gnome-abrt
+gnome-autoar
+gnome-backgrounds
+gnome-bluetooth
+gnome-bluetooth-libs
+gnome-boxes
+gnome-calculator
+gnome-calendar
+gnome-characters
+gnome-classic-session
+gnome-clocks
+gnome-color-manager
+gnome-contacts
+gnome-desktop3
+gnome-disk-utility
+gnome-documents
+gnome-documents-libs
+gnome-font-viewer
+gnome-getting-started-docs
+gnome-initial-setup
+gnome-keyring
+gnome-keyring-pam
+gnome-logs
+gnome-maps
+gnome-menus
+gnome-online-accounts
+gnome-online-miners
+gnome-screenshot
+gnome-session
+gnome-session-wayland-session
+gnome-session-xsession
+gnome-settings-daemon
+gnome-shell
+gnome-shell-extension-alternate-tab
+gnome-shell-extension-apps-menu
+gnome-shell-extension-background-logo
+gnome-shell-extension-common
+gnome-shell-extension-launch-new-instance
+gnome-shell-extension-places-menu
+gnome-shell-extension-window-list
+gnome-software
+gnome-system-monitor
+gnome-terminal
+gnome-terminal-nautilus
+gnome-themes-standard
+gnome-todo
+gnome-user-docs
+gnome-user-share
+gnome-video-effects
+gnome-weather
+gnu-free-fonts-common
+gnu-free-mono-fonts
+gnu-free-sans-fonts
+gnu-free-serif-fonts
+gnupg
+gnupg2
+gnupg2-smime
+gnutls
+gobject-introspection
+gom
+google-android-emoji-fonts
+google-crosextra-caladea-fonts
+google-crosextra-carlito-fonts
+google-noto-emoji-fonts
+google-noto-fonts-common
+google-noto-sans-lisu-fonts
+google-noto-sans-mandaic-fonts
+google-noto-sans-meetei-mayek-fonts
+google-noto-sans-sinhala-fonts
+google-noto-sans-tagalog-fonts
+google-noto-sans-tai-tham-fonts
+google-noto-sans-tai-viet-fonts
+gperftools-libs
+gpgme
+gpgmepp
+gpg-pubkey
+graphite2
+grep
+grilo
+grilo-plugins
+groff-base
+grub2-common
+grub2-efi-ia32
+grub2-efi-ia32-cdboot
+grub2-efi-x64
+grub2-efi-x64-cdboot
+grub2-pc
+grub2-pc-modules
+grub2-tools
+grub2-tools-efi
+grub2-tools-extra
+grub2-tools-minimal
+grubby
+gsettings-desktop-schemas
+gsm
+gsound
+gspell
+gssdp
+gssproxy
+gstreamer1
+gstreamer1-plugins-bad-free
+gstreamer1-plugins-bad-free-gtk
+gstreamer1-plugins-base
+gstreamer1-plugins-good
+gstreamer1-plugins-ugly-free
+gtk2
+gtk3
+gtkmm24
+gtkmm30
+gtksourceview3
+gtkspell3
+gtk-update-icon-cache
+gtk-vnc2
+guile
+gupnp
+gupnp-av
+gupnp-dlna
+gutenprint
+gutenprint-cups
+gutenprint-libs
+gvfs
+gvfs-afc
+gvfs-afp
+gvfs-archive
+gvfs-client
+gvfs-fuse
+gvfs-goa
+gvfs-gphoto2
+gvfs-mtp
+gvfs-smb
+gvnc
+gzip
+hardlink
+harfbuzz
+harfbuzz-icu
+hfsplus-tools
+hicolor-icon-theme
+highlight
+hostname
+hplip
+hplip-common
+hplip-libs
+httpd
+httpd-filesystem
+httpd-tools
+http-parser
+hunspell
+hunspell-en
+hunspell-en-GB
+hunspell-en-US
+hwdata
+hyperv-daemons
+hyperv-daemons-license
+hypervfcopyd
+hypervkvpd
+hypervvssd
+hyphen
+hyphen-en
+ibus
+ibus-gtk2
+ibus-gtk3
+ibus-hangul
+ibus-kkc
+ibus-libpinyin
+ibus-libs
+ibus-libzhuyin
+ibus-m17n
+ibus-qt
+ibus-rawcode
+ibus-setup
+ibus-typing-booster
+ibus-wayland
+iio-sensor-proxy
+info
+initscripts
+ipcalc
+iproute
+iproute-tc
+ipset
+ipset-libs
+iptables
+iptables-libs
+iptstate
+iputils
+ipw2100-firmware
+ipw2200-firmware
+ipxe-roms-qemu
+iscsi-initiator-utils
+iscsi-initiator-utils-iscsiuio
+isns-utils-libs
+iso-codes
+isomd5sum
+iw
+iwl1000-firmware
+iwl100-firmware
+iwl105-firmware
+iwl135-firmware
+iwl2000-firmware
+iwl2030-firmware
+iwl3160-firmware
+iwl3945-firmware
+iwl4965-firmware
+iwl5000-firmware
+iwl5150-firmware
+iwl6000-firmware
+iwl6000g2a-firmware
+iwl6000g2b-firmware
+iwl6050-firmware
+iwl7260-firmware
+jansson
+jasper-libs
+java-1.8.0-openjdk-headless
+javapackages-tools
+jbigkit-libs
+jimtcl
+jomolhari-fonts
+js-jquery
+json-c
+json-glib
+julietaula-montserrat-fonts
+jwhois
+kbd
+kbd-legacy
+kbd-misc
+kernel
+kernel-core
+kernel-modules
+kernel-modules-extra
+kexec-tools
+kexec-tools-anaconda-addon
+keybinder3
+keyutils
+keyutils-libs
+khmeros-base-fonts
+khmeros-fonts-common
+kmod
+kmod-libs
+kpartx
+krb5-libs
+kyotocabinet-libs
+lame-libs
+langpacks-en
+langtable
+langtable-data
+langtable-python3
+lcms2
+less
+liba52
+libabw
+libacl
+libaio
+libao
+libappstream-glib
+libarchive
+libassuan
+libasyncns
+libatasmart
+libatomic_ops
+libattr
+libavc1394
+libbabeltrace
+libbasicobjects
+libblkid
+libblockdev
+libblockdev-btrfs
+libblockdev-crypto
+libblockdev-dm
+libblockdev-fs
+libblockdev-kbd
+libblockdev-loop
+libblockdev-lvm
+libblockdev-mdraid
+libblockdev-mpath
+libblockdev-part
+libblockdev-plugins-all
+libblockdev-swap
+libblockdev-utils
+libbluray
+libbytesize
+libcacard
+libcanberra
+libcanberra-gtk2
+libcanberra-gtk3
+libcap
+libcap-ng
+libcdio
+libcdio-paranoia
+libcdr
+libcgroup
+libchamplain
+libchamplain-gtk
+libcmis
+libcollection
+libcom_err
+libcomps
+libconfig
+libcroco
+libcrypt-nss
+libcryptui
+libcue
+libcurl
+libdaemon
+libdatrie
+libdb
+libdb-utils
+libdfu
+libdhash
+libdmapsharing
+libdmx
+libdnet
+libdnf
+libdrm
+libdv
+libdvdnav
+libdvdread
+libe-book
+libedit
+libeot
+libepoxy
+liberation-fonts-common
+liberation-mono-fonts
+liberation-sans-fonts
+liberation-serif-fonts
+libertas-usb8388-firmware
+libetonyek
+libev
+libevdev
+libevent
+libexif
+libexttextcat
+libfdisk
+libfdt
+libffi
+libfontenc
+libfprint
+libfreehand
+libgcab1
+libgcc
+libgcrypt
+libgdata
+libgdither
+libgee
+libgepub
+libgexiv2
+libgltf
+libglvnd
+libglvnd-egl
+libglvnd-gles
+libglvnd-glx
+libgnomekbd
+libgnome-keyring
+libgomp
+libgovirt
+libgpg-error
+libgphoto2
+libgpod
+libgrss
+libgsf
+libgtop2
+libgudev
+libgusb
+libgweather
+libgxps
+libhangul
+libibverbs
+libical
+libICE
+libicu
+libidn
+libidn2
+libiec61883
+libieee1284
+libimagequant
+libimobiledevice
+libini_config
+libinput
+libipa_hbac
+libipt
+libiptcdata
+libiscsi
+libjpeg-turbo
+libkadm5
+libkkc
+libkkc-common
+libkkc-data
+libksba
+liblangtag
+liblangtag-data
+libldb
+liblouis
+libmbim
+libmbim-utils
+libmcpp
+libmediaart
+libmetalink
+libmng
+libmnl
+libmodman
+libmount
+libmpc
+libmpcdec
+libmspack
+libmspub
+libmtp
+libmusicbrainz5
+libmwaw
+libmx
+libndp
+libnetfilter_conntrack
+libnfnetlink
+libnfs
+libnfsidmap
+libnghttp2
+libnl3
+libnl3-cli
+libnma
+libnm-gtk
+libnotify
+liboauth
+libodfgen
+libogg
+liborcus
+libosinfo
+libpagemaker
+libpath_utils
+libpcap
+libpciaccess
+libpeas
+libpeas-gtk
+libpeas-loader-python3
+libphodav
+libpinyin
+libpinyin-data
+libpipeline
+libpkgconf
+libplist
+libpng
+libproxy
+libproxy-mozjs
+libpskc
+libpsl
+libpwquality
+libqb
+libqmi
+libqmi-utils
+libquvi
+libquvi-scripts
+librados2
+LibRaw
+libraw1394
+librbd1
+librdmacm
+libref_array
+libreoffice-calc
+libreoffice-core
+libreoffice-data
+libreoffice-draw
+libreoffice-emailmerge
+libreoffice-filters
+libreoffice-graphicfilter
+libreoffice-gtk2
+libreoffice-gtk3
+libreoffice-help-en
+libreoffice-impress
+libreofficekit
+libreoffice-langpack-en
+libreoffice-math
+libreoffice-opensymbol-fonts
+libreoffice-pdfimport
+libreoffice-pyuno
+libreoffice-ure
+libreoffice-ure-common
+libreoffice-writer
+libreoffice-x11
+libreoffice-xsltfilter
+librepo
+libreport
+libreport-anaconda
+libreport-cli
+libreport-fedora
+libreport-filesystem
+libreport-gtk
+libreport-plugin-bugzilla
+libreport-plugin-kerneloops
+libreport-plugin-logger
+libreport-plugin-reportuploader
+libreport-plugin-systemd-journal
+libreport-plugin-ureport
+libreport-python3
+libreport-web
+librevenge
+librsvg2
+libsamplerate
+libsane-hpaio
+libseccomp
+libsecret
+libselinux
+libselinux-python3
+libselinux-utils
+libsemanage
+libsemanage-python3
+libsepol
+libshout
+libsigc++20
+libsigsegv
+libSM
+libsmartcols
+libsmbclient
+libsmbios
+libsndfile
+libsolv
+libsoup
+libspectre
+libsrtp
+libss
+libssh
+libssh2
+libsss_autofs
+libsss_certmap
+libsss_idmap
+libsss_nss_idmap
+libsss_sudo
+libstaroffice
+libstdc++
+libstemmer
+libsysfs
+libtalloc
+libtar
+libtasn1
+libtdb
+libteam
+libtevent
+libthai
+libtheora
+libtiff
+libtimezonemap
+libtirpc
+libtool-ltdl
+libudisks2
+libunistring
+libunwind
+libusal
+libusb
+libusbmuxd
+libusbx
+libuser
+libutempter
+libuuid
+libv4l
+libvdpau
+libverto
+libverto-libev
+libvirt-daemon
+libvirt-daemon-config-network
+libvirt-daemon-driver-interface
+libvirt-daemon-driver-network
+libvirt-daemon-driver-nodedev
+libvirt-daemon-driver-nwfilter
+libvirt-daemon-driver-qemu
+libvirt-daemon-driver-secret
+libvirt-daemon-driver-storage
+libvirt-daemon-driver-storage-core
+libvirt-daemon-driver-storage-disk
+libvirt-daemon-driver-storage-gluster
+libvirt-daemon-driver-storage-iscsi
+libvirt-daemon-driver-storage-logical
+libvirt-daemon-driver-storage-mpath
+libvirt-daemon-driver-storage-rbd
+libvirt-daemon-driver-storage-scsi
+libvirt-daemon-driver-storage-sheepdog
+libvirt-daemon-driver-storage-zfs
+libvirt-daemon-kvm
+libvirt-gconfig
+libvirt-glib
+libvirt-gobject
+libvirt-libs
+libvisio
+libvisual
+libvorbis
+libvpx
+libwacom
+libwacom-data
+libwayland-client
+libwayland-cursor
+libwayland-server
+libwbclient
+libwebp
+libwnck3
+libwpd
+libwpg
+libwps
+libwsman1
+libwvstreams
+libX11
+libX11-common
+libX11-xcb
+libXau
+libxcb
+libXcomposite
+libXcursor
+libXdamage
+libXdmcp
+libXext
+libXfixes
+libXfont
+libXfont2
+libXft
+libXi
+libXinerama
+libxkbcommon
+libxkbcommon-x11
+libxkbfile
+libxklavier
+libxml2
+libXmu
+libXpm
+libXrandr
+libXrender
+libXres
+libxshmfence
+libxslt
+libXt
+libXtst
+libXv
+libXvMC
+libXxf86dga
+libXxf86misc
+libXxf86vm
+libzapojit
+libzhuyin
+libzmf
+linux-atm-libs
+linux-firmware
+lksctp-tools
+lldpad
+llvm-libs
+Lmod
+lockdev
+logrotate
+lohit-assamese-fonts
+lohit-bengali-fonts
+lohit-devanagari-fonts
+lohit-gujarati-fonts
+lohit-gurmukhi-fonts
+lohit-kannada-fonts
+lohit-odia-fonts
+lohit-tamil-fonts
+lohit-telugu-fonts
+lpsolve
+lrzsz
+lsof
+lttng-ust
+lua
+lua-expat
+lua-filesystem
+lua-json
+lua-libs
+lua-lpeg
+lua-posix
+lua-socket
+lua-term
+lvm2
+lvm2-libs
+lxpolkit
+lz4
+lz4-libs
+lzo
+lzop
+m17n-db
+m17n-lib
+mactel-boot
+mailcap
+make
+man-db
+man-pages
+marisa
+mcelog
+mcpp
+mdadm
+media-player-info
+memtest86+
+mesa-dri-drivers
+mesa-filesystem
+mesa-libEGL
+mesa-libgbm
+mesa-libGL
+mesa-libglapi
+mesa-libwayland-egl
+mesa-libxatracker
+microcode_ctl
+mlocate
+mobile-broadband-provider-info
+mod_dnssd
+ModemManager
+ModemManager-glib
+mod_http2
+mokutil
+mousetweaks
+mozilla-filesystem
+mozjs17
+mozjs38
+mozjs52
+mpage
+mpfr
+mpg123-libs
+mtdev
+mtools
+mtr
+mutter
+mythes
+mythes-en
+nautilus
+nautilus-extensions
+nautilus-sendto
+naver-nanum-fonts-common
+naver-nanum-gothic-fonts
+ncurses
+ncurses-base
+ncurses-libs
+neon
+netcf-libs
+net-snmp-libs
+nettle
+net-tools
+NetworkManager
+NetworkManager-adsl
+NetworkManager-bluetooth
+NetworkManager-config-connectivity-fedora
+NetworkManager-glib
+NetworkManager-libnm
+NetworkManager-openconnect
+NetworkManager-openconnect-gnome
+NetworkManager-openvpn
+NetworkManager-openvpn-gnome
+NetworkManager-pptp
+NetworkManager-pptp-gnome
+NetworkManager-ssh
+NetworkManager-ssh-gnome
+NetworkManager-team
+NetworkManager-vpnc
+NetworkManager-vpnc-gnome
+NetworkManager-wifi
+NetworkManager-wwan
+newt
+nfs-utils
+nmap-ncat
+nm-connection-editor
+npth
+nspr
+nss
+nss-mdns
+nss-pem
+nss-softokn
+nss-softokn-freebl
+nss-sysinit
+nss-tools
+nss-util
+ntfs-3g
+ntfsprogs
+numactl-libs
+numad
+opencc
+openCOLLADA
+openconnect
+openjpeg2
+openldap
+openssh
+openssh-clients
+openssh-server
+openssl
+openssl-libs
+open-vm-tools
+open-vm-tools-desktop
+openvpn
+opus
+orc
+orca
+osinfo-db
+osinfo-db-tools
+os-prober
+ostree
+ostree-libs
+p11-kit
+p11-kit-trust
+PackageKit
+PackageKit-command-not-found
+PackageKit-glib
+PackageKit-gstreamer-plugin
+PackageKit-gtk3-module
+pakchois
+paktype-naskh-basic-fonts
+pam
+pam_krb5
+pango
+pangomm
+paps
+paps-libs
+paratype-pt-sans-fonts
+parted
+passwd
+passwdqc
+passwdqc-lib
+pciutils
+pciutils-libs
+pcre
+pcre2
+pcre2-utf16
+pcsc-lite-libs
+perl-Carp
+perl-constant
+perl-Data-Dumper
+perl-Encode
+perl-Errno
+perl-Error
+perl-Exporter
+perl-File-Path
+perl-File-Temp
+perl-Getopt-Long
+perl-Git
+perl-HTTP-Tiny
+perl-interpreter
+perl-IO
+perl-IO-Socket-IP
+perl-IO-Socket-SSL
+perl-libnet
+perl-libs
+perl-macros
+perl-MIME-Base64
+perl-Mozilla-CA
+perl-Net-SSLeay
+perl-parent
+perl-PathTools
+perl-Pod-Escapes
+perl-podlators
+perl-Pod-Perldoc
+perl-Pod-Simple
+perl-Pod-Usage
+perl-Scalar-List-Utils
+perl-Socket
+perl-Storable
+perl-Term-ANSIColor
+perl-Term-Cap
+perl-TermReadKey
+perl-Text-ParseWords
+perl-Text-Tabs+Wrap
+perl-threads
+perl-threads-shared
+perl-Time-Local
+perl-Unicode-Normalize
+perl-URI
+pigz
+pinentry
+pinentry-gnome3
+pinentry-gtk
+pinfo
+pipewire
+pipewire-libs
+pixman
+pkcs11-helper
+pkgconf
+pkgconf-m4
+pkgconf-pkg-config
+plymouth
+plymouth-core-libs
+plymouth-graphics-libs
+plymouth-plugin-label
+plymouth-plugin-two-step
+plymouth-scripts
+plymouth-system-theme
+plymouth-theme-charge
+policycoreutils
+policycoreutils-python3
+policycoreutils-python-utils
+polkit
+polkit-libs
+polkit-pkla-compat
+poppler
+poppler-data
+poppler-glib
+poppler-utils
+popt
+ppp
+pptp
+procps-ng
+psacct
+psmisc
+publicsuffix-list-dafsa
+pulseaudio
+pulseaudio-gdm-hooks
+pulseaudio-libs
+pulseaudio-libs-glib2
+pulseaudio-module-bluetooth
+pulseaudio-module-x11
+pulseaudio-utils
+python2
+python2-libs
+python2-pip
+python2-setuptools
+python2-talloc
+python3
+python3-abrt
+python3-abrt-addon
+python3-asn1crypto
+python3-augeas
+python3-beaker
+python3-bind
+python3-blivet
+python3-blockdev
+python3-brlapi
+python3-bytesize
+python3-cairo
+python3-caribou
+python3-cffi
+python3-chardet
+python3-coverage
+python3-cryptography
+python3-cups
+python3-dbus
+python3-decorator
+python3-dmidecode
+python3-dnf
+python3-dnf-plugins-core
+python3-enchant
+python3-firewall
+python3-gobject
+python3-gobject-base
+python3-gpg
+python3-hawkey
+python3-humanize
+python3-idna
+python3-iniparse
+python3-inotify
+python3-IPy
+python3-iscsi-initiator-utils
+python3-kickstart
+python3-libcomps
+python3-librepo
+python3-libs
+python3-libxml2
+python3-louis
+python3-mako
+python3-markupsafe
+python3-meh
+python3-meh-gui
+python3-ntplib
+python3-olefile
+python3-ordered-set
+python3-pid
+python3-pillow
+python3-pip
+python3-ply
+python3-pwquality
+python3-pyatspi
+python3-pycparser
+python3-pycurl
+python3-pydbus
+python3-pyOpenSSL
+python3-pyparted
+python3-pysocks
+python3-pytz
+python3-pyudev
+python3-pyxdg
+python3-requests
+python3-requests-file
+python3-requests-ftp
+python3-rpm
+python3-setuptools
+python3-simpleline
+python3-six
+python3-slip
+python3-slip-dbus
+python3-speechd
+python3-sssdconfig
+python3-systemd
+python3-urllib3
+python3-wrapt
+python-systemd-doc
+qemu-block-curl
+qemu-block-dmg
+qemu-block-gluster
+qemu-block-iscsi
+qemu-block-nfs
+qemu-block-rbd
+qemu-block-ssh
+qemu-common
+qemu-guest-agent
+qemu-img
+qemu-kvm
+qemu-system-x86
+qemu-system-x86-core
+qgnomeplatform
+qpdf-libs
+qrencode-libs
+qt
+qt5-qtbase
+qt5-qtbase-common
+qt5-qtbase-gui
+qt5-qtdeclarative
+qt5-qtxmlpatterns
+qt-common
+qt-settings
+qt-x11
+quota
+quota-nls
+radvd
+raptor2
+rasqal
+rdist
+rdma-core
+readline
+realmd
+redhat-menus
+redland
+rest
+rhythmbox
+rng-tools
+rootfiles
+rpcbind
+rpm
+rpm-build-libs
+rpm-libs
+rpm-plugin-selinux
+rpm-plugin-systemd-inhibit
+rp-pppoe
+rsync
+rtkit
+rygel
+samba-client
+samba-client-libs
+samba-common
+samba-common-libs
+samba-dc-libs
+samba-libs
+sane-backends
+sane-backends-drivers-cameras
+sane-backends-drivers-scanners
+sane-backends-libs
+satyr
+sbc
+scl-utils
+SDL2
+seabios-bin
+seavgabios-bin
+sed
+selinux-policy
+selinux-policy-targeted
+setools-python3
+setroubleshoot
+setroubleshoot-plugins
+setroubleshoot-server
+setup
+setuptool
+sg3_utils-libs
+sgabios-bin
+sgpio
+shadow-utils
+shared-mime-info
+sheepdog
+shim-ia32
+shim-x64
+shotwell
+sil-abyssinica-fonts
+sil-mingzat-fonts
+sil-nuosu-fonts
+sil-padauk-fonts
+simple-scan
+skkdic
+slang
+smc-fonts-common
+smc-meera-fonts
+snappy
+sni-qt
+sos
+sound-theme-freedesktop
+soundtouch
+soxr
+speech-dispatcher
+speech-dispatcher-espeak
+speex
+speexdsp
+spice-glib
+spice-gtk3
+spice-server
+spice-vdagent
+sqlite-libs
+sshpass
+sssd
+sssd-ad
+sssd-client
+sssd-common
+sssd-common-pac
+sssd-ipa
+sssd-kcm
+sssd-krb5
+sssd-krb5-common
+sssd-ldap
+sssd-nfs-idmap
+sssd-proxy
+startup-notification
+stix-fonts
+stoken-libs
+sudo
+sushi
+switcheroo-control
+symlinks
+syslinux
+syslinux-extlinux
+syslinux-extlinux-nonlinux
+syslinux-nonlinux
+system-config-printer-libs
+system-config-printer-udev
+systemd
+systemd-bootchart
+systemd-container
+systemd-libs
+systemd-pam
+systemd-udev
+tabish-eeyek-fonts
+taglib
+tar
+tcl
+tcpdump
+tcp_wrappers
+tcp_wrappers-libs
+teamd
+telepathy-filesystem
+telepathy-glib
+telepathy-logger
+telnet
+thai-scalable-fonts-common
+thai-scalable-waree-fonts
+tigervnc-license
+tigervnc-server-minimal
+time
+timedatex
+totem
+totem-nautilus
+totem-pl-parser
+traceroute
+tracker
+tracker-miners
+tree
+trousers
+trousers-lib
+tzdata
+tzdata-java
+udisks2
+unicode-ucd
+unique
+unoconv
+unzip
+upower
+urw-fonts
+usb_modeswitch
+usb_modeswitch-data
+usbmuxd
+usbredir
+usbutils
+usermode
+userspace-rcu
+util-linux
+vconfig
+vim-minimal
+vino
+virglrenderer
+vlgothic-fonts
+volume_key-libs
+vpnc
+vpnc-script
+vte291
+vte-profile
+wavpack
+web-assets-filesystem
+webkitgtk4
+webkitgtk4-jsc
+webkitgtk4-plugin-process-gtk2
+webrtc-audio-processing
+wget
+which
+wireless-tools
+words
+wpa_supplicant
+wvdial
+xcb-util
+xcb-util-image
+xcb-util-keysyms
+xcb-util-renderutil
+xcb-util-wm
+xdg-desktop-portal
+xdg-desktop-portal-gtk
+xdg-user-dirs
+xdg-user-dirs-gtk
+xdg-utils
+xen-libs
+xen-licenses
+xfsprogs
+xkeyboard-config
+xml-common
+xmlrpc-c
+xmlrpc-c-client
+xmlsec1
+xmlsec1-openssl
+xorg-x11-drv-ati
+xorg-x11-drv-evdev
+xorg-x11-drv-fbdev
+xorg-x11-drv-intel
+xorg-x11-drv-libinput
+xorg-x11-drv-nouveau
+xorg-x11-drv-openchrome
+xorg-x11-drv-qxl
+xorg-x11-drv-vesa
+xorg-x11-drv-vmware
+xorg-x11-drv-wacom
+xorg-x11-font-utils
+xorg-x11-server-common
+xorg-x11-server-utils
+xorg-x11-server-Xorg
+xorg-x11-server-Xwayland
+xorg-x11-utils
+xorg-x11-xauth
+xorg-x11-xinit
+xorg-x11-xkb-utils
+xz
+xz-libs
+yajl
+yelp
+yelp-libs
+yelp-xsl
+zd1211-firmware
+zenity
+zfs-fuse
+zip
+zlib
diff --git a/generate-files.sh b/generate-files.sh
new file mode 100755
index 0000000..0219a61
--- /dev/null
+++ b/generate-files.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+
+out=$1
+base=$(basename $out)
+
+case $base in
+ freedesktop-*)
+ ns=org.freedesktop
+ version=1.6
+ ;;
+ gnome-*)
+ ns=org.gnome
+ version=3.26
+ ;;
+ *)
+ echo 1>&2 "Can't identify runtime for $base"
+ exit 1
+ ;;
+esac
+
+case $base in
+ *-Platform.files)
+ sdk=
+ type=Platform
+ ;;
+ *-Sdk.files)
+ sdk=--sdk
+ type=Sdk
+ ;;
+ *)
+ echo 1>&2 "Can't identify type for $base"
+ exit 1
+ ;;
+esac
+
+runtime="$ns.$type/x86_64/$version"
+
+echo "$base: listing files in $runtime"
+
+flatpak run --file-forwarding --command=/usr/bin/python3 $runtime @@ list-files.py @@ $sdk > $out
diff --git a/generate-report.py b/generate-report.py
new file mode 100755
index 0000000..0cb1adf
--- /dev/null
+++ b/generate-report.py
@@ -0,0 +1,142 @@
+#!/usr/bin/python3
+
+from jinja2 import Environment, FileSystemLoader, select_autoescape
+import locale
+
+class Package(object):
+ def __init__(self, name):
+ self.name = name
+ self.freedesktop_platform = False
+ self.freedesktop_platform_files = None
+ self.gnome_platform = False
+ self.gnome_platform_files = None
+ self.freedesktop_sdk = False
+ self.freedesktop_sdk_files = None
+ self.gnome_sdk = False
+ self.gnome_sdk_files = None
+ self.live = False
+ self.rf26 = False
+
+ @property
+ def runtimes(self):
+ return self.freedesktop_platform or self.gnome_platform or self.freedesktop_sdk or self.gnome_sdk
+
+ @property
+ def klass(self):
+ if self.live and not self.runtimes:
+ return "live-only"
+ if self.gnome_platform and not self.live:
+ return "not-on-live"
+ return ""
+
+ @property
+ def note(self):
+ return {
+ "not-on-live": "platform package not on Live image"
+ }.get(self.klass, "")
+
+ def files_str(self, which):
+ files = getattr(self, which + '_files')
+ if files is None:
+ return ''
+ elif len(files) <= 3:
+ return ' '.join(files)
+ else:
+ return ' '.join(files[:3]) + ' ...'
+
+ @property
+ def freedesktop_platform_files_str(self):
+ return self.files_str('freedesktop_platform')
+
+ @property
+ def freedesktop_sdk_files_str(self):
+ return self.files_str('freedesktop_sdk')
+
+ @property
+ def gnome_platform_files_str(self):
+ return self.files_str('gnome_platform')
+
+ @property
+ def gnome_sdk_files_str(self):
+ return self.files_str('gnome_sdk')
+
+class Letter(object):
+ def __init__(self, letter):
+ self.letter = letter
+ self.packages = []
+
+env = Environment(
+ loader=FileSystemLoader('.'),
+ autoescape=select_autoescape(['html', 'xml']),
+ trim_blocks=True,
+ lstrip_blocks=True
+)
+
+packages = dict()
+def add_package(name, which):
+ pkg = packages.get(name, None)
+ if pkg is None:
+ pkg = Package(name)
+ packages[name] = pkg
+ setattr(pkg,which, True)
+
+def add_packages(filename, which):
+ with open(filename) as f:
+ for line in f:
+ add_package(line.strip(), which)
+
+def add_package_files(filename, which):
+ with open(filename) as f:
+ for line in f:
+ f, p = line.strip().split()
+ f = f[:-1] # strip trailing :
+ pkg = packages[p]
+ old = getattr(pkg, which + '_files')
+ if old is not None:
+ old.append(f)
+ else:
+ setattr(pkg, which + '_files', [f])
+
+add_packages('out/freedesktop-Platform.packages', 'freedesktop_platform')
+add_packages('out/freedesktop-Sdk.packages', 'freedesktop_sdk')
+add_packages('out/gnome-Platform.packages', 'gnome_platform')
+add_packages('out/gnome-Sdk.packages', 'gnome_sdk')
+add_packages('f27-live.packages', 'live')
+add_packages('f26-flatpak-runtime.packages', 'rf26')
+
+add_package_files('out/freedesktop-Platform.matched', 'freedesktop_platform')
+add_package_files('out/freedesktop-Sdk.matched', 'freedesktop_sdk')
+add_package_files('out/gnome-Platform.matched', 'gnome_platform')
+add_package_files('out/gnome-Sdk.matched', 'gnome_sdk')
+
+def count_lines(fname):
+ with open(fname) as f:
+ return len(list(f))
+
+unmatched_counts = {
+ 'freedesktop_platform': count_lines('out/freedesktop-Platform.unmatched'),
+ 'gnome_platform': count_lines('out/gnome-Platform.unmatched'),
+ 'freedesktop_sdk': count_lines('out/freedesktop-Sdk.unmatched'),
+ 'gnome_sdk': count_lines('out/gnome-Sdk.unmatched'),
+}
+
+letters_map = dict()
+for k, v in packages.items():
+ l = v.name[0].upper()
+ letter = letters_map.get(l, None)
+ if letter is None:
+ letter = Letter(l)
+ letters_map[l] = letter
+ letter.packages.append(v)
+
+letters = []
+for k in sorted(letters_map.keys()):
+ letter = letters_map[k]
+ letter.packages.sort(key=lambda p: locale.strxfrm(p.name))
+ letters.append(letter)
+
+template = env.get_template('report-template.html')
+
+with open('report.html', 'w') as f:
+ f.write(template.render(letters=letters, unmatched=unmatched_counts))
+
diff --git a/list-files.py b/list-files.py
new file mode 100755
index 0000000..3e95058
--- /dev/null
+++ b/list-files.py
@@ -0,0 +1,45 @@
+#!/usr/bin/python3
+
+import os
+import re
+import sys
+
+sdk = len(sys.argv) > 1 and sys.argv[1] == '--sdk'
+
+def output_dir(d):
+ for f in sorted(os.listdir(d)):
+ full = os.path.join(d, f)
+ if not os.path.isdir(full):
+ print(os.path.join(d, f))
+
+def output_dir_recurse(d):
+ for dirName, subdirs, files in os.walk(d):
+ for f in sorted(files):
+ print(os.path.join(dirName, f))
+
+output_dir('/usr/bin')
+
+for f in os.listdir('/usr/lib'):
+ full = os.path.join('/usr/lib', f)
+ if (re.match(r'^.*\.so\.\d+$', f) is not None or
+ re.match(r'^.*\.so$', f) is not None and not os.path.islink(full)):
+ print(full)
+
+output_dir_recurse('/usr/share/fonts')
+
+if sdk:
+ output_dir_recurse('/usr/include')
+ output_dir('/usr/lib/pkgconfig')
+ output_dir('/usr/share/pkgconfig')
+
+# import pkgutil
+# for f in pkgutil.iter_modules():
+# try:
+# path = f[0].path
+# if path.find('site-packages') < 0:
+# continue
+# except AttributeError:
+# continue
+# if not(f[1].startswith('_')):
+# print(f, 'python3dist({})'.format(f[1]))
+
diff --git a/report-template.html b/report-template.html
new file mode 100644
index 0000000..86272a5
--- /dev/null
+++ b/report-template.html
@@ -0,0 +1,95 @@
+
+
+
+
+
+
+
+
+
show packages in:
+
Runtimes
+
Live Image
+
F26 Runtime
+
+
+
+
+ {% for letter in letters %}
+
+
+ {% for package in letter.packages %}
+
+ {{ package.name }} |
+ |
+ |
+ |
+ |
+ |
+ |
+ {{ package.note }} |
+
+ {% endfor %}
+ {% endfor %}
+
+
+
diff --git a/report.css b/report.css
new file mode 100644
index 0000000..3317647
--- /dev/null
+++ b/report.css
@@ -0,0 +1,81 @@
+body {
+ font-family: cantarell, sans-serif;
+ font-size: 12px;
+}
+.filter, .summary {
+ border: 1px solid black;
+ border-radius: 5px;
+ background: #eeeeee;
+ padding: 10px;
+ margin: 10px;
+ position: fixed;
+ box-shadow: 5px 5px 5px;
+}
+.filter {
+ right: 5px;
+ top: 5px;
+}
+.summary {
+ right: 5px;
+ bottom: 5px;
+}
+.filter .button {
+ background: #ffffff;
+ border-radius: 5px;
+ border: 1px solid black;
+ margin: 3px;
+ padding: 3px;
+}
+.filter .button:active {
+ background: #ccbbbb;
+}
+.filter .button-selected {
+ background: #ddcccc;
+}
+table.packages {
+ border-collapse: collapse;
+}
+table.packages tr td, tr th.letter {
+ padding-left: 10px;
+ padding-right: 10px;
+}
+tr.letter-header-above {
+ border-left: none;
+ border-right: none;
+ border-bottom: 1px solid #aa8888;
+ border-top: 1px solid #aa8888;
+ height: 10px;
+}
+tr.letter-header-above:first-child {
+ border: non;
+}
+tr.letter-header {
+ border: 1px solid #aa8888;
+ background: #eeeeee;
+}
+tr.letter-header th.letter {
+ text-align: left;
+ font-size: 16px;
+}
+tr {
+ border-left: 1px solid #aa8888;
+ border-right: 1px solid #aa8888;
+}
+td.present {
+ background: #bbbbbb;
+ border: 1px solid #888888;
+ padding: 0px;
+}
+td.absent {
+ border: 1px solid #888888;
+ padding: 0px;
+}
+tr.not-on-live {
+ color: #aa0000;
+}
+tr.live-only {
+ color: #aaaaaa;
+}
+.hidden {
+ display: none;
+}
diff --git a/resolve-files.py b/resolve-files.py
new file mode 100755
index 0000000..6d62f07
--- /dev/null
+++ b/resolve-files.py
@@ -0,0 +1,419 @@
+#!/usr/bin/python3
+
+from functools import cmp_to_key
+import dnf
+import gzip
+import hashlib
+import os
+import pickle
+import re
+import sys
+
+REPO_F27 = "https://mirrors.fedoraproject.org/metalink?repo=fedora-27&arch=x86_64"
+REPO_F27_UPDATES = "https://mirrors.fedoraproject.org/metalink?repo=updates-released-f27&arch=x86_64"
+REPO_F27_UPDATES_TESTING = "https://mirrors.fedoraproject.org/metalink?repo=updates-testing-f27&arch=x86_64"
+
+ignore = set()
+rename = dict()
+
+bin_ignore = [
+ # A bunch of binaries built as part of nss. A few of these are
+ # in /usr/lib64/nss/unsupported-tools/ as part of nss-tools, the rest are not considered
+ # worth installing at all (test utilities, etc.)
+ 'addbuiltin', 'atob', 'baddbdir', 'bltest', 'btoa', 'certcgi', 'chktest', 'conflict',
+ 'crmftest', 'dbtest', 'derdump', 'dertimetest', 'digest', 'ecperf', 'encodeinttest',
+ 'fipstest', 'httpserv', 'listsuites', 'makepqg', 'mangle', 'multinit', 'nonspr10',
+ 'ocspclnt', 'ocspresp', 'oidcalc', 'p7content', 'p7env', 'p7sign', 'p7verify',
+ 'pk11gcmtest', 'pk11mode', 'pk1sign', 'pkix-errcodes', 'pp', 'pwdecrypt', 'remtest',
+ 'rsaperf', 'sdrtest', 'secmodtest', 'selfserv', 'shlibsign', 'signtool', 'strsclnt',
+ 'symkeyutil', 'tstclnt', 'vfychain', 'vfyserv',
+
+ # Script added into nss by openembedded
+ 'signlibs.sh',
+
+ # /usr/share/doc/aspell/aspell-import in Fedora
+ 'aspell-import',
+
+ # Removed in perl-5.27
+ 'c2ph',
+
+ # Removed - https://lists.fedorahosted.org/archives/list/elfutils-devel@lists.fedorahosted.org/thread/22LIIMXI6EDGCOIO6QFSBUO2KHEXIGSJ/
+ 'eu-ld',
+
+ # compatibility perl script in zenity for something quite old, not packaged in fedora
+ 'gdialog',
+
+ # An openembedded thing
+ # "Tool that installs the GNU config.guess / config.sub into a directory tree"
+ 'gnu-configize',
+
+ # GPG test program (https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=tree;f=tests)
+ 'gpgscm',
+
+ # An implementation of tar for cross-platform compatibility, disabled in gnupg2.spec
+ 'gpgtar',
+
+ # Removed from gtk-doc
+ # https://git.gnome.org/browse/gtk-doc/commit/?id=46df4354abed5724697fd5e39630c5bbc6637cc4
+ 'gtkdoc-mktmpl',
+
+ # installed in openembedded with a coreutils suffix along with the more normal version
+ 'kill.coreutils', 'uptime.coreutils',
+
+ # nettle utilities not currently packaged in fedora
+ # (https://src.fedoraproject.org/rpms/nettle/c/2ec204e2de17006b566c9ff7d90ec65ca1680ed5?branch=master)
+ 'nettle-hash', 'nettle-lfib-stream', 'nettle-pbkdf2', 'pkcs1-conv', 'sexp-conv',
+
+ # Not built by default as of util-linux-2.29
+ '/usr/bin/pg',
+
+ # These are installed as -64 in Fedora, we just ignore them because they will be
+ # pulled in by the corresponding library
+ 'gdk-pixbuf-query-loaders', 'gtk-query-immodules-2.0',
+ 'gio-querymodules', 'gtk-query-immodules-3.0',
+
+ # Removed in krb5-1.13 (https://web.mit.edu/kerberos/krb5-1.13/README-1.13.5.txt)
+ 'krb5-send-pr',
+
+ # Removed in util-linux-2.30'
+ 'tailf',
+
+ # OpenEmbedded uses Debian's ca-certificates, Fedora is different
+ 'update-ca-certificates',
+]
+ignore.update('/usr/bin/' + x for x in bin_ignore)
+
+bin_rename = {
+ # lcms2 compiled with --program-suffix=2 in Fedora, even though there are no actual
+ # conflicts between lcms and lcms2 - jpegicc was renamed to jpgicc, etc.
+ 'jpgicc': 'jpgicc2',
+ 'linkicc': 'linkicc2',
+ 'psicc': 'psicc2',
+ 'tificc': 'tificc2',
+ 'transicc': 'transicc2',
+}
+rename.update({ '/usr/bin/' + k: '/usr/bin/' + v for k, v in bin_rename.items() })
+
+lib_ignore = [
+ # Symlink created in freedesktop.org flatpak runtime, not standard
+ 'libEGL_indirect.so.0',
+
+ # Removed in gpgme-1.9.0
+ 'libgpgme-pthread.so.11',
+
+ # Not enabled in fedora (consider fixing)
+ 'libharfbuzz-gobject.so.0',
+
+ # Part of glibc
+ 'libssp.so.0',
+]
+ignore.update('/usr/lib64/' + x for x in lib_ignore)
+
+fonts_ignore = {
+ # Added in 2.36
+ 'dejavu/DejaVuMathTeXGyre.ttf',
+}
+ignore.update('/usr/share/fonts/' + x for x in fonts_ignore)
+
+lib_rename = {
+ # Newer in Fedora
+ 'libhunspell-1.3.so.0': 'libhunspell-1.5.so.0',
+ 'libwebp.so.6': 'libwebp.so.7',
+ 'libwebpmux.so.2': 'libwebpmux.so.3',
+ 'libpcre2-posix.so.1': 'libpcre2-posix.so.2',
+ 'libvpx.so.3': 'libvpx.so.4',
+ 'libkadm5clnt_mit.so.9': 'libkadm5clnt_mit.so.11',
+ 'libkadm5srv_mit.so.9': 'libkadm5srv_mit.so.11',
+
+ # Newer in Flatpak runtime
+ 'libprocps.so.6': 'libprocps.so.4', # procps-3.10 vs. procps-3.12
+ 'libgif.so.7': 'libgif.so.4', # giflib 4 vs giflib-5 - https://bugzilla.redhat.com/show_bug.cgi?id=822844
+
+ # Fedora arch-handling
+ 'ld-linux.so.2': 'ld-linux-x86-64.so.2',
+}
+rename.update({ '/usr/lib64/' + k: '/usr/lib64/' + v for k, v in lib_rename.items() })
+
+include_ignore = {
+ # https://git.gnome.org/browse/at-spi2-core/commit/?id=1eb223bb48464d707290ef540581e9763b0ceee8
+ 'at-spi-2.0/atspi/atspi-gmain.c',
+
+ # Removed in 7.55 https://github.com/curl/curl/commit/73a2fcea0b4adea6ba342cd7ed1149782c214ae3
+ 'curl/curlbuild-64.h', 'curl/curlbuild.h', 'curl/curlrules.h',
+
+ # Not enabled on Fedora
+ 'harfbuzz/hb-gobject-enums.h',
+ 'harfbuzz/hb-gobject-structs.h',
+ 'harfbuzz/hb-gobject.h',
+
+ # https://github.com/hunspell/hunspell/commit/99675e791d123cbe1be914b1a49dd83062134301
+ 'hunspell/affentry.hxx', 'hunspell/affixmgr.hxx', 'hunspell/baseaffix.hxx', 'hunspell/dictmgr.hxx',
+ 'hunspell/filemgr.hxx','hunspell/hashmgr.hxx','hunspell/hunzip.hxx','hunspell/langnum.hxx',
+ 'hunspell/phonet.hxx','hunspell/replist.hxx','hunspell/suggestmgr.hxx',
+}
+ignore.update('/usr/include/' + x for x in include_ignore)
+
+include_rename = {
+ 'assuan.h': 'libassuan2/assuan.h',
+ 'nss3/nssck.api': 'nss3/templates/nssck.api'
+}
+rename.update({ '/usr/include/' + k: '/usr/include/' + v for k, v in include_rename.items() })
+
+nspr_include = [
+ 'nspr.h', 'plarena.h', 'plarenas.h', 'plbase64.h', 'plerror.h', 'plgetopt.h', 'plhash.h',
+ 'plstr.h', 'pratom.h', 'prbit.h', 'prclist.h', 'prcmon.h', 'prcountr.h', 'prcpucfg.h',
+ 'prcvar.h', 'prdtoa.h', 'prenv.h', 'prerr.h', 'prerror.h', 'prinet.h', 'prinit.h',
+ 'prinrval.h', 'prio.h', 'pripcsem.h', 'private/pprio.h', 'private/pprthred.h', 'private/prpriv.h',
+ 'prlink.h', 'prlock.h', 'prlog.h', 'prlong.h', 'prmem.h', 'prmon.h', 'prmwait.h', 'prnetdb.h',
+ 'prolock.h', 'prpdce.h', 'prprf.h', 'prproces.h', 'prrng.h', 'prrwlock.h', 'prshm.h', 'prshma.h',
+ 'prsystem.h', 'prthread.h', 'prtime.h', 'prtpool.h', 'prtrace.h', 'prtypes.h', 'prvrsion.h',
+ 'prwin16.h', 'stropts.h', 'obsolete/pralarm.h', 'obsolete/probslet.h', 'obsolete/protypes.h', 'obsolete/prsem.h'
+]
+rename.update({ '/usr/include/' + x: '/usr/include/nspr4/' + x for x in nspr_include })
+
+pc_ignore = {
+ # Not enabled on Fedora
+ 'harfbuzz-gobject.pc',
+
+ # https://github.com/ostroproject/ostro-os/blob/master/meta/recipes-support/libassuan/libassuan/libassuan-add-pkgconfig-support.patch
+ 'libassuan.pc',
+
+ # http://cgit.openembedded.org/openembedded-core/tree/meta/recipes-support/libgpg-error/libgpg-error/pkgconfig.patch
+ 'gpg-error.pc',
+
+ # http://cgit.openembedded.org/openembedded-core/tree/meta/recipes-support/libgcrypt/files/0001-Add-and-use-pkg-config-for-libgcrypt-instead-of-conf.patch
+ 'libgcrypt.pc',
+}
+ignore.update('/usr/lib64/pkgconfig/' + x for x in pc_ignore)
+
+ignore_patterns = [
+ # Flatpak runtime has a versioned gawk-4.1.3
+ r'/usr/bin/gawk-.*',
+
+ # Architecture specific aliases for gcc, binutils, etc
+ r'^/usr/bin/x86_64-unknown-linux-.*',
+
+ # From NSPR, intentionally not installed on Fedora
+ r'/usr/include/md/.*',
+
+ # .install files litter the include directories of openembedded
+ r'.*/\.install$'
+]
+ignore_compiled = [re.compile(x) for x in ignore_patterns]
+
+rename_patterns = [
+ (r'^/usr/include/c\+\+/6.2.0/(.*)', r'/usr/include/c++/7/\1'),
+ (r'^/usr/include/c\+\+/7/x86_64-unknown-linux/(.*)', r'/usr/include/c++/7/x86_64-redhat-linux/\1'),
+ (r'^/usr/lib64/pkgconfig/(.*proto.pc)', r'/usr/share/pkgconfig/\1'),
+ (r'^/usr/share/fonts/liberation-fonts/(.*)', r'/usr/share/fonts/liberation/\1'),
+]
+rename_compiled = [(re.compile(a), b) for a, b in rename_patterns]
+
+def package_cmp(a, b):
+ if a.arch == 'i686' and b.arch != 'i686':
+ return 1
+ if a.arch != 'i686' and b.arch == 'i686':
+ return -1
+ c = - a.evr_cmp(b)
+ if c < 0:
+ return -1
+ elif c == 0:
+ return 0
+ else:
+ return 1
+
+class Progress(dnf.callback.DownloadProgress):
+ def __init__(self, name):
+ self.name = name
+ self.hashes = -1
+ def start(self, total_files, total_size, total_drpms=0):
+ pass
+ def progress(self, payload, done):
+ if payload.download_size == 0:
+ return
+ hashes = int(60 * done / payload.download_size)
+ if hashes != self.hashes:
+ hashline = "[" + "#" * hashes + " " * (60 - hashes) + "]"
+ if self.hashes != -1:
+ print("\r", end="")
+ print("{} - {}k - {}".format(self.name, int(payload.download_size / 1024), hashline), end="")
+ self.hashes = hashes
+ def end(self, payload, status, message):
+ if status == dnf.callback.STATUS_OK:
+ print(" - DONE")
+ else:
+ print
+
+class PackageInfo(object):
+ def __init__(self):
+ self.base = dnf.Base()
+
+ self._add_repo(self.base, 'f27', metalink=REPO_F27)
+ self._add_repo(self.base, 'f27-updates', metalink=REPO_F27_UPDATES)
+ self._add_repo(self.base, 'f27-updates-testing', metalink=REPO_F27_UPDATES_TESTING)
+
+ self.base.fill_sack(load_available_repos=True, load_system_repo=False)
+
+ def _add_repo(self, base, reponame, repourl=None, metalink=None):
+ repo = dnf.repo.Repo(reponame, self.base.conf)
+ if repourl is not None:
+ repo.baseurl = repourl
+ elif metalink is not None:
+ repo.metalink = metalink
+ else:
+ raise RuntimeError("Either baseurl or metalink must be specified")
+ repo.set_progress_bar(Progress(reponame))
+ repo.load()
+ repo.enable()
+ base.repos.add(repo)
+
+ def repo_hash(self):
+ h = hashlib.sha256()
+ for r in sorted(self.base.repos.all(), key=lambda x: x.name):
+ repomd_file = os.path.join(r._cachedir, 'repodata/repomd.xml')
+ with open(repomd_file, 'rb') as f:
+ h.update(f.read())
+ return h.hexdigest()
+
+if len(sys.argv) != 2:
+ print("Usage: resolve-files.py INFILE", file=sys.stderr)
+ sys.exit(1)
+
+inpath = sys.argv[1]
+if not inpath.endswith('.files'):
+ print("INFILE must have .files suffix", file=sys.stderr)
+ sys.exit(1)
+
+base_path = inpath[:-len('.files')]
+
+def warn(msg):
+ print("{}: \033[31m{}\033[39m".format(inpath, msg), file=sys.stderr)
+
+def start(msg):
+ print("{}: \033[90m{} ... \033[39m".format(inpath, msg), file=sys.stderr, end="")
+ sys.stderr.flush()
+
+def done():
+ print("\033[90mdone\033[39m", file=sys.stderr)
+
+start("Reading file list")
+
+to_resolve = []
+with open(inpath) as f:
+ for l in f:
+ r = l.rstrip()
+ if r.startswith('/usr/lib/'):
+ r = '/usr/lib64/' + r[len('/usr/lib/'):]
+ to_resolve.append(r)
+
+to_resolve.sort()
+
+done()
+
+pkgs = PackageInfo()
+
+files_map = None
+
+# We need to look up a lot of file dependencies. dnf/libsolv is not fast at doing
+# this (at least when we look up files one-by-one) so we create a hash table that
+# maps from *all* files in the distribution to the "best" package that provides
+# the file. To further speed this up, we pickle the result and store it, and only
+# recreate it when the DNF metadata changes. We gzip the pickle to save space
+# (70M instead of 700M), this slows things down by about 2 seconds.
+#
+repo_hash = pkgs.repo_hash()
+f = None
+try:
+ f = gzip.open('cache/files.map.gz', 'rb')
+ with f:
+ old_repo_hash = f.read(64).decode('utf-8')
+ if old_repo_hash == repo_hash:
+ start("Reading cached file map")
+ files_map = pickle.load(f)
+ done()
+except FileNotFoundError:
+ pass
+except (pickle.UnpicklingError, EOFError) as e:
+ done()
+ warn("Failed to load cache/files.map.gz:", e)
+
+if files_map is None:
+ start("Creating file map")
+ files_map = {}
+ for p in pkgs.base.sack.query().filter():
+ for f in p.files:
+ old = files_map.get(f, None)
+ if old is None or package_cmp(p, old) < 0:
+ files_map[f] = p
+
+ for k, v in files_map.items():
+ files_map[k] = v.name
+ done()
+
+ start("Writing file map to cache")
+ with gzip.open('cache/files.map.gz', 'wb') as f:
+ f.write(repo_hash.encode('utf-8'))
+ pickle.dump(files_map, f)
+ done()
+
+found_packages = set()
+
+start("Resolving files to packages")
+
+matched_file = open(base_path + '.matched', 'w')
+unmatched_file = open(base_path + '.unmatched', 'w')
+unmatched_count = 0
+
+for r in to_resolve:
+ if r in ignore:
+ continue
+
+ skip = False
+ for p in ignore_compiled:
+ if p.match(r) is not None:
+ skip = True
+ if skip:
+ continue
+
+ if r in rename:
+ r = rename[r]
+
+ for p, replacement in rename_compiled:
+ if p.match(r) is not None:
+ r = p.sub(replacement, r)
+
+ if r.startswith('/usr/lib64/'):
+ search = [r, '/lib64/' + os.path.basename(r)]
+ elif r.startswith('/usr/bin/'):
+ search = [r, '/bin/' + os.path.basename(r), '/usr/sbin/' + os.path.basename(r), '/sbin/' + os.path.basename(r)]
+ else:
+ search = [r]
+
+ if r.startswith('/usr/lib64/libLLVM'):
+ # freedesktop SDK builds "split" LLVM libraries
+ found_packages.add('llvm-libs')
+ continue
+
+ for s in search:
+ providing = files_map.get(s, None)
+ if providing is not None:
+ break
+
+ if providing is None:
+ print(r, file=unmatched_file)
+ unmatched_count += 1
+ else:
+ found_packages.add(providing)
+ print("{}: {}".format(r, providing), file=matched_file)
+
+unmatched_file.close()
+matched_file.close()
+
+with open(base_path + '.packages', 'w') as f:
+ for p in sorted(found_packages):
+ print(p, file=f)
+
+done()
+
+if unmatched_count > 0:
+ warn("{} unmatched files, see {}".format(unmatched_count, base_path + ".unmatched"))