Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 275217 | Differences between
and this patch

Collapse All | Expand All

(-)depgraph.py (-524 / +537 lines)
Lines 52-68 Link Here
52
from _emerge.UnmergeDepPriority import UnmergeDepPriority
52
from _emerge.UnmergeDepPriority import UnmergeDepPriority
53
from _emerge.visible import visible
53
from _emerge.visible import visible
54
54
55
class depgraph(object):
55
class _frozen_depgraph_config(object):
56
56
57
	pkg_tree_map = RootConfig.pkg_tree_map
57
	def __init__(self, settings, trees, myopts, spinner, dynamic_config, depgraph):
58
59
	_dep_keys = ["DEPEND", "RDEPEND", "PDEPEND"]
60
61
	def __init__(self, settings, trees, myopts, myparams, spinner):
62
		self.settings = settings
58
		self.settings = settings
63
		self.target_root = settings["ROOT"]
59
		self.target_root = settings["ROOT"]
64
		self.myopts = myopts
60
		self.myopts = myopts
65
		self.myparams = myparams
66
		self.edebug = 0
61
		self.edebug = 0
67
		if settings.get("PORTAGE_DEBUG", "") == "1":
62
		if settings.get("PORTAGE_DEBUG", "") == "1":
68
			self.edebug = 1
63
			self.edebug = 1
Lines 71-92 Link Here
71
		self._opts_no_restart = frozenset(["--buildpkgonly",
66
		self._opts_no_restart = frozenset(["--buildpkgonly",
72
			"--fetchonly", "--fetch-all-uri", "--pretend"])
67
			"--fetchonly", "--fetch-all-uri", "--pretend"])
73
		self.pkgsettings = {}
68
		self.pkgsettings = {}
74
		# Maps slot atom to package for each Package added to the graph.
75
		self._slot_pkg_map = {}
76
		# Maps nodes to the reasons they were selected for reinstallation.
77
		self._reinstall_nodes = {}
78
		self.mydbapi = {}
79
		self.trees = {}
69
		self.trees = {}
80
		self._trees_orig = trees
70
		self._trees_orig = trees
81
		self.roots = {}
71
		self.roots = {}
82
		# Contains a filtered view of preferred packages that are selected
83
		# from available repositories.
84
		self._filtered_trees = {}
85
		# Contains installed packages and new packages that have been added
72
		# Contains installed packages and new packages that have been added
86
		# to the graph.
73
		# to the graph.
87
		self._graph_trees = {}
74
		self._graph_trees = {}
88
		# All Package instances
89
		self._pkg_cache = {}
90
		for myroot in trees:
75
		for myroot in trees:
91
			self.trees[myroot] = {}
76
			self.trees[myroot] = {}
92
			# Create a RootConfig instance that references
77
			# Create a RootConfig instance that references
Lines 99-108 Link Here
99
				self.trees[myroot][tree] = trees[myroot][tree]
84
				self.trees[myroot][tree] = trees[myroot][tree]
100
			self.trees[myroot]["vartree"] = \
85
			self.trees[myroot]["vartree"] = \
101
				FakeVartree(trees[myroot]["root_config"],
86
				FakeVartree(trees[myroot]["root_config"],
102
					pkg_cache=self._pkg_cache)
87
					pkg_cache=dynamic_config._pkg_cache)
103
			self.pkgsettings[myroot] = portage.config(
88
			self.pkgsettings[myroot] = portage.config(
104
				clone=self.trees[myroot]["vartree"].settings)
89
				clone=self.trees[myroot]["vartree"].settings)
105
			self._slot_pkg_map[myroot] = {}
90
			dynamic_config._slot_pkg_map[myroot] = {}
106
			vardb = self.trees[myroot]["vartree"].dbapi
91
			vardb = self.trees[myroot]["vartree"].dbapi
107
			preload_installed_pkgs = "--nodeps" not in self.myopts and \
92
			preload_installed_pkgs = "--nodeps" not in self.myopts and \
108
				"--buildpkgonly" not in self.myopts
93
				"--buildpkgonly" not in self.myopts
Lines 123-134 Link Here
123
			trees[myroot]["vartree"].dbapi._clear_cache()
108
			trees[myroot]["vartree"].dbapi._clear_cache()
124
			gc.collect()
109
			gc.collect()
125
110
126
			self.mydbapi[myroot] = fakedb
111
			dynamic_config.mydbapi[myroot] = fakedb
127
			def graph_tree():
112
			def graph_tree():
128
				pass
113
				pass
129
			graph_tree.dbapi = fakedb
114
			graph_tree.dbapi = fakedb
130
			self._graph_trees[myroot] = {}
115
			self._graph_trees[myroot] = {}
131
			self._filtered_trees[myroot] = {}
116
			dynamic_config._filtered_trees[myroot] = {}
132
			# Substitute the graph tree for the vartree in dep_check() since we
117
			# Substitute the graph tree for the vartree in dep_check() since we
133
			# want atom selections to be consistent with package selections
118
			# want atom selections to be consistent with package selections
134
			# have already been made.
119
			# have already been made.
Lines 136-143 Link Here
136
			self._graph_trees[myroot]["vartree"]    = graph_tree
121
			self._graph_trees[myroot]["vartree"]    = graph_tree
137
			def filtered_tree():
122
			def filtered_tree():
138
				pass
123
				pass
139
			filtered_tree.dbapi = self._dep_check_composite_db(self, myroot)
124
			filtered_tree.dbapi = _dep_check_composite_db(depgraph, myroot)
140
			self._filtered_trees[myroot]["porttree"] = filtered_tree
125
			dynamic_config._filtered_trees[myroot]["porttree"] = filtered_tree
141
126
142
			# Passing in graph_tree as the vartree here could lead to better
127
			# Passing in graph_tree as the vartree here could lead to better
143
			# atom selections in some cases by causing atoms for packages that
128
			# atom selections in some cases by causing atoms for packages that
Lines 155-162 Link Here
155
			# the parent package into self._select_atoms() calls so that
140
			# the parent package into self._select_atoms() calls so that
156
			# unresolvable direct circular dependencies can be detected and
141
			# unresolvable direct circular dependencies can be detected and
157
			# avoided when possible.
142
			# avoided when possible.
158
			self._filtered_trees[myroot]["graph_db"] = graph_tree.dbapi
143
			dynamic_config._filtered_trees[myroot]["graph_db"] = graph_tree.dbapi
159
			self._filtered_trees[myroot]["vartree"] = self.trees[myroot]["vartree"]
144
			dynamic_config._filtered_trees[myroot]["vartree"] = self.trees[myroot]["vartree"]
160
145
161
			dbs = []
146
			dbs = []
162
			portdb = self.trees[myroot]["porttree"].dbapi
147
			portdb = self.trees[myroot]["porttree"].dbapi
Lines 171-186 Link Here
171
				dbs.append((bindb,  "binary", True, False, db_keys))
156
				dbs.append((bindb,  "binary", True, False, db_keys))
172
			db_keys = list(trees[myroot]["vartree"].dbapi._aux_cache_keys)
157
			db_keys = list(trees[myroot]["vartree"].dbapi._aux_cache_keys)
173
			dbs.append((vardb, "installed", True, True, db_keys))
158
			dbs.append((vardb, "installed", True, True, db_keys))
174
			self._filtered_trees[myroot]["dbs"] = dbs
159
			dynamic_config._filtered_trees[myroot]["dbs"] = dbs
175
			if "--usepkg" in self.myopts:
160
			if "--usepkg" in self.myopts:
176
				self.trees[myroot]["bintree"].populate(
161
				self.trees[myroot]["bintree"].populate(
177
					"--getbinpkg" in self.myopts,
162
					"--getbinpkg" in self.myopts,
178
					"--getbinpkgonly" in self.myopts)
163
					"--getbinpkgonly" in self.myopts)
179
		del trees
164
		del trees
180
165
166
		self._required_set_names = set(["system", "world"])
167
168
class _dynamic_depgraph_config(object):
169
170
	def __init__(self, myparams):
171
		self.myparams = myparams
172
		# Maps slot atom to package for each Package added to the graph.
173
		self._slot_pkg_map = {}
174
		# Maps nodes to the reasons they were selected for reinstallation.
175
		self._reinstall_nodes = {}
176
		self.mydbapi = {}
177
		# Contains a filtered view of preferred packages that are selected
178
		# from available repositories.
179
		self._filtered_trees = {}
180
		# All Package instances
181
		self._pkg_cache = {}
181
		#contains the args created by select_files
182
		#contains the args created by select_files
182
		self._initial_arg_list = []
183
		self._initial_arg_list = []
183
		self.digraph=portage.digraph()
184
		self.digraph = portage.digraph()
184
		# contains all sets added to the graph
185
		# contains all sets added to the graph
185
		self._sets = {}
186
		self._sets = {}
186
		# contains atoms given as arguments
187
		# contains atoms given as arguments
Lines 225-234 Link Here
225
		self._unsatisfied_deps = []
226
		self._unsatisfied_deps = []
226
		self._initially_unsatisfied_deps = []
227
		self._initially_unsatisfied_deps = []
227
		self._ignored_deps = []
228
		self._ignored_deps = []
228
		self._required_set_names = set(["system", "world"])
229
		self._highest_pkg_cache = {}
230
231
232
class depgraph(object):
233
234
	pkg_tree_map = RootConfig.pkg_tree_map
235
236
	_dep_keys = ["DEPEND", "RDEPEND", "PDEPEND"]
237
	
238
	def __init__(self, settings, trees, myopts, myparams, spinner):	
239
		self._dynamic_config = _dynamic_depgraph_config(myparams)
240
		self._frozen_config = _frozen_depgraph_config(settings, trees, \
241
			myopts, spinner, self._dynamic_config, self)
242
		
229
		self._select_atoms = self._select_atoms_highest_available
243
		self._select_atoms = self._select_atoms_highest_available
230
		self._select_package = self._select_pkg_highest_available
244
		self._select_package = self._select_pkg_highest_available
231
		self._highest_pkg_cache = {}
232
245
233
	def _show_slot_collision_notice(self):
246
	def _show_slot_collision_notice(self):
234
		"""Show an informational message advising the user to mask one of the
247
		"""Show an informational message advising the user to mask one of the
Lines 238-244 Link Here
238
		cases.
251
		cases.
239
		"""
252
		"""
240
253
241
		if not self._slot_collision_info:
254
		if not self._dynamic_config._slot_collision_info:
242
			return
255
			return
243
256
244
		self._show_merge_list()
257
		self._show_merge_list()
Lines 254-274 Link Here
254
		explanation_columns = 70
267
		explanation_columns = 70
255
		explanations = 0
268
		explanations = 0
256
		for (slot_atom, root), slot_nodes \
269
		for (slot_atom, root), slot_nodes \
257
			in self._slot_collision_info.iteritems():
270
			in self._dynamic_config._slot_collision_info.iteritems():
258
			msg.append(str(slot_atom))
271
			msg.append(str(slot_atom))
259
			msg.append("\n\n")
272
			msg.append("\n\n")
260
273
261
			for node in slot_nodes:
274
			for node in slot_nodes:
262
				msg.append(indent)
275
				msg.append(indent)
263
				msg.append(str(node))
276
				msg.append(str(node))
264
				parent_atoms = self._parent_atoms.get(node)
277
				parent_atoms = self._dynamic_config._parent_atoms.get(node)
265
				if parent_atoms:
278
				if parent_atoms:
266
					pruned_list = set()
279
					pruned_list = set()
267
					# Prefer conflict atoms over others.
280
					# Prefer conflict atoms over others.
268
					for parent_atom in parent_atoms:
281
					for parent_atom in parent_atoms:
269
						if len(pruned_list) >= max_parents:
282
						if len(pruned_list) >= max_parents:
270
							break
283
							break
271
						if parent_atom in self._slot_conflict_parent_atoms:
284
						if parent_atom in self._dynamic_config._slot_conflict_parent_atoms:
272
							pruned_list.add(parent_atom)
285
							pruned_list.add(parent_atom)
273
286
274
					# If this package was pulled in by conflict atoms then
287
					# If this package was pulled in by conflict atoms then
Lines 290-296 Link Here
290
							parent, atom = parent_atom
303
							parent, atom = parent_atom
291
							if isinstance(parent, Package) and \
304
							if isinstance(parent, Package) and \
292
								(parent.slot_atom, parent.root) \
305
								(parent.slot_atom, parent.root) \
293
								in self._slot_collision_info:
306
								in self._dynamic_config._slot_collision_info:
294
								pruned_list.add(parent_atom)
307
								pruned_list.add(parent_atom)
295
						for parent_atom in parent_atoms:
308
						for parent_atom in parent_atoms:
296
							if len(pruned_list) >= max_parents:
309
							if len(pruned_list) >= max_parents:
Lines 329-337 Link Here
329
		sys.stderr.write("".join(msg))
342
		sys.stderr.write("".join(msg))
330
		sys.stderr.flush()
343
		sys.stderr.flush()
331
344
332
		explanations_for_all = explanations == len(self._slot_collision_info)
345
		explanations_for_all = explanations == len(self._dynamic_config._slot_collision_info)
333
346
334
		if explanations_for_all or "--quiet" in self.myopts:
347
		if explanations_for_all or "--quiet" in self._frozen_config.myopts:
335
			return
348
			return
336
349
337
		msg = []
350
		msg = []
Lines 385-396 Link Here
385
			# conflicts between two packages.
398
			# conflicts between two packages.
386
			return None
399
			return None
387
400
388
		all_conflict_atoms = self._slot_conflict_parent_atoms
401
		all_conflict_atoms = self._dynamic_config._slot_conflict_parent_atoms
389
		matched_node = None
402
		matched_node = None
390
		matched_atoms = None
403
		matched_atoms = None
391
		unmatched_node = None
404
		unmatched_node = None
392
		for node in slot_nodes:
405
		for node in slot_nodes:
393
			parent_atoms = self._parent_atoms.get(node)
406
			parent_atoms = self._dynamic_config._parent_atoms.get(node)
394
			if not parent_atoms:
407
			if not parent_atoms:
395
				# Normally, there are always parent atoms. If there are
408
				# Normally, there are always parent atoms. If there are
396
				# none then something unexpected is happening and there's
409
				# none then something unexpected is happening and there's
Lines 456-475 Link Here
456
		packages that have been pulled into a given slot.
469
		packages that have been pulled into a given slot.
457
		"""
470
		"""
458
		for (slot_atom, root), slot_nodes \
471
		for (slot_atom, root), slot_nodes \
459
			in self._slot_collision_info.iteritems():
472
			in self._dynamic_config._slot_collision_info.iteritems():
460
473
461
			all_parent_atoms = set()
474
			all_parent_atoms = set()
462
			for pkg in slot_nodes:
475
			for pkg in slot_nodes:
463
				parent_atoms = self._parent_atoms.get(pkg)
476
				parent_atoms = self._dynamic_config._parent_atoms.get(pkg)
464
				if not parent_atoms:
477
				if not parent_atoms:
465
					continue
478
					continue
466
				all_parent_atoms.update(parent_atoms)
479
				all_parent_atoms.update(parent_atoms)
467
480
468
			for pkg in slot_nodes:
481
			for pkg in slot_nodes:
469
				parent_atoms = self._parent_atoms.get(pkg)
482
				parent_atoms = self._dynamic_config._parent_atoms.get(pkg)
470
				if parent_atoms is None:
483
				if parent_atoms is None:
471
					parent_atoms = set()
484
					parent_atoms = set()
472
					self._parent_atoms[pkg] = parent_atoms
485
					self._dynamic_config._parent_atoms[pkg] = parent_atoms
473
				for parent_atom in all_parent_atoms:
486
				for parent_atom in all_parent_atoms:
474
					if parent_atom in parent_atoms:
487
					if parent_atom in parent_atoms:
475
						continue
488
						continue
Lines 481-500 Link Here
481
					if atom_set.findAtomForPackage(pkg):
494
					if atom_set.findAtomForPackage(pkg):
482
						parent_atoms.add(parent_atom)
495
						parent_atoms.add(parent_atom)
483
					else:
496
					else:
484
						self._slot_conflict_parent_atoms.add(parent_atom)
497
						self._dynamic_config._slot_conflict_parent_atoms.add(parent_atom)
485
498
486
	def _reinstall_for_flags(self, forced_flags,
499
	def _reinstall_for_flags(self, forced_flags,
487
		orig_use, orig_iuse, cur_use, cur_iuse):
500
		orig_use, orig_iuse, cur_use, cur_iuse):
488
		"""Return a set of flags that trigger reinstallation, or None if there
501
		"""Return a set of flags that trigger reinstallation, or None if there
489
		are no such flags."""
502
		are no such flags."""
490
		if "--newuse" in self.myopts:
503
		if "--newuse" in self._frozen_config.myopts:
491
			flags = set(orig_iuse.symmetric_difference(
504
			flags = set(orig_iuse.symmetric_difference(
492
				cur_iuse).difference(forced_flags))
505
				cur_iuse).difference(forced_flags))
493
			flags.update(orig_iuse.intersection(orig_use).symmetric_difference(
506
			flags.update(orig_iuse.intersection(orig_use).symmetric_difference(
494
				cur_iuse.intersection(cur_use)))
507
				cur_iuse.intersection(cur_use)))
495
			if flags:
508
			if flags:
496
				return flags
509
				return flags
497
		elif "changed-use" == self.myopts.get("--reinstall"):
510
		elif "changed-use" == self._frozen_config.myopts.get("--reinstall"):
498
			flags = orig_iuse.intersection(orig_use).symmetric_difference(
511
			flags = orig_iuse.intersection(orig_use).symmetric_difference(
499
				cur_iuse.intersection(cur_use))
512
				cur_iuse.intersection(cur_use))
500
			if flags:
513
			if flags:
Lines 502-511 Link Here
502
		return None
515
		return None
503
516
504
	def _create_graph(self, allow_unsatisfied=False):
517
	def _create_graph(self, allow_unsatisfied=False):
505
		dep_stack = self._dep_stack
518
		dep_stack = self._dynamic_config._dep_stack
506
		dep_disjunctive_stack = self._dep_disjunctive_stack
519
		dep_disjunctive_stack = self._dynamic_config._dep_disjunctive_stack
507
		while dep_stack or dep_disjunctive_stack:
520
		while dep_stack or dep_disjunctive_stack:
508
			self.spinner.update()
521
			self._frozen_config.spinner.update()
509
			while dep_stack:
522
			while dep_stack:
510
				dep = dep_stack.pop()
523
				dep = dep_stack.pop()
511
				if isinstance(dep, Package):
524
				if isinstance(dep, Package):
Lines 521-536 Link Here
521
		return 1
534
		return 1
522
535
523
	def _add_dep(self, dep, allow_unsatisfied=False):
536
	def _add_dep(self, dep, allow_unsatisfied=False):
524
		debug = "--debug" in self.myopts
537
		debug = "--debug" in self._frozen_config.myopts
525
		buildpkgonly = "--buildpkgonly" in self.myopts
538
		buildpkgonly = "--buildpkgonly" in self._frozen_config.myopts
526
		nodeps = "--nodeps" in self.myopts
539
		nodeps = "--nodeps" in self._frozen_config.myopts
527
		empty = "empty" in self.myparams
540
		empty = "empty" in self._dynamic_config.myparams
528
		deep = "deep" in self.myparams
541
		deep = "deep" in self._dynamic_config.myparams
529
		update = "--update" in self.myopts and dep.depth <= 1
542
		update = "--update" in self._frozen_config.myopts and dep.depth <= 1
530
		if dep.blocker:
543
		if dep.blocker:
531
			if not buildpkgonly and \
544
			if not buildpkgonly and \
532
				not nodeps and \
545
				not nodeps and \
533
				dep.parent not in self._slot_collision_nodes:
546
				dep.parent not in self._dynamic_config._slot_collision_nodes:
534
				if dep.parent.onlydeps:
547
				if dep.parent.onlydeps:
535
					# It's safe to ignore blockers if the
548
					# It's safe to ignore blockers if the
536
					# parent is an --onlydeps node.
549
					# parent is an --onlydeps node.
Lines 540-546 Link Here
540
				blocker = Blocker(atom=dep.atom,
553
				blocker = Blocker(atom=dep.atom,
541
					eapi=dep.parent.metadata["EAPI"],
554
					eapi=dep.parent.metadata["EAPI"],
542
					root=dep.parent.root)
555
					root=dep.parent.root)
543
				self._blocker_parents.add(blocker, dep.parent)
556
				self._dynamic_config._blocker_parents.add(blocker, dep.parent)
544
			return 1
557
			return 1
