]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - release/scripts/package-split.py
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.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 dvd1.
27 def dvd1_packages():
28     pkgs = ['archivers/unzip',
29             'devel/subversion',
30             'devel/subversion-static',
31             'emulators/linux_base-f10',
32             'lang/perl5.14',
33             'misc/freebsd-doc-all',
34             'net/mpd5',
35             'net/rsync',
36             'ports-mgmt/portaudit',
37             'ports-mgmt/portmaster',
38             'shells/bash',
39             'shells/zsh',
40             'security/sudo',
41             'sysutils/screen',
42             'www/firefox',
43             'www/links',
44             'x11-drivers/xf86-video-vmware',
45             'x11/gnome2',
46             'x11/kde4',
47             'x11/xorg'];
48     return pkgs
49
50 # The list of desired packages
51 def desired_packages():
52     dvd1 = dvd1_packages()
53     return [dvd1]
54
55 # Suck the entire INDEX file into a two different dictionaries.  The first
56 # dictionary maps port names (origins) to package names.  The second
57 # dictionary maps a package name to a list of its dependent packages.
58 PACKAGE_COL=0
59 ORIGIN_COL=1
60 DEPENDS_COL=8
61
62 def load_index(index):
63     deps = {}
64     pkgs = {}
65     line_num = 1
66     for line in index:
67         fields = line.split('|')
68         name = fields[PACKAGE_COL]
69         if name in deps:
70             sys.stderr.write('%d: Duplicate package %s\n' % (line_num, name))
71             sys.exit(1)
72         origin = fields[ORIGIN_COL].replace('/usr/ports/', '', 1)
73         if origin in pkgs:
74             sys.stderr.write('%d: Duplicate port %s\n' % (line_num, origin))
75             sys.exit(1)
76         deps[name] = fields[DEPENDS_COL].split()
77         pkgs[origin] = name
78         line_num = line_num + 1
79     return (deps, pkgs)
80
81 # Layout the packages on the various CD images.  Here's how it works.  We walk
82 # each disc in the list of discs.  Within each disc we walk the list of ports.
83 # For each port, we add the package name to a dictionary with the value being
84 # the current disc number.  We also add all of the dependent packages.  If
85 # a package is already in the dictionary when we go to add it, we just leave
86 # the dictionary as it is.  This means that each package ends up on the first
87 # disc that either lists it or contains it as a dependency.
88 def layout_discs(discs, pkgs, deps):
89     disc_num = 1
90     layout = {}
91     for disc in discs:
92         for port in disc:
93             if port not in pkgs:
94                 sys.stderr.write('Disc %d: Unable to find package for %s\n' %
95                                  (disc_num, port))
96                 continue
97             pkg = pkgs[port]
98             pkg_list = [pkg] + deps[pkg]
99             for pkg in pkg_list:
100                 if pkg not in layout:
101                     if verbose:
102                         print "--> Adding %s to Disc %d" % (pkg, disc_num)
103                     layout[pkg] = disc_num
104         disc_num = disc_num + 1
105     return layout
106
107 # Generate a master INDEX file based on the generated layout.  The way this
108 # works is that for each INDEX line, we check to see if the package is in the
109 # layout.  If it is, we put that INDEX line into the master INDEX and append
110 # a new field with the disc number to the line.
111 def generate_index(index, layout, master_index):
112     for line in index:
113         pkg = line.split('|')[PACKAGE_COL]
114         if pkg in layout:
115             new_line = '%s|%d\n' % (line.splitlines()[0], layout[pkg])
116             master_index.write(new_line)
117
118 # Verify the command line arguments
119 if len(sys.argv) != 3:
120     sys.stderr.write('Invalid number of arguments\n')
121     sys.stderr.write('Usage: package-split.py <source INDEX> <master INDEX>\n')
122     sys.exit(1)
123
124 print "Loading %s..." % (sys.argv[1])
125 index = file(sys.argv[1])
126 (deps, pkgs) = load_index(index)
127 discs = desired_packages()
128 layout = layout_discs(discs, pkgs, deps)
129 index.seek(0)
130 print "Generating %s..." % (sys.argv[2])
131 master_index = file(sys.argv[2], 'w')
132 generate_index(index, layout, master_index)
133 index.close()
134 master_index.close()