6 # This is a replacement for the formerly bash-written function pl_parsePkgs ()
8 # Usage: $0 [-a arch] default_arch keyword fcdistro pldistro pkgs-file[..s]
9 # default_arch is $pl_DISTRO_ARCH, but can be overridden
12 #################### original language was (in this example, keyword=package)
13 ## to add to all distros
15 ## to add in one distro
17 ## to remove in one distro
19 #################### replacement language
24 ## add in fedora distros starting with f10
25 # +package>=f10: p1 p2
28 ## ditto but remove instead
29 # -package=centos5: p1 p2
30 # -package<=centos5: p1 p2
33 from sys import stderr
34 from optparse import OptionParser
38 known_arch = ['i386','x86_64']
39 default_fcdistro='f12'
40 known_fcdistros = [ 'centos5','centos6','f8', 'f9','f10','f11','f12', 'f13' ]
41 default_pldistro='onelab'
43 known_keywords=['groupname', 'groupdesc', 'kexclude', 'package', 'group', 'precious', 'junk', 'mirror', ]
46 m_fcdistro_cutter = re.compile('([a-z]+)([0-9]+)')
51 def __init__ (self,arch,fcdistro,pldistro,keyword,inputs,options):
53 self.fcdistro=fcdistro
54 self.pldistro=pldistro
57 # for verbose, new_line, and the like
60 for known in known_fcdistros:
62 (distro,version)=m_fcdistro_cutter.match(fcdistro).groups()
66 self.version=int(version)
68 print >> stderr, 'unrecognized fcdistro', fcdistro
71 # qualifier is either '>=','<=', or '='
72 def match (self, qualifier, version):
74 return self.version == version
75 elif qualifier == '>=':
76 return self.version >= version
77 elif qualifier == '<=':
78 return self.version <= version
80 raise Exception, 'Internal error - unexpected qualifier %r' % qualifier
82 m_comment=re.compile('\A\s*#')
83 m_blank=re.compile('\A\s*\Z')
85 m_ident=re.compile('\A'+re_ident+'\Z')
87 re_qualified += '(?P<plus_minus>[+-]?)'
89 re_qualified += '(?P<keyword>%s)'%re_ident
91 re_qualified += '(?P<qualifier>>=|<=|=)'
93 re_qualified += '(?P<fcdistro>%s[0-9]+)'%re_ident
95 m_qualified = re.compile('\A%s\Z'%re_qualified)
97 re_old = '[a-z]+[+-][a-z]+[0-9]+'
98 m_old = re.compile ('\A%s\Z'%re_old)
100 # returns a tuple (included,excluded)
101 def parse (self,filename):
107 for line in file(filename).readlines():
110 if self.m_comment.match(line) or self.m_blank.match(line):
113 [lefts,rights] = line.split(':',1)
114 for left in lefts.split():
115 ########## single ident
116 if self.m_ident.match(left):
117 if left not in known_keywords:
118 raise Exception,"Unknown keyword %r"%left
119 elif left == self.keyword:
120 included += rights.split()
122 m=self.m_qualified.match(left)
124 (plus_minus,kw,qual,fcdistro) = m.groups()
125 if kw not in known_keywords:
126 raise Exception,"Unknown keyword in %r"%left
127 if fcdistro not in known_fcdistros:
128 raise Exception, 'Unknown fcdistro %r'%fcdistro
129 # skip if another keyword
130 if kw != self.keyword: continue
131 # does this fcdistro match ?
132 (distro,version)=m_fcdistro_cutter.match(fcdistro).groups()
133 version = int (version)
134 # skip if another distro family
135 if distro != self.distro: continue
136 # skip if the qualifier does not fit
137 if not self.match (qual, version):
138 if self.options.verbose: print >> stderr,'%s:%d:qualifer %s does not apply'%(filename,lineno,left)
140 # we're in, let's add (default) or remove (if plus_minus is minus)
141 if plus_minus == '-':
142 if self.options.verbose: print >> stderr,'%s:%d: from %s, excluding %r'%(filename,lineno,left,rights)
143 excluded += rights.split()
145 if self.options.verbose: print >> stderr,'%s:%d: from %s, including %r'%(filename,lineno,left,rights)
146 included += rights.split()
147 elif self.m_old.match(left):
148 raise Exception,'Old-fashioned syntax not supported anymore %r'%left
150 raise Exception,'error in left expression %r'%left
154 print >> stderr, "%s:%d:syntax error: %r"%(filename,lineno,e)
157 print >> stderr, 'Could not parse file',filename,e
158 return (ok,included,excluded)
164 for input in self.inputs:
165 (o,i,e) = self.parse (input)
169 results = list (set(included).difference(set(excluded)))
171 results = [ x.replace('@arch@',self.arch).\
172 replace('@fcdistro@',self.fcdistro).\
173 replace('@pldistro@',self.pldistro) for x in results]
175 # default is space-separated
176 if not self.options.new_line:
177 print " ".join(results)
178 # but for tests results are printed each on a line
180 for result in results : print result
184 usage="Usage: %prog [options] keyword input[...]"
185 parser=OptionParser (usage=usage)
186 parser.add_option ('-a','--arch',dest='arch',action='store',default=default_arch,
187 help='target arch, e.g. i386 or x86_64')
188 parser.add_option ('-f','--fcdistro',dest='fcdistro',action='store', default=default_fcdistro,
189 help='fcdistro, e.g. f12 or centos5')
190 parser.add_option ('-d','--pldistro',dest='pldistro',action='store', default=default_pldistro,
191 help='pldistro, e.g. onelab or planetlab')
192 parser.add_option ('-v', '--verbose',dest='verbose',action='store_true',default=False,
193 help='verbose when using qualifiers')
194 parser.add_option ('-n', '--new-line',dest='new_line',action='store_true',default=False,
195 help='print outputs separated with newlines rather than with a space')
196 (options,args) = parser.parse_args()
199 parser.print_help(file=stderr)
203 if not options.arch in known_arch:
204 print >> stderr, 'Unsupported arch',options.arch
205 parser.print_help(file=stderr)
207 if not options.fcdistro in known_fcdistros:
208 print >> stderr, 'Unsupported fcdistro',options.fcdistro
209 parser.print_help(file=stderr)
212 pkgs = PkgsParser (options.arch,options.fcdistro,options.pldistro,keyword,inputs,options)
218 if __name__ == '__main__':