545
		dep_pkg, existing_node = self._select_package(dep.root, dep.atom,
558
		dep_pkg, existing_node = self._select_package(dep.root, dep.atom,
546
			onlydeps=dep.onlydeps)
559
			onlydeps=dep.onlydeps)
Lines 550-558 Link Here
550
				# pulled in by --with-bdeps=y.
563
				# pulled in by --with-bdeps=y.
551
				return 1
564
				return 1
552
			if allow_unsatisfied:
565
			if allow_unsatisfied:
553
				self._unsatisfied_deps.append(dep)
566
				self._dynamic_config._unsatisfied_deps.append(dep)
554
				return 1
567
				return 1
555
			self._unsatisfied_deps_for_display.append(
568
			self._dynamic_config._unsatisfied_deps_for_display.append(
556
				((dep.root, dep.atom), {"myparent":dep.parent}))
569
				((dep.root, dep.atom), {"myparent":dep.parent}))
557
			return 0
570
			return 0
558
		# In some cases, dep_check will return deps that shouldn't
571
		# In some cases, dep_check will return deps that shouldn't
Lines 564-570 Link Here
564
			not dep_pkg.installed and \
577
			not dep_pkg.installed and \
565
			not (existing_node or empty or deep or update):
578
			not (existing_node or empty or deep or update):
566
			myarg = None
579
			myarg = None
567
			if dep.root == self.target_root:
580
			if dep.root == self._frozen_config.target_root:
568
				try:
581
				try:
569
					myarg = self._iter_atoms_for_pkg(dep_pkg).next()
582
					myarg = self._iter_atoms_for_pkg(dep_pkg).next()
570
				except StopIteration:
583
				except StopIteration:
Lines 575-581 Link Here
575
						# should have been masked.
588
						# should have been masked.
576
						raise
589
						raise
577
			if not myarg:
590
			if not myarg:
578
				self._ignored_deps.append(dep)
591
				self._dynamic_config._ignored_deps.append(dep)
579
				return 1
592
				return 1
580
593
581
		if not self._add_pkg(dep_pkg, dep):
594
		if not self._add_pkg(dep_pkg, dep):
Lines 607-617 Link Here
607
		"""
620
		"""
608
		# Ensure that the dependencies of the same package
621
		# Ensure that the dependencies of the same package
609
		# are never processed more than once.
622
		# are never processed more than once.
610
		previously_added = pkg in self.digraph
623
		previously_added = pkg in self._dynamic_config.digraph
611
624
612
		# select the correct /var database that we'll be checking against
625
		# select the correct /var database that we'll be checking against
613
		vardbapi = self.trees[pkg.root]["vartree"].dbapi
626
		vardbapi = self._frozen_config.trees[pkg.root]["vartree"].dbapi
614
		pkgsettings = self.pkgsettings[pkg.root]
627
		pkgsettings = self._frozen_config.pkgsettings[pkg.root]
615
628
616
		arg_atoms = None
629
		arg_atoms = None
617
		if True:
630
		if True:
Lines 626-632 Link Here
626
639
627
		if not pkg.onlydeps:
640
		if not pkg.onlydeps:
628
			if not pkg.installed and \
641
			if not pkg.installed and \
629
				"empty" not in self.myparams and \
642
				"empty" not in self._dynamic_config.myparams and \
630
				vardbapi.match(pkg.slot_atom):
643
				vardbapi.match(pkg.slot_atom):
631
				# Increase the priority of dependencies on packages that
644
				# Increase the priority of dependencies on packages that
632
				# are being rebuilt. This optimizes merge order so that
645
				# are being rebuilt. This optimizes merge order so that
Lines 638-644 Link Here
638
				# are being merged in that case.
651
				# are being merged in that case.
639
				priority.rebuild = True
652
				priority.rebuild = True
640
653
641
			existing_node = self._slot_pkg_map[pkg.root].get(pkg.slot_atom)
654
			existing_node = self._dynamic_config._slot_pkg_map[pkg.root].get(pkg.slot_atom)
642
			slot_collision = False
655
			slot_collision = False
643
			if existing_node:
656
			if existing_node:
644
				existing_node_matches = pkg.cpv == existing_node.cpv
657
				existing_node_matches = pkg.cpv == existing_node.cpv
Lines 655-661 Link Here
655
					if arg_atoms:
668
					if arg_atoms:
656
						for parent_atom in arg_atoms:
669
						for parent_atom in arg_atoms:
657
							parent, atom = parent_atom
670
							parent, atom = parent_atom
658
							self.digraph.add(existing_node, parent,
671
							self._dynamic_config.digraph.add(existing_node, parent,
659
								priority=priority)
672
								priority=priority)
660
							self._add_parent_atom(existing_node, parent_atom)
673
							self._add_parent_atom(existing_node, parent_atom)
661
					# If a direct circular dependency is not an unsatisfied
674
					# If a direct circular dependency is not an unsatisfied
Lines 664-670 Link Here
664
					# way.
677
					# way.
665
					if existing_node != myparent or \
678
					if existing_node != myparent or \
666
						(priority.buildtime and not priority.satisfied):
679
						(priority.buildtime and not priority.satisfied):
667
						self.digraph.addnode(existing_node, myparent,
680
						self._dynamic_config.digraph.addnode(existing_node, myparent,
668
							priority=priority)
681
							priority=priority)
669
						if dep.atom is not None and dep.parent is not None:
682
						if dep.atom is not None and dep.parent is not None:
670
							self._add_parent_atom(existing_node,
683
							self._add_parent_atom(existing_node,
Lines 684-699 Link Here
684
				# only being partially added to the graph.  It must not be
697
				# only being partially added to the graph.  It must not be
685
				# allowed to interfere with the other nodes that have been
698
				# allowed to interfere with the other nodes that have been
686
				# added.  Do not overwrite data for existing nodes in
699
				# added.  Do not overwrite data for existing nodes in
687
				# self.mydbapi since that data will be used for blocker
700
				# self._dynamic_config.mydbapi since that data will be used for blocker
688
				# validation.
701
				# validation.
689
				# Even though the graph is now invalid, continue to process
702
				# Even though the graph is now invalid, continue to process
690
				# dependencies so that things like --fetchonly can still
703
				# dependencies so that things like --fetchonly can still
691
				# function despite collisions.
704
				# function despite collisions.
692
				pass
705
				pass
693
			elif not previously_added:
706
			elif not previously_added:
694
				self._slot_pkg_map[pkg.root][pkg.slot_atom] = pkg
707
				self._dynamic_config._slot_pkg_map[pkg.root][pkg.slot_atom] = pkg
695
				self.mydbapi[pkg.root].cpv_inject(pkg)
708
				self._dynamic_config.mydbapi[pkg.root].cpv_inject(pkg)
696
				self._filtered_trees[pkg.root]["porttree"].dbapi._clear_cache()
709
				self._dynamic_config._filtered_trees[pkg.root]["porttree"].dbapi._clear_cache()
697
710
698
			if not pkg.installed:
711
			if not pkg.installed:
699
				# Allow this package to satisfy old-style virtuals in case it
712
				# Allow this package to satisfy old-style virtuals in case it
Lines 702-708 Link Here
702
				try:
715
				try:
703
					pkgsettings.setinst(pkg.cpv, pkg.metadata)
716
					pkgsettings.setinst(pkg.cpv, pkg.metadata)
704
					# For consistency, also update the global virtuals.
717
					# For consistency, also update the global virtuals.
705
					settings = self.roots[pkg.root].settings
718
					settings = self._frozen_config.roots[pkg.root].settings
706
					settings.unlock()
719
					settings.unlock()
707
					settings.setinst(pkg.cpv, pkg.metadata)
720
					settings.setinst(pkg.cpv, pkg.metadata)
708
					settings.lock()
721
					settings.lock()
Lines 713-731 Link Here
713
					return 0
726
					return 0
714
727
715
		if arg_atoms:
728
		if arg_atoms:
716
			self._set_nodes.add(pkg)
729
			self._dynamic_config._set_nodes.add(pkg)
717
730
718
		# Do this even when addme is False (--onlydeps) so that the
731
		# Do this even when addme is False (--onlydeps) so that the
719
		# parent/child relationship is always known in case
732
		# parent/child relationship is always known in case
720
		# self._show_slot_collision_notice() needs to be called later.
733
		# self._show_slot_collision_notice() needs to be called later.
721
		self.digraph.add(pkg, myparent, priority=priority)
734
		self._dynamic_config.digraph.add(pkg, myparent, priority=priority)
722
		if dep.atom is not None and dep.parent is not None:
735
		if dep.atom is not None and dep.parent is not None:
723
			self._add_parent_atom(pkg, (dep.parent, dep.atom))
736
			self._add_parent_atom(pkg, (dep.parent, dep.atom))
724
737
725
		if arg_atoms:
738
		if arg_atoms:
726
			for parent_atom in arg_atoms:
739
			for parent_atom in arg_atoms:
727
				parent, atom = parent_atom
740
				parent, atom = parent_atom
728
				self.digraph.add(pkg, parent, priority=priority)
741
				self._dynamic_config.digraph.add(pkg, parent, priority=priority)
729
				self._add_parent_atom(pkg, parent_atom)
742
				self._add_parent_atom(pkg, parent_atom)
730
743
731
		""" This section determines whether we go deeper into dependencies or not.
744
		""" This section determines whether we go deeper into dependencies or not.
Lines 734-747 Link Here
734
		    emerge --deep <pkgspec>; we need to recursively check dependencies of pkgspec
747
		    emerge --deep <pkgspec>; we need to recursively check dependencies of pkgspec
735
		    If we are in --nodeps (no recursion) mode, we obviously only check 1 level of dependencies.
748
		    If we are in --nodeps (no recursion) mode, we obviously only check 1 level of dependencies.
736
		"""
749
		"""
737
		dep_stack = self._dep_stack
750
		dep_stack = self._dynamic_config._dep_stack
738
		if "recurse" not in self.myparams:
751
		if "recurse" not in self._dynamic_config.myparams:
739
			return 1
752
			return 1
740
		elif pkg.installed and \
753
		elif pkg.installed and \
741
			"deep" not in self.myparams:
754
			"deep" not in self._dynamic_config.myparams:
742
			dep_stack = self._ignored_deps
755
			dep_stack = self._dynamic_config._ignored_deps
743
756
744
		self.spinner.update()
757
		self._frozen_config.spinner.update()
745
758
746
		if arg_atoms:
759
		if arg_atoms:
747
			depth = 0
760
			depth = 0
Lines 751-770 Link Here
751
		return 1
764
		return 1
752
765
753
	def _add_parent_atom(self, pkg, parent_atom):
766
	def _add_parent_atom(self, pkg, parent_atom):
754
		parent_atoms = self._parent_atoms.get(pkg)
767
		parent_atoms = self._dynamic_config._parent_atoms.get(pkg)
755
		if parent_atoms is None:
768
		if parent_atoms is None:
756
			parent_atoms = set()
769
			parent_atoms = set()
757
			self._parent_atoms[pkg] = parent_atoms
770
			self._dynamic_config._parent_atoms[pkg] = parent_atoms
758
		parent_atoms.add(parent_atom)
771
		parent_atoms.add(parent_atom)
759
772
760
	def _add_slot_conflict(self, pkg):
773
	def _add_slot_conflict(self, pkg):
761
		self._slot_collision_nodes.add(pkg)
774
		self._dynamic_config._slot_collision_nodes.add(pkg)
762
		slot_key = (pkg.slot_atom, pkg.root)
775
		slot_key = (pkg.slot_atom, pkg.root)
763
		slot_nodes = self._slot_collision_info.get(slot_key)
776
		slot_nodes = self._dynamic_config._slot_collision_info.get(slot_key)
764
		if slot_nodes is None:
777
		if slot_nodes is None:
765
			slot_nodes = set()
778
			slot_nodes = set()
766
			slot_nodes.add(self._slot_pkg_map[pkg.root][pkg.slot_atom])
779
			slot_nodes.add(self._dynamic_config._slot_pkg_map[pkg.root][pkg.slot_atom])
767
			self._slot_collision_info[slot_key] = slot_nodes
780
			self._dynamic_config._slot_collision_info[slot_key] = slot_nodes
768
		slot_nodes.add(pkg)
781
		slot_nodes.add(pkg)
769
782
770
	def _add_pkg_deps(self, pkg, allow_unsatisfied=False):
783
	def _add_pkg_deps(self, pkg, allow_unsatisfied=False):
Lines 776-782 Link Here
776
		myuse = pkg.use.enabled
789
		myuse = pkg.use.enabled
777
		jbigkey = pkg
790
		jbigkey = pkg
778
		depth = pkg.depth + 1
791
		depth = pkg.depth + 1
779
		removal_action = "remove" in self.myparams
792
		removal_action = "remove" in self._dynamic_config.myparams
780
793
781
		edepend={}
794
		edepend={}
782
		depkeys = ["DEPEND","RDEPEND","PDEPEND"]
795
		depkeys = ["DEPEND","RDEPEND","PDEPEND"]
Lines 784-798 Link Here
784
			edepend[k] = metadata[k]
797
			edepend[k] = metadata[k]
785
798
786
		if not pkg.built and \
799
		if not pkg.built and \
787
			"--buildpkgonly" in self.myopts and \
800
			"--buildpkgonly" in self._frozen_config.myopts and \
788
			"deep" not in self.myparams and \
801
			"deep" not in self._dynamic_config.myparams and \
789
			"empty" not in self.myparams:
802
			"empty" not in self._dynamic_config.myparams:
790
			edepend["RDEPEND"] = ""
803
			edepend["RDEPEND"] = ""
791
			edepend["PDEPEND"] = ""
804
			edepend["PDEPEND"] = ""
792
		bdeps_optional = False
805
		bdeps_optional = False
793
806
794
		if pkg.built and not removal_action:
807
		if pkg.built and not removal_action:
795
			if self.myopts.get("--with-bdeps", "n") == "y":
808
			if self._frozen_config.myopts.get("--with-bdeps", "n") == "y":
796
				# Pull in build time deps as requested, but marked them as
809
				# Pull in build time deps as requested, but marked them as
797
				# "optional" since they are not strictly required. This allows
810
				# "optional" since they are not strictly required. This allows
798
				# more freedom in the merge order calculation for solving
811
				# more freedom in the merge order calculation for solving
Lines 805-815 Link Here
805
				# built packages do not have build time dependencies.
818
				# built packages do not have build time dependencies.
806
				edepend["DEPEND"] = ""
819
				edepend["DEPEND"] = ""
807
820
808
		if removal_action and self.myopts.get("--with-bdeps", "y") == "n":
821
		if removal_action and self._frozen_config.myopts.get("--with-bdeps", "y") == "n":
809
			edepend["DEPEND"] = ""
822
			edepend["DEPEND"] = ""
810
823
811
		bdeps_root = "/"
824
		bdeps_root = "/"
812
		root_deps = self.myopts.get("--root-deps")
825
		root_deps = self._frozen_config.myopts.get("--root-deps")
813
		if root_deps is not None:
826
		if root_deps is not None:
814
			if root_deps is True:
827
			if root_deps is True:
815
				bdeps_root = myroot
828
				bdeps_root = myroot
Lines 824-830 Link Here
824
			(myroot, edepend["PDEPEND"], self._priority(runtime_post=True))
837
			(myroot, edepend["PDEPEND"], self._priority(runtime_post=True))
825
		)
838
		)
826
839
827
		debug = "--debug" in self.myopts
840
		debug = "--debug" in self._frozen_config.myopts
828
		strict = mytype != "installed"
841
		strict = mytype != "installed"
829
		try:
842
		try:
830
			if not strict:
843
			if not strict:
Lines 878-884 Link Here
878
					"!!! This binary package cannot be installed: '%s'\n" % \
891
					"!!! This binary package cannot be installed: '%s'\n" % \
879
					mykey, noiselevel=-1)
892
					mykey, noiselevel=-1)
880
			elif mytype == "ebuild":
893
			elif mytype == "ebuild":
881
				portdb = self.roots[myroot].trees["porttree"].dbapi
894
				portdb = self._frozen_config.roots[myroot].trees["porttree"].dbapi
882
				myebuild, mylocation = portdb.findname2(mykey)
895
				myebuild, mylocation = portdb.findname2(mykey)
883
				portage.writemsg("!!! This ebuild cannot be installed: " + \
896
				portage.writemsg("!!! This ebuild cannot be installed: " + \
884
					"'%s'\n" % myebuild, noiselevel=-1)
897
					"'%s'\n" % myebuild, noiselevel=-1)
Lines 892-898 Link Here
892
	def _add_pkg_dep_string(self, pkg, dep_root, dep_priority, dep_string,
905
	def _add_pkg_dep_string(self, pkg, dep_root, dep_priority, dep_string,
893
		allow_unsatisfied):
906
		allow_unsatisfied):
894
		depth = pkg.depth + 1
907
		depth = pkg.depth + 1
895
		debug = "--debug" in self.myopts
908
		debug = "--debug" in self._frozen_config.myopts
896
		strict = pkg.type_name != "installed"
909
		strict = pkg.type_name != "installed"
897
910
898
		if debug:
911
		if debug:
Lines 915-921 Link Here
915
		if debug:
928
		if debug:
916
			print "Candidates:", selected_atoms
929
			print "Candidates:", selected_atoms
917
930
918
		vardb = self.roots[dep_root].trees["vartree"].dbapi
931
		vardb = self._frozen_config.roots[dep_root].trees["vartree"].dbapi
919
932
920
		for atom in selected_atoms:
933
		for atom in selected_atoms:
921
			try:
934
			try:
Lines 946-952 Link Here
946
959
947
	def _queue_disjunctive_deps(self, pkg, dep_root, dep_priority, dep_struct):
960
	def _queue_disjunctive_deps(self, pkg, dep_root, dep_priority, dep_struct):
948
		"""
961
		"""
949
		Queue disjunctive (virtual and ||) deps in self._dep_disjunctive_stack.
962
		Queue disjunctive (virtual and ||) deps in self._dynamic_config._dep_disjunctive_stack.
950
		Yields non-disjunctive deps. Raises InvalidDependString when 
963
		Yields non-disjunctive deps. Raises InvalidDependString when 
951
		necessary.
964
		necessary.
952
		"""
965
		"""
Lines 980-995 Link Here
980
			i += 1
993
			i += 1
981
994
982
	def _queue_disjunction(self, pkg, dep_root, dep_priority, dep_struct):
995
	def _queue_disjunction(self, pkg, dep_root, dep_priority, dep_struct):
983
		self._dep_disjunctive_stack.append(
996
		self._dynamic_config._dep_disjunctive_stack.append(
984
			(pkg, dep_root, dep_priority, dep_struct))
997
			(pkg, dep_root, dep_priority, dep_struct))
985
998
986
	def _pop_disjunction(self, allow_unsatisfied):
999
	def _pop_disjunction(self, allow_unsatisfied):
987
		"""
1000
		"""
988
		Pop one disjunctive dep from self._dep_disjunctive_stack, and use it to
1001
		Pop one disjunctive dep from self._dynamic_config._dep_disjunctive_stack, and use it to
989
		populate self._dep_stack.
1002
		populate self._dynamic_config._dep_stack.
990
		"""
1003
		"""
991
		pkg, dep_root, dep_priority, dep_struct = \
1004
		pkg, dep_root, dep_priority, dep_struct = \
992
			self._dep_disjunctive_stack.pop()
1005
			self._dynamic_config._dep_disjunctive_stack.pop()
993
		dep_string = portage.dep.paren_enclose(dep_struct)
1006
		dep_string = portage.dep.paren_enclose(dep_struct)
994
		if not self._add_pkg_dep_string(
1007
		if not self._add_pkg_dep_string(
995
			pkg, dep_root, dep_priority, dep_string, allow_unsatisfied):
1008
			pkg, dep_root, dep_priority, dep_string, allow_unsatisfied):
Lines 997-1003 Link Here
997
		return 1
1010
		return 1
998
1011
999
	def _priority(self, **kwargs):
1012
	def _priority(self, **kwargs):
1000
		if "remove" in self.myparams:
1013
		if "remove" in self._dynamic_config.myparams:
1001
			priority_constructor = UnmergeDepPriority
1014
			priority_constructor = UnmergeDepPriority
1002
		else:
1015
		else:
1003
			priority_constructor = DepPriority
1016
			priority_constructor = DepPriority
Lines 1016-1022 Link Here
1016
			atom_without_category, "null"))
1029
			atom_without_category, "null"))
1017
		cat, atom_pn = portage.catsplit(null_cp)
1030
		cat, atom_pn = portage.catsplit(null_cp)
1018
1031
1019
		dbs = self._filtered_trees[root_config.root]["dbs"]
