/[gentoo-src]/portage/pym/portage_config.py
Gentoo

Contents of /portage/pym/portage_config.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1.2.1 - (hide annotations) (download) (as text)
Fri Feb 7 16:19:47 2003 UTC (15 years, 3 months ago) by alain
Branch: portage_2_1
Changes since 1.1: +350 -0 lines
File MIME type: text/x-python
Initial version of portage_config.py (configuration does no longer use
globals).  Moved all config related functions into the config class to
simplify variable handling.  Added PortageContext class to portage.py,
and moved a bunch of the global data and init code into it.  Cleaned up
profiledir handling.

1 alain 1.1.2.1 # portage.py -- core Portage functionality
2     # Copyright 1998-2003 Gentoo Technologies, Inc. and Authors
3     # Authors: Daniel Robbins, Nick Jones, Alain Penders
4     # Distributed under the GNU Public License v2
5    
6    
7     from stat import *
8     from commands import *
9     from select import *
10     from output import *
11     import string,os,types,sys,shlex,shutil,xpak,fcntl,signal,time,missingos,cPickle,atexit,grp,traceback,commands,pwd
12     import portage
13    
14    
15     #-----------------------------------------------------------------------------
16    
17    
18     class config:
19     def __init__(self, ctx):
20     self.ctx = ctx
21    
22     self.usesplit=[]
23     self.cexpand={}
24    
25     self.usemasks=[]
26     self.configlist=[]
27     self.backupenv={}
28     # back up our incremental variables:
29     self.configdict={}
30     # configlist will contain: [ globals, (optional) profile, make.conf, backupenv (incrementals), origenv ]
31    
32     #get the masked use flags
33     if os.path.exists("/etc/make.profile/use.mask"):
34     usemasks=grabfile("/etc/make.profile/use.mask")
35     if os.path.exists("/etc/portage/use.mask"):
36     usemasks=usemasks+grabfile("/etc/portage/use.mask")
37    
38     self.mygcfg=self.getconfig("/etc/make.globals")
39     if self.mygcfg==None:
40     print "!!! Parse error in /etc/make.globals. NEVER EDIT THIS FILE."
41     print "!!! Incorrect multiline literals can cause this. Do not use them."
42     print "!!! Errors in this file should be reported on bugs.gentoo.org."
43     sys.exit(1)
44     self.configlist.append(self.mygcfg)
45     self.configdict["globals"]=self.configlist[-1]
46    
47     # Does /etc/make.profile/make.defaults exist?
48     if self.ctx.getProfileDir():
49     self.mygcfg=self.getconfig("/etc/make.profile/make.defaults")
50     if self.mygcfg==None:
51     print "!!! Parse error in /etc/make.defaults. Never modify this file."
52     print "!!! 'emerge sync' may fix this. If it does not then please report"
53     print "!!! this to bugs.gentoo.org and, if possible, a dev on #gentoo (IRC)"
54     sys.exit(1)
55     self.configlist.append(self.mygcfg)
56     self.configdict["defaults"]=self.configlist[-1]
57    
58     self.mygcfg=self.getconfig("/etc/make.conf")
59     if self.mygcfg==None:
60     print "!!! Parse error in /etc/make.conf."
61     print "!!! Incorrect multiline literals can cause this. Do not use them."
62     sys.exit(1)
63     self.configlist.append(self.mygcfg)
64     self.configdict["conf"]=self.configlist[-1]
65    
66     for x in self.ctx.getIncrementals():
67     if os.environ.has_key(x):
68     self.backupenv[x]=os.environ[x]
69     #auto-use:
70     self.configlist.append({})
71     self.configdict["auto"]=self.configlist[-1]
72     #backup-env (for recording our calculated incremental variables:)
73     self.configlist.append(self.backupenv)
74     self.configlist.append(os.environ.copy())
75     self.configdict["env"]=self.configlist[-1]
76     self.lookuplist=self.configlist[:]
77     self.lookuplist.reverse()
78    
79     useorder=self["USE_ORDER"]
80     if not useorder:
81     #reasonable defaults; this is important as without USE_ORDER, USE will always be "" (nothing set)!
82     useorder="env:conf:auto:defaults"
83     usevaluelist=useorder.split(":")
84     self.uvlist=[]
85     for x in usevaluelist:
86     if self.configdict.has_key(x):
87     #prepend db to list to get correct order
88     self.uvlist[0:0]=[self.configdict[x]]
89     self.regenerate()
90    
91     def regenerate(self,useonly=0):
92     if useonly:
93     myincrementals=["USE"]
94     else:
95     myincrementals=self.ctx.getIncrementals()
96     for mykey in myincrementals:
97     if mykey=="USE":
98     mydbs=self.uvlist
99     self.configdict["auto"]["USE"]=self.autouse(self.ctx.db[self.ctx.getRoot()]["vartree"])
100     else:
101     mydbs=self.configlist[:-1]
102     mysetting=[]
103     for curdb in mydbs:
104     if not curdb.has_key(mykey):
105     continue
106     #variables are already expanded
107     mysplit=curdb[mykey].split()
108     for x in mysplit:
109     if x=="-*":
110     # "-*" is a special "minus" var that means "unset all settings". so USE="-* gnome" will have *just* gnome enabled.
111     mysetting=[]
112     continue
113     add=x
114     if x[0]=="-":
115     remove=x[1:]
116     else:
117     remove=x
118     #remove any previous settings of this variable
119     dellist=[]
120     for y in range(0,len(mysetting)):
121     if mysetting[y]==remove:
122     #we found a previously-defined variable; add it to our dellist for later removal.
123     dellist.append(mysetting[y])
124     for y in dellist:
125     while y in mysetting:
126     mysetting.remove(y)
127     #now append our new setting
128     if add:
129     mysetting.append(add)
130     #store setting in last element of configlist, the original environment:
131     self.configlist[-1][mykey]=string.join(mysetting," ")
132     #cache split-up USE var in a global
133     self.usesplit=[]
134     for x in string.split(self.configlist[-1]["USE"]):
135     if x not in self.usemasks:
136     self.usesplit.append(x)
137    
138     # Pre-Pend ARCH variable to USE settings so '-*' in env doesn't kill arch.
139     if self.ctx.getProfileDir():
140     if self.configdict["defaults"].has_key("ARCH"):
141     if self.configdict["defaults"]["ARCH"]:
142     if self.configdict["defaults"]["ARCH"] not in self.usesplit:
143     self.usesplit.insert(0,self.configdict["defaults"]["ARCH"])
144     self.configlist[-1]["USE"]=string.join(self.usesplit," ")
145    
146     def getUseSplit(self):
147     return self.usesplit
148    
149     def __getitem__(self,mykey):
150     if mykey=="CONFIG_PROTECT_MASK":
151     suffix=" /etc/env.d"
152     else:
153     suffix=""
154     for x in self.lookuplist:
155     if x == None:
156     print "!!! lookuplist is null."
157     elif x.has_key(mykey):
158     return x[mykey]+suffix
159     return suffix
160    
161     def has_key(self,mykey):
162     for x in self.lookuplist:
163     if x.has_key(mykey):
164     return 1
165     return 0
166    
167     def keys(self):
168     mykeys=[]
169     for x in self.lookuplist:
170     for y in x.keys():
171     if y not in mykeys:
172     mykeys.append(y)
173     return mykeys
174    
175     def __setitem__(self,mykey,myvalue):
176     "set a value; will be thrown away at reset() time"
177     self.configdict["env"][mykey]=myvalue
178    
179     def reset(self):
180     "reset environment to original settings"
181     #for x in self.backupenv.keys():
182     # self.configdict["env"][x]==self.backupenv[x]
183     #self.regenerate(useonly=1)
184     pass
185    
186     def environ(self):
187     "return our locally-maintained environment"
188     mydict={}
189     for x in self.keys():
190     mydict[x]=self[x]
191     if not mydict.has_key("HOME") and mydict.has_key("BUILD_PREFIX"):
192     print "*** HOME not set. Setting to",mydict["BUILD_PREFIX"]
193     mydict["HOME"]=mydict["BUILD_PREFIX"]
194     return mydict
195    
196     def getconfig(self, mycfg, tolerant=0):
197     mykeys={}
198     f=open(mycfg,'r')
199     lex=shlex.shlex(f)
200     lex.wordchars=string.digits+string.letters+"~!@#$%*_\:;?,./-+{}"
201     lex.quotes="\"'"
202     while 1:
203     key=lex.get_token()
204     if (key==''):
205     #normal end of file
206     break;
207     equ=lex.get_token()
208     if (equ==''):
209     #unexpected end of file
210     #lex.error_leader(self.filename,lex.lineno)
211     if not tolerant:
212     print "!!! Unexpected end of config file: variable",key
213     return None
214     else:
215     return mykeys
216     elif (equ!='='):
217     #invalid token
218     #lex.error_leader(self.filename,lex.lineno)
219     if not tolerant:
220     print "!!! Invalid token (not \"=\")",equ
221     return None
222     else:
223     return mykeys
224     val=lex.get_token()
225     if (val==''):
226     #unexpected end of file
227     #lex.error_leader(self.filename,lex.lineno)
228     if not tolerant:
229     print "!!! Unexpected end of config file: variable",key
230     return None
231     else:
232     return mykeys
233     mykeys[key]=self.varexpand(val,mykeys)
234     return mykeys
235    
236     def varexpand(self, mystring, mydict={}):
237     try:
238     return self.cexpand[" "+mystring]
239     except KeyError:
240     pass
241     """
242     new variable expansion code. Removes quotes, handles \n, etc.
243     This code is used by the configfile code, as well as others (parser)
244     This would be a good bunch of code to port to C.
245     """
246     numvars=0
247     mystring=" "+mystring
248     #in single, double quotes
249     insing=0
250     indoub=0
251     pos=1
252     newstring=" "
253     while (pos<len(mystring)):
254     if (mystring[pos]=="'") and (mystring[pos-1]!="\\"):
255     if (indoub):
256     newstring=newstring+"'"
257     else:
258     insing=not insing
259     pos=pos+1
260     continue
261     elif (mystring[pos]=='"') and (mystring[pos-1]!="\\"):
262     if (insing):
263     newstring=newstring+'"'
264     else:
265     indoub=not indoub
266     pos=pos+1
267     continue
268     if (not insing):
269     #expansion time
270     if (mystring[pos]=="\n"):
271     #convert newlines to spaces
272     newstring=newstring+" "
273     pos=pos+1
274     elif (mystring[pos]=="\\"):
275     #backslash expansion time
276     if (pos+1>=len(mystring)):
277     newstring=newstring+mystring[pos]
278     break
279     else:
280     a=mystring[pos+1]
281     pos=pos+2
282     if a=='a':
283     newstring=newstring+chr(007)
284     elif a=='b':
285     newstring=newstring+chr(010)
286     elif a=='e':
287     newstring=newstring+chr(033)
288     elif (a=='f') or (a=='n'):
289     newstring=newstring+chr(012)
290     elif a=='r':
291     newstring=newstring+chr(015)
292     elif a=='t':
293     newstring=newstring+chr(011)
294     elif a=='v':
295     newstring=newstring+chr(013)
296     else:
297     #remove backslash only, as bash does: this takes care of \\ and \' and \" as well
298     newstring=newstring+mystring[pos-1:pos]
299     continue
300     elif (mystring[pos]=="$") and (mystring[pos-1]!="\\"):
301     pos=pos+1
302     if (pos+1)>=len(mystring):
303     self.cexpand[mystring]=""
304     return ""
305     if mystring[pos]=="{":
306     pos=pos+1
307     terminus="}"
308     else:
309     terminus=string.whitespace
310     myvstart=pos
311     while mystring[pos] not in terminus:
312     if (pos+1)>=len(mystring):
313     self.cexpand[mystring]=""
314     return ""
315     pos=pos+1
316     myvarname=mystring[myvstart:pos]
317     pos=pos+1
318     if len(myvarname)==0:
319     self.cexpand[mystring]=""
320     return ""
321     numvars=numvars+1
322     if mydict.has_key(myvarname):
323     newstring=newstring+mydict[myvarname]
324     else:
325     newstring=newstring+mystring[pos]
326     pos=pos+1
327     else:
328     newstring=newstring+mystring[pos]
329     pos=pos+1
330     if numvars==0:
331     self.cexpand[mystring]=newstring[1:]
332     return newstring[1:]
333    
334     def autouse(self, myvartree):
335     """returns set of USE variables auto-enabled due to packages being installed"""
336     myusevars=""
337     for x in self.ctx.getUseDefaults():
338     mysplit=string.split(x)
339     if len(mysplit)<2:
340     #invalid line
341     continue
342     myuse=mysplit[0]
343     mydep=x[len(mysplit[0]):]
344     #check dependencies; tell depcheck() to ignore settings["USE"] since we are still forming it.
345     myresult=portage.dep_check(mydep,myvartree.dbapi,use="no")
346     if myresult[0]==1 and not myresult[1]:
347     #deps satisfied, add USE variable...
348     myusevars=myusevars+" "+myuse
349     return myusevars
350    

  ViewVC Help
Powered by ViewVC 1.1.20