ci-test/comps-sync.py
Colin Walters 092c1bdb78 Add comps-sync script, use it to trim package set
This script looks for packages not in comps at all, which
helps us lose things that were there only as dependencies.

Also, it now supports showing packages in the workstation environment
but not in the manifest.  (I'm not yet taking action on those though)

Some leaf packages do drop out. All of these I believe are right to stop
shipping by default with the possible exception of `media-player-info`...I'm not
sure if that was intentional or not. Anyways let's start this sync process.

```
-Installing 1344 packages:
+Installing 1335 packages:
-  bcache-tools-1.0.8-10.fc27.x86_64 (fedora-rawhide)
-  isomd5sum-1:1.2.2-1.fc28.x86_64 (fedora-rawhide)
-  kexec-tools-2.0.16-3.fc28.x86_64 (fedora-rawhide)
-  keybinder3-0.3.2-3.fc27.x86_64 (fedora-rawhide)
-  langtable-0.0.38-2.fc28.noarch (fedora-rawhide)
-  langtable-data-0.0.38-2.fc28.noarch (fedora-rawhide)
-  langtable-python3-0.0.38-2.fc28.noarch (fedora-rawhide)
-  lpsolve-5.5.2.0-16.fc27.x86_64 (fedora-rawhide)
-  media-player-info-23-1.fc28.noarch (fedora-rawhide)
```
2018-02-17 16:05:31 -05:00

98 lines
3.2 KiB
Python
Executable file

#!/usr/bin/python3
# Usage: ./comps-sync.py /path/to/comps-f28.xml.in
# Currently just *removes* packages from the manifest
# which are not mentioned in comps.
import os, sys, subprocess, argparse, shlex, json
import libcomps
def fatal(msg):
print >>sys.stderr, msg
sys.exit(1)
parser = argparse.ArgumentParser()
parser.add_argument("--save", help="Write changes", action='store_true')
parser.add_argument("src", help="Source path")
args = parser.parse_args()
base_pkgs_path = 'fedora-workstation-base-pkgs.json'
with open(base_pkgs_path) as f:
manifest = json.load(f)
manifest_packages = set(manifest['packages'])
comps_unknown = set()
comps_packages = set()
workstation_product_packages = set()
# Parse comps, and build up a set of all packages so we
# can find packages not listed in comps *at all*, beyond
# just the workstation environment.
comps = libcomps.Comps()
comps.fromxml_f(args.src)
for group in comps.groups:
for pkg in group.packages:
comps_packages.add(pkg.name)
for pkg in manifest_packages:
if pkg not in comps_packages:
comps_unknown.add(pkg)
# Parse the workstation-product environment, gathering
# default or mandatory packages.
ws_environ = comps.environments['workstation-product-environment']
ws_pkgs = {}
for gid in ws_environ.group_ids:
group = comps.groups_match(id=gid.name)[0]
for pkg in group.packages:
pkgname = pkg.name
if pkg.type not in (libcomps.PACKAGE_TYPE_DEFAULT,
libcomps.PACKAGE_TYPE_MANDATORY):
continue
pkgdata = ws_pkgs.get(pkgname)
if pkgdata is None:
ws_pkgs[pkgname] = pkgdata = (pkg.type, set([gid.name]))
if (pkgdata[0] == libcomps.PACKAGE_TYPE_DEFAULT and
pkg.type == libcomps.PACKAGE_TYPE_MANDATORY):
ws_pkgs[pkgname] = pkgdata = (pkg.type, pkgdata[1])
pkgdata[1].add(gid.name)
# Look for packages in the manifest but not in comps at all
n_manifest_new = len(comps_unknown)
if n_manifest_new == 0:
print("All manifest packages are already listed in comps.")
else:
print("{} packages not in comps:".format(n_manifest_new))
for pkg in sorted(comps_unknown):
print(' ' + pkg)
manifest_packages.remove(pkg)
# Look for packages in workstation but not in the manifest
ws_added = {}
for (pkg,data) in ws_pkgs.items():
if pkg not in manifest_packages:
ws_added[pkg] = data
def format_pkgtype(n):
if n == libcomps.PACKAGE_TYPE_DEFAULT:
return 'default'
elif n == libcomps.PACKAGE_TYPE_MANDATORY:
return 'mandatory'
else:
assert False
n_comps_new = len(ws_added)
if n_comps_new == 0:
print("All comps packages are already listed in manifest.")
else:
print("{} packages not in manifest:".format(n_comps_new))
for pkg in sorted(ws_added):
(req, groups) = ws_added[pkg]
print(' {} ({}, groups: {})'.format(pkg, format_pkgtype(req), ', '.join(groups)))
if (n_manifest_new > 0 or n_comps_new > 0) and args.save:
manifest['packages'] = sorted(manifest_packages)
with open(base_pkgs_path, 'w') as f:
json.dump(manifest, f, indent=4, sort_keys=True)
f.write('\n')
print("Wrote {}".format(base_pkgs_path))