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

Contents of /portage/pym/config.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.5 - (show annotations) (download) (as text)
Sat May 7 00:50:54 2005 UTC (11 years, 4 months ago) by ferringb
Branch: MAIN
CVS Tags: HEAD
Branch point for: portage_2_1
Changes since 1.4: +1 -1 lines
File MIME type: text/x-python
dsd supplied a fix for the quote issues w/ env transfering down the pipe.

1 import os, copy, re
2 import portage_const
3 import sys #has a few daft sys.exit
4
5 import portage_util, portage_versions, portage_dep
6 from portage_util import getconfig, grabfile, grab_multiple, grabfile_package, grabdict, writemsg, grabdict_package, \
7 abssymlink, flatten
8
9
10 from portage_file import listdir
11 from portage_data import portage_gid
12
13 class config:
14 def clone(self, clone):
15 self.incrementals = copy.deepcopy(clone.incrementals)
16 self.profile_path = copy.deepcopy(clone.profile_path)
17
18 self.module_priority = copy.deepcopy(clone.module_priority)
19 self.modules = copy.deepcopy(clone.modules)
20
21 self.depcachedir = copy.deepcopy(clone.depcachedir)
22
23 self.packages = copy.deepcopy(clone.packages)
24 self.virtuals = copy.deepcopy(clone.virtuals)
25
26 self.use_defs = copy.deepcopy(clone.use_defs)
27 self.usemask = copy.deepcopy(clone.usemask)
28
29 self.configlist = copy.deepcopy(clone.configlist)
30 self.configlist[-1] = os.environ.copy()
31 self.configdict = { "globals": self.configlist[0],
32 "defaults": self.configlist[1],
33 "conf": self.configlist[2],
34 "pkg": self.configlist[3],
35 "auto": self.configlist[4],
36 "backupenv": self.configlist[5],
37 "env": self.configlist[6] }
38 self.backupenv = copy.deepcopy(clone.backupenv)
39 self.pusedict = copy.deepcopy(clone.pusedict)
40 self.categories = copy.deepcopy(clone.categories)
41 self.pkeywordsdict = copy.deepcopy(clone.pkeywordsdict)
42 self.pmaskdict = copy.deepcopy(clone.pmaskdict)
43 self.punmaskdict = copy.deepcopy(clone.punmaskdict)
44 self.prevmaskdict = copy.deepcopy(clone.prevmaskdict)
45 self.pprovideddict = copy.deepcopy(clone.pprovideddict)
46 self.lookuplist = copy.deepcopy(clone.lookuplist)
47 self.uvlist = copy.deepcopy(clone.uvlist)
48 self.dirVirtuals = copy.deepcopy(clone.dirVirtuals)
49 self.treeVirtuals = copy.deepcopy(clone.treeVirtuals)
50 self.userVirtuals = copy.deepcopy(clone.userVirtuals)
51
52 def __init__(self, clone=None, mycpv=None, config_profile_path=portage_const.PROFILE_PATH, config_incrementals=None):
53
54 self.already_in_regenerate = 0
55
56 self.locked = 0
57 self.mycpv = None
58 self.puse = []
59 self.modifiedkeys = []
60
61 self.virtuals = {}
62 self.v_count = 0
63
64 if clone:
65 self.clone( clone )
66 else:
67 self.depcachedir = portage_const.DEPCACHE_PATH
68
69 if not os.path.exists(config_profile_path):
70 writemsg("config_profile_path not specified to class config\n")
71 sys.exit(1)
72 self.profile_path = config_profile_path
73
74 if not config_incrementals:
75 import traceback
76 traceback.print_stack()
77 writemsg("incrementals not specified to class config\n")
78 writemsg("sayonara, sucker.\n")
79 sys.exit(1)
80 self.incrementals = copy.deepcopy(config_incrementals)
81
82 self.module_priority = ["user","default"]
83 self.modules = {}
84 self.modules["user"] = getconfig(portage_const.MODULES_FILE_PATH)
85 if self.modules["user"] == None:
86 self.modules["user"] = {}
87 self.modules["default"] = {
88 "portdbapi.metadbmodule": "cache.metadata.database",
89 "portdbapi.auxdbmodule": "cache.flat_list.database",
90 }
91
92 self.usemask=[]
93 self.configlist=[]
94 self.backupenv={}
95 # back up our incremental variables:
96 self.configdict={}
97 # configlist will contain: [ globals, defaults, conf, pkg, auto, backupenv (incrementals), origenv ]
98
99 # The symlink might not exist or might not be a symlink.
100 try:
101 self.profiles=[abssymlink(self.profile_path)]
102 except (OSError, IOError):
103 self.profiles=[self.profile_path]
104
105 mypath = self.profiles[0]
106 while os.path.exists(mypath+"/parent"):
107 mypath = os.path.normpath(mypath+"///"+grabfile(mypath+"/parent")[0])
108 if os.path.exists(mypath):
109 self.profiles.insert(0,mypath)
110
111 if os.environ.get("PORTAGE_CALLER",'') == "repoman":
112 pass
113 else:
114 # XXX: This should depend on ROOT?
115 if os.path.exists("/"+portage_const.CUSTOM_PROFILE_PATH):
116 self.profiles.append("/"+portage_const.CUSTOM_PROFILE_PATH)
117
118 self.packages_list = grab_multiple("packages", self.profiles, grabfile_package)
119 self.packages = stack_lists(self.packages_list, incremental=1)
120 del self.packages_list
121 #self.packages = grab_stacked("packages", self.profiles, grabfile, incremental_lines=1)
122
123 # revmaskdict
124 self.prevmaskdict={}
125 for x in self.packages:
126 mycatpkg=portage_dep.dep_getkey(x)
127 if not self.prevmaskdict.has_key(mycatpkg):
128 self.prevmaskdict[mycatpkg]=[x]
129 else:
130 self.prevmaskdict[mycatpkg].append(x)
131
132 # get profile-masked use flags -- INCREMENTAL Child over parent
133 usemask_lists = grab_multiple("use.mask", self.profiles, grabfile)
134 self.usemask = stack_lists(usemask_lists, incremental=True)
135 del usemask_lists
136 use_defs_lists = grab_multiple("use.defaults", self.profiles, grabdict)
137 self.use_defs = stack_dictlist(use_defs_lists, incremental=True)
138 del use_defs_lists
139
140 try:
141 mygcfg_dlists = grab_multiple("make.globals", self.profiles+["/etc"], getconfig)
142 self.mygcfg = stack_dicts(mygcfg_dlists, incrementals=portage_const.INCREMENTALS, ignore_none=1)
143
144 if self.mygcfg == None:
145 self.mygcfg = {}
146 except SystemExit, e:
147 raise
148 except Exception, e:
149 writemsg("!!! %s\n" % (e))
150 writemsg("!!! Incorrect multiline literals can cause this. Do not use them.\n")
151 writemsg("!!! Errors in this file should be reported on bugs.gentoo.org.\n")
152 sys.exit(1)
153 self.configlist.append(self.mygcfg)
154 self.configdict["globals"]=self.configlist[-1]
155
156 self.mygcfg = {}
157 if self.profiles:
158 try:
159 mygcfg_dlists = grab_multiple("make.defaults", self.profiles, getconfig)
160 self.mygcfg = stack_dicts(mygcfg_dlists, incrementals=self.incrementals[:], ignore_none=1)
161 #self.mygcfg = grab_stacked("make.defaults", self.profiles, getconfig)
162 if self.mygcfg == None:
163 self.mygcfg = {}
164 except SystemExit, e:
165 raise
166 except Exception, e:
167 writemsg("!!! %s\n" % (e))
168 writemsg("!!! 'rm -Rf /usr/portage/profiles; emerge sync' may fix this. If it does\n")
169 writemsg("!!! not then please report this to bugs.gentoo.org and, if possible, a dev\n")
170 writemsg("!!! on #gentoo (irc.freenode.org)\n")
171 sys.exit(1)
172 self.configlist.append(self.mygcfg)
173 self.configdict["defaults"]=self.configlist[-1]
174
175 try:
176 # XXX: Should depend on root?
177 self.mygcfg=getconfig("/"+portage_const.MAKE_CONF_FILE)
178 if self.mygcfg == None:
179 self.mygcfg = {}
180 except SystemExit, e:
181 raise
182 except Exception, e:
183 writemsg("!!! %s\n" % (e))
184 writemsg("!!! Incorrect multiline literals can cause this. Do not use them.\n")
185 sys.exit(1)
186
187
188 self.configlist.append(self.mygcfg)
189 self.configdict["conf"]=self.configlist[-1]
190
191 self.configlist.append({})
192 self.configdict["pkg"]=self.configlist[-1]
193
194 #auto-use:
195 self.configlist.append({})
196 self.configdict["auto"]=self.configlist[-1]
197
198 #backup-env (for recording our calculated incremental variables:)
199 self.backupenv = os.environ.copy()
200 self.configlist.append(self.backupenv) # XXX Why though?
201 self.configdict["backupenv"]=self.configlist[-1]
202
203 self.configlist.append(os.environ.copy())
204 self.configdict["env"]=self.configlist[-1]
205
206 # make lookuplist for loading package.*
207 self.lookuplist=self.configlist[:]
208 self.lookuplist.reverse()
209
210 archlist = grabfile(self["PORTDIR"]+"/profiles/arch.list")
211 self.configdict["conf"]["PORTAGE_ARCHLIST"] = ' '.join(archlist)
212
213 if os.environ.get("PORTAGE_CALLER",'') == "repoman":
214 # repoman shouldn't use local settings.
215 locations = [self["PORTDIR"] + "/profiles"]
216 self.pusedict = {}
217 self.pkeywordsdict = {}
218 self.punmaskdict = {}
219 else:
220 locations = [self["PORTDIR"] + "/profiles", portage_const.USER_CONFIG_PATH]
221
222 # Never set anything in this. It's for non-originals.
223 self.pusedict=grabdict_package(portage_const.USER_CONFIG_PATH+"/package.use")
224
225 #package.keywords
226 pkgdict=grabdict_package(portage_const.USER_CONFIG_PATH+"/package.keywords")
227 self.pkeywordsdict = {}
228
229 for key in pkgdict.keys():
230 # default to ~arch if no specific keyword is given
231 if not pkgdict[key]:
232 mykeywordlist = []
233 if self.configdict["defaults"] and self.configdict["defaults"].has_key("ACCEPT_KEYWORDS"):
234 groups = self.configdict["defaults"]["ACCEPT_KEYWORDS"].split()
235 else:
236 groups = []
237 for keyword in groups:
238 if not keyword[0] in "~-":
239 mykeywordlist.append("~"+keyword)
240 pkgdict[key] = mykeywordlist
241 cp = portage_dep.dep_getkey(key)
242 if not self.pkeywordsdict.has_key(cp):
243 self.pkeywordsdict[cp] = {}
244 self.pkeywordsdict[cp][key] = pkgdict[key]
245
246 #package.unmask
247 pkgunmasklines = grabfile_package(portage_const.USER_CONFIG_PATH+"/package.unmask")
248 self.punmaskdict = {}
249 for x in pkgunmasklines:
250 mycatpkg=portage_dep.dep_getkey(x)
251 L = self.punmaskdict.setdefault(mycatpkg,[])
252 L.append(x)
253
254 #getting categories from an external file now
255 categories = grab_multiple("categories", locations, grabfile)
256 self.categories = stack_lists(categories, incremental=1)
257 del categories
258
259 # get virtuals -- needs categories
260 self.loadVirtuals('/')
261
262 #package.mask
263 # Don't enable per profile package.mask unless the profile
264 # specifically depends on the >=portage-2.0.51 using
265 # <portage-2.0.51 syntax.
266 # don't hardcode portage versions into portage. It's not nice.
267 if self.profiles and (">=sys-apps/portage-2.0.51" in self.packages \
268 or "*>=sys-apps/portage-2.0.51" in self.packages):
269 pkgmasklines = grab_multiple("package.mask", self.profiles + locations, grabfile_package)
270 else:
271 pkgmasklines = grab_multiple("package.mask", locations, grabfile_package)
272 pkgmasklines = stack_lists(pkgmasklines, incremental=1)
273
274 self.pmaskdict = {}
275 for x in pkgmasklines:
276 mycatpkg = portage_dep.dep_getkey(x)
277 L = self.pmaskdict.setdefault(mycatpkg,[])
278 L.append(x)
279
280 pkgprovidedlines = grab_multiple("package.provided", self.profiles, grabfile)
281 pkgprovidedlines = stack_lists(pkgprovidedlines, incremental=1)
282
283 self.pprovideddict = {}
284 for x in pkgprovidedlines:
285 cpv=portage_versions.catpkgsplit(x)
286 if not x:
287 continue
288 mycatpkg=portage_dep.dep_getkey(x)
289 L = self.pprovideddict.setdefault(mycatpkg,[])
290 L.append(x)
291
292
293 self.lookuplist=self.configlist[:]
294 self.lookuplist.reverse()
295
296 useorder=self["USE_ORDER"]
297 if not useorder:
298 # reasonable defaults; this is important as without USE_ORDER,
299 # USE will always be "" (nothing set)!
300 useorder="env:pkg:conf:auto:defaults"
301 useordersplit=useorder.split(":")
302
303 self.uvlist=[]
304 for x in useordersplit:
305 if x in self.configdict:
306 if "PKGUSE" in self.configdict[x]:
307 # Delete PkgUse, Not legal to set.
308 del self.configdict[x]["PKGUSE"]
309 #prepend db to list to get correct order
310 self.uvlist.insert(0,self.configdict[x])
311
312 self.configdict["env"]["PORTAGE_GID"]=str(portage_gid)
313 self.backupenv["PORTAGE_GID"]=str(portage_gid)
314
315 if self.has_key("PORT_LOGDIR") and not self["PORT_LOGDIR"]:
316 # port_logdir is defined, but empty. this causes a traceback in doebuild.
317 writemsg(yellow("!!!")+" PORT_LOGDIR was defined, but set to nothing.\n")
318 writemsg(yellow("!!!")+" Disabling it. Please set it to a non null value.\n")
319 del self["PORT_LOGDIR"]
320
321 if self["PORTAGE_CACHEDIR"]:
322 # XXX: Deprecated -- April 15 -- NJ
323 writemsg(yellow(">>> PORTAGE_CACHEDIR has been deprecated!")+"\n")
324 writemsg(">>> Please use PORTAGE_DEPCACHEDIR instead.\n")
325 self.depcachedir = self["PORTAGE_CACHEDIR"]
326 del self["PORTAGE_CACHEDIR"]
327
328 if self["PORTAGE_DEPCACHEDIR"]:
329 #the auxcache is the only /var/cache/edb/ entry that stays at / even when "root" changes.
330 # XXX: Could move with a CHROOT functionality addition.
331 self.depcachedir = self["PORTAGE_DEPCACHEDIR"]
332 del self["PORTAGE_DEPCACHEDIR"]
333
334 overlays = self["PORTDIR_OVERLAY"].split()
335 if overlays:
336 new_ov=[]
337 for ov in overlays:
338 ov=os.path.normpath(ov)
339 if os.path.isdir(ov):
340 new_ov.append(ov)
341 else:
342 writemsg(red("!!! Invalid PORTDIR_OVERLAY (not a dir): "+ov+"\n"))
343 self["PORTDIR_OVERLAY"] = " ".join(new_ov)
344 self.backup_changes("PORTDIR_OVERLAY")
345
346 self.regenerate()
347
348
349 self.features = portage_util.unique_array(self["FEATURES"].split())
350 self.features.sort()
351
352 #XXX: Should this be temporary? Is it possible at all to have a default?
353 if "gpg" in self.features:
354 if not os.path.exists(self["PORTAGE_GPG_DIR"]) or not os.path.isdir(self["PORTAGE_GPG_DIR"]):
355 writemsg("PORTAGE_GPG_DIR is invalid. Removing gpg from FEATURES.\n")
356 self.features.remove("gpg")
357 self["FEATURES"] = " ".join(self.features)
358 self.backup_changes("FEATURES")
359
360 if mycpv:
361 self.setcpv(mycpv)
362
363 def autouse(self, myvartree, use_cache=1):
364 "returns set of USE variables auto-enabled due to packages being installed"
365 # XXX: harring wonders why profiledir is checked here...
366 from portage import profiledir
367 if profiledir==None:
368 return ""
369 myusevars=""
370 for myuse in self.use_defs:
371 dep_met = True
372 for mydep in self.use_defs[myuse]:
373 if not myvartree.dep_match(mydep,use_cache=True):
374 dep_met = False
375 break
376 if dep_met:
377 myusevars += " "+myuse
378 return myusevars
379
380
381
382 def loadVirtuals(self,root):
383 self.virtuals = self.getvirtuals(root)
384
385 def load_best_module(self,property_string):
386 best_mod = best_from_dict(property_string,self.modules,self.module_priority)
387 return load_mod(best_mod)
388
389 def lock(self):
390 self.locked = 1
391
392 def unlock(self):
393 self.locked = 0
394
395 def modifying(self):
396 if self.locked:
397 raise Exception, "Configuration is locked."
398
399 def backup_changes(self,key=None):
400 if key and self.configdict["env"].has_key(key):
401 self.backupenv[key] = copy.deepcopy(self.configdict["env"][key])
402 else:
403 raise KeyError, "No such key defined in environment: %s" % key
404
405 def reset(self,keeping_pkg=0,use_cache=1):
406 "reset environment to original settings"
407 envdict = self.configdict["env"]
408 # reinitialize env values to those of backupenv
409 envdict.clear()
410 envdict.update(self.backupenv)
411 self.modifiedkeys = []
412 if not keeping_pkg:
413 self.puse = ""
414 self.configdict["pkg"].clear()
415 self.regenerate(use_cache=use_cache)
416
417 def load_infodir(self,infodir):
418 if self.configdict.has_key("pkg"):
419 self.configdict["pkg"].clear()
420 else:
421 writemsg("No pkg setup for settings instance?\n")
422 sys.exit(17)
423
424 if os.path.exists(infodir):
425 if os.path.exists(infodir+"/environment"):
426 self.configdict["pkg"]["PORT_ENV_FILE"] = infodir+"/environment"
427 elif os.path.exists(infodir+"/environment.bz2"):
428 self.configdict["pkg"]["PORT_ENV_FILE"] = infodir+"/environment.bz2"
429 # else:
430 # print "wth, no env found in the infodir, '%s'" % infodir
431 # import traceback
432 # traceback.print_stack()
433 # sys.exit(15)
434 myre = re.compile('^[A-Z]+$')
435 for filename in listdir(infodir,filesonly=1):
436 if myre.match(filename):
437 try:
438 mydata = open(infodir+"/"+filename).read().strip()
439 if len(mydata)<2048:
440 if filename == "USE":
441 self.configdict["pkg"][filename] = "-* "+mydata
442 else:
443 self.configdict["pkg"][filename] = mydata
444 except SystemExit, e:
445 raise
446 except:
447 writemsg("!!! Unable to read file: %s\n" % infodir+"/"+filename)
448 pass
449 return 1
450 return 0
451
452 def setcpv(self,mycpv,use_cache=1):
453 self.modifying()
454 self.mycpv = mycpv
455 self.pusekey = portage_dep.best_match_to_list(self.mycpv, self.pusedict.keys())
456 if self.pusekey:
457 newpuse = " ".join(self.pusedict[self.pusekey])
458 else:
459 newpuse = ""
460 if newpuse == self.puse:
461 return
462 self.puse = newpuse
463 self.configdict["pkg"]["PKGUSE"] = self.puse[:] # For saving to PUSE file
464 self.configdict["pkg"]["USE"] = self.puse[:] # this gets appended to USE
465 self.reset(keeping_pkg=1,use_cache=use_cache)
466
467 def setinst(self,mycpv,mydbapi):
468 """
469 Grab the virtuals this package provides and add them into the tree virtuals.
470 """
471 provides = mydbapi.aux_get(mycpv, ["PROVIDE"])[0]
472
473 #XXX HACK
474 from portage import portdbapi
475
476 if isinstance(mydbapi, portdbapi):
477 myuse = self["USE"]
478 else:
479 myuse = mydbapi.aux_get(mycpv, ["USE"])[0]
480 virts = flatten(portage_dep.use_reduce(portage_dep.paren_reduce(provides), uselist=myuse.split()))
481
482 cp = portage_dep.dep_getkey(mycpv)
483 for virt in virts:
484 virt = portage_dep.dep_getkey(virt)
485 if not self.treeVirtuals.has_key(virt):
486 self.treeVirtuals[virt] = []
487 self.treeVirtuals[virt] = portage_util.unique_array(self.treeVirtuals[virt]+[cp])
488 # Reconstruct the combined virtuals.
489 val = stack_dictlist( [self.userVirtuals, self.treeVirtuals]+self.dirVirtuals, incremental=1)
490 for v in val.values():
491 v.reverse()
492 self.virtuals = val
493
494 def regenerate(self,useonly=0,use_cache=1):
495 if self.already_in_regenerate:
496 # XXX: THIS REALLY NEEDS TO GET FIXED. autouse() loops.
497 writemsg("!!! Looping in regenerate.\n",1)
498 return
499 else:
500 self.already_in_regenerate = 1
501
502 if useonly:
503 myincrementals=["USE"]
504 else:
505 myincrementals=self.incrementals[:]
506
507 # XXX HACK, harring
508 # this is a design flaw of the code.
509 from portage import db, root
510
511 rootdb = db.get(root)
512 for mykey in myincrementals:
513 if mykey=="USE":
514 mydbs=self.uvlist
515 # XXX Global usage of db... Needs to go away somehow.
516 if rootdb and "vartree" in rootdb:
517 _use = self.autouse( rootdb["vartree"], use_cache=use_cache)
518 else:
519 _use = ""
520 self.configdict["auto"]["USE"]= _use
521 else:
522 mydbs=self.configlist[:-1]
523
524 myflags=[]
525 for curdb in mydbs:
526 if mykey not in curdb:
527 continue
528 #variables are already expanded
529 mysplit=curdb[mykey].split()
530
531 for x in mysplit:
532 if x=="-*":
533 # "-*" is a special "minus" var that means "unset all settings".
534 # so USE="-* gnome" will have *just* gnome enabled.
535 myflags=[]
536 continue
537
538 if x[0]=="+":
539 # Not legal. People assume too much. Complain.
540 writemsg(red("USE flags should not start with a '+': %s\n" % x))
541 x=x[1:]
542
543 if x[0]=="-":
544 if x[1:] in myflags:
545 # Unset/Remove it.
546 myflags.remove(x[1:])
547 continue
548
549 # We got here, so add it now.
550 if x not in myflags:
551 myflags.append(x)
552
553 myflags.sort()
554 #store setting in last element of configlist, the original environment:
555 self.configlist[-1][mykey]=" ".join(myflags)
556 del myflags
557
558 #cache split-up USE var in a global
559 usesplit=[]
560
561 for x in self.configlist[-1]["USE"].split():
562 if x not in self.usemask:
563 usesplit.append(x)
564
565 if self.has_key("USE_EXPAND"):
566 for var in self["USE_EXPAND"].split():
567 if self.has_key(var):
568 for x in self[var].split():
569 mystr = var.lower()+"_"+x
570 if mystr not in usesplit:
571 usesplit.append(mystr)
572
573 # Pre-Pend ARCH variable to USE settings so '-*' in env doesn't kill arch.
574 # XXX: harring wonders why profiledir is checked here...
575 from portage import profiledir
576 if profiledir:
577 if self.configdict["defaults"].has_key("ARCH"):
578 if self.configdict["defaults"]["ARCH"]:
579 if self.configdict["defaults"]["ARCH"] not in usesplit:
580 usesplit.insert(0,self.configdict["defaults"]["ARCH"])
581
582 self.configlist[-1]["USE"]=" ".join(usesplit)
583
584 self.already_in_regenerate = 0
585
586 def getvirtuals(self, myroot):
587 myvirts = {}
588
589 # This breaks catalyst/portage when setting to a fresh/empty root.
590 # Virtuals cannot be calculated because there is nothing to work
591 # from. So the only ROOT prefixed dir should be local configs.
592 #myvirtdirs = prefix_array(self.profiles,myroot+"/")
593 myvirtdirs = copy.deepcopy(self.profiles)
594
595 self.treeVirtuals = {}
596
597 # Repoman should ignore these.
598 user_profile_dir = None
599 if os.environ.get("PORTAGE_CALLER","") != "repoman":
600 user_profile_dir = myroot+portage_const.USER_CONFIG_PATH
601
602 # XXX: Removing this as virtuals and profile/virtuals behave
603 # differently. portage/profile/virtuals overrides the default
604 # virtuals but are overridden by installed virtuals whereas
605 # portage/virtuals overrides everything.
606
607 #if os.path.exists("/etc/portage/virtuals"):
608 # writemsg("\n\n*** /etc/portage/virtuals should be moved to /etc/portage/profile/virtuals\n")
609 # writemsg("*** Please correct this by merging or moving the file. (Deprecation notice)\n\n")
610 # time.sleep(1)
611
612
613 self.dirVirtuals = grab_multiple("virtuals", myvirtdirs, grabdict)
614 self.dirVirtuals.reverse()
615 self.userVirtuals = {}
616 if user_profile_dir and os.path.exists(user_profile_dir+"/virtuals"):
617 self.userVirtuals = grabdict(user_profile_dir+"/virtuals")
618
619 # User settings and profile settings take precedence over tree.
620 profile_virtuals = stack_dictlist([self.userVirtuals]+self.dirVirtuals,incremental=1)
621
622 # repoman doesn't need local virtuals
623 if os.environ.get("PORTAGE_CALLER","") != "repoman":
624 from portage import vartree
625 temp_vartree = vartree(myroot,profile_virtuals,categories=self.categories)
626 myTreeVirtuals = {}
627 for key, val in temp_vartree.get_all_provides().items():
628 myTreeVirtuals[key] = portage_util.unique_array( [ portage_versions.pkgsplit(x)[0] for x in val ] )
629 self.treeVirtuals.update(myTreeVirtuals)
630 del myTreeVirtuals
631 # myTreeVirtuals = map_dictlist_vals(getCPFromCPV,temp_vartree.get_all_provides())
632 # for x,v in myTreeVirtuals.items():
633 # self.treeVirtuals[x] = portage_util.unique_array(v)
634
635 # User settings and profile settings take precedence over tree
636 val = stack_dictlist([self.userVirtuals,self.treeVirtuals]+self.dirVirtuals,incremental=1)
637
638 for x in val.values():
639 x.reverse()
640 return val
641
642 def __delitem__(self,mykey):
643 for x in self.lookuplist:
644 if x != None:
645 if mykey in x:
646 del x[mykey]
647
648 def __getitem__(self,mykey):
649 match = ''
650 for x in self.lookuplist:
651 if x == None:
652 writemsg("!!! lookuplist is null.\n")
653 elif x.has_key(mykey):
654 match = x[mykey]
655 break
656
657 if 0 and match and mykey in ["PORTAGE_BINHOST"]:
658 # These require HTTP Encoding
659 try:
660 import urllib
661 if urllib.unquote(match) != match:
662 writemsg("Note: %s already contains escape codes." % (mykey))
663 else:
664 match = urllib.quote(match)
665 except SystemExit, e:
666 raise
667 except:
668 writemsg("Failed to fix %s using urllib, attempting to continue.\n" % (mykey))
669 pass
670
671 elif mykey == "CONFIG_PROTECT_MASK":
672 match += " /etc/env.d"
673
674 return match
675
676 def has_key(self,mykey):
677 for x in self.lookuplist:
678 if x.has_key(mykey):
679 return 1
680 return 0
681
682 def keys(self):
683 mykeys=[]
684 for x in self.lookuplist:
685 for y in x.keys():
686 if y not in mykeys:
687 mykeys.append(y)
688 return mykeys
689
690 def __setitem__(self,mykey,myvalue):
691 "set a value; will be thrown away at reset() time"
692 if not isinstance(myvalue, str):
693 raise ValueError("Invalid type being used as a value: '%s': '%s'" % (str(mykey),str(myvalue)))
694 self.modifying()
695 self.modifiedkeys += [mykey]
696 self.configdict["env"][mykey]=myvalue
697
698 def environ(self):
699 "return our locally-maintained environment"
700 mydict={}
701 for x in self.keys():
702 mydict[x]=self[x]
703 if not mydict.has_key("HOME") and mydict.has_key("BUILD_PREFIX"):
704 writemsg("*** HOME not set. Setting to "+mydict["BUILD_PREFIX"]+"\n")
705 mydict["HOME"]=mydict["BUILD_PREFIX"][:]
706
707 return mydict
708
709 def bash_environ(self):
710 "return our locally-maintained environment in a suitable bash assignment form"
711 mydict=self.environ()
712 final={}
713 for k in mydict.keys():
714 # quotes and escaped chars suck.
715 s=mydict[k].replace("\\","\\\\\\\\")
716 s=s.replace("'","\\\\'")
717 s=s.replace("\n","\\\n")
718 final[k]="$'%s'" % s
719 return final
720
721
722 def stack_dicts(dicts, incremental=0, incrementals=[], ignore_none=0):
723 """Stacks an array of dict-types into one array. Optionally merging or
724 overwriting matching key/value pairs for the dict[key]->string.
725 Returns a single dict."""
726 final_dict = None
727 for mydict in dicts:
728 if mydict == None:
729 if ignore_none:
730 continue
731 else:
732 return None
733 if final_dict == None:
734 final_dict = {}
735 for y in mydict.keys():
736 if mydict[y]:
737 if final_dict.has_key(y) and (incremental or (y in incrementals)):
738 final_dict[y] += " "+mydict[y][:]
739 else:
740 final_dict[y] = mydict[y][:]
741 mydict[y] = ' '.join(mydict[y].split()) # Remove extra spaces.
742 return final_dict
743
744 def stack_lists(lists, incremental=1):
745 """Stacks an array of list-types into one array. Optionally removing
746 distinct values using '-value' notation. Higher index is preferenced."""
747 new_list = []
748 for x in lists:
749 for y in x:
750 if y:
751 if incremental and y[0]=='-':
752 while y[1:] in new_list:
753 del new_list[new_list.index(y[1:])]
754 else:
755 if y not in new_list:
756 new_list.append(y[:])
757 return new_list
758
759 def stack_dictlist(original_dicts, incremental=0, incrementals=[], ignore_none=0):
760 """Stacks an array of dict-types into one array. Optionally merging or
761 overwriting matching key/value pairs for the dict[key]->list.
762 Returns a single dict. Higher index in lists is preferenced."""
763 final_dict = None
764 kill_list = {}
765 for mydict in original_dicts:
766 if mydict == None:
767 continue
768 if final_dict == None:
769 final_dict = {}
770 for y in mydict.keys():
771 if not final_dict.has_key(y):
772 final_dict[y] = []
773 if not kill_list.has_key(y):
774 kill_list[y] = []
775
776 for thing in mydict[y]:
777 if thing and (thing not in kill_list[y]):
778 if (incremental or (y in incrementals)) and thing[0] == '-':
779 if thing[1:] not in kill_list[y]:
780 kill_list[y] += [thing[1:]]
781 # while(thing[1:] in final_dict[y]):
782 # del final_dict[y][final_dict[y].index(thing[1:])]
783 else:
784 if thing not in final_dict[y]:
785 final_dict[y].insert(0,thing[:])
786 if final_dict.has_key(y) and not final_dict[y]:
787 del final_dict[y]
788 return final_dict
789
790
791 def best_from_dict(key, top_dict, key_order, EmptyOnError=1, FullCopy=1, AllowEmpty=1):
792 for x in key_order:
793 dico = top_dict.get(x)
794 if dico and key in dico:
795 if FullCopy:
796 return copy.deepcopy(dico[key])
797 else:
798 return dico[key]
799 if EmptyOnError:
800 return ""
801 else:
802 raise KeyError, "Key not found in list; '%s'" % key
803
804
805 def load_mod(name):
806 components = name.split('.')
807 modname = ".".join(components[:-1])
808 mod = __import__(modname)
809 for comp in components[1:]:
810 mod = getattr(mod, comp)
811 return mod

  ViewVC Help
Powered by ViewVC 1.1.20