1032
		dbs = self._dynamic_config._filtered_trees[root_config.root]["dbs"]
1020
		categories = set()
1033
		categories = set()
1021
		for db, pkg_type, built, installed, db_keys in dbs:
1034
		for db, pkg_type, built, installed, db_keys in dbs:
1022
			for cat in db.categories:
1035
			for cat in db.categories:
Lines 1032-1038 Link Here
1032
	def _have_new_virt(self, root, atom_cp):
1045
	def _have_new_virt(self, root, atom_cp):
1033
		ret = False
1046
		ret = False
1034
		for db, pkg_type, built, installed, db_keys in \
1047
		for db, pkg_type, built, installed, db_keys in \
1035
			self._filtered_trees[root]["dbs"]:
1048
			self._dynamic_config._filtered_trees[root]["dbs"]:
1036
			if db.cp_list(atom_cp):
1049
			if db.cp_list(atom_cp):
1037
				ret = True
1050
				ret = True
1038
				break
1051
				break
Lines 1040-1050 Link Here
1040
1053
1041
	def _iter_atoms_for_pkg(self, pkg):
1054
	def _iter_atoms_for_pkg(self, pkg):
1042
		# TODO: add multiple $ROOT support
1055
		# TODO: add multiple $ROOT support
1043
		if pkg.root != self.target_root:
1056
		if pkg.root != self._frozen_config.target_root:
1044
			return
1057
			return
1045
		atom_arg_map = self._atom_arg_map
1058
		atom_arg_map = self._dynamic_config._atom_arg_map
1046
		root_config = self.roots[pkg.root]
1059
		root_config = self._frozen_config.roots[pkg.root]
1047
		for atom in self._set_atoms.iterAtomsForPackage(pkg):
1060
		for atom in self._dynamic_config._set_atoms.iterAtomsForPackage(pkg):
1048
			atom_cp = portage.dep_getkey(atom)
1061
			atom_cp = portage.dep_getkey(atom)
1049
			if atom_cp != pkg.cp and \
1062
			if atom_cp != pkg.cp and \
1050
				self._have_new_virt(pkg.root, atom_cp):
1063
				self._have_new_virt(pkg.root, atom_cp):
Lines 1072-1093 Link Here
1072
1085
1073
	def select_files(self, myfiles):
1086
	def select_files(self, myfiles):
1074
		"""Given a list of .tbz2s, .ebuilds sets, and deps, populate
1087
		"""Given a list of .tbz2s, .ebuilds sets, and deps, populate
1075
		self._initial_arg_list and call self._resolve to create the 
1088
		self._dynamic_config._initial_arg_list and call self._resolve to create the 
1076
		appropriate depgraph and return a favorite list."""
1089
		appropriate depgraph and return a favorite list."""
1077
		debug = "--debug" in self.myopts
1090
		debug = "--debug" in self._frozen_config.myopts
1078
		root_config = self.roots[self.target_root]
1091
		root_config = self._frozen_config.roots[self._frozen_config.target_root]
1079
		sets = root_config.sets
1092
		sets = root_config.sets
1080
		getSetAtoms = root_config.setconfig.getSetAtoms
1093
		getSetAtoms = root_config.setconfig.getSetAtoms
1081
		myfavorites=[]
1094
		myfavorites=[]
1082
		myroot = self.target_root
1095
		myroot = self._frozen_config.target_root
1083
		dbs = self._filtered_trees[myroot]["dbs"]
1096
		dbs = self._dynamic_config._filtered_trees[myroot]["dbs"]
1084
		vardb = self.trees[myroot]["vartree"].dbapi
1097
		vardb = self._frozen_config.trees[myroot]["vartree"].dbapi
1085
		real_vardb = self._trees_orig[myroot]["vartree"].dbapi
1098
		real_vardb = self._frozen_config._trees_orig[myroot]["vartree"].dbapi
1086
		portdb = self.trees[myroot]["porttree"].dbapi
1099
		portdb = self._frozen_config.trees[myroot]["porttree"].dbapi
1087
		bindb = self.trees[myroot]["bintree"].dbapi
1100
		bindb = self._frozen_config.trees[myroot]["bintree"].dbapi
1088
		pkgsettings = self.pkgsettings[myroot]
1101
		pkgsettings = self._frozen_config.pkgsettings[myroot]
1089
		args = []
1102
		args = []
1090
		onlydeps = "--onlydeps" in self.myopts
1103
		onlydeps = "--onlydeps" in self._frozen_config.myopts
1091
		lookup_owners = []
1104
		lookup_owners = []
1092
		for x in myfiles:
1105
		for x in myfiles:
1093
			ext = os.path.splitext(x)[1]
1106
			ext = os.path.splitext(x)[1]
Lines 1106-1112 Link Here
1106
				mytbz2=portage.xpak.tbz2(x)
1119
				mytbz2=portage.xpak.tbz2(x)
1107
				mykey=mytbz2.getelements("CATEGORY")[0]+"/"+os.path.splitext(os.path.basename(x))[0]
1120
				mykey=mytbz2.getelements("CATEGORY")[0]+"/"+os.path.splitext(os.path.basename(x))[0]
1108
				if os.path.realpath(x) != \
1121
				if os.path.realpath(x) != \
1109
					os.path.realpath(self.trees[myroot]["bintree"].getname(mykey)):
1122
					os.path.realpath(self._frozen_config.trees[myroot]["bintree"].getname(mykey)):
1110
					print colorize("BAD", "\n*** You need to adjust PKGDIR to emerge this package.\n")
1123
					print colorize("BAD", "\n*** You need to adjust PKGDIR to emerge this package.\n")
1111
					return 0, myfavorites
1124
					return 0, myfavorites
1112
				db_keys = list(bindb._aux_cache_keys)
1125
				db_keys = list(bindb._aux_cache_keys)
Lines 1114-1120 Link Here
1114
				pkg = Package(type_name="binary", root_config=root_config,
1127
				pkg = Package(type_name="binary", root_config=root_config,
1115
					cpv=mykey, built=True, metadata=metadata,
1128
					cpv=mykey, built=True, metadata=metadata,
1116
					onlydeps=onlydeps)
1129
					onlydeps=onlydeps)
1117
				self._pkg_cache[pkg] = pkg
1130
				self._dynamic_config._pkg_cache[pkg] = pkg
1118
				args.append(PackageArg(arg=x, package=pkg,
1131
				args.append(PackageArg(arg=x, package=pkg,
1119
					root_config=root_config))
1132
					root_config=root_config))
1120
			elif ext==".ebuild":
1133
			elif ext==".ebuild":
Lines 1142-1148 Link Here
1142
						print colorize("BAD", "\n*** You are emerging a masked package. It is MUCH better to use")
1155
						print colorize("BAD", "\n*** You are emerging a masked package. It is MUCH better to use")
1143
						print colorize("BAD", "*** /etc/portage/package.* to accomplish this. See portage(5) man")
1156
						print colorize("BAD", "*** /etc/portage/package.* to accomplish this. See portage(5) man")
1144
						print colorize("BAD", "*** page for details.")
1157
						print colorize("BAD", "*** page for details.")
1145
						countdown(int(self.settings["EMERGE_WARNING_DELAY"]),
1158
						countdown(int(self._frozen_config.settings["EMERGE_WARNING_DELAY"]),
1146
							"Continuing...")
1159
							"Continuing...")
1147
				else:
1160
				else:
