1 #!/usr/local/bin/python
3 # This script generates a master INDEX file for the CD images built by the
4 # FreeBSD release engineers. Each disc is given a list of desired packages.
5 # Dependencies of these packages are placed on either the same disc or an
6 # earlier disc. The resulting master INDEX file is then written out.
8 # Usage: package-split.py <INDEX> <master INDEX>
16 arch = os.environ["PKG_ARCH"]
19 print "Using arch %s" % (arch)
21 if 'PKG_VERBOSE' in os.environ:
26 # List of packages for disc1. This just includes packages sysinstall can
27 # install as a distribution
29 pkgs = ['lang/perl5.8']
30 pkgs.extend(['x11/xorg',
31 'x11-drivers/xorg-drivers',
32 'x11-fonts/xorg-fonts',
33 'x11-servers/xorg-nestserver',
34 'x11-servers/xorg-vfbserver',
37 pkgs.append('emulators/linux_base-fc4')
40 # List of packages for disc2. This includes packages that the X desktop
41 # menu depends on (if it still exists) and other "nice to have" packages.
42 # For architectures that use a separate livefs, this is actually disc3.
46 pkgs = ['x11/gnome2-lite',
53 'graphics/kdegraphics3',
55 'multimedia/kdemultimedia3',
85 'net/cvsup-without-gui',
90 'ports-mgmt/portupgrade',
93 'print/ghostscript7-nox11',
95 'print/psutils-letter',
101 'textproc/docproj-jadetex',
103 'www/apache13-modssl',
109 'ports-mgmt/portaudit']
110 if arch == 'amd64' or arch == 'i386':
111 pkgs.extend(['www/opera'])
113 pkgs.extend(['misc/compat4x'])
116 # The list of desired packages
117 def desired_packages():
118 disc1 = disc1_packages()
119 disc2 = disc2_packages()
120 disc3 = disc3_packages()
121 return [disc1, disc2, disc3]
123 # Suck the entire INDEX file into a two different dictionaries. The first
124 # dictionary maps port names (origins) to package names. The second
125 # dictionary maps a package name to a list of its dependent packages.
130 def load_index(index):
135 fields = line.split('|')
136 name = fields[PACKAGE_COL]
138 sys.stderr.write('%d: Duplicate package %s\n' % (line_num, name))
140 origin = fields[ORIGIN_COL].replace('/usr/ports/', '', 1)
142 sys.stderr.write('%d: Duplicate port %s\n' % (line_num, origin))
144 deps[name] = fields[DEPENDS_COL].split()
146 line_num = line_num + 1
149 # Layout the packages on the various CD images. Here's how it works. We walk
150 # each disc in the list of discs. Within each disc we walk the list of ports.
151 # For each port, we add the package name to a dictionary with the value being
152 # the current disc number. We also add all of the dependent packages. If
153 # a package is already in the dictionary when we go to add it, we just leave
154 # the dictionary as it is. This means that each package ends up on the first
155 # disc that either lists it or contains it as a dependency.
156 def layout_discs(discs, pkgs, deps):
162 sys.stderr.write('Disc %d: Unable to find package for %s\n' %
166 pkg_list = [pkg] + deps[pkg]
168 if pkg not in layout:
170 print "--> Adding %s to Disc %d" % (pkg, disc_num)
171 layout[pkg] = disc_num
172 disc_num = disc_num + 1
175 # Generate a master INDEX file based on the generated layout. The way this
176 # works is that for each INDEX line, we check to see if the package is in the
177 # layout. If it is, we put that INDEX line into the master INDEX and append
178 # a new field with the disc number to the line.
179 def generate_index(index, layout, master_index):
181 pkg = line.split('|')[PACKAGE_COL]
183 new_line = '%s|%d\n' % (line.splitlines()[0], layout[pkg])
184 master_index.write(new_line)
186 # Verify the command line arguments
187 if len(sys.argv) != 3:
188 sys.stderr.write('Invalid number of arguments\n')
189 sys.stderr.write('Usage: package-split.py <source INDEX> <master INDEX>\n')
192 print "Loading %s..." % (sys.argv[1])
193 index = file(sys.argv[1])
194 (deps, pkgs) = load_index(index)
195 discs = desired_packages()
196 layout = layout_discs(discs, pkgs, deps)
198 print "Generating %s..." % (sys.argv[2])
199 master_index = file(sys.argv[2], 'w')
200 generate_index(index, layout, master_index)