-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcomps-sync.py
executable file
·185 lines (159 loc) · 6.47 KB
/
comps-sync.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
#!/usr/bin/python3
# Usage: ./comps-sync.py /path/to/comps-f35.xml.in
#
# Can both remove packages from the manifest
# which are not mentioned in comps, and add packages from
# comps.
import os, sys, subprocess, argparse, shlex, json, yaml, re
import libcomps
def fatal(msg):
print >>sys.stderr, msg
sys.exit(1)
def format_pkgtype(n):
if n == libcomps.PACKAGE_TYPE_DEFAULT:
return 'default'
elif n == libcomps.PACKAGE_TYPE_MANDATORY:
return 'mandatory'
else:
assert False
def write_manifest(fpath, pkgs, include=None):
with open(fpath, 'w') as f:
f.write("# DO NOT EDIT! This content is generated from comps-sync.py\n")
if include is not None:
f.write("include: {}\n".format(include))
f.write("packages:\n")
for pkg in sorted(pkgs):
f.write(" - {}\n".format(pkg))
print("Wrote {}".format(fpath))
parser = argparse.ArgumentParser()
parser.add_argument("--save", help="Write changes", action='store_true')
parser.add_argument("src", help="Source path")
args = parser.parse_args()
print("Syncing packages common to all desktops:")
base_pkgs_path = 'fedora-common-ostree-pkgs.yaml'
with open(base_pkgs_path) as f:
manifest = yaml.safe_load(f)
manifest_packages = set(manifest['packages'])
with open('comps-sync-exclude-list.yml') as f:
doc = yaml.safe_load(f)
comps_exclude_list = doc['exclude_list']
comps_include_list = doc['include_list']
comps_exclude_list_groups = doc['exclude_list_groups']
comps_desktop_exclude_list = doc['desktop_exclude_list']
comps_exclude_list_all = [re.compile(x) for x in doc['exclude_list_all_regexp']]
def is_exclude_listed(pkgname):
for br in comps_exclude_list_all:
if br.match(pkgname):
return True
return False
# 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)
# Parse the workstation-product environment, gathering
# default or mandatory packages.
ws_env_name = 'workstation-product-environment'
ws_ostree_name = 'workstation-ostree-support'
ws_environ = comps.environments[ws_env_name]
ws_pkgs = {}
for gid in ws_environ.group_ids:
group = comps.groups_match(id=gid.name)[0]
if gid.name in comps_exclude_list_groups:
continue
exclude_list = comps_exclude_list.get(gid.name, set())
for pkg in group.packages:
pkgname = pkg.name
if pkg.type not in (libcomps.PACKAGE_TYPE_DEFAULT,
libcomps.PACKAGE_TYPE_MANDATORY):
continue
if pkgname in exclude_list or is_exclude_listed(pkgname):
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)
ws_ostree_pkgs = set()
for pkg in comps.groups_match(id=ws_ostree_name)[0].packages:
if not is_exclude_listed(pkg.name):
ws_ostree_pkgs.add(pkg.name)
comps_unknown = set()
for pkg in manifest_packages:
if (pkg not in comps_include_list and
pkg not in ws_pkgs and
pkg not in ws_ostree_pkgs):
comps_unknown.add(pkg)
# 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 {}:".format(n_manifest_new, ws_env_name))
for pkg in sorted(comps_unknown):
print(' {}'.format(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
manifest_packages.add(pkg)
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:
write_manifest(base_pkgs_path, manifest_packages)
# Generate treefiles for all desktops
for desktop in [ 'gnome-desktop', 'kde-desktop', 'xfce-desktop',
'lxqt-desktop', 'deepin-desktop', 'pantheon-desktop', 'mate-desktop']:
print()
print("Syncing packages for {}:".format(desktop))
manifest_path = '{}-pkgs.yaml'.format(desktop)
with open(manifest_path) as f:
manifest = yaml.safe_load(f)
manifest_packages = set(manifest['packages'])
# Filter packages in the comps desktop group using the exclude_list
comps_group_pkgs = set()
for pkg in comps.groups_match(id=desktop)[0].packages:
pkgname = pkg.name
exclude_list = comps_desktop_exclude_list.get(desktop, set())
if pkgname in exclude_list or is_exclude_listed(pkgname):
continue
comps_group_pkgs.add(pkg.name)
# Look for packages in the manifest but not in comps group
comps_unknown = set()
for pkg in manifest_packages:
if pkg not in comps_group_pkgs:
comps_unknown.add(pkg)
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 group:".format(n_manifest_new, desktop))
for pkg in sorted(comps_unknown):
print(' {}'.format(pkg))
manifest_packages.remove(pkg)
# Look for packages in comps but not in the manifest
desktop_pkgs_added = set()
for pkg in comps_group_pkgs:
if pkg not in manifest_packages:
desktop_pkgs_added.add(pkg)
n_comps_new = len(desktop_pkgs_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, desktop))
for pkg in sorted(desktop_pkgs_added):
print(' {}'.format(pkg))
manifest_packages.add(pkg)
# Update manifest
if (n_manifest_new > 0 or n_comps_new > 0) and args.save:
write_manifest(manifest_path, manifest_packages, include="fedora-common-ostree.yaml")