1148
					raise portage.exception.PackageNotFound(
1161
					raise portage.exception.PackageNotFound(
Lines 1151-1157 Link Here
1151
				metadata = izip(db_keys, portdb.aux_get(mykey, db_keys))
1164
				metadata = izip(db_keys, portdb.aux_get(mykey, db_keys))
1152
				pkg = Package(type_name="ebuild", root_config=root_config,
1165
				pkg = Package(type_name="ebuild", root_config=root_config,
1153
					cpv=mykey, metadata=metadata, onlydeps=onlydeps)
1166
					cpv=mykey, metadata=metadata, onlydeps=onlydeps)
1154
				self._pkg_cache[pkg] = pkg
1167
				self._dynamic_config._pkg_cache[pkg] = pkg
1155
				args.append(PackageArg(arg=x, package=pkg,
1168
				args.append(PackageArg(arg=x, package=pkg,
1156
					root_config=root_config))
1169
					root_config=root_config))
1157
			elif x.startswith(os.path.sep):
1170
			elif x.startswith(os.path.sep):
Lines 1169-1182 Link Here
1169
					s = x[len(SETPREFIX):]
1182
					s = x[len(SETPREFIX):]
1170
					if s not in sets:
1183
					if s not in sets:
1171
						raise portage.exception.PackageSetNotFound(s)
1184
						raise portage.exception.PackageSetNotFound(s)
1172
					if s in self._sets:
1185
					if s in self._dynamic_config._sets:
1173
						continue
1186
						continue
1174
					# Recursively expand sets so that containment tests in
1187
					# Recursively expand sets so that containment tests in
1175
					# self._get_parent_sets() properly match atoms in nested
1188
					# self._get_parent_sets() properly match atoms in nested
1176
					# sets (like if world contains system).
1189
					# sets (like if world contains system).
1177
					expanded_set = InternalPackageSet(
1190
					expanded_set = InternalPackageSet(
1178
						initial_atoms=getSetAtoms(s))
1191
						initial_atoms=getSetAtoms(s))
1179
					self._sets[s] = expanded_set
1192
					self._dynamic_config._sets[s] = expanded_set
1180
					args.append(SetArg(arg=x, set=expanded_set,
1193
					args.append(SetArg(arg=x, set=expanded_set,
1181
						root_config=root_config))
1194
						root_config=root_config))
1182
					continue
1195
					continue
Lines 1221-1227 Link Here
1221
					print
1234
					print
1222
					print
1235
					print
1223
					ambiguous_package_name(x, expanded_atoms, root_config,
1236
					ambiguous_package_name(x, expanded_atoms, root_config,
1224
						self.spinner, self.myopts)
1237
						self._frozen_config.spinner, self._frozen_config.myopts)
1225
					return False, myfavorites
1238
					return False, myfavorites
1226
				if expanded_atoms:
1239
				if expanded_atoms:
1227
					atom = expanded_atoms[0]
1240
					atom = expanded_atoms[0]
Lines 1273-1279 Link Here
1273
				args.append(AtomArg(arg=atom, atom=atom,
1286
				args.append(AtomArg(arg=atom, atom=atom,
1274
					root_config=root_config))
1287
					root_config=root_config))
1275
1288
1276
		if "--update" in self.myopts:
1289
		if "--update" in self._frozen_config.myopts:
1277
			# In some cases, the greedy slots behavior can pull in a slot that
1290
			# In some cases, the greedy slots behavior can pull in a slot that
1278
			# the user would want to uninstall due to it being blocked by a
1291
			# the user would want to uninstall due to it being blocked by a
1279
			# newer version in a different slot. Therefore, it's necessary to
1292
			# newer version in a different slot. Therefore, it's necessary to
Lines 1332-1353 Link Here
1332
		# Order needs to be preserved since a feature of --nodeps
1345
		# Order needs to be preserved since a feature of --nodeps
1333
		# is to allow the user to force a specific merge order.
1346
		# is to allow the user to force a specific merge order.
1334
		args.reverse()
1347
		args.reverse()
1335
		self._initial_arg_list = args[:]
1348
		self._dynamic_config._initial_arg_list = args[:]
1336
	
1349
	
1337
		return self._resolve(myfavorites)
1350
		return self._resolve(myfavorites)
1338
	
1351
	
1339
	def _resolve(self, myfavorites):
1352
	def _resolve(self, myfavorites):
1340
		"""Given self._initial_arg_list, pull in the root nodes, 
1353
		"""Given self._dynamic_config._initial_arg_list, pull in the root nodes, 
1341
		call self._creategraph to process theier deps and return 
1354
		call self._creategraph to process theier deps and return 
1342
		a favorite list."""
1355
		a favorite list."""
1343
		debug = "--debug" in self.myopts
1356
		debug = "--debug" in self._frozen_config.myopts
1344
		onlydeps = "--onlydeps" in self.myopts
1357
		onlydeps = "--onlydeps" in self._frozen_config.myopts
1345
		myroot = self.target_root
1358
		myroot = self._frozen_config.target_root
1346
		pkgsettings = self.pkgsettings[myroot]
1359
		pkgsettings = self._frozen_config.pkgsettings[myroot]
1347
		pprovideddict = pkgsettings.pprovideddict
1360
		pprovideddict = pkgsettings.pprovideddict
1348
		for arg in self._initial_arg_list:
1361
		for arg in self._dynamic_config._initial_arg_list:
1349
			for atom in arg.set:
1362
			for atom in arg.set:
1350
				self.spinner.update()
1363
				self._frozen_config.spinner.update()
1351
				dep = Dependency(atom=atom, onlydeps=onlydeps,
1364
				dep = Dependency(atom=atom, onlydeps=onlydeps,
1352
					root=myroot, parent=arg)
1365
					root=myroot, parent=arg)
1353
				atom_cp = portage.dep_getkey(atom)
1366
				atom_cp = portage.dep_getkey(atom)
Lines 1355-1361 Link Here
1355
					pprovided = pprovideddict.get(portage.dep_getkey(atom))
1368
					pprovided = pprovideddict.get(portage.dep_getkey(atom))
1356
					if pprovided and portage.match_from_list(atom, pprovided):
1369
					if pprovided and portage.match_from_list(atom, pprovided):
1357
						# A provided package has been specified on the command line.
1370
						# A provided package has been specified on the command line.
1358
						self._pprovided_args.append((arg, atom))
1371
						self._dynamic_config._pprovided_args.append((arg, atom))
1359
						continue
1372
						continue
1360
					if isinstance(arg, PackageArg):
1373
					if isinstance(arg, PackageArg):
1361
						if not self._add_pkg(arg.package, dep) or \
1374
						if not self._add_pkg(arg.package, dep) or \
Lines 1372-1381 Link Here
1372
					if not pkg:
1385
					if not pkg:
1373
						if not (isinstance(arg, SetArg) and \
1386
						if not (isinstance(arg, SetArg) and \
1374
							arg.name in ("system", "world")):
1387
							arg.name in ("system", "world")):
1375
							self._unsatisfied_deps_for_display.append(
1388
							self._dynamic_config._unsatisfied_deps_for_display.append(
1376
								((myroot, atom), {}))
1389
								((myroot, atom), {}))
1377
							return 0, myfavorites
1390
							return 0, myfavorites
1378
						self._missing_args.append((arg, atom))
1391
						self._dynamic_config._missing_args.append((arg, atom))
1379
						continue
1392
						continue
1380
					if atom_cp != pkg.cp:
1393
					if atom_cp != pkg.cp:
1381
						# For old-style virtuals, we need to repeat the
1394
						# For old-style virtuals, we need to repeat the
Lines 1386-1395 Link Here
1386
							portage.match_from_list(expanded_atom, pprovided):
1399
							portage.match_from_list(expanded_atom, pprovided):
1387
							# A provided package has been
1400
							# A provided package has been
1388
							# specified on the command line.
1401
							# specified on the command line.
1389
							self._pprovided_args.append((arg, atom))
1402
							self._dynamic_config._pprovided_args.append((arg, atom))
1390
							continue
1403
							continue
1391
					if pkg.installed and "selective" not in self.myparams:
1404
					if pkg.installed and "selective" not in self._dynamic_config.myparams:
1392
						self._unsatisfied_deps_for_display.append(
1405
						self._dynamic_config._unsatisfied_deps_for_display.append(
1393
							((myroot, atom), {}))
1406
							((myroot, atom), {}))
1394
						# Previous behavior was to bail out in this case, but
1407
						# Previous behavior was to bail out in this case, but
1395
						# since the dep is satisfied by the installed package,
1408
						# since the dep is satisfied by the installed package,
Lines 1441-1448 Link Here
1441
			return 0, myfavorites
1454
			return 0, myfavorites
1442
1455
1443
		missing=0
1456
		missing=0
1444
		if "--usepkgonly" in self.myopts:
1457
		if "--usepkgonly" in self._frozen_config.myopts:
1445
			for xs in self.digraph.all_nodes():
1458
			for xs in self._dynamic_config.digraph.all_nodes():
1446
				if not isinstance(xs, Package):
1459
				if not isinstance(xs, Package):
1447
					continue
1460
					continue
1448
				if len(xs) >= 4 and xs[0] != "binary" and xs[3] == "merge":
1461
				if len(xs) >= 4 and xs[0] != "binary" and xs[3] == "merge":
Lines 1466-1472 Link Here
1466
		The package selection cache is automatically invalidated, since
1479
		The package selection cache is automatically invalidated, since
1467
		arguments influence package selections.
1480
		arguments influence package selections.
1468
		"""
1481
		"""
1469
		args_set = self._sets["args"]
1482
		args_set = self._dynamic_config._sets["args"]
1470
		args_set.clear()
1483
		args_set.clear()
1471
		for arg in args:
1484
		for arg in args:
1472
			if not isinstance(arg, (AtomArg, PackageArg)):
1485
			if not isinstance(arg, (AtomArg, PackageArg)):
Lines 1476-1484 Link Here
1476
				continue
1489
				continue
1477
			args_set.add(atom)
1490
			args_set.add(atom)
1478
1491
1479
		self._set_atoms.clear()
1492
		self._dynamic_config._set_atoms.clear()
1480
		self._set_atoms.update(chain(*self._sets.itervalues()))
1493
		self._dynamic_config._set_atoms.update(chain(*self._dynamic_config._sets.itervalues()))
1481
		atom_arg_map = self._atom_arg_map
1494
		atom_arg_map = self._dynamic_config._atom_arg_map
1482
		atom_arg_map.clear()
1495
		atom_arg_map.clear()
1483
		for arg in args:
1496
		for arg in args:
1484
			for atom in arg.set:
1497
			for atom in arg.set:
Lines 1492-1499 Link Here
1492
1505
1493
		# Invalidate the package selection cache, since
1506
		# Invalidate the package selection cache, since
1494
		# arguments influence package selections.
1507
		# arguments influence package selections.
1495
		self._highest_pkg_cache.clear()
1508
		self._dynamic_config._highest_pkg_cache.clear()
1496
		for trees in self._filtered_trees.itervalues():
1509
		for trees in self._dynamic_config._filtered_trees.itervalues():
1497
			trees["porttree"].dbapi._clear_cache()
1510
			trees["porttree"].dbapi._clear_cache()
1498
1511
1499
	def _greedy_slots(self, root_config, atom, blocker_lookahead=False):
1512
	def _greedy_slots(self, root_config, atom, blocker_lookahead=False):
Lines 1583-1598 Link Here
1583
		added to the graph or those that are installed and have
1596
		added to the graph or those that are installed and have
1584
		not been scheduled for replacement.
1597
		not been scheduled for replacement.
1585
		"""
1598
		"""
1586
		kwargs["trees"] = self._graph_trees
1599
		kwargs["trees"] = self._frozen_config._graph_trees
1587
		return self._select_atoms_highest_available(*pargs, **kwargs)
1600
		return self._select_atoms_highest_available(*pargs, **kwargs)
1588
1601
1589
	def _select_atoms_highest_available(self, root, depstring,
1602
	def _select_atoms_highest_available(self, root, depstring,
1590
		myuse=None, parent=None, strict=True, trees=None, priority=None):
1603
		myuse=None, parent=None, strict=True, trees=None, priority=None):
1591
		"""This will raise InvalidDependString if necessary. If trees is
1604
		"""This will raise InvalidDependString if necessary. If trees is
1592
		None then self._filtered_trees is used."""
1605
		None then self._dynamic_config._filtered_trees is used."""
1593
		pkgsettings = self.pkgsettings[root]
1606
		pkgsettings = self._frozen_config.pkgsettings[root]
1594
		if trees is None:
1607
		if trees is None:
1595
			trees = self._filtered_trees
1608
			trees = self._dynamic_config._filtered_trees
1596
		if True:
1609
		if True:
1597
			try:
1610
			try:
1598
				if parent is not None:
1611
				if parent is not None:
Lines 1634-1644 Link Here
1634
		masked_pkg_instances = set()
1647
		masked_pkg_instances = set()
1635
		missing_licenses = []
1648
		missing_licenses = []
1636
		have_eapi_mask = False
1649
		have_eapi_mask = False
1637
		pkgsettings = self.pkgsettings[root]
1650
		pkgsettings = self._frozen_config.pkgsettings[root]
1638
		implicit_iuse = pkgsettings._get_implicit_iuse()
1651
		implicit_iuse = pkgsettings._get_implicit_iuse()
1639
		root_config = self.roots[root]
1652
		root_config = self._frozen_config.roots[root]
1640
		portdb = self.roots[root].trees["porttree"].dbapi
1653
		portdb = self._frozen_config.roots[root].trees["porttree"].dbapi
1641
		dbs = self._filtered_trees[root]["dbs"]
1654
		dbs = self._dynamic_config._filtered_trees[root]["dbs"]
1642
		for db, pkg_type, built, installed, db_keys in dbs:
1655
		for db, pkg_type, built, installed, db_keys in dbs:
1643
			if installed:
1656
			if installed:
1644
				continue
1657
				continue
Lines 1755-1761 Link Here
1755
			# since arguments are root nodes. Never traverse the same
1768
			# since arguments are root nodes. Never traverse the same
1756
			# package twice, in order to prevent an infinite loop.
1769
			# package twice, in order to prevent an infinite loop.
1757
			selected_parent = None
1770
			selected_parent = None
1758
			for parent in self.digraph.parent_nodes(node):
1771
			for parent in self._dynamic_config.digraph.parent_nodes(node):
1759
				if isinstance(parent, DependencyArg):
1772
				if isinstance(parent, DependencyArg):
1760
					msg.append('(dependency required by "%s" [argument])' % \
1773
					msg.append('(dependency required by "%s" [argument])' % \
1761
						(colorize('INFORM', str(parent))))
1774
						(colorize('INFORM', str(parent))))
Lines 1796-1802 Link Here
1796
				slot_available = False
1809
				slot_available = False
1797
				for other_db, other_type, other_built, \
1810
				for other_db, other_type, other_built, \
1798
					other_installed, other_keys in \
1811
					other_installed, other_keys in \
1799
					self._filtered_trees[root_config.root]["dbs"]:
1812
					self._dynamic_config._filtered_trees[root_config.root]["dbs"]:
1800
					try:
1813
					try:
1801
						if atom.slot == \
1814
						if atom.slot == \
1802
							other_db.aux_get(cpv, ["SLOT"])[0]:
1815
							other_db.aux_get(cpv, ["SLOT"])[0]:
Lines 1842-1860 Link Here
1842
1855
1843
	def _select_pkg_highest_available(self, root, atom, onlydeps=False):
1856
	def _select_pkg_highest_available(self, root, atom, onlydeps=False):
1844
		cache_key = (root, atom, onlydeps)
1857
		cache_key = (root, atom, onlydeps)
1845
		ret = self._highest_pkg_cache.get(cache_key)
1858
		ret = self._dynamic_config._highest_pkg_cache.get(cache_key)
1846
		if ret is not None:
1859
		if ret is not None:
1847
			pkg, existing = ret
1860
			pkg, existing = ret
1848
			if pkg and not existing:
1861
			if pkg and not existing:
1849
				existing = self._slot_pkg_map[root].get(pkg.slot_atom)
1862
				existing = self._dynamic_config._slot_pkg_map[root].get(pkg.slot_atom)
1850
				if existing and existing == pkg:
1863
				if existing and existing == pkg:
1851
					# Update the cache to reflect that the
1864
					# Update the cache to reflect that the
1852
					# package has been added to the graph.
1865
					# package has been added to the graph.
1853
					ret = pkg, pkg
1866
					ret = pkg, pkg
1854
					self._highest_pkg_cache[cache_key] = ret
1867
					self._dynamic_config._highest_pkg_cache[cache_key] = ret
1855
			return ret
1868
			return ret
1856
		ret = self._select_pkg_highest_available_imp(root, atom, onlydeps=onlydeps)
1869
		ret = self._select_pkg_highest_available_imp(root, atom, onlydeps=onlydeps)
1857
		self._highest_pkg_cache[cache_key] = ret
1870
		self._dynamic_config._highest_pkg_cache[cache_key] = ret
1858
		pkg, existing = ret
1871
		pkg, existing = ret
1859
		if pkg is not None:
1872
		if pkg is not None:
1860
			settings = pkg.root_config.settings
1873
			settings = pkg.root_config.settings
Lines 1864-1874 Link Here
1864
		return ret
1877
		return ret
1865
1878
1866
	def _select_pkg_highest_available_imp(self, root, atom, onlydeps=False):
1879
	def _select_pkg_highest_available_imp(self, root, atom, onlydeps=False):
1867
		root_config = self.roots[root]
1880
		root_config = self._frozen_config.roots[root]
1868
		pkgsettings = self.pkgsettings[root]
1881
		pkgsettings = self._frozen_config.pkgsettings[root]
1869
		dbs = self._filtered_trees[root]["dbs"]
1882
		dbs = self._dynamic_config._filtered_trees[root]["dbs"]
1870
		vardb = self.roots[root].trees["vartree"].dbapi
1883
		vardb = self._frozen_config.roots[root].trees["vartree"].dbapi
1871
		portdb = self.roots[root].trees["porttree"].dbapi
1884
		portdb = self._frozen_config.roots[root].trees["porttree"].dbapi
1872
		# List of acceptable packages, ordered by type preference.
1885
		# List of acceptable packages, ordered by type preference.
1873
		matched_packages = []
1886
		matched_packages = []
1874
		highest_version = None
1887
		highest_version = None
Lines 1877-1887 Link Here
1877
		atom_cp = atom.cp
1890
		atom_cp = atom.cp
1878
		existing_node = None
1891
		existing_node = None
1879
		myeb = None
1892
		myeb = None
1880
		usepkgonly = "--usepkgonly" in self.myopts
1893
		usepkgonly = "--usepkgonly" in self._frozen_config.myopts
1881
		empty = "empty" in self.myparams
1894
		empty = "empty" in self._dynamic_config.myparams
1882
		selective = "selective" in self.myparams
1895
		selective = "selective" in self._dynamic_config.myparams
1883
		reinstall = False
1896
		reinstall = False
1884
		noreplace = "--noreplace" in self.myopts
1897
		noreplace = "--noreplace" in self._frozen_config.myopts
1885
		# Behavior of the "selective" parameter depends on
1898
		# Behavior of the "selective" parameter depends on
1886
		# whether or not a package matches an argument atom.
1899
		# whether or not a package matches an argument atom.
1887
		# If an installed package provides an old-style
1900
		# If an installed package provides an old-style
Lines 1972-1978 Link Here
1972
					# above visibility checks are complete.
1985
					# above visibility checks are complete.
1973
1986
1974
					myarg = None
1987
					myarg = None
1975
					if root == self.target_root:
1988
					if root == self._frozen_config.target_root:
1976
						try:
1989
						try:
1977
							myarg = self._iter_atoms_for_pkg(pkg).next()
1990
							myarg = self._iter_atoms_for_pkg(pkg).next()
1978
						except StopIteration:
1991
						except StopIteration:
Lines 2001-2007 Link Here
2001
					# will always end with a break statement below
2014
					# will always end with a break statement below
2002
					# this point.
2015
					# this point.
2003
					if find_existing_node:
2016
					if find_existing_node:
2004
						e_pkg = self._slot_pkg_map[root].get(pkg.slot_atom)
2017
						e_pkg = self._dynamic_config._slot_pkg_map[root].get(pkg.slot_atom)
2005
						if not e_pkg:
2018
						if not e_pkg:
2006
							break
2019
							break
2007
						if portage.dep.match_from_list(atom, [e_pkg]):
2020
						if portage.dep.match_from_list(atom, [e_pkg]):
Lines 2020-2027 Link Here
2020
					# Compare built package to current config and
2033
					# Compare built package to current config and
2021
					# reject the built package if necessary.
2034
					# reject the built package if necessary.
2022
					if built and not installed and \
2035
					if built and not installed and \
2023
						("--newuse" in self.myopts or \
2036
						("--newuse" in self._frozen_config.myopts or \
2024
						"--reinstall" in self.myopts):
2037
						"--reinstall" in self._frozen_config.myopts):
2025
						iuses = pkg.iuse.all
2038
						iuses = pkg.iuse.all
2026
						old_use = pkg.use.enabled
2039
						old_use = pkg.use.enabled
2027
						if myeb:
2040
						if myeb:
Lines 2042-2049 Link Here
2042
					# Compare current config to installed package
2055
					# Compare current config to installed package
2043
					# and do not reinstall if possible.
2056
					# and do not reinstall if possible.
2044
					if not installed and \
2057
					if not installed and \
2045
						("--newuse" in self.myopts or \
2058
						("--newuse" in self._frozen_config.myopts or \
2046
						"--reinstall" in self.myopts) and \
2059
						"--reinstall" in self._frozen_config.myopts) and \
2047
						cpv in vardb.match(atom):
2060
						cpv in vardb.match(atom):
2048
						pkgsettings.setcpv(pkg)
2061
						pkgsettings.setcpv(pkg)
2049
						forced_flags = set()
2062
						forced_flags = set()
Lines 2064-2077 Link Here
2064
						myeb = pkg
2077
						myeb = pkg
2065
					matched_packages.append(pkg)
2078
					matched_packages.append(pkg)
2066
					if reinstall_for_flags:
2079
					if reinstall_for_flags:
2067
						self._reinstall_nodes[pkg] = \
2080
						self._dynamic_config._reinstall_nodes[pkg] = \
2068
							reinstall_for_flags
2081
							reinstall_for_flags
2069
					break
2082
					break
2070
2083
2071
		if not matched_packages:
2084
		if not matched_packages:
2072
			return None, None
2085
			return None, None
2073
2086
2074
		if "--debug" in self.myopts:
2087
		if "--debug" in self._frozen_config.myopts:
2075
			for pkg in matched_packages:
2088
			for pkg in matched_packages:
2076
				portage.writemsg("%s %s\n" % \
2089
				portage.writemsg("%s %s\n" % \
2077
					((pkg.type_name + ":").rjust(10), pkg.cpv), noiselevel=-1)
2090
					((pkg.type_name + ":").rjust(10), pkg.cpv), noiselevel=-1)
Lines 2110-2121 Link Here
2110
		those that are installed and have not been scheduled for
2123
		those that are installed and have not been scheduled for
2111
		replacement.
2124
		replacement.
2112
		"""
2125
		"""
2113
		graph_db = self._graph_trees[root]["porttree"].dbapi
2126
		graph_db = self._frozen_config._graph_trees[root]["porttree"].dbapi
2114
		matches = graph_db.match_pkgs(atom)
2127
		matches = graph_db.match_pkgs(atom)
2115
		if not matches:
2128
		if not matches:
2116
			return None, None
2129
			return None, None
2117
		pkg = matches[-1] # highest match
2130
		pkg = matches[-1] # highest match
2118
		in_graph = self._slot_pkg_map[root].get(pkg.slot_atom)
2131
		in_graph = self._dynamic_config._slot_pkg_map[root].get(pkg.slot_atom)
2119
		return pkg, in_graph
2132
		return pkg, in_graph
2120
2133
2121
	def _complete_graph(self):
2134
	def _complete_graph(self):
Lines 2130-2140 Link Here
2130
		Since this method can consume enough time to disturb users, it is
2143
		Since this method can consume enough time to disturb users, it is
2131
		currently only enabled by the --complete-graph option.
2144
		currently only enabled by the --complete-graph option.
2132
		"""
2145
		"""
2133
		if "--buildpkgonly" in self.myopts or \
2146
		if "--buildpkgonly" in self._frozen_config.myopts or \
2134
			"recurse" not in self.myparams:
2147
			"recurse" not in self._dynamic_config.myparams:
2135
			return 1
2148
			return 1
2136
2149
2137
		if "complete" not in self.myparams:
2150
		if "complete" not in self._dynamic_config.myparams:
2138
			# Skip this to avoid consuming enough time to disturb users.
2151
			# Skip this to avoid consuming enough time to disturb users.
2139
			return 1
2152
			return 1
2140
2153
Lines 2146-2167 Link Here
2146
		# accounted for.
2159
		# accounted for.
2147
		self._select_atoms = self._select_atoms_from_graph
2160
		self._select_atoms = self._select_atoms_from_graph
2148
		self._select_package = self._select_pkg_from_graph
2161
		self._select_package = self._select_pkg_from_graph
2149
		already_deep = "deep" in self.myparams
2162
		already_deep = "deep" in self._dynamic_config.myparams
2150
		if not already_deep:
2163
		if not already_deep:
2151
			self.myparams.add("deep")
2164
			self._dynamic_config.myparams.add("deep")
2152
2165
2153
		for root in self.roots:
2166
		for root in self._frozen_config.roots:
2154
			required_set_names = self._required_set_names.copy()
2167
			required_set_names = self._frozen_config._required_set_names.copy()
2155
			if root == self.target_root and \
2168
			if root == self._frozen_config.target_root and \
2156
				(already_deep or "empty" in self.myparams):
2169
				(already_deep or "empty" in self._dynamic_config.myparams):
2157
				required_set_names.difference_update(self._sets)
2170
				required_set_names.difference_update(self._dynamic_config._sets)
2158
			if not required_set_names and not self._ignored_deps:
2171
			if not required_set_names and not self._dynamic_config._ignored_deps:
2159
				continue
2172
				continue
2160
			root_config = self.roots[root]
2173
			root_config = self._frozen_config.roots[root]
2161
			setconfig = root_config.setconfig
2174
			setconfig = root_config.setconfig
2162
			args = []
2175
			args = []
2163
			# Reuse existing SetArg instances when available.
2176
			# Reuse existing SetArg instances when available.
2164
			for arg in self.digraph.root_nodes():
2177
			for arg in self._dynamic_config.digraph.root_nodes():
2165
				if not isinstance(arg, SetArg):
2178
				if not isinstance(arg, SetArg):
2166
					continue
2179
					continue
2167
				if arg.root_config != root_config:
2180
				if arg.root_config != root_config:
Lines 2179-2200 Link Here
2179
			vardb = root_config.trees["vartree"].dbapi
2192
			vardb = root_config.trees["vartree"].dbapi
2180
			for arg in args:
2193
			for arg in args:
2181
				for atom in arg.set:
2194
				for atom in arg.set:
2182
					self._dep_stack.append(
2195
					self._dynamic_config._dep_stack.append(
2183
						Dependency(atom=atom, root=root, parent=arg))
2196
						Dependency(atom=atom, root=root, parent=arg))
2184
			if self._ignored_deps:
2197
			if self._dynamic_config._ignored_deps:
2185
				self._dep_stack.extend(self._ignored_deps)
2198
				self._dynamic_config._dep_stack.extend(self._dynamic_config._ignored_deps)
2186
				self._ignored_deps = []
2199
				self._dynamic_config._ignored_deps = []
2187
			if not self._create_graph(allow_unsatisfied=True):
2200
			if not self._create_graph(allow_unsatisfied=True):
2188
				return 0
2201
				return 0
2189
			# Check the unsatisfied deps to see if any initially satisfied deps
2202
			# Check the unsatisfied deps to see if any initially satisfied deps
2190
			# will become unsatisfied due to an upgrade. Initially unsatisfied
2203
			# will become unsatisfied due to an upgrade. Initially unsatisfied
2191
			# deps are irrelevant since we only want to avoid breaking deps
2204
			# deps are irrelevant since we only want to avoid breaking deps
2192
			# that are initially satisfied.
2205
			# that are initially satisfied.
2193
			while self._unsatisfied_deps:
2206
			while self._dynamic_config._unsatisfied_deps:
2194
				dep = self._unsatisfied_deps.pop()
2207
				dep = self._dynamic_config._unsatisfied_deps.pop()
2195
				matches = vardb.match_pkgs(dep.atom)
2208
				matches = vardb.match_pkgs(dep.atom)
2196
				if not matches:
2209
				if not matches:
2197
					self._initially_unsatisfied_deps.append(dep)
2210
					self._dynamic_config._initially_unsatisfied_deps.append(dep)
2198
					continue
2211
					continue
2199
				# An scheduled installation broke a deep dependency.
2212
				# An scheduled installation broke a deep dependency.
2200
				# Add the installed package to the graph so that it
2213
				# Add the installed package to the graph so that it
Lines 2218-2234 Link Here
2218
		operation = "merge"
2231
		operation = "merge"
2219
		if installed or onlydeps:
2232
		if installed or onlydeps:
2220
			operation = "nomerge"
2233
			operation = "nomerge"
2221
		pkg = self._pkg_cache.get(
2234
		pkg = self._dynamic_config._pkg_cache.get(
2222
			(type_name, root_config.root, cpv, operation))
2235
			(type_name, root_config.root, cpv, operation))
2223
		if pkg is None and onlydeps and not installed:
2236
		if pkg is None and onlydeps and not installed:
2224
			# Maybe it already got pulled in as a "merge" node.
2237
			# Maybe it already got pulled in as a "merge" node.
2225
			pkg = self.mydbapi[root_config.root].get(
2238
			pkg = self._dynamic_config.mydbapi[root_config.root].get(
2226
				(type_name, root_config.root, cpv, 'merge'))
2239
				(type_name, root_config.root, cpv, 'merge'))
2227
2240
2228
		if pkg is None:
2241
		if pkg is None:
2229
			tree_type = self.pkg_tree_map[type_name]
2242
			tree_type = self.pkg_tree_map[type_name]
2230
			db = root_config.trees[tree_type].dbapi
2243
			db = root_config.trees[tree_type].dbapi
2231
			db_keys = list(self._trees_orig[root_config.root][
2244
			db_keys = list(self._frozen_config._trees_orig[root_config.root][
2232
				tree_type].dbapi._aux_cache_keys)
2245
				tree_type].dbapi._aux_cache_keys)
2233
			try:
2246
			try:
2234
				metadata = izip(db_keys, db.aux_get(cpv, db_keys))
2247
				metadata = izip(db_keys, db.aux_get(cpv, db_keys))
Lines 2237-2243 Link Here
2237
			pkg = Package(built=(type_name != "ebuild"), cpv=cpv,
2250
			pkg = Package(built=(type_name != "ebuild"), cpv=cpv,
2238
				installed=installed, metadata=metadata,
2251
				installed=installed, metadata=metadata,
2239
				root_config=root_config, type_name=type_name)
2252
				root_config=root_config, type_name=type_name)
2240
			self._pkg_cache[pkg] = pkg
2253
			self._dynamic_config._pkg_cache[pkg] = pkg
2241
		return pkg
2254
		return pkg
2242
2255
2243
	def _validate_blockers(self):
2256
	def _validate_blockers(self):
Lines 2246-2256 Link Here
2246
		correct merge order such that mutually blocking packages are never
2259
		correct merge order such that mutually blocking packages are never
2247
		installed simultaneously."""
2260
		installed simultaneously."""
2248
2261
2249
		if "--buildpkgonly" in self.myopts or \
2262
		if "--buildpkgonly" in self._frozen_config.myopts or \
2250
			"--nodeps" in self.myopts:
2263
			"--nodeps" in self._frozen_config.myopts:
2251
			return True
2264
			return True
2252
2265
2253
		#if "deep" in self.myparams:
2266
		#if "deep" in self._dynamic_config.myparams:
2254
		if True:
2267
		if True:
2255
			# Pull in blockers from all installed packages that haven't already
2268
			# Pull in blockers from all installed packages that haven't already
2256
			# been pulled into the depgraph.  This is not enabled by default
2269
			# been pulled into the depgraph.  This is not enabled by default
Lines 2258-2275 Link Here
2258
			# additional dep_check calls that are required.
2271
			# additional dep_check calls that are required.
2259
2272
2260
			dep_keys = ["DEPEND","RDEPEND","PDEPEND"]
2273
			dep_keys = ["DEPEND","RDEPEND","PDEPEND"]
2261
			for myroot in self.trees:
2274
			for myroot in self._frozen_config.trees:
2262
				vardb = self.trees[myroot]["vartree"].dbapi
2275
				vardb = self._frozen_config.trees[myroot]["vartree"].dbapi
2263
				portdb = self.trees[myroot]["porttree"].dbapi
2276
				portdb = self._frozen_config.trees[myroot]["porttree"].dbapi
2264
				pkgsettings = self.pkgsettings[myroot]
2277
				pkgsettings = self._frozen_config.pkgsettings[myroot]
2265
				final_db = self.mydbapi[myroot]
2278
				final_db = self._dynamic_config.mydbapi[myroot]
2266
2279
2267
				blocker_cache = BlockerCache(myroot, vardb)
2280
				blocker_cache = BlockerCache(myroot, vardb)
2268
				stale_cache = set(blocker_cache)
2281
				stale_cache = set(blocker_cache)
2269
				for pkg in vardb:
2282
				for pkg in vardb:
2270
					cpv = pkg.cpv
2283
					cpv = pkg.cpv
2271
					stale_cache.discard(cpv)
2284
					stale_cache.discard(cpv)
2272
					pkg_in_graph = self.digraph.contains(pkg)
2285
					pkg_in_graph = self._dynamic_config.digraph.contains(pkg)
2273
2286
2274
					# Check for masked installed packages. Only warn about
2287
					# Check for masked installed packages. Only warn about
2275
					# packages that are in the graph in order to avoid warning
2288
					# packages that are in the graph in order to avoid warning
Lines 2277-2283 Link Here
2277
					# the merge process or by --depclean.
2290
					# the merge process or by --depclean.
2278
					if pkg in final_db:
2291
					if pkg in final_db:
2279
						if pkg_in_graph and not visible(pkgsettings, pkg):
2292
						if pkg_in_graph and not visible(pkgsettings, pkg):
2280
							self._masked_installed.add(pkg)
2293
							self._dynamic_config._masked_installed.add(pkg)
2281
2294
2282
					blocker_atoms = None
2295
					blocker_atoms = None
2283
					blockers = None
2296
					blockers = None
Lines 2285-2296 Link Here
2285
						blockers = []
2298
						blockers = []
2286
						try:
2299
						try:
2287
							blockers.extend(
2300
							blockers.extend(
2288
								self._blocker_parents.child_nodes(pkg))
2301
								self._dynamic_config._blocker_parents.child_nodes(pkg))
2289
						except KeyError:
2302
						except KeyError:
2290
							pass
2303
							pass
2291
						try:
2304
						try:
2292
							blockers.extend(
2305
							blockers.extend(
2293
								self._irrelevant_blockers.child_nodes(pkg))
2306
								self._dynamic_config._irrelevant_blockers.child_nodes(pkg))
2294
						except KeyError:
2307
						except KeyError:
2295
							pass
2308
							pass
2296
					if blockers is not None:
2309
					if blockers is not None:
Lines 2299-2305 Link Here
2299
2312
2300
					# If this node has any blockers, create a "nomerge"
2313
					# If this node has any blockers, create a "nomerge"
2301
					# node for it so that they can be enforced.
2314
					# node for it so that they can be enforced.
2302
					self.spinner.update()
2315
					self._frozen_config.spinner.update()
2303
					blocker_data = blocker_cache.get(cpv)
2316
					blocker_data = blocker_cache.get(cpv)
2304
					if blocker_data is not None and \
2317
					if blocker_data is not None and \
2305
						blocker_data.counter != long(pkg.metadata["COUNTER"]):
2318
						blocker_data.counter != long(pkg.metadata["COUNTER"]):
Lines 2339-2345 Link Here
2339
							try:
2352
							try:
2340
								success, atoms = portage.dep_check(depstr,
2353
								success, atoms = portage.dep_check(depstr,
2341
									final_db, pkgsettings, myuse=pkg.use.enabled,
2354
									final_db, pkgsettings, myuse=pkg.use.enabled,
2342
									trees=self._graph_trees, myroot=myroot)
2355
									trees=self._frozen_config._graph_trees, myroot=myroot)
2343
							except Exception, e:
2356
							except Exception, e:
2344
								if isinstance(e, SystemExit):
2357
								if isinstance(e, SystemExit):
2345
									raise
2358
									raise
Lines 2375-2381 Link Here
2375
							for atom in blocker_atoms:
2388
							for atom in blocker_atoms:
2376
								blocker = Blocker(atom=portage.dep.Atom(atom),
2389
								blocker = Blocker(atom=portage.dep.Atom(atom),
2377
									eapi=pkg.metadata["EAPI"], root=myroot)
2390
									eapi=pkg.metadata["EAPI"], root=myroot)
2378
								self._blocker_parents.add(blocker, pkg)
2391
								self._dynamic_config._blocker_parents.add(blocker, pkg)
2379
						except portage.exception.InvalidAtom, e:
2392
						except portage.exception.InvalidAtom, e:
2380
							depstr = " ".join(vardb.aux_get(pkg.cpv, dep_keys))
2393
							depstr = " ".join(vardb.aux_get(pkg.cpv, dep_keys))
2381
							show_invalid_depstring_notice(
2394
							show_invalid_depstring_notice(
Lines 2389-2406 Link Here
2389
		# Discard any "uninstall" tasks scheduled by previous calls
2402
		# Discard any "uninstall" tasks scheduled by previous calls
2390
		# to this method, since those tasks may not make sense given
2403
		# to this method, since those tasks may not make sense given
2391
		# the current graph state.
2404
		# the current graph state.
2392
		previous_uninstall_tasks = self._blocker_uninstalls.leaf_nodes()
2405
		previous_uninstall_tasks = self._dynamic_config._blocker_uninstalls.leaf_nodes()
2393
		if previous_uninstall_tasks:
2406
		if previous_uninstall_tasks:
2394
			self._blocker_uninstalls = digraph()
2407
			self._dynamic_config._blocker_uninstalls = digraph()
2395
			self.digraph.difference_update(previous_uninstall_tasks)
2408
			self._dynamic_config.digraph.difference_update(previous_uninstall_tasks)
2396
2409
2397
		for blocker in self._blocker_parents.leaf_nodes():
2410
		for blocker in self._dynamic_config._blocker_parents.leaf_nodes():
2398
			self.spinner.update()
2411
			self._frozen_config.spinner.update()
2399
			root_config = self.roots[blocker.root]
2412
			root_config = self._frozen_config.roots[blocker.root]
2400
			virtuals = root_config.settings.getvirtuals()
2413
			virtuals = root_config.settings.getvirtuals()
2401
			myroot = blocker.root
2414
			myroot = blocker.root
2402
			initial_db = self.trees[myroot]["vartree"].dbapi
2415
			initial_db = self._frozen_config.trees[myroot]["vartree"].dbapi
2403
			final_db = self.mydbapi[myroot]
2416
			final_db = self._dynamic_config.mydbapi[myroot]
2404
			
2417
			
2405
			provider_virtual = False
2418
			provider_virtual = False
2406
			if blocker.cp in virtuals and \
2419
			if blocker.cp in virtuals and \
Lines 2435-2449 Link Here
2435
						blocked_final.add(pkg)
2448
						blocked_final.add(pkg)
2436
2449
2437
			if not blocked_initial and not blocked_final:
2450
			if not blocked_initial and not blocked_final:
2438
				parent_pkgs = self._blocker_parents.parent_nodes(blocker)
2451
				parent_pkgs = self._dynamic_config._blocker_parents.parent_nodes(blocker)
2439
				self._blocker_parents.remove(blocker)
2452
				self._dynamic_config._blocker_parents.remove(blocker)
2440
				# Discard any parents that don't have any more blockers.
2453
				# Discard any parents that don't have any more blockers.
2441
				for pkg in parent_pkgs:
2454
				for pkg in parent_pkgs:
2442
					self._irrelevant_blockers.add(blocker, pkg)
2455
					self._dynamic_config._irrelevant_blockers.add(blocker, pkg)
2443
					if not self._blocker_parents.child_nodes(pkg):
2456
					if not self._dynamic_config._blocker_parents.child_nodes(pkg):
2444
						self._blocker_parents.remove(pkg)
2457
						self._dynamic_config._blocker_parents.remove(pkg)
2445
				continue
2458
				continue
2446
			for parent in self._blocker_parents.parent_nodes(blocker):
2459
			for parent in self._dynamic_config._blocker_parents.parent_nodes(blocker):
2447
				unresolved_blocks = False
2460
				unresolved_blocks = False
2448
				depends_on_order = set()
2461
				depends_on_order = set()
2449
				for pkg in blocked_initial:
2462
				for pkg in blocked_initial:
Lines 2462-2468 Link Here
2462
						# confuse users if displayed like a normal blocker.
2475
						# confuse users if displayed like a normal blocker.
2463
						continue
2476
						continue
2464
2477
2465
					self._blocked_pkgs.add(pkg, blocker)
2478
					self._dynamic_config._blocked_pkgs.add(pkg, blocker)
2466
2479
2467
					if parent.operation == "merge":
2480
					if parent.operation == "merge":
2468
						# Maybe the blocked package can be replaced or simply
2481
						# Maybe the blocked package can be replaced or simply
Lines 2487-2493 Link Here
2487
						# merge of either package is triggered.
2500
						# merge of either package is triggered.
2488
						continue
2501
						continue
2489
2502
2490
					self._blocked_pkgs.add(pkg, blocker)
2503
					self._dynamic_config._blocked_pkgs.add(pkg, blocker)
2491
2504
2492
					# Maybe the blocking package can be
2505
					# Maybe the blocking package can be
2493
					# unmerged to resolve this block.
2506
					# unmerged to resolve this block.
Lines 2505-2512 Link Here
2505
				# into the graph.
2518
				# into the graph.
2506
				if not unresolved_blocks and depends_on_order:
2519
				if not unresolved_blocks and depends_on_order:
2507
					for inst_pkg, inst_task in depends_on_order:
2520
					for inst_pkg, inst_task in depends_on_order:
2508
						if self.digraph.contains(inst_pkg) and \
2521
						if self._dynamic_config.digraph.contains(inst_pkg) and \
2509
							self.digraph.parent_nodes(inst_pkg):
2522
							self._dynamic_config.digraph.parent_nodes(inst_pkg):
2510
							unresolved_blocks = True
2523
							unresolved_blocks = True
2511
							break
2524
							break
2512
2525
Lines 2518-2540 Link Here
2518
							operation="uninstall",
2531
							operation="uninstall",
2519
							root_config=inst_pkg.root_config,
2532
							root_config=inst_pkg.root_config,
2520
							type_name=inst_pkg.type_name)
2533
							type_name=inst_pkg.type_name)
2521
						self._pkg_cache[uninst_task] = uninst_task
2534
						self._dynamic_config._pkg_cache[uninst_task] = uninst_task
2522
						# Enforce correct merge order with a hard dep.
2535
						# Enforce correct merge order with a hard dep.
2523
						self.digraph.addnode(uninst_task, inst_task,
2536
						self._dynamic_config.digraph.addnode(uninst_task, inst_task,
2524
							priority=BlockerDepPriority.instance)
2537
							priority=BlockerDepPriority.instance)
2525
						# Count references to this blocker so that it can be
2538
						# Count references to this blocker so that it can be
2526
						# invalidated after nodes referencing it have been
2539
						# invalidated after nodes referencing it have been
2527
						# merged.
2540
						# merged.
2528
						self._blocker_uninstalls.addnode(uninst_task, blocker)
2541
						self._dynamic_config._blocker_uninstalls.addnode(uninst_task, blocker)
2529
				if not unresolved_blocks and not depends_on_order:
2542
				if not unresolved_blocks and not depends_on_order:
2530
					self._irrelevant_blockers.add(blocker, parent)
2543
					self._dynamic_config._irrelevant_blockers.add(blocker, parent)
2531
					self._blocker_parents.remove_edge(blocker, parent)
2544
					self._dynamic_config._blocker_parents.remove_edge(blocker, parent)
2532
					if not self._blocker_parents.parent_nodes(blocker):
2545
					if not self._dynamic_config._blocker_parents.parent_nodes(blocker):
2533
						self._blocker_parents.remove(blocker)
2546
						self._dynamic_config._blocker_parents.remove(blocker)
2534
					if not self._blocker_parents.child_nodes(parent):
2547
					if not self._dynamic_config._blocker_parents.child_nodes(parent):
2535
						self._blocker_parents.remove(parent)
2548
						self._dynamic_config._blocker_parents.remove(parent)
2536
				if unresolved_blocks:
2549
				if unresolved_blocks:
2537
					self._unsolvable_blockers.add(blocker, parent)
2550
					self._dynamic_config._unsolvable_blockers.add(blocker, parent)
2538
2551
2539
		return True
2552
		return True
2540
2553
Lines 2542-2548 Link Here
2542
		acceptable = False
2555
		acceptable = False
2543
		for x in ("--buildpkgonly", "--fetchonly",
2556
		for x in ("--buildpkgonly", "--fetchonly",
2544
			"--fetch-all-uri", "--nodeps"):
2557
			"--fetch-all-uri", "--nodeps"):
2545
			if x in self.myopts:
2558
			if x in self._frozen_config.myopts:
2546
				acceptable = True
2559
				acceptable = True
2547
				break
2560
				break
2548
		return acceptable
2561
		return acceptable
Lines 2583-2597 Link Here
2583
2596
2584
	def altlist(self, reversed=False):
2597
	def altlist(self, reversed=False):
2585
2598
2586
		while self._serialized_tasks_cache is None:
2599
		while self._dynamic_config._serialized_tasks_cache is None:
2587
			self._resolve_conflicts()
2600
			self._resolve_conflicts()
2588
			try:
2601
			try:
2589
				self._serialized_tasks_cache, self._scheduler_graph = \
2602
				self._dynamic_config._serialized_tasks_cache, self._dynamic_config._scheduler_graph = \
2590
					self._serialize_tasks()
2603
					self._serialize_tasks()
2591
			except self._serialize_tasks_retry:
2604
			except self._serialize_tasks_retry:
2592
				pass
2605
				pass
2593
2606
2594
		retlist = self._serialized_tasks_cache[:]
2607
		retlist = self._dynamic_config._serialized_tasks_cache[:]
2595
		if reversed:
2608
		if reversed:
2596
			retlist.reverse()
2609
			retlist.reverse()
2597
		return retlist
2610
		return retlist
Lines 2610-2619 Link Here
2610
		internal Package instances such that this depgraph instance should
2623
		internal Package instances such that this depgraph instance should
2611
		not be used to perform any more calculations.
2624
		not be used to perform any more calculations.
2612
		"""
2625
		"""
2613
		if self._scheduler_graph is None:
2626
		if self._dynamic_config._scheduler_graph is None:
2614
			self.altlist()
2627
			self.altlist()
2615
		self.break_refs(self._scheduler_graph.order)
2628
		self.break_refs(self._dynamic_config._scheduler_graph.order)
2616
		return self._scheduler_graph
2629
		return self._dynamic_config._scheduler_graph
2617
2630
2618
	def break_refs(self, nodes):
2631
	def break_refs(self, nodes):
2619
		"""
2632
		"""
Lines 2631-2637 Link Here
2631
				# original RootConfig instance which references the actual
2644
				# original RootConfig instance which references the actual
2632
				# vartree.
2645
				# vartree.
2633
				node.root_config = \
2646
				node.root_config = \
2634
					self._trees_orig[node.root_config.root]["root_config"]
2647
					self._frozen_config._trees_orig[node.root_config.root]["root_config"]
2635
2648
2636
	def _resolve_conflicts(self):
2649
	def _resolve_conflicts(self):
2637
		if not self._complete_graph():
2650
		if not self._complete_graph():
Lines 2640-2664 Link Here
2640
		if not self._validate_blockers():
2653
		if not self._validate_blockers():
2641
			raise self._unknown_internal_error()
2654
			raise self._unknown_internal_error()
2642
2655
2643
		if self._slot_collision_info:
2656
		if self._dynamic_config._slot_collision_info:
2644
			self._process_slot_conflicts()
2657
			self._process_slot_conflicts()
2645
2658
2646
	def _serialize_tasks(self):
2659
	def _serialize_tasks(self):
2647
2660
2648
		if "--debug" in self.myopts:
2661
		if "--debug" in self._frozen_config.myopts:
2649
			writemsg("\ndigraph:\n\n", noiselevel=-1)
2662
			writemsg("\ndigraph:\n\n", noiselevel=-1)
2650
			self.digraph.debug_print()
2663
			self._dynamic_config.digraph.debug_print()
2651
			writemsg("\n", noiselevel=-1)
2664
			writemsg("\n", noiselevel=-1)
2652
2665
2653
		scheduler_graph = self.digraph.copy()
2666
		scheduler_graph = self._dynamic_config.digraph.copy()
2654
2667
2655
		if '--nodeps' in self.myopts:
2668
		if '--nodeps' in self._frozen_config.myopts:
2656
			# Preserve the package order given on the command line.
2669
			# Preserve the package order given on the command line.
2657
			return ([node for node in scheduler_graph \
2670
			return ([node for node in scheduler_graph \
2658
				if isinstance(node, Package) \
2671
				if isinstance(node, Package) \
2659
				and node.operation == 'merge'], scheduler_graph)
2672
				and node.operation == 'merge'], scheduler_graph)
2660
2673
2661
		mygraph=self.digraph.copy()
2674
		mygraph=self._dynamic_config.digraph.copy()
2662
		# Prune "nomerge" root nodes if nothing depends on them, since
2675
		# Prune "nomerge" root nodes if nothing depends on them, since
2663
		# otherwise they slow down merge order calculation. Don't remove
2676
		# otherwise they slow down merge order calculation. Don't remove
2664
		# non-root nodes since they help optimize merge order in some cases
2677
		# non-root nodes since they help optimize merge order in some cases
Lines 2670-2676 Link Here
2670
					node.installed or node.onlydeps:
2683
					node.installed or node.onlydeps:
2671
					removed_nodes.add(node)
2684
					removed_nodes.add(node)
2672
			if removed_nodes:
2685
			if removed_nodes:
2673
				self.spinner.update()
2686
				self._frozen_config.spinner.update()
2674
				mygraph.difference_update(removed_nodes)
2687
				mygraph.difference_update(removed_nodes)
2675
			if not removed_nodes:
2688
			if not removed_nodes:
2676
				break
2689
				break
Lines 2691-2697 Link Here
2691
			elif n1_n2_medium:
2704
			elif n1_n2_medium:
2692
				return 1
2705
				return 1
2693
			return -1
2706
			return -1
2694
		myblocker_uninstalls = self._blocker_uninstalls.copy()
2707
		myblocker_uninstalls = self._dynamic_config._blocker_uninstalls.copy()
2695
		retlist=[]
2708
		retlist=[]
2696
		# Contains uninstall tasks that have been scheduled to
2709
		# Contains uninstall tasks that have been scheduled to
2697
		# occur after overlapping blockers have been installed.
2710
		# occur after overlapping blockers have been installed.
Lines 2702-2708 Link Here
2702
		# resolved.
2715
		# resolved.
2703
		ignored_uninstall_tasks = set()
2716
		ignored_uninstall_tasks = set()
2704
		have_uninstall_task = False
2717
		have_uninstall_task = False
2705
		complete = "complete" in self.myparams
2718
		complete = "complete" in self._dynamic_config.myparams
2706
		asap_nodes = []
2719
		asap_nodes = []
2707
2720
2708
		def get_nodes(**kwargs):
2721
		def get_nodes(**kwargs):
Lines 2716-2728 Link Here
2716
					node in scheduled_uninstalls)]
