]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - release/scripts/package-split.py
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.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 if 'PKG_DVD' in os.environ:
27     doing_dvd = 1
28 else:
29     doing_dvd = 0
30
31 # List of packages for disc1.
32 def disc1_packages():
33     pkgs = ['misc/freebsd-doc-bn', 
34             'misc/freebsd-doc-da',
35             'misc/freebsd-doc-de',
36             'misc/freebsd-doc-el',
37             'misc/freebsd-doc-en',
38             'misc/freebsd-doc-es',
39             'misc/freebsd-doc-fr',
40             'misc/freebsd-doc-hu',
41             'misc/freebsd-doc-it',
42             'misc/freebsd-doc-ja',
43             'misc/freebsd-doc-mn',
44             'misc/freebsd-doc-nl',
45             'misc/freebsd-doc-pl',
46             'misc/freebsd-doc-pt',
47             'misc/freebsd-doc-ru',
48             'misc/freebsd-doc-sr',
49             'misc/freebsd-doc-tr',
50             'misc/freebsd-doc-zh_cn',
51             'misc/freebsd-doc-zh_tw']
52
53     if doing_dvd:
54         pkgs.extend(['archivers/unzip',
55             'astro/xearth',
56             'devel/gmake',
57             'devel/imake',
58             'editors/emacs',
59             'editors/vim-lite',
60             'emulators/linux_base-f10',
61             'emulators/mtools',
62             'graphics/png',
63             'graphics/xv',
64             'irc/xchat',
65             'lang/perl5.8',
66             'mail/alpine',
67             'mail/exim',
68             'mail/fetchmail',
69             'mail/mutt',
70             'mail/popd',
71             'mail/postfix',
72             'mail/xfmail',
73             'net/cvsup-without-gui',
74             'net/rsync',
75             'net/samba3',
76             'news/slrn',
77             'news/tin',
78             'ports-mgmt/p5-FreeBSD-Portindex',
79             'ports-mgmt/portaudit',
80             'ports-mgmt/portmaster',
81             'ports-mgmt/portupgrade',
82             'print/a2ps-letter',
83             'print/apsfilter',
84             'print/ghostscript7-nox11',
85             'print/psutils-letter',
86             'print/gv',
87             'shells/bash',
88             'shells/pdksh',
89             'shells/zsh',
90             'security/sudo',
91             'sysutils/screen',
92             'www/links',
93             'www/lynx',
94             'x11/gnome2',
95             'x11/kde4',
96             'x11/rxvt',
97             'x11/xorg',
98             'x11-wm/afterstep',
99             'x11-wm/fvwm2',
100             'x11-wm/windowmaker'])
101     return pkgs
102
103 # The list of desired packages
104 def desired_packages():
105     disc1 = disc1_packages()
106     return [disc1]
107
108 # Suck the entire INDEX file into a two different dictionaries.  The first
109 # dictionary maps port names (origins) to package names.  The second
110 # dictionary maps a package name to a list of its dependent packages.
111 PACKAGE_COL=0
112 ORIGIN_COL=1
113 DEPENDS_COL=8
114
115 def load_index(index):
116     deps = {}
117     pkgs = {}
118     line_num = 1
119     for line in index:
120         fields = line.split('|')
121         name = fields[PACKAGE_COL]
122         if name in deps:
123             sys.stderr.write('%d: Duplicate package %s\n' % (line_num, name))
124             sys.exit(1)
125         origin = fields[ORIGIN_COL].replace('/usr/ports/', '', 1)
126         if origin in pkgs:
127             sys.stderr.write('%d: Duplicate port %s\n' % (line_num, origin))
128             sys.exit(1)
129         deps[name] = fields[DEPENDS_COL].split()
130         pkgs[origin] = name
131         line_num = line_num + 1
132     return (deps, pkgs)
133
134 # Layout the packages on the various CD images.  Here's how it works.  We walk
135 # each disc in the list of discs.  Within each disc we walk the list of ports.
136 # For each port, we add the package name to a dictionary with the value being
137 # the current disc number.  We also add all of the dependent packages.  If
138 # a package is already in the dictionary when we go to add it, we just leave
139 # the dictionary as it is.  This means that each package ends up on the first
140 # disc that either lists it or contains it as a dependency.
141 def layout_discs(discs, pkgs, deps):
142     disc_num = 1
143     layout = {}
144     for disc in discs:
145         for port in disc:
146             if port not in pkgs:
147                 sys.stderr.write('Disc %d: Unable to find package for %s\n' %
148                                  (disc_num, port))
149                 continue
150             pkg = pkgs[port]
151             pkg_list = [pkg] + deps[pkg]
152             for pkg in pkg_list:
153                 if pkg not in layout:
154                     if verbose:
155                         print "--> Adding %s to Disc %d" % (pkg, disc_num)
156                     layout[pkg] = disc_num
157         disc_num = disc_num + 1
158     return layout
159
160 # Generate a master INDEX file based on the generated layout.  The way this
161 # works is that for each INDEX line, we check to see if the package is in the
162 # layout.  If it is, we put that INDEX line into the master INDEX and append
163 # a new field with the disc number to the line.
164 def generate_index(index, layout, master_index):
165     for line in index:
166         pkg = line.split('|')[PACKAGE_COL]
167         if pkg in layout:
168             new_line = '%s|%d\n' % (line.splitlines()[0], layout[pkg])
169             master_index.write(new_line)
170
171 # Verify the command line arguments
172 if len(sys.argv) != 3:
173     sys.stderr.write('Invalid number of arguments\n')
174     sys.stderr.write('Usage: package-split.py <source INDEX> <master INDEX>\n')
175     sys.exit(1)
176
177 print "Loading %s..." % (sys.argv[1])
178 index = file(sys.argv[1])
179 (deps, pkgs) = load_index(index)
180 discs = desired_packages()
181 layout = layout_discs(discs, pkgs, deps)
182 index.seek(0)
183 print "Generating %s..." % (sys.argv[2])
184 master_index = file(sys.argv[2], 'w')
185 generate_index(index, layout, master_index)
186 index.close()
187 master_index.close()