]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - release/scripts/package-split.py
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / release / scripts / package-split.py
1 #!/usr/local/bin/python
2 #
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.
7 #
8 # Usage: package-split.py <INDEX> <master INDEX>
9 #
10 # $FreeBSD$
11
12 import os
13 import sys
14
15 try:
16     arch = os.environ["PKG_ARCH"]
17 except:
18     arch = os.uname()[4]
19 print "Using arch %s" % (arch)
20
21 if 'PKG_VERBOSE' in os.environ:
22     verbose = 1
23 else:
24     verbose = 0
25
26 # List of packages for disc1.  This just includes packages sysinstall can
27 # install as a distribution
28 def disc1_packages():
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',
35                  'devel/imake'])
36     if arch == 'i386':
37         pkgs.append('emulators/linux_base-fc4')
38     return pkgs
39
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.
43 def disc2_packages():
44             # X Desktops
45     if arch == 'ia64':
46         pkgs = ['x11/gnome2-lite',
47                 'x11/kde-lite']
48     else:
49         pkgs = ['x11/gnome2',
50                 'x11/kdebase3',
51                 'x11/kdelibs3',
52                 'games/kdegames3',
53                 'graphics/kdegraphics3',
54                 'misc/kdeutils3',
55                 'multimedia/kdemultimedia3',
56                 'net/kdenetwork3']
57     return pkgs
58
59 def disc3_packages():
60     pkgs = ['x11/kde3',
61             'x11-wm/afterstep',
62             'x11-wm/windowmaker',
63             'x11-wm/fvwm2',
64             # "Nice to have"
65             'archivers/unzip',
66             'astro/xearth',                 
67             'devel/gmake',
68             'editors/emacs',
69             'editors/vim-lite',
70             'editors/xemacs',
71             'emulators/mtools',
72             'graphics/png',
73             'graphics/xv',
74             'irc/xchat',
75             'lang/php5',
76             'mail/alpine',
77             'mail/exim',
78             'mail/fetchmail',
79             'mail/mutt',
80             'mail/popd',
81             'mail/xfmail',
82             'mail/postfix',
83             'misc/compat5x',
84             'misc/compat6x',
85             'net/cvsup-without-gui',
86             'net/rsync',
87             'net/samba3',
88             'news/slrn',
89             'news/tin',
90             'ports-mgmt/portupgrade',
91             'print/a2ps-letter',
92             'print/apsfilter',
93             'print/ghostscript7-nox11',
94             'print/gv',
95             'print/psutils-letter',
96             'print/teTeX',
97             'shells/bash',
98             'shells/pdksh',
99             'shells/zsh',
100             'security/sudo',
101             'textproc/docproj-jadetex',
102             'www/apache13',
103             'www/apache13-modssl',
104             'www/apache22',
105             'www/links',
106             'www/lynx',
107             'x11/rxvt',
108             # Formerly on disc3
109             'ports-mgmt/portaudit']
110     if arch == 'amd64' or arch == 'i386':
111         pkgs.extend(['www/opera'])
112     if arch == 'i386':
113         pkgs.extend(['misc/compat4x'])
114     return pkgs
115
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]
122
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.
126 PACKAGE_COL=0
127 ORIGIN_COL=1
128 DEPENDS_COL=8
129
130 def load_index(index):
131     deps = {}
132     pkgs = {}
133     line_num = 1
134     for line in index:
135         fields = line.split('|')
136         name = fields[PACKAGE_COL]
137         if name in deps:
138             sys.stderr.write('%d: Duplicate package %s\n' % (line_num, name))
139             sys.exit(1)
140         origin = fields[ORIGIN_COL].replace('/usr/ports/', '', 1)
141         if origin in pkgs:
142             sys.stderr.write('%d: Duplicate port %s\n' % (line_num, origin))
143             sys.exit(1)
144         deps[name] = fields[DEPENDS_COL].split()
145         pkgs[origin] = name
146         line_num = line_num + 1
147     return (deps, pkgs)
148
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):
157     disc_num = 1
158     layout = {}
159     for disc in discs:
160         for port in disc:
161             if port not in pkgs:
162                 sys.stderr.write('Disc %d: Unable to find package for %s\n' %
163                                  (disc_num, port))
164                 continue
165             pkg = pkgs[port]
166             pkg_list = [pkg] + deps[pkg]
167             for pkg in pkg_list:
168                 if pkg not in layout:
169                     if verbose:
170                         print "--> Adding %s to Disc %d" % (pkg, disc_num)
171                     layout[pkg] = disc_num
172         disc_num = disc_num + 1
173     return layout
174
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):
180     for line in index:
181         pkg = line.split('|')[PACKAGE_COL]
182         if pkg in layout:
183             new_line = '%s|%d\n' % (line.splitlines()[0], layout[pkg])
184             master_index.write(new_line)
185
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')
190     sys.exit(1)
191
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)
197 index.seek(0)
198 print "Generating %s..." % (sys.argv[2])
199 master_index = file(sys.argv[2], 'w')
200 generate_index(index, layout, master_index)
201 index.close()
202 master_index.close()