2729
					node in scheduled_uninstalls)]
2717
2730
2718
		# sys-apps/portage needs special treatment if ROOT="/"
2731
		# sys-apps/portage needs special treatment if ROOT="/"
2719
		running_root = self._running_root.root
2732
		running_root = self._frozen_config._running_root.root
2720
		from portage.const import PORTAGE_PACKAGE_ATOM
2733
		from portage.const import PORTAGE_PACKAGE_ATOM
2721
		runtime_deps = InternalPackageSet(
2734
		runtime_deps = InternalPackageSet(
2722
			initial_atoms=[PORTAGE_PACKAGE_ATOM])
2735
			initial_atoms=[PORTAGE_PACKAGE_ATOM])
2723
		running_portage = self.trees[running_root]["vartree"].dbapi.match_pkgs(
2736
		running_portage = self._frozen_config.trees[running_root]["vartree"].dbapi.match_pkgs(
2724
			PORTAGE_PACKAGE_ATOM)
2737
			PORTAGE_PACKAGE_ATOM)
2725
		replacement_portage = self.mydbapi[running_root].match_pkgs(
2738
		replacement_portage = self._dynamic_config.mydbapi[running_root].match_pkgs(
2726
			PORTAGE_PACKAGE_ATOM)
2739
			PORTAGE_PACKAGE_ATOM)
2727
2740
2728
		if running_portage:
2741
		if running_portage:
Lines 2792-2798 Link Here
2792
				return True
2805
				return True
2793
			return priority_range.ignore_medium_soft(priority)
2806
			return priority_range.ignore_medium_soft(priority)
2794
2807
2795
		tree_mode = "--tree" in self.myopts
2808
		tree_mode = "--tree" in self._frozen_config.myopts
2796
		# Tracks whether or not the current iteration should prefer asap_nodes
2809
		# Tracks whether or not the current iteration should prefer asap_nodes
2797
		# if available.  This is set to False when the previous iteration
2810
		# if available.  This is set to False when the previous iteration
2798
		# failed to select any nodes.  It is reset whenever nodes are
2811
		# failed to select any nodes.  It is reset whenever nodes are
Lines 2818-2824 Link Here
2818
		# unresolved blockers or circular dependencies.
