]> git.donarmstrong.com Git - wannabuild.git/blob - bin/add-sources.py
b9ffa4ee6be38b1747836f36033be53b9651eb95
[wannabuild.git] / bin / add-sources.py
1 #!/usr/bin/python
2
3 # Given as input a Packages and a Sources file, produces as output a new
4 # Packages containing fake packages which are installable if and only if the
5 # corresponding source package has satisfiable build dependencies.
6
7 # Copyright (C) 2008 Stefano Zacchiroli <zack@debian.org>
8 # This program is free software: you can redistribute it and/or modify it under
9 # the terms of the GNU General Public License as published by the Free Software
10 # Foundation, either version 3 of the License, or (at your option) any later
11 # version.
12
13 # $Id: add-sources.py 5957 2008-08-16 18:32:17Z zack $
14
15 # build-essential packages. All build-dependencies and build-conflicts
16 # to one of these packages is simply ignored.
17 # TODO: this list should be obtained from the binary package file,
18 # by grep-dctrl -F Build-Essential --pattern=yes -s Package -n
19 # but then we have to change the way this command is called.
20 buildessentials = ['apt', 'binutils', 'cpio', 'cpp', 'dpkg-dev',
21                    'g++', 'gcc', 'libc6-dev', 'make', 'patch',
22                    'perl', 'perl-modules']
23
24
25 import string
26 import sys
27
28 from optparse import OptionParser
29 from debian_bundle import deb822
30
31 usage = 'Usage: cat Packages | add-sources [OPTION...] Sources ARCH > Packages.new'
32 cli = OptionParser(usage=usage)
33 cli.add_option('-p', '--prefix', dest='prefix', default='source---',
34         help='set the prefix for fake source packages to PREFIX (default: source---)',
35         metavar='PREFIX')
36 (options, args) = cli.parse_args()
37 if len(args) != 2:
38     cli.print_help()
39     sys.exit(2)
40 sources_file = args[0]
41 architecture = args[1]
42
43 def pkg_of_src(src):
44     global architecture, options
45     pkg = deb822.Packages()
46     pkg['Package'] = options.prefix + src['Package']
47
48     def dep_for_me(dep):
49         for_me = None
50         if buildessentials.count(dep['name']) > 0:
51             for_me = False
52         elif dep['arch'] is None:
53             for_me = True
54         elif dep['arch']:
55             (polarity, _) = dep['arch'][0]
56             if polarity:    # list is inclusive
57                 for_me = (True, architecture) in dep['arch']
58             else:   # list is exclusive
59                 for_me = not ((False, architecture) in dep['arch'])
60         else:
61             for_me = False
62         return for_me
63
64     def mk_bin_rels(fields, relations):
65         def strip_arch(dep):
66             dep['arch'] = None
67             return dep
68
69         def get_rels(fields, relations):
70             rels = []
71             for name in fields:
72                 if relations.has_key(name):
73                     rels.extend(relations[name])
74             return rels
75
76         src_rels = get_rels(fields, relations)
77         bin_rels = []
78         for or_deps in src_rels:
79             my_or_deps = map(strip_arch, filter(dep_for_me, or_deps))
80             if my_or_deps:
81                 bin_rels.append(my_or_deps)
82
83         return bin_rels
84
85     def str_of_relations(rels):
86         # XXX this is cut and paste from python-debian's deb822.py, more
87         # precisely it matches the str() method of the PkgRelation class
88         # TODO to be removed as soon as python-debian 0.1.12 hits unstable
89         def pp_arch(arch_spec):
90             (excl, arch) = arch_spec
91             if excl:
92                 return arch
93             else:
94                 return '!' + arch
95         def pp_atomic_dep(dep):
96             s = dep['name']
97             if dep.has_key('version') and dep['version'] is not None:
98                 s += ' (%s %s)' % dep['version']
99             if dep.has_key('arch') and dep['arch'] is not None:
100                 s += ' [%s]' % string.join(map(pp_arch, dep['arch']))
101             return s
102         pp_or_dep = lambda deps: string.join(map(pp_atomic_dep, deps), ' | ')
103         return string.join(map(pp_or_dep, rels), ', ')
104
105     for field in ['Version', 'Priority', 'Section', 'Maintainer', 'Architecture']:
106         if src.has_key(field):
107             pkg[field] = src[field]
108     bin_depends = mk_bin_rels(['build-depends', 'build-depends-indep'],
109             src.relations)
110     if bin_depends:
111         #pkg['Depends'] = deb822.PkgRelation.str(bin_depends)
112         pkg['Depends'] = str_of_relations(bin_depends)
113     bin_conflicts = mk_bin_rels(['build-conflicts', 'build-conflicts-indep'],
114             src.relations)
115     if bin_conflicts:
116         #pkg['Conflicts'] = deb822.PkgRelation.str(bin_conflicts)
117         pkg['Conflicts'] = str_of_relations(bin_conflicts)
118     pkg['Description'] = 'dummy counterpart of "%s" source package' % \
119             src['Package']
120     pkg['Description'] += "\n I don't exist, go away."
121
122     return pkg
123
124 #for pkg in deb822.Packages.iter_paragraphs(sys.stdin):
125 line = None
126 for line in sys.stdin:
127     print line,
128 # stanzas have to be separated by a blank line
129 if line and not line.isspace(): print 
130 for src in deb822.Sources.iter_paragraphs(file(sources_file)):
131     if src['Architecture'] in ['any', 'all']:
132         pkg = pkg_of_src(src)
133         print pkg
134     elif architecture in src['Architecture'].split():
135         pkg = pkg_of_src(src)
136         pkg['Architecture'] = architecture
137         print pkg
138