2831
		# unresolved blockers or circular dependencies.
2819
2832
2820
		while not mygraph.empty():
2833
		while not mygraph.empty():
2821
			self.spinner.update()
2834
			self._frozen_config.spinner.update()
2822
			selected_nodes = None
2835
			selected_nodes = None
2823
			ignore_priority = None
2836
			ignore_priority = None
2824
			if drop_satisfied or (prefer_asap and asap_nodes):
2837
			if drop_satisfied or (prefer_asap and asap_nodes):
Lines 2855-2861 Link Here
2855
							with_some_uninstalls_excluded = []
2868
							with_some_uninstalls_excluded = []
2856
							for node in nodes:
2869
							for node in nodes:
2857
								if node.operation == "uninstall":
2870
								if node.operation == "uninstall":
2858
									slot_node = self.mydbapi[node.root
2871
									slot_node = self._dynamic_config.mydbapi[node.root
2859
										].match_pkgs(node.slot_atom)
2872
										].match_pkgs(node.slot_atom)
2860
									if slot_node and \
2873
									if slot_node and \
2861
										slot_node[0].operation == "merge":
2874
										slot_node[0].operation == "merge":
Lines 2971-2981 Link Here
2971
						# on installation of blocking packages.
2984
						# on installation of blocking packages.
2972
						continue
2985
						continue
2973
2986
2974
					root_config = self.roots[task.root]
2987
					root_config = self._frozen_config.roots[task.root]
2975
					inst_pkg = self._pkg_cache[
2988
					inst_pkg = self._dynamic_config._pkg_cache[
2976
						("installed", task.root, task.cpv, "nomerge")]
2989
						("installed", task.root, task.cpv, "nomerge")]
2977
2990
2978
					if self.digraph.contains(inst_pkg):
2991
					if self._dynamic_config.digraph.contains(inst_pkg):
2979
						continue
2992
						continue
2980
2993
2981
					forbid_overlap = False
2994
					forbid_overlap = False
Lines 3050-3056 Link Here
3050
						# For packages in the world set, go ahead an uninstall
3063
						# For packages in the world set, go ahead an uninstall
3051
						# when necessary, as long as the atom will be satisfied
3064
						# when necessary, as long as the atom will be satisfied
3052
						# in the final state.
3065
						# in the final state.
3053
						graph_db = self.mydbapi[task.root]
3066
						graph_db = self._dynamic_config.mydbapi[task.root]
3054
						skip = False
3067
						skip = False
3055
						try:
3068
						try:
3056
							for atom in root_config.sets[
3069
							for atom in root_config.sets[
Lines 3063-3069 Link Here
3063
									break
3076
									break
3064
								if not satisfied:
3077
								if not satisfied:
3065
									skip = True
3078
									skip = True
3066
									self._blocked_world_pkgs[inst_pkg] = atom
3079
									self._dynamic_config._blocked_world_pkgs[inst_pkg] = atom
3067
									break
3080
									break
3068
						except portage.exception.InvalidDependString, e:
3081
						except portage.exception.InvalidDependString, e:
3069
							portage.writemsg("!!! Invalid PROVIDE in " + \
3082
							portage.writemsg("!!! Invalid PROVIDE in " + \
Lines 3158-3164 Link Here
3158
					continue
3171
					continue
3159
3172
3160
			if not selected_nodes:
3173
			if not selected_nodes:
3161
				self._circular_deps_for_display = mygraph
3174
				self._dynamic_config._circular_deps_for_display = mygraph
3162
				raise self._unknown_internal_error()
3175
				raise self._unknown_internal_error()
3163
3176
3164
			# At this point, we've succeeded in selecting one or more nodes, so
3177
			# At this point, we've succeeded in selecting one or more nodes, so
Lines 3182-3188 Link Here
3182
					have_uninstall_task = True
3195
					have_uninstall_task = True
3183
					uninst_task = node
3196
					uninst_task = node
3184
				else:
3197
				else:
3185
					vardb = self.trees[node.root]["vartree"].dbapi
3198
					vardb = self._frozen_config.trees[node.root]["vartree"].dbapi
3186
					previous_cpv = vardb.match(node.slot_atom)
3199
					previous_cpv = vardb.match(node.slot_atom)
3187
					if previous_cpv:
3200
					if previous_cpv:
3188
						# The package will be replaced by this one, so remove
3201
						# The package will be replaced by this one, so remove
Lines 3221-3227 Link Here
3221
							root=blocker.root, eapi=blocker.eapi,
3234
							root=blocker.root, eapi=blocker.eapi,
3222
							satisfied=True))
3235
							satisfied=True))
3223
3236
3224
		unsolvable_blockers = set(self._unsolvable_blockers.leaf_nodes())
3237
		unsolvable_blockers = set(self._dynamic_config._unsolvable_blockers.leaf_nodes())
3225
		for node in myblocker_uninstalls.root_nodes():
3238
		for node in myblocker_uninstalls.root_nodes():
3226
			unsolvable_blockers.add(node)
3239
			unsolvable_blockers.add(node)
3227
3240
Lines 3236-3255 Link Here
3236
		if have_uninstall_task and \
3249
		if have_uninstall_task and \
3237
			not complete and \
3250
			not complete and \
3238
			not unsolvable_blockers:
3251
			not unsolvable_blockers:
3239
			self.myparams.add("complete")
3252
			self._dynamic_config.myparams.add("complete")
3240
			raise self._serialize_tasks_retry("")
3253
			raise self._serialize_tasks_retry("")
3241
3254
3242
		if unsolvable_blockers and \
3255
		if unsolvable_blockers and \
3243
			not self._accept_blocker_conflicts():
3256
			not self._accept_blocker_conflicts():
3244
			self._unsatisfied_blockers_for_display = unsolvable_blockers
3257
			self._dynamic_config._unsatisfied_blockers_for_display = unsolvable_blockers
3245
			self._serialized_tasks_cache = retlist[:]
3258
			self._dynamic_config._serialized_tasks_cache = retlist[:]
3246
			self._scheduler_graph = scheduler_graph
3259
			self._dynamic_config._scheduler_graph = scheduler_graph
3247
			raise self._unknown_internal_error()
3260
			raise self._unknown_internal_error()
3248
3261
3249
		if self._slot_collision_info and \
3262
		if self._dynamic_config._slot_collision_info and \
3250
			not self._accept_blocker_conflicts():
3263
			not self._accept_blocker_conflicts():
3251
			self._serialized_tasks_cache = retlist[:]
3264
			self._dynamic_config._serialized_tasks_cache = retlist[:]
3252
			self._scheduler_graph = scheduler_graph
3265
			self._dynamic_config._scheduler_graph = scheduler_graph
3253
			raise self._unknown_internal_error()
3266
			raise self._unknown_internal_error()
3254
3267
3255
		return retlist, scheduler_graph
3268
		return retlist, scheduler_graph
Lines 3279-3287 Link Here
3279
			display_order.append(node)
3292
			display_order.append(node)
3280
			tempgraph.remove(node)
3293
			tempgraph.remove(node)
3281
		display_order.reverse()
3294
		display_order.reverse()
3282
		self.myopts.pop("--quiet", None)
3295
		self._frozen_config.myopts.pop("--quiet", None)
3283
		self.myopts.pop("--verbose", None)
3296
		self._frozen_config.myopts.pop("--verbose", None)
3284
		self.myopts["--tree"] = True
3297
		self._frozen_config.myopts["--tree"] = True
3285
		portage.writemsg("\n\n", noiselevel=-1)
3298
		portage.writemsg("\n\n", noiselevel=-1)
3286
		self.display(display_order)
3299
		self.display(display_order)
3287
		prefix = colorize("BAD", " * ")
3300
		prefix = colorize("BAD", " * ")
Lines 3297-3309 Link Here
3297
			"optional dependencies.\n", noiselevel=-1)
3310
			"optional dependencies.\n", noiselevel=-1)
3298
3311
3299
	def _show_merge_list(self):
3312
	def _show_merge_list(self):
3300
		if self._serialized_tasks_cache is not None and \
3313
		if self._dynamic_config._serialized_tasks_cache is not None and \
3301
			not (self._displayed_list and \
3314
			not (self._dynamic_config._displayed_list and \
3302
			(self._displayed_list == self._serialized_tasks_cache or \
3315
			(self._dynamic_config._displayed_list == self._dynamic_config._serialized_tasks_cache or \
3303
			self._displayed_list == \
3316
			self._dynamic_config._displayed_list == \
3304
				list(reversed(self._serialized_tasks_cache)))):
3317
				list(reversed(self._dynamic_config._serialized_tasks_cache)))):
3305
			display_list = self._serialized_tasks_cache[:]
3318
			display_list = self._dynamic_config._serialized_tasks_cache[:]
3306
			if "--tree" in self.myopts:
3319
			if "--tree" in self._frozen_config.myopts:
3307
				display_list.reverse()
3320
				display_list.reverse()
3308
			self.display(display_list)
3321
			self.display(display_list)
3309
3322
Lines 3326-3336 Link Here
3326
3339
3327
		conflict_pkgs = {}
3340
		conflict_pkgs = {}
3328
		for blocker in blockers:
3341
		for blocker in blockers:
3329
			for pkg in chain(self._blocked_pkgs.child_nodes(blocker), \
3342
			for pkg in chain(self._dynamic_config._blocked_pkgs.child_nodes(blocker), \
3330
				self._blocker_parents.parent_nodes(blocker)):
3343
				self._dynamic_config._blocker_parents.parent_nodes(blocker)):
3331
				parent_atoms = self._parent_atoms.get(pkg)
3344
				parent_atoms = self._dynamic_config._parent_atoms.get(pkg)
3332
				if not parent_atoms:
3345
				if not parent_atoms:
3333
					atom = self._blocked_world_pkgs.get(pkg)
3346
					atom = self._dynamic_config._blocked_world_pkgs.get(pkg)
3334
					if atom is not None:
3347
					if atom is not None:
3335
						parent_atoms = set([("@world", atom)])
3348
						parent_atoms = set([("@world", atom)])
3336
				if parent_atoms:
3349
				if parent_atoms:
Lines 3400-3406 Link Here
3400
			sys.stderr.write("".join(msg))
3413
			sys.stderr.write("".join(msg))
3401
			sys.stderr.flush()
3414
			sys.stderr.flush()
3402
3415
3403
		if "--quiet" not in self.myopts:
3416
		if "--quiet" not in self._frozen_config.myopts:
3404
			show_blocker_docs_link()
3417
			show_blocker_docs_link()
3405
3418
3406
	def display(self, mylist, favorites=[], verbosity=None):
3419
	def display(self, mylist, favorites=[], verbosity=None):
Lines 3408-3437 Link Here
3408
		# This is used to prevent display_problems() from
3421
		# This is used to prevent display_problems() from
3409
		# redundantly displaying this exact same merge list
3422
		# redundantly displaying this exact same merge list
3410
		# again via _show_merge_list().
3423
		# again via _show_merge_list().
3411
		self._displayed_list = mylist
3424
		self._dynamic_config._displayed_list = mylist
3412
3425
3413
		if verbosity is None:
3426
		if verbosity is None:
3414
			verbosity = ("--quiet" in self.myopts and 1 or \
3427
			verbosity = ("--quiet" in self._frozen_config.myopts and 1 or \
3415
				"--verbose" in self.myopts and 3 or 2)
3428
				"--verbose" in self._frozen_config.myopts and 3 or 2)
3416
		favorites_set = InternalPackageSet(favorites)
3429
		favorites_set = InternalPackageSet(favorites)
3417
		oneshot = "--oneshot" in self.myopts or \
3430
		oneshot = "--oneshot" in self._frozen_config.myopts or \
3418
			"--onlydeps" in self.myopts
3431
			"--onlydeps" in self._frozen_config.myopts
3419
		columns = "--columns" in self.myopts
3432
		columns = "--columns" in self._frozen_config.myopts
3420
		changelogs=[]
3433
		changelogs=[]
3421
		p=[]
3434
		p=[]
3422
		blockers = []
3435
		blockers = []
3423
3436
3424
		counters = PackageCounters()
3437
		counters = PackageCounters()
3425
3438
3426
		if verbosity == 1 and "--verbose" not in self.myopts:
3439
		if verbosity == 1 and "--verbose" not in self._frozen_config.myopts:
3427
			def create_use_string(*args):
3440
			def create_use_string(*args):
3428
				return ""
3441
				return ""
3429
		else:
3442
		else:
3430
			def create_use_string(name, cur_iuse, iuse_forced, cur_use,
3443
			def create_use_string(name, cur_iuse, iuse_forced, cur_use,
3431
				old_iuse, old_use,
3444
				old_iuse, old_use,
3432
				is_new, reinst_flags,
3445
				is_new, reinst_flags,
3433
				all_flags=(verbosity == 3 or "--quiet" in self.myopts),
3446
				all_flags=(verbosity == 3 or "--quiet" in self._frozen_config.myopts),
3434
				alphabetical=("--alphabetical" in self.myopts)):
3447
				alphabetical=("--alphabetical" in self._frozen_config.myopts)):
3435
				enabled = []
3448
				enabled = []
3436
				if alphabetical:
3449
				if alphabetical:
3437
					disabled = enabled
3450
					disabled = enabled
Lines 3493-3503 Link Here
3493
					ret = '%s="%s" ' % (name, ret)
3506
					ret = '%s="%s" ' % (name, ret)
3494
				return ret
3507
				return ret
3495
3508
3496
		repo_display = RepoDisplay(self.roots)
3509
		repo_display = RepoDisplay(self._frozen_config.roots)
3497
3510
3498
		tree_nodes = []
3511
		tree_nodes = []
3499
		display_list = []
3512
		display_list = []
3500
		mygraph = self.digraph.copy()
3513
		mygraph = self._dynamic_config.digraph.copy()
3501
3514
3502
		# If there are any Uninstall instances, add the corresponding
3515
		# If there are any Uninstall instances, add the corresponding
3503
		# blockers to the digraph (useful for --tree display).
3516
		# blockers to the digraph (useful for --tree display).
Lines 3505-3519 Link Here
3505
		executed_uninstalls = set(node for node in mylist \
3518
		executed_uninstalls = set(node for node in mylist \
3506
			if isinstance(node, Package) and node.operation == "unmerge")
3519
			if isinstance(node, Package) and node.operation == "unmerge")
3507
3520
3508
		for uninstall in self._blocker_uninstalls.leaf_nodes():
3521
		for uninstall in self._dynamic_config._blocker_uninstalls.leaf_nodes():
3509
			uninstall_parents = \
3522
			uninstall_parents = \
3510
				self._blocker_uninstalls.parent_nodes(uninstall)
3523
				self._dynamic_config._blocker_uninstalls.parent_nodes(uninstall)
3511
			if not uninstall_parents:
3524
			if not uninstall_parents:
3512
				continue
3525
				continue
3513
3526
3514
			# Remove the corresponding "nomerge" node and substitute
3527
			# Remove the corresponding "nomerge" node and substitute
3515
			# the Uninstall node.
3528
			# the Uninstall node.
3516
			inst_pkg = self._pkg_cache[
3529
			inst_pkg = self._dynamic_config._pkg_cache[
3517
				("installed", uninstall.root, uninstall.cpv, "nomerge")]
3530
				("installed", uninstall.root, uninstall.cpv, "nomerge")]
3518
			try:
3531
			try:
3519
				mygraph.remove(inst_pkg)
3532
				mygraph.remove(inst_pkg)
Lines 3521-3527 Link Here
3521
				pass
3534
				pass
3522
3535
3523
			try:
3536
			try:
3524
				inst_pkg_blockers = self._blocker_parents.child_nodes(inst_pkg)
3537
				inst_pkg_blockers = self._dynamic_config._blocker_parents.child_nodes(inst_pkg)
3525
			except KeyError:
3538
			except KeyError:
3526
				inst_pkg_blockers = []
3539
				inst_pkg_blockers = []
3527
3540
Lines 3537-3543 Link Here
3537
			# Package -> Blocker -> Uninstall edges.
3550
			# Package -> Blocker -> Uninstall edges.
3538
			for blocker in uninstall_parents:
3551
			for blocker in uninstall_parents:
3539
				mygraph.add(uninstall, blocker)
3552
				mygraph.add(uninstall, blocker)
3540
				for parent in self._blocker_parents.parent_nodes(blocker):
3553
				for parent in self._dynamic_config._blocker_parents.parent_nodes(blocker):
3541
					if parent != inst_pkg:
3554
					if parent != inst_pkg:
3542
						mygraph.add(blocker, parent)
3555
						mygraph.add(blocker, parent)
3543
3556
Lines 3545-3551 Link Here
3545
			# of an upgrade, display Blocker -> Upgrade edges since the
3558
			# of an upgrade, display Blocker -> Upgrade edges since the
3546
			# corresponding Blocker -> Uninstall edges will not be shown.
3559
			# corresponding Blocker -> Uninstall edges will not be shown.
3547
			upgrade_node = \
3560
			upgrade_node = \
3548
				self._slot_pkg_map[uninstall.root].get(uninstall.slot_atom)
3561
				self._dynamic_config._slot_pkg_map[uninstall.root].get(uninstall.slot_atom)
3549
			if upgrade_node is not None and \
3562
			if upgrade_node is not None and \
3550
				uninstall not in executed_uninstalls:
3563
				uninstall not in executed_uninstalls:
3551
				for blocker in uninstall_parents:
3564
				for blocker in uninstall_parents:
Lines 3560-3566 Link Here
3560
				unsatisfied_blockers.append(x)
3573
				unsatisfied_blockers.append(x)
3561
				continue
3574
				continue
3562
			graph_key = x
3575
			graph_key = x
3563
			if "--tree" in self.myopts:
3576
			if "--tree" in self._frozen_config.myopts:
3564
				depth = len(tree_nodes)
3577
				depth = len(tree_nodes)
3565
				while depth and graph_key not in \
3578
				while depth and graph_key not in \
3566
					mygraph.child_nodes(tree_nodes[depth-1]):
3579
					mygraph.child_nodes(tree_nodes[depth-1]):
Lines 3578-3584 Link Here
3578
						# Do not traverse to parents if this node is an
3591
						# Do not traverse to parents if this node is an
3579
						# an argument or a direct member of a set that has
3592
						# an argument or a direct member of a set that has
3580
						# been specified as an argument (system or world).
3593
						# been specified as an argument (system or world).
3581
						if current_node not in self._set_nodes:
3594
						if current_node not in self._dynamic_config._set_nodes:
3582
							parent_nodes = mygraph.parent_nodes(current_node)
3595
							parent_nodes = mygraph.parent_nodes(current_node)
3583
						if parent_nodes:
3596
						if parent_nodes:
3584
							child_nodes = set(mygraph.child_nodes(current_node))
3597
							child_nodes = set(mygraph.child_nodes(current_node))
Lines 3653-3663 Link Here
3653
			pkg_type = x[0]
3666
			pkg_type = x[0]
3654
			myroot = x[1]
3667
			myroot = x[1]
3655
			pkg_key = x[2]
3668
			pkg_key = x[2]
3656
			portdb = self.trees[myroot]["porttree"].dbapi
3669
			portdb = self._frozen_config.trees[myroot]["porttree"].dbapi
3657
			bindb  = self.trees[myroot]["bintree"].dbapi
3670
			bindb  = self._frozen_config.trees[myroot]["bintree"].dbapi
3658
			vardb = self.trees[myroot]["vartree"].dbapi
3671
			vardb = self._frozen_config.trees[myroot]["vartree"].dbapi
3659
			vartree = self.trees[myroot]["vartree"]
3672
			vartree = self._frozen_config.trees[myroot]["vartree"]
3660
			pkgsettings = self.pkgsettings[myroot]
3673
			pkgsettings = self._frozen_config.pkgsettings[myroot]
3661
3674
3662
			fetch=" "
3675
			fetch=" "
3663
			indent = " " * depth
3676
			indent = " " * depth
Lines 3675-3687 Link Here
3675
						counters.blocks_satisfied += 1
3688
						counters.blocks_satisfied += 1
3676
				resolved = portage.key_expand(
3689
				resolved = portage.key_expand(
3677
					str(x.atom).lstrip("!"), mydb=vardb, settings=pkgsettings)
3690
					str(x.atom).lstrip("!"), mydb=vardb, settings=pkgsettings)
3678
				if "--columns" in self.myopts and "--quiet" in self.myopts:
3691
				if "--columns" in self._frozen_config.myopts and "--quiet" in self._frozen_config.myopts:
3679
					addl += " " + colorize(blocker_style, resolved)
3692
					addl += " " + colorize(blocker_style, resolved)
3680
				else:
3693
				else:
3681
					addl = "[%s %s] %s%s" % \
3694
					addl = "[%s %s] %s%s" % \
3682
						(colorize(blocker_style, "blocks"),
3695
						(colorize(blocker_style, "blocks"),
3683
						addl, indent, colorize(blocker_style, resolved))
3696
						addl, indent, colorize(blocker_style, resolved))
3684
				block_parents = self._blocker_parents.parent_nodes(x)
3697
				block_parents = self._dynamic_config._blocker_parents.parent_nodes(x)
3685
				block_parents = set([pnode[2] for pnode in block_parents])
3698
				block_parents = set([pnode[2] for pnode in block_parents])
3686
				block_parents = ", ".join(block_parents)
3699
				block_parents = ", ".join(block_parents)
3687
				if resolved!=x[2]:
3700
				if resolved!=x[2]:
Lines 3771-3777 Link Here
3771
						if ordered:
3784
						if ordered:
3772
							counters.newslot += 1
3785
							counters.newslot += 1
3773
3786
3774
					if "--changelog" in self.myopts:
3787
					if "--changelog" in self._frozen_config.myopts:
3775
						inst_matches = vardb.match(pkg.slot_atom)
3788
						inst_matches = vardb.match(pkg.slot_atom)
3776
						if inst_matches:
3789
						if inst_matches:
3777
							changelogs.extend(calc_changelog(
3790
							changelogs.extend(calc_changelog(
Lines 3847-3853 Link Here
3847
					# Prevent USE_EXPAND_HIDDEN flags from being hidden if they
3860
					# Prevent USE_EXPAND_HIDDEN flags from being hidden if they
3848
					# are the only thing that triggered reinstallation.
3861
					# are the only thing that triggered reinstallation.
3849
					reinst_flags_map = {}
3862
					reinst_flags_map = {}
3850
					reinstall_for_flags = self._reinstall_nodes.get(pkg)
3863
					reinstall_for_flags = self._dynamic_config._reinstall_nodes.get(pkg)
3851
					reinst_expand_map = None
3864
					reinst_expand_map = None
3852
					if reinstall_for_flags:
3865
					if reinstall_for_flags:
3853
						reinst_flags_map = map_to_use_expand(
3866
						reinst_flags_map = map_to_use_expand(
Lines 3889-3895 Link Here
3889
					if pkg_type == "ebuild" and pkg_merge:
3902
					if pkg_type == "ebuild" and pkg_merge:
3890
						try:
3903
						try:
3891
							myfilesdict = portdb.getfetchsizes(pkg_key,
3904
							myfilesdict = portdb.getfetchsizes(pkg_key,
3892
								useflags=pkg_use, debug=self.edebug)
3905
								useflags=pkg_use, debug=self._frozen_config.edebug)
3893
						except portage.exception.InvalidDependString, e:
3906
						except portage.exception.InvalidDependString, e:
3894
							src_uri = portdb.aux_get(pkg_key, ["SRC_URI"])[0]
3907
							src_uri = portdb.aux_get(pkg_key, ["SRC_URI"])[0]
3895
							show_invalid_depstring_notice(x, src_uri, str(e))
3908
							show_invalid_depstring_notice(x, src_uri, str(e))
Lines 3943-3956 Link Here
3943
					xs[2] = "-" + xs[2]
3956
					xs[2] = "-" + xs[2]
3944
3957
3945
				mywidth = 130
3958
				mywidth = 130
3946
				if "COLUMNWIDTH" in self.settings:
3959
				if "COLUMNWIDTH" in self._frozen_config.settings:
3947
					try:
3960
					try:
3948
						mywidth = int(self.settings["COLUMNWIDTH"])
3961
						mywidth = int(self._frozen_config.settings["COLUMNWIDTH"])
3949
					except ValueError, e:
3962
					except ValueError, e:
3950
						portage.writemsg("!!! %s\n" % str(e), noiselevel=-1)
3963
						portage.writemsg("!!! %s\n" % str(e), noiselevel=-1)
3951
						portage.writemsg(
3964
						portage.writemsg(
3952
							"!!! Unable to parse COLUMNWIDTH='%s'\n" % \
3965
							"!!! Unable to parse COLUMNWIDTH='%s'\n" % \
3953
							self.settings["COLUMNWIDTH"], noiselevel=-1)
3966
							self._frozen_config.settings["COLUMNWIDTH"], noiselevel=-1)
3954
						del e
3967
						del e
3955
				oldlp = mywidth - 30
3968
				oldlp = mywidth - 30
3956
				newlp = oldlp - 30
3969
				newlp = oldlp - 30
Lines 3968-3974 Link Here
3968
					myoldbest = blue("["+", ".join(myoldbest)+"]")
3981
					myoldbest = blue("["+", ".join(myoldbest)+"]")
3969
3982
3970
				pkg_cp = xs[0]
3983
				pkg_cp = xs[0]
3971
				root_config = self.roots[myroot]
3984
				root_config = self._frozen_config.roots[myroot]
3972
				system_set = root_config.sets["system"]
3985
				system_set = root_config.sets["system"]
3973
				world_set  = root_config.sets["world"]
3986
				world_set  = root_config.sets["world"]
3974
3987
Lines 3978-3984 Link Here
3978
					pkg_system = system_set.findAtomForPackage(pkg)
3991
					pkg_system = system_set.findAtomForPackage(pkg)
3979
					pkg_world  = world_set.findAtomForPackage(pkg)
3992
					pkg_world  = world_set.findAtomForPackage(pkg)
3980
					if not (oneshot or pkg_world) and \
3993
					if not (oneshot or pkg_world) and \
3981
						myroot == self.target_root and \
3994
						myroot == self._frozen_config.target_root and \
3982
						favorites_set.findAtomForPackage(pkg):
3995
						favorites_set.findAtomForPackage(pkg):
3983
						# Maybe it will be added to world now.
3996
						# Maybe it will be added to world now.
3984
						if create_world_atom(pkg, favorites_set, root_config):
3997
						if create_world_atom(pkg, favorites_set, root_config):
Lines 4014-4021 Link Here
4014
				if x[1]!="/":
4027
				if x[1]!="/":
4015
					if myoldbest:
4028
					if myoldbest:
4016
						myoldbest +=" "
4029
						myoldbest +=" "
4017
					if "--columns" in self.myopts:
4030
					if "--columns" in self._frozen_config.myopts:
4018
						if "--quiet" in self.myopts:
4031
						if "--quiet" in self._frozen_config.myopts:
4019
							myprint=addl+" "+indent+pkgprint(pkg_cp)
4032
							myprint=addl+" "+indent+pkgprint(pkg_cp)
4020
							myprint=myprint+darkblue(" "+xs[1]+xs[2])+" "
4033
							myprint=myprint+darkblue(" "+xs[1]+xs[2])+" "
4021
							myprint=myprint+myoldbest
4034
							myprint=myprint+myoldbest
Lines 4045-4052 Link Here
4045
						myprint += indent + pkgprint(pkg_key) + " " + \
4058
						myprint += indent + pkgprint(pkg_key) + " " + \
4046
							myoldbest + darkgreen("to " + myroot)
4059
							myoldbest + darkgreen("to " + myroot)
4047
				else:
4060
				else:
4048
					if "--columns" in self.myopts:
4061
					if "--columns" in self._frozen_config.myopts:
4049
						if "--quiet" in self.myopts:
4062
						if "--quiet" in self._frozen_config.myopts:
4050
							myprint=addl+" "+indent+pkgprint(pkg_cp)
4063
							myprint=addl+" "+indent+pkgprint(pkg_cp)
4051
							myprint=myprint+" "+green(xs[1]+xs[2])+" "
4064
							myprint=myprint+" "+green(xs[1]+xs[2])+" "
4052
							myprint=myprint+myoldbest
4065
							myprint=myprint+myoldbest
Lines 4081-4094 Link Here
4081
					continue
4094
					continue
4082
				p.append((myprint, verboseadd, repoadd))
4095
				p.append((myprint, verboseadd, repoadd))
4083
4096
4084
				if "--tree" not in self.myopts and \
4097
				if "--tree" not in self._frozen_config.myopts and \
4085
					"--quiet" not in self.myopts and \
4098
					"--quiet" not in self._frozen_config.myopts and \
4086
					not self._opts_no_restart.intersection(self.myopts) and \
4099
					not self._frozen_config._opts_no_restart.intersection(self._frozen_config.myopts) and \
4087
					pkg.root == self._running_root.root and \
4100
					pkg.root == self._frozen_config._running_root.root and \
4088
					portage.match_from_list(
4101
					portage.match_from_list(
4089
					portage.const.PORTAGE_PACKAGE_ATOM, [pkg]) and \
4102
					portage.const.PORTAGE_PACKAGE_ATOM, [pkg]) and \
4090
					not vardb.cpv_exists(pkg.cpv) and \
4103
					not vardb.cpv_exists(pkg.cpv) and \
4091
					"--quiet" not in self.myopts:
4104
					"--quiet" not in self._frozen_config.myopts:
4092
						if mylist_index < len(mylist) - 1:
4105
						if mylist_index < len(mylist) - 1:
4093
							p.append(colorize("WARN", "*** Portage will stop merging at this point and reload itself,"))
4106
							p.append(colorize("WARN", "*** Portage will stop merging at this point and reload itself,"))
4094
							p.append(colorize("WARN", "    then resume the merge."))
4107
							p.append(colorize("WARN", "    then resume the merge."))
Lines 4120-4126 Link Here
4120
			if show_repos:
4133
			if show_repos:
4121
				sys.stdout.write(str(repo_display))
4134
				sys.stdout.write(str(repo_display))
4122
4135
4123
		if "--changelog" in self.myopts:
4136
		if "--changelog" in self._frozen_config.myopts:
4124
			print
4137
			print
4125
			for revision,text in changelogs:
4138
			for revision,text in changelogs:
4126
				print bold('*'+revision)
4139
				print bold('*'+revision)
Lines 4161-4192 Link Here
4161
			sys.stderr.flush()
4174
			sys.stderr.flush()
4162
4175
4163
		# This goes to stdout for parsing by programs like autounmask.
4176
		# This goes to stdout for parsing by programs like autounmask.
4164
		for pargs, kwargs in self._unsatisfied_deps_for_display:
4177
		for pargs, kwargs in self._dynamic_config._unsatisfied_deps_for_display:
4165
			self._show_unsatisfied_dep(*pargs, **kwargs)
4178
			self._show_unsatisfied_dep(*pargs, **kwargs)
4166
4179
4167
	def _display_problems(self):
4180
	def _display_problems(self):
4168
		if self._circular_deps_for_display is not None:
4181
		if self._dynamic_config._circular_deps_for_display is not None:
4169
			self._show_circular_deps(
4182
			self._show_circular_deps(
4170
				self._circular_deps_for_display)
4183
				self._dynamic_config._circular_deps_for_display)
4171
4184
4172
		# The user is only notified of a slot conflict if
4185
		# The user is only notified of a slot conflict if
4173
		# there are no unresolvable blocker conflicts.
4186
		# there are no unresolvable blocker conflicts.
4174
		if self._unsatisfied_blockers_for_display is not None:
4187
		if self._dynamic_config._unsatisfied_blockers_for_display is not None:
4175
			self._show_unsatisfied_blockers(
4188
			self._show_unsatisfied_blockers(
4176
				self._unsatisfied_blockers_for_display)
4189
				self._dynamic_config._unsatisfied_blockers_for_display)
4177
		else:
4190
		else:
4178
			self._show_slot_collision_notice()
4191
			self._show_slot_collision_notice()
4179
4192
4180
		# TODO: Add generic support for "set problem" handlers so that
4193
		# TODO: Add generic support for "set problem" handlers so that
4181
		# the below warnings aren't special cases for world only.
4194
		# the below warnings aren't special cases for world only.
4182
4195
4183
		if self._missing_args:
4196
		if self._dynamic_config._missing_args:
4184
			world_problems = False
4197
			world_problems = False
4185
			if "world" in self._sets:
4198
			if "world" in self._dynamic_config._sets:
4186
				# Filter out indirect members of world (from nested sets)
4199
				# Filter out indirect members of world (from nested sets)
4187
				# since only direct members of world are desired here.
4200
				# since only direct members of world are desired here.
4188
				world_set = self.roots[self.target_root].sets["world"]
4201
				world_set = self._frozen_config.roots[self._frozen_config.target_root].sets["world"]
4189
				for arg, atom in self._missing_args:
4202
				for arg, atom in self._dynamic_config._missing_args:
4190
					if arg.name == "world" and atom in world_set:
4203
					if arg.name == "world" and atom in world_set:
4191
						world_problems = True
4204
						world_problems = True
4192
						break
4205
						break
Lines 4197-4213 Link Here
4197
				sys.stderr.write("!!! Please run " + \
4210
				sys.stderr.write("!!! Please run " + \
4198
					green("emaint --check world")+"\n\n")
4211
					green("emaint --check world")+"\n\n")
4199
4212
4200
		if self._missing_args:
4213
		if self._dynamic_config._missing_args:
4201
			sys.stderr.write("\n" + colorize("BAD", "!!!") + \
4214
			sys.stderr.write("\n" + colorize("BAD", "!!!") + \
4202
				" Ebuilds for the following packages are either all\n")
4215
				" Ebuilds for the following packages are either all\n")
4203
			sys.stderr.write(colorize("BAD", "!!!") + \
4216
			sys.stderr.write(colorize("BAD", "!!!") + \
4204
				" masked or don't exist:\n")
4217
				" masked or don't exist:\n")
4205
			sys.stderr.write(" ".join(str(atom) for arg, atom in \
4218
			sys.stderr.write(" ".join(str(atom) for arg, atom in \
4206
				self._missing_args) + "\n")
4219
				self._dynamic_config._missing_args) + "\n")
4207
4220
4208
		if self._pprovided_args:
4221
		if self._dynamic_config._pprovided_args:
4209
			arg_refs = {}
4222
			arg_refs = {}
4210
			for arg, atom in self._pprovided_args:
4223
			for arg, atom in self._dynamic_config._pprovided_args:
4211
				if isinstance(arg, SetArg):
4224
				if isinstance(arg, SetArg):
4212
					parent = arg.name
4225
					parent = arg.name
4213
					arg_atom = (atom, atom)
4226
					arg_atom = (atom, atom)
Lines 4219-4225 Link Here
4219
					refs.append(parent)
4232
					refs.append(parent)
4220
			msg = []
4233
			msg = []
4221
			msg.append(bad("\nWARNING: "))
4234
			msg.append(bad("\nWARNING: "))
4222
			if len(self._pprovided_args) > 1:
4235
			if len(self._dynamic_config._pprovided_args) > 1:
4223
				msg.append("Requested packages will not be " + \
4236
				msg.append("Requested packages will not be " + \
4224
					"merged because they are listed in\n")
4237
					"merged because they are listed in\n")
4225
			else:
4238
			else:
Lines 4246-4254 Link Here
4246
			sys.stderr.write("".join(msg))
4259
			sys.stderr.write("".join(msg))
4247
4260
4248
		masked_packages = []
4261
		masked_packages = []
4249
		for pkg in self._masked_installed:
4262
		for pkg in self._dynamic_config._masked_installed:
4250
			root_config = pkg.root_config
4263
			root_config = pkg.root_config
4251
			pkgsettings = self.pkgsettings[pkg.root]
4264
			pkgsettings = self._frozen_config.pkgsettings[pkg.root]
4252
			mreasons = get_masking_status(pkg, pkgsettings, root_config)
4265
			mreasons = get_masking_status(pkg, pkgsettings, root_config)
4253
			masked_packages.append((root_config, pkgsettings,
4266
			masked_packages.append((root_config, pkgsettings,
4254
				pkg.cpv, pkg.metadata, mreasons))
4267
				pkg.cpv, pkg.metadata, mreasons))
Lines 4264-4272 Link Here
4264
		to the world file if necessary."""
4277
		to the world file if necessary."""
4265
		for x in ("--buildpkgonly", "--fetchonly", "--fetch-all-uri",
4278
		for x in ("--buildpkgonly", "--fetchonly", "--fetch-all-uri",
4266
			"--oneshot", "--onlydeps", "--pretend"):
4279
			"--oneshot", "--onlydeps", "--pretend"):
4267
			if x in self.myopts:
4280
			if x in self._frozen_config.myopts:
4268
				return
4281
				return
4269
		root_config = self.roots[self.target_root]
4282
		root_config = self._frozen_config.roots[self._frozen_config.target_root]
4270
		world_set = root_config.sets["world"]
4283
		world_set = root_config.sets["world"]
4271
4284
4272
		world_locked = False
4285
		world_locked = False
Lines 4277-4286 Link Here
4277
		if hasattr(world_set, "load"):
4290
		if hasattr(world_set, "load"):
4278
			world_set.load() # maybe it's changed on disk
4291
			world_set.load() # maybe it's changed on disk
4279
4292
4280
		args_set = self._sets["args"]
4293
		args_set = self._dynamic_config._sets["args"]
4281
		portdb = self.trees[self.target_root]["porttree"].dbapi
4294
		portdb = self._frozen_config.trees[self._frozen_config.target_root]["porttree"].dbapi
4282
		added_favorites = set()
4295
		added_favorites = set()
4283
		for x in self._set_nodes:
4296
		for x in self._dynamic_config._set_nodes:
4284
			pkg_type, root, pkg_key, pkg_status = x
4297
			pkg_type, root, pkg_key, pkg_status = x
4285
			if pkg_status != "nomerge":
4298
			if pkg_status != "nomerge":
4286
				continue
4299
				continue
Lines 4298-4304 Link Here
4298
					root, portage.VDB_PATH, pkg_key, "PROVIDE"), noiselevel=-1)
4311
					root, portage.VDB_PATH, pkg_key, "PROVIDE"), noiselevel=-1)
4299
				del e
4312
				del e
4300
		all_added = []
4313
		all_added = []
4301
		for k in self._sets:
4314
		for k in self._dynamic_config._sets:
4302
			if k in ("args", "world") or not root_config.sets[k].world_candidate:
4315
			if k in ("args", "world") or not root_config.sets[k].world_candidate:
4303
				continue
4316
				continue
4304
			s = SETPREFIX + k
4317
			s = SETPREFIX + k
Lines 4330-4337 Link Here
4330
		if not isinstance(mergelist, list):
4343
		if not isinstance(mergelist, list):
4331
			mergelist = []
4344
			mergelist = []
4332
4345
4333
		fakedb = self.mydbapi
4346
		fakedb = self._dynamic_config.mydbapi
4334
		trees = self.trees
4347
		trees = self._frozen_config.trees
4335
		serialized_tasks = []
4348
		serialized_tasks = []
4336
		masked_tasks = []
4349
		masked_tasks = []
4337
		for x in mergelist:
4350
		for x in mergelist:
Lines 4344-4350 Link Here
4344
				continue
4357
				continue
4345
			tree_type = self.pkg_tree_map[pkg_type]
4358
			tree_type = self.pkg_tree_map[pkg_type]
4346
			mydb = trees[myroot][tree_type].dbapi
4359
			mydb = trees[myroot][tree_type].dbapi
4347
			db_keys = list(self._trees_orig[myroot][
4360
			db_keys = list(self._frozen_config._trees_orig[myroot][
4348
				tree_type].dbapi._aux_cache_keys)
4361
				tree_type].dbapi._aux_cache_keys)
4349
			try:
4362
			try:
4350
				metadata = izip(db_keys, mydb.aux_get(pkg_key, db_keys))
4363
				metadata = izip(db_keys, mydb.aux_get(pkg_key, db_keys))
Lines 4358-4392 Link Here
4358
				raise portage.exception.PackageNotFound(pkg_key)
4371
				raise portage.exception.PackageNotFound(pkg_key)
4359
			installed = action == "uninstall"
4372
			installed = action == "uninstall"
4360
			built = pkg_type != "ebuild"
4373
			built = pkg_type != "ebuild"
4361
			root_config = self.roots[myroot]
4374
			root_config = self._frozen_config.roots[myroot]
4362
			pkg = Package(built=built, cpv=pkg_key,
4375
			pkg = Package(built=built, cpv=pkg_key,
4363
				installed=installed, metadata=metadata,
4376
				installed=installed, metadata=metadata,
4364
				operation=action, root_config=root_config,
4377
				operation=action, root_config=root_config,
4365
				type_name=pkg_type)
4378
				type_name=pkg_type)
4366
			self._pkg_cache[pkg] = pkg
4379
			self._dynamic_config._pkg_cache[pkg] = pkg
4367
4380
4368
			root_config = self.roots[pkg.root]
4381
			root_config = self._frozen_config.roots[pkg.root]
4369
			if "merge" == pkg.operation and \
4382
			if "merge" == pkg.operation and \
4370
				not visible(root_config.settings, pkg):
4383
				not visible(root_config.settings, pkg):
4371
				if skip_masked:
4384
				if skip_masked:
4372
					masked_tasks.append(Dependency(root=pkg.root, parent=pkg))
4385
					masked_tasks.append(Dependency(root=pkg.root, parent=pkg))
4373
				else:
4386
				else:
4374
					self._unsatisfied_deps_for_display.append(
4387
					self._dynamic_config._unsatisfied_deps_for_display.append(
4375
						((pkg.root, "="+pkg.cpv), {"myparent":None}))
4388
						((pkg.root, "="+pkg.cpv), {"myparent":None}))
4376
4389
4377
			fakedb[myroot].cpv_inject(pkg)
4390
			fakedb[myroot].cpv_inject(pkg)
4378
			serialized_tasks.append(pkg)
4391
			serialized_tasks.append(pkg)
4379
			self.spinner.update()
4392
			self._frozen_config.spinner.update()
4380
4393
4381
		if self._unsatisfied_deps_for_display:
4394
		if self._dynamic_config._unsatisfied_deps_for_display:
4382
			return False
4395
			return False
4383
4396
4384
		if not serialized_tasks or "--nodeps" in self.myopts:
4397
		if not serialized_tasks or "--nodeps" in self._frozen_config.myopts:
4385
			self._serialized_tasks_cache = serialized_tasks
4398
			self._dynamic_config._serialized_tasks_cache = serialized_tasks
4386
			self._scheduler_graph = self.digraph
4399
			self._dynamic_config._scheduler_graph = self._dynamic_config.digraph
4387
		else:
4400
		else:
4388
			self._select_package = self._select_pkg_from_graph
4401
			self._select_package = self._select_pkg_from_graph
4389
			self.myparams.add("selective")
4402
			self._dynamic_config.myparams.add("selective")
4390
			# Always traverse deep dependencies in order to account for
4403
			# Always traverse deep dependencies in order to account for
4391
			# potentially unsatisfied dependencies of installed packages.
4404
			# potentially unsatisfied dependencies of installed packages.
4392
			# This is necessary for correct --keep-going or --resume operation
4405
			# This is necessary for correct --keep-going or --resume operation
Lines 4399-4408 Link Here
4399
			# deep depenedencies of a scheduled build, that build needs to
4412
			# deep depenedencies of a scheduled build, that build needs to
4400
			# be cancelled. In order for this type of situation to be
4413
			# be cancelled. In order for this type of situation to be
4401
			# recognized, deep traversal of dependencies is required.
4414
			# recognized, deep traversal of dependencies is required.
4402
			self.myparams.add("deep")
4415
			self._dynamic_config.myparams.add("deep")
4403
4416
4404
			favorites = resume_data.get("favorites")
4417
			favorites = resume_data.get("favorites")
4405
			args_set = self._sets["args"]
4418
			args_set = self._dynamic_config._sets["args"]
4406
			if isinstance(favorites, list):
4419
			if isinstance(favorites, list):
4407
				args = self._load_favorites(favorites)
4420
				args = self._load_favorites(favorites)
4408
			else:
4421
			else:
Lines 4434-4440 Link Here
4434
				return False
4447
				return False
4435
4448
4436
			unsatisfied_deps = []
4449
			unsatisfied_deps = []
4437
			for dep in self._unsatisfied_deps:
4450
			for dep in self._dynamic_config._unsatisfied_deps:
4438
				if not isinstance(dep.parent, Package):
4451
				if not isinstance(dep.parent, Package):
4439
					continue
4452
					continue
4440
				if dep.parent.operation == "merge":
4453
				if dep.parent.operation == "merge":
Lines 4446-4452 Link Here
4446
				# which is scheduled to be installed.
4459
				# which is scheduled to be installed.
4447
				unsatisfied_install = False
4460
				unsatisfied_install = False
4448
				traversed = set()
4461
				traversed = set()
4449
				dep_stack = self.digraph.parent_nodes(dep.parent)
4462
				dep_stack = self._dynamic_config.digraph.parent_nodes(dep.parent)
4450
				while dep_stack:
4463
				while dep_stack:
4451
					node = dep_stack.pop()
4464
					node = dep_stack.pop()
4452
					if not isinstance(node, Package):
4465
					if not isinstance(node, Package):
Lines 4457-4463 Link Here
4457
					if node in traversed:
4470
					if node in traversed:
4458
						continue
4471
						continue
4459
					traversed.add(node)
4472
					traversed.add(node)
4460
					dep_stack.extend(self.digraph.parent_nodes(node))
4473
					dep_stack.extend(self._dynamic_config.digraph.parent_nodes(node))
4461
4474
4462
				if unsatisfied_install:
4475
				if unsatisfied_install:
4463
					unsatisfied_deps.append(dep)
4476
					unsatisfied_deps.append(dep)
Lines 4469-4475 Link Here
4469
				# UnsatisfiedResumeDep exception.
4482
				# UnsatisfiedResumeDep exception.
4470
				raise self.UnsatisfiedResumeDep(self,
4483
				raise self.UnsatisfiedResumeDep(self,
4471
					masked_tasks + unsatisfied_deps)
4484
					masked_tasks + unsatisfied_deps)
4472
			self._serialized_tasks_cache = None
4485
			self._dynamic_config._serialized_tasks_cache = None
4473
			try:
4486
			try:
4474
				self.altlist()
4487
				self.altlist()
4475
			except self._unknown_internal_error:
4488
			except self._unknown_internal_error:
Lines 4486-4492 Link Here
4486
		This allows Package instances to be matched with
4499
		This allows Package instances to be matched with
4487
		DependencyArg instances during graph creation.
4500
		DependencyArg instances during graph creation.
4488
		"""
4501
		"""
4489
		root_config = self.roots[self.target_root]
4502
		root_config = self._frozen_config.roots[self._frozen_config.target_root]
4490
		getSetAtoms = root_config.setconfig.getSetAtoms
4503
		getSetAtoms = root_config.setconfig.getSetAtoms
4491
		sets = root_config.sets
4504
		sets = root_config.sets
4492
		args = []
4505
		args = []
Lines 4499-4512 Link Here
4499
				s = x[len(SETPREFIX):]
4512
				s = x[len(SETPREFIX):]
4500
				if s not in sets:
4513
				if s not in sets:
4501
					continue
4514
					continue
4502
				if s in self._sets:
4515
				if s in self._dynamic_config._sets:
4503
					continue
4516
					continue
4504
				# Recursively expand sets so that containment tests in
4517
				# Recursively expand sets so that containment tests in
4505
				# self._get_parent_sets() properly match atoms in nested
4518
				# self._get_parent_sets() properly match atoms in nested
4506
				# sets (like if world contains system).
4519
				# sets (like if world contains system).
4507
				expanded_set = InternalPackageSet(
4520
				expanded_set = InternalPackageSet(
4508
					initial_atoms=getSetAtoms(s))
4521
					initial_atoms=getSetAtoms(s))
4509
				self._sets[s] = expanded_set
4522
				self._dynamic_config._sets[s] = expanded_set
4510
				args.append(SetArg(arg=x, set=expanded_set,
4523
				args.append(SetArg(arg=x, set=expanded_set,
4511
					root_config=root_config))
4524
					root_config=root_config))
4512
			else:
4525
			else:
Lines 4548-4694 Link Here
4548
		graph in order to avoid making a potentially unsafe decision.
4561
		graph in order to avoid making a potentially unsafe decision.
4549
		"""
4562
		"""
4550
4563
4551
	class _dep_check_composite_db(portage.dbapi):
4564
class _dep_check_composite_db(portage.dbapi):
4552
		"""
4565
	"""
4553
		A dbapi-like interface that is optimized for use in dep_check() calls.
4566
	A dbapi-like interface that is optimized for use in dep_check() calls.
4554
		This is built on top of the existing depgraph package selection logic.
4567
	This is built on top of the existing depgraph package selection logic.
4555
		Some packages that have been added to the graph may be masked from this
4568
	Some packages that have been added to the graph may be masked from this
4556
		view in order to influence the atom preference selection that occurs
4569
	view in order to influence the atom preference selection that occurs
4557
		via dep_check().
4570
	via dep_check().
4558
		"""
4571
	"""
4559
		def __init__(self, depgraph, root):
4572
	def __init__(self, depgraph, root):
4560
			portage.dbapi.__init__(self)
4573
		portage.dbapi.__init__(self)
4561
			self._depgraph = depgraph
4574
		self._depgraph = depgraph
4562
			self._root = root
4575
		self._root = root
4563
			self._match_cache = {}
4576
		self._match_cache = {}
4564
			self._cpv_pkg_map = {}
4577
		self._cpv_pkg_map = {}
4565
4578
4566
		def _clear_cache(self):
4579
	def _clear_cache(self):
4567
			self._match_cache.clear()
4580
		self._match_cache.clear()
4568
			self._cpv_pkg_map.clear()
4581
		self._cpv_pkg_map.clear()
4569
4582
4570
		def match(self, atom):
4583
	def match(self, atom):
4571
			ret = self._match_cache.get(atom)
4584
		ret = self._match_cache.get(atom)
4572
			if ret is not None:
4585
		if ret is not None:
4573
				return ret[:]
4574
			orig_atom = atom
4575
			if "/" not in atom:
4576
				atom = self._dep_expand(atom)
4577
			pkg, existing = self._depgraph._select_package(self._root, atom)
4578
			if not pkg:
4579
				ret = []
4580
			else:
4581
				# Return the highest available from select_package() as well as
4582
				# any matching slots in the graph db.
4583
				slots = set()
4584
				slots.add(pkg.metadata["SLOT"])
4585
				atom_cp = portage.dep_getkey(atom)
4586
				if pkg.cp.startswith("virtual/"):
4587
					# For new-style virtual lookahead that occurs inside
4588
					# dep_check(), examine all slots. This is needed
4589
					# so that newer slots will not unnecessarily be pulled in
4590
					# when a satisfying lower slot is already installed. For
4591
					# example, if virtual/jdk-1.4 is satisfied via kaffe then
4592
					# there's no need to pull in a newer slot to satisfy a
4593
					# virtual/jdk dependency.
4594
					for db, pkg_type, built, installed, db_keys in \
4595
						self._depgraph._filtered_trees[self._root]["dbs"]:
4596
						for cpv in db.match(atom):
4597
							if portage.cpv_getkey(cpv) != pkg.cp:
4598
								continue
4599
							slots.add(db.aux_get(cpv, ["SLOT"])[0])
4600
				ret = []
4601
				if self._visible(pkg):
4602
					self._cpv_pkg_map[pkg.cpv] = pkg
4603
					ret.append(pkg.cpv)
4604
				slots.remove(pkg.metadata["SLOT"])
4605
				while slots:
4606
					slot_atom = "%s:%s" % (atom_cp, slots.pop())
4607
					pkg, existing = self._depgraph._select_package(
4608
						self._root, slot_atom)
4609
					if not pkg:
4610
						continue
4611
					if not self._visible(pkg):
4612
						continue
4613
					self._cpv_pkg_map[pkg.cpv] = pkg
4614
					ret.append(pkg.cpv)
4615
				if ret:
4616
					self._cpv_sort_ascending(ret)
4617
			self._match_cache[orig_atom] = ret
4618
			return ret[:]
4586
			return ret[:]
4587
		orig_atom = atom
4588
		if "/" not in atom:
4589
			atom = self._dep_expand(atom)
4590
		pkg, existing = self._depgraph._select_package(self._root, atom)
4591
		if not pkg:
4592
			ret = []
4593
		else:
4594
			# Return the highest available from select_package() as well as
4595
			# any matching slots in the graph db.
4596
			slots = set()
4597
			slots.add(pkg.metadata["SLOT"])
4598
			atom_cp = portage.dep_getkey(atom)
4599
			if pkg.cp.startswith("virtual/"):
4600
				# For new-style virtual lookahead that occurs inside
4601
				# dep_check(), examine all slots. This is needed
4602
				# so that newer slots will not unnecessarily be pulled in
4603
				# when a satisfying lower slot is already installed. For
4604
				# example, if virtual/jdk-1.4 is satisfied via kaffe then
4605
				# there's no need to pull in a newer slot to satisfy a
4606
				# virtual/jdk dependency.
4607
				for db, pkg_type, built, installed, db_keys in \
4608
					self._depgraph._dynamic_config._filtered_trees[self._root]["dbs"]:
4609
					for cpv in db.match(atom):
4610
						if portage.cpv_getkey(cpv) != pkg.cp:
4611
							continue
4612
						slots.add(db.aux_get(cpv, ["SLOT"])[0])
4613
			ret = []
4614
			if self._visible(pkg):
4615
				self._cpv_pkg_map[pkg.cpv] = pkg
4616
				ret.append(pkg.cpv)
4617
			slots.remove(pkg.metadata["SLOT"])
4618
			while slots:
4619
				slot_atom = "%s:%s" % (atom_cp, slots.pop())
4620
				pkg, existing = self._depgraph._select_package(
4621
					self._root, slot_atom)
4622
				if not pkg:
4623
					continue
4624
				if not self._visible(pkg):
4625
					continue
4626
				self._cpv_pkg_map[pkg.cpv] = pkg
4627
				ret.append(pkg.cpv)
4628
			if ret:
4629
				self._cpv_sort_ascending(ret)
4630
		self._match_cache[orig_atom] = ret
4631
		return ret[:]
4619
4632
4620
		def _visible(self, pkg):
4633
	def _visible(self, pkg):
4621
			if pkg.installed and "selective" not in self._depgraph.myparams:
4634
		if pkg.installed and "selective" not in self._depgraph.myparams:
4622
				try:
4635
			try:
4623
					arg = self._depgraph._iter_atoms_for_pkg(pkg).next()
4636
				arg = self._depgraph._iter_atoms_for_pkg(pkg).next()
4624
				except (StopIteration, portage.exception.InvalidDependString):
4637
			except (StopIteration, portage.exception.InvalidDependString):
4625
					arg = None
4638
				arg = None
4626
				if arg:
4639
			if arg:
4640
				return False
4641
		if pkg.installed:
4642
			try:
4643
				if not visible(
4644
					self._depgraph.pkgsettings[pkg.root], pkg):
4627
					return False
4645
					return False
4628
			if pkg.installed:
4646
			except portage.exception.InvalidDependString:
4629
				try:
4647
				pass
4630
					if not visible(
4648
		in_graph = self._depgraph._dynamic_config._slot_pkg_map[
4631
						self._depgraph.pkgsettings[pkg.root], pkg):
4649
			self._root].get(pkg.slot_atom)
4632
						return False
4650
		if in_graph is None:
4633
				except portage.exception.InvalidDependString:
4651
			# Mask choices for packages which are not the highest visible
4634
					pass
4652
			# version within their slot (since they usually trigger slot
4635
			in_graph = self._depgraph._slot_pkg_map[
4653
			# conflicts).
4636
				self._root].get(pkg.slot_atom)
4654
			highest_visible, in_graph = self._depgraph._select_package(
4637
			if in_graph is None:
4655
				self._root, pkg.slot_atom)
4638
				# Mask choices for packages which are not the highest visible
4656
			if pkg != highest_visible:
4639
				# version within their slot (since they usually trigger slot
4640
				# conflicts).
4641
				highest_visible, in_graph = self._depgraph._select_package(
4642
					self._root, pkg.slot_atom)
4643
				if pkg != highest_visible:
4644
					return False
4645
			elif in_graph != pkg:
4646
				# Mask choices for packages that would trigger a slot
4647
				# conflict with a previously selected package.
4648
				return False
4657
				return False
4649
			return True
4658
		elif in_graph != pkg:
4659
			# Mask choices for packages that would trigger a slot
4660
			# conflict with a previously selected package.
4661
			return False
4662
		return True
4650
4663
4651
		def _dep_expand(self, atom):
4664
	def _dep_expand(self, atom):
4652
			"""
4665
		"""
4653
			This is only needed for old installed packages that may
4666
		This is only needed for old installed packages that may
4654
			contain atoms that are not fully qualified with a specific
4667
		contain atoms that are not fully qualified with a specific
4655
			category. Emulate the cpv_expand() function that's used by
4668
		category. Emulate the cpv_expand() function that's used by
4656
			dbapi.match() in cases like this. If there are multiple
4669
		dbapi.match() in cases like this. If there are multiple
4657
			matches, it's often due to a new-style virtual that has
4670
		matches, it's often due to a new-style virtual that has
4658
			been added, so try to filter those out to avoid raising
4671
		been added, so try to filter those out to avoid raising
4659
			a ValueError.
4672
		a ValueError.
4660
			"""
4673
		"""
4661
			root_config = self._depgraph.roots[self._root]
4674
		root_config = self._depgraph.roots[self._root]
4662
			orig_atom = atom
4675
		orig_atom = atom
4663
			expanded_atoms = self._depgraph._dep_expand(root_config, atom)
4676
		expanded_atoms = self._depgraph._dep_expand(root_config, atom)
4664
			if len(expanded_atoms) > 1:
4677
		if len(expanded_atoms) > 1:
4665
				non_virtual_atoms = []
4678
			non_virtual_atoms = []
4666
				for x in expanded_atoms:
4679
			for x in expanded_atoms:
4667
					if not portage.dep_getkey(x).startswith("virtual/"):
4680
				if not portage.dep_getkey(x).startswith("virtual/"):
4668
						non_virtual_atoms.append(x)
4681
					non_virtual_atoms.append(x)
4669
				if len(non_virtual_atoms) == 1:
4682
			if len(non_virtual_atoms) == 1:
4670
					expanded_atoms = non_virtual_atoms
4683
				expanded_atoms = non_virtual_atoms
4671
			if len(expanded_atoms) > 1:
4684
		if len(expanded_atoms) > 1:
4672
				# compatible with portage.cpv_expand()
4685
			# compatible with portage.cpv_expand()
4673
				raise portage.exception.AmbiguousPackageName(
4686
			raise portage.exception.AmbiguousPackageName(
4674
					[portage.dep_getkey(x) for x in expanded_atoms])
4687
				[portage.dep_getkey(x) for x in expanded_atoms])
4675
			if expanded_atoms:
4688
		if expanded_atoms:
4676
				atom = expanded_atoms[0]
4689
			atom = expanded_atoms[0]
4690
		else:
4691
			null_atom = insert_category_into_atom(atom, "null")
4692
			null_cp = portage.dep_getkey(null_atom)
4693
			cat, atom_pn = portage.catsplit(null_cp)
4694
			virts_p = root_config.settings.get_virts_p().get(atom_pn)
4695
			if virts_p:
4696
				# Allow the resolver to choose which virtual.
4697
				atom = insert_category_into_atom(atom, "virtual")
4677
			else:
4698
			else:
4678
				null_atom = insert_category_into_atom(atom, "null")
4699
				atom = insert_category_into_atom(atom, "null")
4679
				null_cp = portage.dep_getkey(null_atom)
4700
		return atom
4680
				cat, atom_pn = portage.catsplit(null_cp)
4681
				virts_p = root_config.settings.get_virts_p().get(atom_pn)
4682
				if virts_p:
4683
					# Allow the resolver to choose which virtual.
4684
					atom = insert_category_into_atom(atom, "virtual")
4685
				else:
4686
					atom = insert_category_into_atom(atom, "null")
4687
			return atom
4688
4701
4689
		def aux_get(self, cpv, wants):
4702
	def aux_get(self, cpv, wants):
4690
			metadata = self._cpv_pkg_map[cpv].metadata
4703
		metadata = self._cpv_pkg_map[cpv].metadata
4691
			return [metadata.get(x, "") for x in wants]
4704
		return [metadata.get(x, "") for x in wants]
4692
4705
4693
4706
4694
def ambiguous_package_name(arg, atoms, root_config, spinner, myopts):
4707
def ambiguous_package_name(arg, atoms, root_config, spinner, myopts):
Lines 4743-4749 Link Here
4743
			if not skip_unsatisfied:
4756
			if not skip_unsatisfied:
4744
				raise
4757
				raise
4745
4758
4746
			graph = mydepgraph.digraph
4759
			graph = mydepgraph._dynamic_config.digraph
4747
			unsatisfied_parents = dict((dep.parent, dep.parent) \
4760
			unsatisfied_parents = dict((dep.parent, dep.parent) \
4748
				for dep in e.value)
4761
				for dep in e.value)
4749
			traversed_nodes = set()
4762
			traversed_nodes = set()

Return to bug 275217