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

Collapse All | Expand All

(-)emerge.old (-1277 / +23 lines)
Lines 882-2158 Link Here
882
		mynewdict[portage.dep_getkey(x)]=x
882
		mynewdict[portage.dep_getkey(x)]=x
883
	return mynewdict
883
	return mynewdict
884
884
885
olddbapi=None
886
class depgraph:
887
888
	def __init__(self,myaction,myopts):
889
		global olddbapi
890
		self.pkgsettings = portage.config(clone=portage.settings)
891
		if not self.pkgsettings["ARCH"]:
892
			portage.writemsg(red("\a!!! ARCH is not set... Are you missing the /etc/make.profile symlink?\n"),
893
				noiselevel=-1)
894
			portage.writemsg(red("\a!!! Is the symlink correct? Is your portage tree complete?\n\n"),
895
				noiselevel=-1)
896
			sys.exit(9)
897
		self.applied_useflags = {}
898
899
		self.missingbins=[]
900
		self.myaction=myaction
901
		self.digraph=portage.digraph()
902
		self.orderedkeys=[]
903
		self.outdatedpackages=[]
904
		self.mydbapi={}
905
		self.mydbapi["/"] = portage.fakedbapi()
906
		if "empty" not in myparams or portage.root != "/":
907
			for pkg in portage.db["/"]["vartree"].getallcpv():
908
				self.mydbapi["/"].cpv_inject(pkg)
909
		if portage.root != "/":
910
			self.mydbapi[portage.root] = portage.fakedbapi()
911
			if "empty" not in myparams:
912
				for pkg in portage.db[portage.root]["vartree"].getallcpv():
913
					self.mydbapi[portage.root].cpv_inject(pkg)
914
915
		if "--usepkg" in myopts:
916
			portage.db["/"]["bintree"].populate(("--getbinpkg" in myopts), ("--getbinpkgonly" in myopts))
917
918
	def create(self,mybigkey,myparent=None,addme=1,myuse=None):
919
		"""creates the actual digraph of packages to merge.  return 1 on success, 0 on failure
920
		mybigkey = specification of package to merge; myparent = parent package (one depending on me);
921
		addme = should I be added to the tree? (for the --onlydeps mode)"""
922
		#stuff to add:
923
		#SLOT-aware emerge
924
		#IUSE-aware emerge
925
		#"no downgrade" emerge
926
		#print "mybigkey:",mybigkey
927
928
		jbigkey=string.join(mybigkey)
929
		if self.digraph.hasnode(jbigkey+" merge") or self.digraph.hasnode(jbigkey+" nomerge"):
930
			#this conditional is needed to prevent infinite recursion on already-processed deps
931
			return 1
932
933
		update_spinner()
934
935
		mytype,myroot,mykey=mybigkey
936
		# select the correct /var database that we'll be checking against
937
		vardbapi=portage.db[myroot]["vartree"].dbapi
938
939
		# if the package is already on the system, we add a "nomerge"
940
		# directive, otherwise we add a "merge" directive.
941
		if mytype=="blocks":
942
			# we've encountered a "blocks" node.  We will totally ignore this
943
			# node and not add it to our digraph if it doesn't apply to us.
944
			if addme and "--buildpkgonly" not in myopts and myparent and (self.mydbapi[myroot].match(mykey) or vardbapi.match(mykey)):
945
				mybigkey.append(myparent.split()[2])
946
				self.digraph.addnode(string.join(mybigkey),myparent)
947
			return 1
948
949
		if myuse is None:
950
			self.pkgsettings.setcpv(mykey)
951
			myuse = self.pkgsettings["USE"].split()
952
		self.applied_useflags[mykey] = myuse
953
954
		merging=1
955
		if addme:
956
		# this is where we add the node to the list of packages to merge
957
			if not myparent:
958
				# command-line specified or part of a world list...
959
				if ("self" not in myparams) or (("selective" in myparams) and vardbapi.cpv_exists(mykey)):
960
					# the package is on the system, so don't merge it.
961
					merging=0
962
			elif ("selective" in myparams) and vardbapi.cpv_exists(mykey):
963
				merging=0
964
965
			if (merging==0 and "--newuse" in myopts and vardbapi.cpv_exists(mykey)):
966
				old_use = vardbapi.aux_get(mykey, ["USE"])[0].split()
967
				if mytype == "binary":
968
					iuses = portage.db["/"]["bintree"].dbapi.aux_get(mykey, ["IUSE"])[0].split()
969
				else:
970
					iuses = portage.db["/"]["porttree"].dbapi.aux_get(mykey, ["IUSE"])[0].split()
971
				for x in iuses:
972
					if (old_use.count(x) and not myuse.count(x)) or (not old_use.count(x) and myuse.count(x)):
973
						merging=1
974
						break
975
		else:
976
			#onlydeps mode; don't merge
977
			merging=2
978
		if merging==1:
979
			mybigkey.append("merge")
980
		else:
981
			mybigkey.append("nomerge")
982
983
		# whatever the case, we need to add the node to our digraph so
984
		# that children can depend upon it.
985
		self.digraph.addnode(string.join(mybigkey),myparent)
986
		if ("deep" not in myparams) and (not merging):
987
			return 1
988
		elif "recurse" not in myparams:
989
			return 1
990
991
		edepend={}
992
		if mytype=="binary":
993
			mypkgparts=portage.catpkgsplit(mykey)
994
			tbz2name = string.split(mykey, "/")[1]+".tbz2"
995
			if tbz2name in portage.db[portage.root]["bintree"].invalids:
996
				sys.stderr.write("\nINVALID PACKAGE (is required to continue): "+str(mykey)+"\n")
997
				sys.exit(1)
998
			if portage.db[portage.root]["bintree"].isremote(mykey):
999
				edepend = portage.db[portage.root]["bintree"].remotepkgs[tbz2name]
1000
				edepend["DEPEND"] =""
1001
				edepend["RDEPEND"]=string.join(string.split(edepend["RDEPEND"])," ")
1002
				edepend["PDEPEND"]=string.join(string.split(edepend["PDEPEND"])," ")
1003
				edepend["SLOT"]   =string.strip(edepend["SLOT"])
1004
				#portage.db[portage.root]["bintree"].gettbz2(mykey)
1005
			else: # It's local.
1006
				mytbz2=xpak.tbz2(portage.db[portage.root]["bintree"].getname(mykey))
1007
				edepend["DEPEND"] =""
1008
				edepend["RDEPEND"]=string.join(mytbz2.getelements("RDEPEND")," ")
1009
				edepend["PDEPEND"]=string.join(mytbz2.getelements("PDEPEND")," ")
1010
				edepend["SLOT"]   =mytbz2.getfile("SLOT",mypkgparts[2])
1011
		elif mytype=="ebuild":
1012
			try:
1013
				mymeta = ["DEPEND","RDEPEND","PDEPEND"]
1014
				myfoo = portage.portdb.aux_get(mykey, mymeta)
1015
				for index in range(0,len(mymeta)):
1016
					edepend[mymeta[index]] = myfoo[index]
1017
				if "--buildpkgonly" in myopts:
1018
					edepend["RDEPEND"] = ""
1019
					edepend["PDEPEND"] = ""
1020
			except (KeyError,IOError):
1021
				print "emerge: create(): aux_get() error on",mykey+"; aborting..."
1022
				sys.exit(1)
1023
		mydep={}
1024
		mp=string.join(mybigkey)
1025
1026
		if myroot=="/":
1027
			mydep["/"]=edepend["DEPEND"]+" "+edepend["RDEPEND"]
1028
			if not self.select_dep("/",mydep["/"],myparent=mp,myuse=myuse):
1029
				return 0
1030
		else:
1031
			mydep["/"]=edepend["DEPEND"]
1032
			mydep[myroot]=edepend["RDEPEND"]
1033
			if not self.select_dep("/",mydep["/"],myparent=mp,myuse=myuse):
1034
				return 0
1035
			if not self.select_dep(myroot,mydep[myroot],myparent=mp,myuse=myuse):
1036
				return 0
1037
1038
		if edepend.has_key("PDEPEND") and edepend["PDEPEND"]:
1039
			# Post Depend -- Add to the list without a parent, as it depends
1040
			# on a package being present AND must be built after that package.
1041
			if not self.select_dep(myroot,edepend["PDEPEND"],myuse=myuse):
1042
				return 0
1043
1044
		return 1
1045
1046
	def select_files(self,myfiles):
1047
		"given a list of .tbz2s, .ebuilds and deps, create the appropriate depgraph and return a favorite list"
1048
		myfavorites=[]
1049
		for x in myfiles:
1050
			ext = os.path.splitext(x)[1]
1051
			if ext==".tbz2":
1052
				if not os.path.exists(x):
1053
					if os.path.exists(self.pkgsettings["PKGDIR"]+"/All/"+x):
1054
						x=self.pkgsettings["PKGDIR"]+"/All/"+x
1055
					elif os.path.exists(self.pkgsettings["PKGDIR"]+"/"+x):
1056
						x=self.pkgsettings["PKGDIR"]+"/"+x
1057
					else:
1058
						print "\n\n!!! Binary package '"+str(x)+"' does not exist."
1059
						print "!!! Please ensure the tbz2 exists as specified.\n"
1060
						sys.exit(1)
1061
				mytbz2=xpak.tbz2(x)
1062
				mykey=mytbz2.getelements("CATEGORY")[0]+"/"+os.path.splitext(os.path.basename(x))[0]
1063
				if os.path.realpath(portage.db["/"]["bintree"].getname(mykey)) != os.path.realpath(x):
1064
					print red("\n*** You need to adjust PKGDIR to emerge this package.\n")
1065
					sys.exit(1)
1066
				if not self.create(["binary",portage.root,mykey],None,"--onlydeps" not in myopts):
1067
					return (0,myfavorites)
1068
				elif not "--oneshot" in myopts:
1069
					myfavorites.append(mykey)
1070
			elif ext==".ebuild":
1071
				x = os.path.realpath(x)
1072
				mykey=os.path.basename(os.path.normpath(x+"/../.."))+"/"+os.path.splitext(os.path.basename(x))[0]
1073
				ebuild_path = portage.db["/"]["porttree"].dbapi.findname(mykey)
1074
				if ebuild_path:
1075
					if os.path.realpath(ebuild_path) != x:
1076
						print red("\n*** You need to adjust PORTDIR or PORTDIR_OVERLAY to emerge this package.\n")
1077
						sys.exit(1)
1078
					if mykey not in portage.db["/"]["porttree"].dbapi.xmatch("match-visible", portage.dep_getkey(mykey)):
1079
						print red("\n*** You are emerging a masked package. It is MUCH better to use")
1080
						print red("*** /etc/portage/package.* to accomplish this. See portage(5) man")
1081
						print red("*** page for details.")
1082
						countdown(EMERGE_WARNING_DELAY, "Continuing...")
1083
				else:
1084
					raise portage_exception.PackageNotFound(
1085
						"%s is not in a valid portage tree hierarchy or does not exist" % x)
1086
				if not self.create(["ebuild",portage.root,mykey],None,"--onlydeps" not in myopts):
1087
					return (0,myfavorites)
1088
				elif not "--oneshot" in myopts:
1089
					myfavorites.append(mykey)
1090
			else:
1091
				if not is_valid_package_atom(x):
1092
					portage.writemsg("\n\n!!! '%s' is not a valid package atom.\n" % x,
1093
						noiselevel=-1)
1094
					portage.writemsg("!!! Please check ebuild(5) for full details.\n")
1095
					portage.writemsg("!!! (Did you specify a version but forget to prefix with '='?)\n")
1096
					return (0,[])
1097
				try:
1098
					mykey=portage.dep_expand(x,mydb=portage.portdb)
1099
				except ValueError, errpkgs:
1100
					print "\n\n!!! The short ebuild name \"" + x + "\" is ambiguous.  Please specify"
1101
					print "!!! one of the following fully-qualified ebuild names instead:\n"
1102
					for i in errpkgs[0]:
1103
						print "    " + green(i)
1104
					print
1105
					sys.exit(1)
1106
1107
				# select needs to return 0 on dep_check failure
1108
1109
				sys.stdout.flush()
1110
				sys.stderr.flush()
1111
1112
				try:
1113
					self.mysd = self.select_dep(portage.root,mykey,arg=x)
1114
				except portage_exception.MissingSignature, e:
1115
					portage.writemsg("\n\n!!! A missing gpg signature is preventing portage from calculating the\n")
1116
					portage.writemsg("!!! required dependencies. This is a security feature enabled by the admin\n")
1117
					portage.writemsg("!!! to aid in the detection of malicious intent.\n\n")
1118
					portage.writemsg("!!! THIS IS A POSSIBLE INDICATION OF TAMPERED FILES -- CHECK CAREFULLY.\n")
1119
					portage.writemsg("!!! Affected file: %s\n" % (e), noiselevel=-1)
1120
					sys.exit(1)
1121
				except portage_exception.InvalidSignature, e:
1122
					portage.writemsg("\n\n!!! An invalid gpg signature is preventing portage from calculating the\n")
1123
					portage.writemsg("!!! required dependencies. This is a security feature enabled by the admin\n")
1124
					portage.writemsg("!!! to aid in the detection of malicious intent.\n\n")
1125
					portage.writemsg("!!! THIS IS A POSSIBLE INDICATION OF TAMPERED FILES -- CHECK CAREFULLY.\n")
1126
					portage.writemsg("!!! Affected file: %s\n" % (e), noiselevel=-1)
1127
					sys.exit(1)
1128
				except SystemExit, e:
1129
					raise # Needed else can't exit
1130
				except Exception, e:
1131
					if "--debug" in myopts:
1132
						raise
1133
					print "\n\n!!! Problem in",mykey,"dependencies."
1134
					print "!!!",str(e),e.__module__
1135
					sys.exit(1)
1136
1137
				if not self.mysd:
1138
					return (0,myfavorites)
1139
				elif not "--oneshot" in myopts:
1140
					myfavorites.append(portage.dep_getkey(mykey))
1141
1142
		missing=0
1143
		if "--usepkgonly" in myopts:
1144
			for x in self.digraph.dict.keys():
1145
				xs=string.split(x," ")
1146
				if (xs[0] != "binary") and (xs[3]=="merge"):
1147
					if missing == 0:
1148
						print
1149
					missing += 1
1150
					print "Missing binary for:",xs[2]
1151
1152
		# We're true here unless we are missing binaries.
1153
		return (not missing,myfavorites)
1154
1155
	def is_newer_ver_installed(self,myroot,pkg,pkgver):
1156
		"if there is a version of pkg installed newer than pkgver, return it"
1157
		vardbapi=portage.db[myroot]["vartree"].dbapi
1158
1159
		matches=portage.db[myroot]["vartree"].dbapi.match(pkg)
1160
		if matches:
1161
			myslot=portage.db["/"]["porttree"].getslot(pkgver)
1162
			for match in matches:
1163
				if portage.pkgcmp(portage.catpkgsplit(pkgver)[1:], portage.catpkgsplit(match)[1:]) < 0:
1164
					curslot=portage.db[myroot]["vartree"].getslot(match)
1165
					if curslot == myslot:
1166
						return match
1167
1168
	def select_dep(self,myroot,depstring,myparent=None,arg=None,myuse=None,raise_on_missing=False):
1169
		"given a dependency string, create the appropriate depgraph and return 1 on success and 0 on failure"
1170
		if "--debug" in myopts:
1171
			print
1172
			print "Parent:   ",myparent
1173
			print "Depstring:",depstring
1174
		if not arg:
1175
			#processing dependencies
1176
			mycheck=portage.dep_check(depstring,self.mydbapi[myroot],self.pkgsettings,myuse=myuse,use_binaries=("--usepkgonly" in myopts),myroot=myroot)
1177
1178
			if not mycheck[0]:
1179
				mymerge=[]
1180
			else:
1181
				mymerge=mycheck[1]
1182
1183
		else:
1184
			#we're processing a command-line argument; unconditionally merge it even if it's already merged
1185
			mymerge=[depstring]
1186
1187
		# dep_check has been run so we can now add our parent to our
1188
		# build state to update virtuals and other settings. This
1189
		# happens after the package is added to the tree so that a
1190
		# package can depend on a virtual which it satisfies.
1191
		if myparent:
1192
			myp = myparent.split()
1193
			if myp[3]=="merge":
1194
				self.mydbapi[myroot].cpv_inject(myp[2])
1195
				if myp[0]=="binary":
1196
					self.pkgsettings.setinst(myp[2],portage.db["/"]["bintree"].dbapi)
1197
				else:
1198
					self.pkgsettings.setinst(myp[2],portage.db[myroot]["porttree"].dbapi)
1199
1200
		if not mymerge:
1201
			return 1
1202
1203
		if "--debug" in myopts:
1204
			print "Candidates:",mymerge
1205
		for x in mymerge:
1206
			myk=None
1207
			binpkguseflags=None
1208
			if x[0]=="!":
1209
				# if this package is myself, don't append it to block list.
1210
				if "--debug" in myopts:
1211
					print "Myparent",myparent
1212
				if (myparent):
1213
					if myparent.split()[2] in portage.portdb.xmatch("match-all", x[1:]):
1214
						# myself, so exit.
1215
						continue
1216
				# adding block
1217
				myk=["blocks",myroot,x[1:]]
1218
			else:
1219
				#We are not processing a blocker but a normal dependency
1220
				myeb=None
1221
				myeb_matches = portage.portdb.xmatch("match-visible",x)
1222
				if ("--usepkgonly" not in myopts):
1223
					myeb=portage.best(myeb_matches)
1224
1225
				myeb_pkg=None
1226
				if ("--usepkg" in myopts):
1227
					# The next line assumes the binarytree has been populated.
1228
					# XXX: Need to work out how we use the binary tree with roots.
1229
					myeb_pkg_matches=portage.db["/"]["bintree"].dbapi.match(x)
1230
					if ("--usepkgonly" not in myopts):
1231
						# Remove any binary package entries that are masked in the portage tree (#55871)
1232
						for idx in range(len(myeb_pkg_matches)-1,-1,-1):
1233
							if myeb_pkg_matches[idx] not in myeb_matches:
1234
								del myeb_pkg_matches[idx]
1235
					myeb_pkg = portage.best(myeb_pkg_matches)
1236
1237
				if not myeb_pkg:
1238
					myeb_pkg = None
1239
				elif ("--newuse" in myopts):
1240
					iuses=string.split(portage.db["/"]["bintree"].dbapi.aux_get(myeb_pkg, ["IUSE"])[0])
1241
					old_use=string.split(portage.db["/"]["bintree"].dbapi.aux_get(myeb_pkg, ["USE"])[0])
1242
					self.pkgsettings.setcpv(myeb_pkg)
1243
					now_use=string.split(self.pkgsettings["USE"])
1244
					for x in iuses:
1245
						if (old_use.count(x) and not now_use.count(x)) or (not old_use.count(x) and now_use.count(x)):
1246
							myeb_pkg = None
1247
							break
1248
1249
				if (not myeb) and (not myeb_pkg):
1250
					if raise_on_missing:
1251
						raise ValueError
1252
					if not arg:
1253
						xinfo='"'+x+'"'
1254
					else:
1255
						xinfo='"'+arg+'"'
1256
					if myparent:
1257
						xfrom = '(dependency required by '+green('"'+myparent.split()[2]+'"')+red(' ['+myparent.split()[0]+"]")+')'
1258
					alleb=portage.portdb.xmatch("match-all",x)
1259
					if alleb:
1260
						if "--usepkgonly" not in myopts:
1261
							print "\n!!! "+red("All ebuilds that could satisfy ")+green(xinfo)+red(" have been masked.")
1262
							print "!!! One of the following masked packages is required to complete your request:"
1263
							oldcomment = ""
1264
							for p in alleb:
1265
								mreasons = portage.getmaskingstatus(p)
1266
								print "- "+p+" (masked by: "+string.join(mreasons, ", ")+")"
1267
								comment = portage.getmaskingreason(p)
1268
								if comment and comment != oldcomment:
1269
									print comment
1270
									oldcomment = comment
1271
							print
1272
							print "For more information, see MASKED PACKAGES section in the emerge man page or "
1273
							print "refer to the Gentoo Handbook."
1274
						else:
1275
							print "\n!!! "+red("There are no packages available to satisfy: ")+green(xinfo)
1276
							print "!!! Either add a suitable binary package or compile from an ebuild."
1277
					else:
1278
						print "\nemerge: there are no ebuilds to satisfy "+green(xinfo)+"."
1279
					if myparent:
1280
						print xfrom
1281
					print
1282
					return 0
1283
1284
				if "--debug" in myopts:
1285
					print "ebuild:",myeb
1286
					print "binpkg:",myeb_pkg
1287
1288
				if myeb and myeb_pkg:
1289
					myeb_s     = portage.catpkgsplit(myeb)
1290
					myeb_s     = [myeb_s[0]+"/"+myeb_s[1], myeb_s[2], myeb_s[3]]
1291
					myeb_pkg_s = portage.catpkgsplit(myeb_pkg)
1292
					myeb_pkg_s = [myeb_pkg_s[0]+"/"+myeb_pkg_s[1], myeb_pkg_s[2], myeb_pkg_s[3]]
1293
1294
					if portage.pkgcmp(myeb_s, myeb_pkg_s) == 0: # pkg is same version as ebuild
1295
						myeb = None
1296
					else:
1297
						myeb_pkg = None
1298
1299
				if myeb:
1300
					myk=["ebuild",myroot,myeb]
1301
				elif myeb_pkg:
1302
					binpkguseflags=portage.db[portage.root]["bintree"].get_use(myeb_pkg)
1303
					myk=["binary",myroot,myeb_pkg]
1304
				else:
1305
					sys.stderr.write("!!! Confused... Don't know what's being used for dependency info. :(\n")
1306
					sys.exit(1)
1307
1308
				#if "--usepkg" in myopts:
1309
				#	#If we want to use packages, see if we have a pre-built one...
1310
				#	mypk=portage.db["/"]["bintree"].dbapi.match(x)
1311
				#	if myeb in mypk:
1312
				#		#Use it only if it's exactly the version we want.
1313
				#		myk=["binary",myroot,myeb]
1314
				#	else:
1315
				#		myk=["ebuild",myroot,myeb]
1316
				#else:
1317
				#	myk=["ebuild",myroot,myeb]
1318
			if myparent:
1319
				#we are a dependency, so we want to be unconditionally added
1320
				if not self.create(myk,myparent,myuse=binpkguseflags):
1321
					return 0
1322
			else:
1323
				#if mysource is not set, then we are a command-line dependency and should not be added
1324
				#if --onlydeps is specified.
1325
				if not self.create(myk,myparent,"--onlydeps" not in myopts,myuse=binpkguseflags):
1326
					return 0
1327
1328
		if "--debug" in myopts:
1329
			print "Exiting...",myparent
1330
		return 1
1331
1332
1333
	def altlist(self):
1334
		mygraph=self.digraph.copy()
1335
		dolist=["/"]
1336
		retlist=[]
1337
		for x in portage.db.keys():
1338
			portage.db[x]["merge"]=[]
1339
			if x not in dolist:
1340
				dolist.append(x)
1341
		while (not mygraph.empty()):
1342
			mycurkey=mygraph.firstzero()
1343
			if not mycurkey:
1344
				print "!!! Error: circular dependencies:"
1345
				print
1346
				for x in mygraph.dict.keys():
1347
					for y in mygraph.dict[x][1]:
1348
						print y,"depends on",x
1349
				print
1350
				sys.exit(1)
1351
			splitski=string.split(mycurkey)
1352
			#I'm not sure of the significance of the following lines (vestigal?) so I'm commenting 'em out.
1353
			#These lines remove already-merged things from our alt-list
1354
			#if "--update" in myopts:
1355
			#	if not portage.db["/"]["vartree"].exists_specific(splitski[2]):
1356
			#		portage.db["/"]["merge"].append(splitski)
1357
			#else:
1358
			portage.db[splitski[1]]["merge"].append(splitski)
1359
			mygraph.delnode(mycurkey)
1360
		for x in dolist:
1361
			for y in portage.db[x]["merge"]:
1362
				retlist.append(y)
1363
		return retlist
1364
1365
	def xcreate(self,mode="system"):
1366
		global syslist
1367
		world_problems = False
1368
		if mode=="system":
1369
			mylist=syslist
1370
		else:
1371
			#world mode
1372
			worldlist=getlist("world")
1373
			sysdict=genericdict(syslist)
1374
			worlddict=genericdict(worldlist)
1375
1376
			for x in worlddict.keys():
1377
				if not portage.isvalidatom(x):
1378
					world_problems = True
1379
				elif not portage.db["/"]["vartree"].dbapi.match(x):
1380
					world_problems = True
1381
				else:
1382
					sysdict[x]=worlddict[x]
1383
1384
			mylist = sysdict.keys()
1385
1386
		newlist = []
1387
		for atom in mylist:
1388
			if portage.dep_getkey(atom).split("/")[-1] == "portage":
1389
				newlist.insert(0, atom)
1390
			else:
1391
				newlist.append(atom)
1392
		mylist = newlist
1393
		
1394
		missing_atoms = []
1395
		for mydep in mylist:
1396
			try:
1397
				if not self.select_dep(portage.root, mydep, raise_on_missing=True):
1398
					print "\n\n!!! Problem resolving dependencies for", mydep
1399
					return 0
1400
			except ValueError:
1401
				if "--debug" in myopts:
1402
					raise
1403
				missing_atoms.append(mydep)
1404
1405
		if world_problems:
1406
			print "\n!!! Problems have been detected with your world file"
1407
			print "!!! Please run "+green("emaint --check world")+"\n"
1408
1409
		if missing_atoms and "--verbose" in myopts:
1410
			print "\n!!! Packages for the following atoms are either all"
1411
			print "!!! masked or don't exist:"
1412
			print " ".join(missing_atoms) + "\n"
1413
1414
		return 1
1415
1416
	def match(self,mydep,myroot=portage.root,mykey=None):
1417
		# support mutual exclusive deps
1418
		mydep2=mydep
1419
		if mydep2[0]=="!":
1420
			mydep2=mydep[1:]
1421
1422
		if mydep[0]=="!":
1423
			#add our blocker; it will be ignored later if necessary (if we are remerging the same pkg, for example)
1424
			myk="blocks "+myroot+" "+mydep2
1425
		else:
1426
			myeb=portage.db[portage.root]["porttree"].dep_bestmatch(mydep2)
1427
			if not myeb:
1428
				if not mykey:
1429
					print "\n!!! Error: couldn't find match for",mydep
1430
				else:
1431
					print "\n!!! Error: couldn't find match for",mydep,"in",mykey
1432
				print
1433
				sys.exit(1)
1434
1435
			if "--usepkg" in myopts:
1436
				mypk=portage.db[portage.root]["bintree"].dep_bestmatch(mydep)
1437
				if myeb==mypk:
1438
					myk="binary "+portage.root+" "+mypk
1439
				else:
1440
					myk="ebuild "+myroot+" "+myeb
1441
			else:
1442
				myk="ebuild "+myroot+" "+myeb
1443
1444
		return myk
1445
1446
	def display(self,mylist,verbosity=("--quiet" in myopts and 1 or "--verbose" in myopts and 3 or 2 )):
1447
		changelogs=[]
1448
		p=[]
1449
		totalsize=0
1450
1451
		if verbosity == 1:
1452
			def create_use_string(*args):
1453
				return ""
1454
		else:
1455
			def create_use_string(name, cur_iuse, cur_use, old_iuse, old_use, is_new,
1456
					all_flags=(verbosity == 3), alphabetical=("--alphabetical" in myopts)):
1457
				enabled = []
1458
				if alphabetical:
1459
					disabled = enabled
1460
				else:
1461
					disabled = []
1462
				for flag in cur_iuse:
1463
					if flag in cur_use:
1464
						if is_new or flag in old_use and all_flags:
1465
							enabled.append(red(flag))
1466
						elif flag not in old_iuse:
1467
							enabled.append(yellow(flag)+"%")
1468
						elif flag not in old_use:
1469
							enabled.append(green(flag)+"*")
1470
					else:
1471
						if is_new or flag in old_iuse and flag not in old_use and all_flags:
1472
							disabled.append(blue("-"+flag))
1473
						elif flag not in old_iuse:
1474
							disabled.append(yellow("-"+flag)+"%")
1475
						elif flag in old_use:
1476
							disabled.append(green("-"+flag)+"*")
1477
1478
				enabled = " ".join(enabled)
1479
				if alphabetical:
1480
					disabled = ""
1481
				else:
1482
					disabled = " ".join(disabled)
1483
				if enabled and disabled:
1484
					ret = enabled + " " + disabled
1485
				elif enabled:
1486
					ret = enabled
1487
				else:
1488
					ret = disabled
1489
				if ret:
1490
					ret = '%s="%s" ' % (name, ret)
1491
				return ret
1492
1493
		if verbosity == 3:
1494
			overlays = self.pkgsettings["PORTDIR_OVERLAY"].split()
1495
			overlays_real = [os.path.realpath(t) \
1496
				for t in self.pkgsettings["PORTDIR_OVERLAY"].split()]
1497
1498
		if "--tree" in myopts:
1499
			mylist.reverse()
1500
			mygraph=self.digraph.copy()
1501
1502
		i = 0
1503
		while i < len(mylist):
1504
			if mylist[i][-1]=="nomerge":
1505
				if not ("--tree" in myopts):
1506
					# we don't care about this elements
1507
					mylist.pop(i)
1508
					continue
1509
				if (i == (len(mylist) - 1)) \
1510
				   or (mygraph.depth(string.join(mylist[i])) \
1511
				       >= mygraph.depth(string.join(mylist[i+1]))):
1512
					# end of a useless branch (may be the last one)
1513
					# -> delete the element and test the previous one
1514
					mylist.pop(i)
1515
					if i > 0:
1516
						i -= 1
1517
					continue
1518
			# the branch continues, or we've found a good element.
1519
			# -> let's see what's next, if anything
1520
			i += 1
1521
1522
		display_overlays=False
1523
		# files to fetch list - avoids counting a same file twice
1524
		# in size display (verbose mode)
1525
		myfetchlist=[]
1526
		for x in mylist:
1527
			pkg_type = x[0]
1528
			pkg_key = x[2]
1529
			if pkg_key not in self.applied_useflags:
1530
				if "binary" == pkg_type:
1531
					self.applied_useflags[pkg_key] = portage.db["/"]["bintree"].dbapi.aux_get(pkg_key, ["USE"])[0].split()
1532
				elif "ebuild" == pkg_type:
1533
					self.pkgsettings.setcpv(pkg_key)
1534
					self.applied_useflags[pkg_key] = self.pkgsettings["USE"].split()
1535
1536
			fetch=" "
1537
1538
			if x[0]=="blocks":
1539
				addl=""+red("B")+"  "+fetch+"  "
1540
				resolved=portage.db[x[1]]["vartree"].resolve_key(x[2])
1541
				print "["+x[0]+" "+addl+"]",red(resolved),
1542
				if resolved!=x[2]:
1543
					if x[3]:
1544
						print red("(\""+x[2]+"\" is blocking "+x[3]+")")
1545
					else:
1546
						print red("(\""+x[2]+"\")")
1547
				else:
1548
					if x[3]:
1549
						print red("(is blocking "+x[3]+")")
1550
					else:
1551
						print
1552
			else:
1553
				if (x[0]!="binary") and ("fetch" in string.split(portage.portdb.aux_get(x[2],["RESTRICT"])[0])):
1554
					fetch = red("F")
1555
					if portage.portdb.fetch_check(x[2], self.applied_useflags[x[2]]):
1556
						fetch = green("f")
1557
1558
				#we need to use "--emptrytree" testing here rather than "empty" param testing because "empty"
1559
				#param is used for -u, where you still *do* want to see when something is being upgraded.
1560
				myoldbest=""
1561
				if (not "--emptytree" in myopts) and portage.db[x[1]]["vartree"].exists_specific(x[2]):
1562
					addl="  "+yellow("R")+fetch+"  "
1563
				elif (not "--emptytree" in myopts) and portage.db[x[1]]["vartree"].exists_specific_cat(x[2]):
1564
					if x[0] == "binary":
1565
						mynewslot=portage.db["/"]["bintree"].getslot(x[2])
1566
					elif x[0] == "ebuild":
1567
						mynewslot=portage.db["/"]["porttree"].getslot(x[2])
1568
					myoldlist=portage.db[x[1]]["vartree"].dbapi.match(portage.pkgsplit(x[2])[0])
1569
					myinslotlist=filter((lambda p: portage.db[portage.root]["vartree"].getslot(p)==mynewslot),myoldlist)
1570
					if myinslotlist:
1571
						myoldbest=portage.best(myinslotlist)
1572
						addl="   "+fetch
1573
						if portage.pkgcmp(portage.pkgsplit(x[2]), portage.pkgsplit(myoldbest)) < 0:
1574
							# Downgrade in slot
1575
							addl+=turquoise("U")+blue("D")
1576
						else:
1577
							# Update in slot
1578
							addl+=turquoise("U")+" "
1579
					else:
1580
						# New slot, mark it new.
1581
						addl=" "+green("NS")+fetch+"  "
1582
1583
					if "--changelog" in myopts:
1584
						changelogs.extend(self.calc_changelog(
1585
							portage.portdb.findname(x[2]),
1586
							portage.db[x[1]]["vartree"].dep_bestmatch('/'.join(portage.catpkgsplit(x[2])[:2])),
1587
							x[2]
1588
							))
1589
				else:
1590
					addl=" "+green("N")+" "+fetch+"  "
1591
1592
				verboseadd=""
1593
				
1594
				if x[2] in self.applied_useflags:
1595
					# USE flag display
1596
					if x[0] == "binary":
1597
						cur_iuse = string.split(portage.db["/"]["bintree"].dbapi.aux_get(x[2],["IUSE"])[0])
1598
					elif x[0] == "ebuild":
1599
						cur_iuse = string.split(portage.portdb.aux_get(x[2],["IUSE"])[0])
1600
					else:
1601
						cur_iuse = []
1602
1603
					cur_iuse = portage.unique_array(cur_iuse)
1604
					cur_iuse = [flag for flag in cur_iuse if flag not in portage.settings.usemask]
1605
					cur_iuse.sort()
1606
					cur_use = self.applied_useflags[x[2]]
1607
					cur_use = [flag for flag in cur_use if flag in cur_iuse]
1608
1609
					if myoldbest:
1610
						pkg = myoldbest
1611
					else:
1612
						pkg = x[2]
1613
					if portage.db[x[1]]["vartree"].dbapi.cpv_exists(pkg):
1614
						(old_iuse, old_use) = portage.db[x[1]]["vartree"].dbapi.aux_get(pkg, ["IUSE", "USE"])
1615
						old_iuse = portage.unique_array(old_iuse.split())
1616
						old_iuse.sort()
1617
						old_use = old_use.split()
1618
						is_new = False
1619
					else:
1620
						old_iuse = []
1621
						old_use = []
1622
						is_new = True
1623
					old_iuse = [flag for flag in old_iuse if flag not in portage.settings.usemask]
1624
					old_use = [flag for flag in old_use if flag in old_iuse]
1625
1626
					use_expand = portage.settings["USE_EXPAND"].lower().split()
1627
					use_expand.sort()
1628
					use_expand.reverse()
1629
					use_expand_hidden = portage.settings["USE_EXPAND_HIDDEN"].lower().split()
1630
1631
					def map_to_use_expand(myvals):
1632
						ret = {}
1633
						for exp in use_expand:
1634
							ret[exp] = []
1635
							for val in myvals[:]:
1636
								if val.startswith(exp.lower()+"_"):
1637
									ret[exp].append(val[len(exp)+1:])
1638
									myvals.remove(val)
1639
						ret["USE"] = myvals
1640
						for exp in use_expand_hidden:
1641
							if exp in ret:
1642
								del ret[exp]
1643
						return ret
1644
1645
					cur_iuse_map = map_to_use_expand(cur_iuse)
1646
					cur_use_map = map_to_use_expand(cur_use)
1647
					old_iuse_map = map_to_use_expand(old_iuse)
1648
					old_use_map = map_to_use_expand(old_use)
1649
1650
					use_expand.sort()
1651
					use_expand.insert(0, "USE")
1652
					
1653
					for key in use_expand:
1654
						if key in use_expand_hidden:
1655
							continue
1656
						verboseadd += create_use_string(key.upper(), cur_iuse_map[key], cur_use_map[key],
1657
						                                old_iuse_map[key], old_use_map[key], is_new)
1658
1659
				if verbosity == 3:
1660
					# size verbose
1661
					mysize=0
1662
					if x[0] == "ebuild" and x[-1]!="nomerge":
1663
						myfilesdict=portage.portdb.getfetchsizes(x[2], useflags=self.applied_useflags[x[2]], debug=edebug)
1664
						if myfilesdict is None:
1665
							myfilesdict="[empty/missing/bad digest]"
1666
						else:
1667
							for myfetchfile in myfilesdict.keys():
1668
								if myfetchfile not in myfetchlist:
1669
									mysize+=myfilesdict[myfetchfile]
1670
									myfetchlist.append(myfetchfile)
1671
							totalsize+=mysize
1672
						verboseadd+=format_size(mysize)+" "
1673
1674
					# overlay verbose
1675
					# XXX: Invalid binaries have caused tracebacks here. 'if file_name'
1676
					# x = ['binary', '/', 'sys-apps/pcmcia-cs-3.2.7.2.6', 'merge']
1677
					file_name=portage.portdb.findname(x[2])
1678
					if file_name: # It might not exist in the tree
1679
						dir_name=os.path.abspath(os.path.dirname(file_name)+"/../..")
1680
						if (overlays_real.count(dir_name)>0):
1681
							verboseadd+=teal("["+str(overlays_real.index(
1682
								os.path.normpath(dir_name))+1)+"]")+" "
1683
							display_overlays=True
1684
					else:
1685
						verboseadd += "[No ebuild?]"
1686
1687
				xs=portage.pkgsplit(x[2])
1688
				if xs[2]=="r0":
1689
					xs[2]=""
1690
				else:
1691
					xs[2]="-"+xs[2]
1692
1693
				if self.pkgsettings.has_key("COLUMNWIDTH"):
1694
					mywidth=int(self.pkgsettings.settings["COLUMNWIDTH"])
1695
				else:
1696
					mywidth=130
1697
				oldlp=mywidth-30
1698
				newlp=oldlp-30
1699
1700
				indent=""
1701
				if ("--tree" in myopts):
1702
					indent=" "*mygraph.depth(string.join(x))
1703
1704
				if myoldbest:
1705
					myoldbest=portage.pkgsplit(myoldbest)[1]+"-"+portage.pkgsplit(myoldbest)[2]
1706
					if myoldbest[-3:]=="-r0":
1707
						myoldbest=myoldbest[:-3]
1708
					myoldbest=blue("["+myoldbest+"]")
1709
1710
				if x[1]!="/":
1711
					if myoldbest:
1712
						myoldbest +=" "
1713
					if "--columns" in myopts:
1714
						if "--quiet" in myopts:
1715
							myprint=addl+" "+indent+darkgreen(xs[0])
1716
							myprint=myprint+darkblue(" "+xs[1]+xs[2])+" "
1717
							myprint=myprint+myoldbest
1718
							myprint=myprint+darkgreen("to "+x[1])
1719
						else:
1720
							myprint="["+x[0]+" "+addl+"] "+indent+darkgreen(xs[0])
1721
							if (newlp-nc_len(myprint)) > 0:
1722
								myprint=myprint+(" "*(newlp-nc_len(myprint)))
1723
							myprint=myprint+"["+darkblue(xs[1]+xs[2])+"] "
1724
							if (oldlp-nc_len(myprint)) > 0:
1725
								myprint=myprint+" "*(oldlp-nc_len(myprint))
1726
							myprint=myprint+myoldbest
1727
							myprint=myprint+darkgreen("to "+x[1])+" "+verboseadd
1728
					else:
1729
						myprint="["+x[0]+" "+addl+"] "+darkgreen(x[2])+" "+myoldbest+darkgreen("to "+x[1])+" "+verboseadd
1730
				else:
1731
					if "--columns" in myopts:
1732
						if "--quiet" in myopts:
1733
							myprint=addl+" "+indent+darkgreen(xs[0])
1734
							myprint=myprint+" "+green(xs[1]+xs[2])+" "
1735
							myprint=myprint+myoldbest
1736
						else:
1737
							myprint="["+x[0]+" "+addl+"] "+indent+darkgreen(xs[0])
1738
							if (newlp-nc_len(myprint)) > 0:
1739
								myprint=myprint+(" "*(newlp-nc_len(myprint)))
1740
							myprint=myprint+green(" ["+xs[1]+xs[2]+"] ")
1741
							if (oldlp-nc_len(myprint)) > 0:
1742
								myprint=myprint+(" "*(oldlp-nc_len(myprint)))
1743
							myprint=myprint+myoldbest+"  "+verboseadd
1744
					else:
1745
						if x[3]=="nomerge":
1746
							myprint=darkblue("[nomerge      ] "+indent+x[2]+" "+myoldbest+" ")+verboseadd
1747
						else:
1748
							myprint="["+x[0]+" "+addl+"] "+indent+darkgreen(x[2])+" "+myoldbest+" "+verboseadd
1749
				p.append(myprint)
1750
1751
			mysplit = portage.pkgsplit(x[2])
1752
			if "--tree" not in myopts and mysplit and len(mysplit) == 3 and \
1753
				mysplit[0] == "sys-apps/portage" and x[1] == "/":
1754
1755
				if mysplit[2] == "r0":
1756
					myversion = mysplit[1]
1757
				else:
1758
					myversion = "%s-%s" % (mysplit[1], mysplit[2])
1759
1760
				if myversion != portage.VERSION :
1761
					if "--emptytree" in myopts:
1762
						p.append(red("***")+" Please update portage to the above version before proceeding.")
1763
						p.append("    Failure to do so may result in failed or improper merges.")
1764
						p.append("    A simple '"+green("emerge portage")+"' is sufficient.")
1765
						p.append("")
1766
					elif mylist.index(x) < len(mylist) - 1 and \
1767
						"livecvsportage" not in portage.settings.features:
1768
						p.append(red("*** Portage will stop merging at this point and reload itself,"))
1769
						p.append(red("    then resume the merge."))
1770
						print
1771
			del mysplit
1772
1773
		for x in p:
1774
			print x
1775
1776
		if verbosity == 3:
1777
			print
1778
			print "Total size of downloads: "+format_size(totalsize)
1779
			if overlays and display_overlays:
1780
				print "Portage overlays:"
1781
				y=0
1782
				for x in overlays:
1783
					y=y+1
1784
					print " "+teal("["+str(y)+"]"),x
1785
1786
		if "--changelog" in myopts:
1787
			print
1788
			for revision,text in changelogs:
1789
				print bold('*'+revision)
1790
				sys.stdout.write(text)
1791
1792
	def calc_changelog(self,ebuildpath,current,next):
1793
		current = '-'.join(portage.catpkgsplit(current)[1:])
1794
		if current.endswith('-r0'): current = current[:-3]
1795
		next = '-'.join(portage.catpkgsplit(next)[1:])
1796
		if next.endswith('-r0'): next = next[:-3]
1797
		changelogpath = os.path.join(os.path.split(ebuildpath)[0],'ChangeLog')
1798
		try:
1799
			changelog = open(changelogpath).read()
1800
		except SystemExit, e:
1801
			raise # Needed else can't exit
1802
		except:
1803
			return []
1804
		divisions = self.find_changelog_tags(changelog)
1805
		#print 'XX from',current,'to',next
1806
		#for div,text in divisions: print 'XX',div
1807
		# skip entries for all revisions above the one we are about to emerge
1808
		for i in range(len(divisions)):
1809
			if divisions[i][0]==next:
1810
				divisions = divisions[i:]
1811
				break
1812
		# find out how many entries we are going to display
1813
		for i in range(len(divisions)):
1814
			if divisions[i][0]==current:
1815
				divisions = divisions[:i]
1816
				break
1817
		else:
1818
		    # couldnt find the current revision in the list. display nothing
1819
			return []
1820
		return divisions
1821
1822
	def find_changelog_tags(self,changelog):
1823
		divs = []
1824
		release = None
1825
		while 1:
1826
			match = re.search(r'^\*\ ?([-a-zA-Z0-9_.+]*)(?:\ .*)?\n',changelog,re.M)
1827
			if match is None:
1828
				if release is not None:
1829
					divs.append((release,changelog))
1830
				return divs
1831
			if release is not None:
1832
				divs.append((release,changelog[:match.start()]))
1833
			changelog = changelog[match.end():]
1834
			release = match.group(1)
1835
			if release.endswith('.ebuild'):
1836
				release = release[:-7]
1837
			if release.endswith('-r0'):
1838
				release = release[:-3]
1839
1840
	def outdated(self):
1841
		return self.outdatedpackages
1842
1843
	def merge(self,mylist):
1844
		returnme=0
1845
		mymergelist=[]
1846
1847
		#check for blocking dependencies
1848
		if ("--fetchonly" not in myopts) and ("--buildpkgonly" not in myopts):
1849
			for x in mylist:
1850
				if x[0]=="blocks":
1851
					print "\n!!! Error: the "+x[2]+" package conflicts with another package;"
1852
					print   "!!!        the two packages cannot be installed on the same system together."
1853
					print   "!!!        Please use 'emerge --pretend' to determine blockers."
1854
					print
1855
					if ("--pretend" not in myopts):
1856
						try:
1857
							del portage.mtimedb["resume"]
1858
						except KeyError:
1859
							pass
1860
						sys.exit(1)
1861
1862
		#buildsyspkg: I need mysysdict also on resume (moved from the else block)
1863
		mysysdict=genericdict(syslist)
1864
		if ("--resume" in myopts):
1865
			# We're resuming.
1866
			print green("*** Resuming merge...")
1867
			emergelog(" *** Resuming merge...")
1868
			mymergelist=portage.mtimedb["resume"]["mergelist"][:]
1869
			if ("--skipfirst" in myopts) and mymergelist:
1870
				del portage.mtimedb["resume"]["mergelist"][0]
1871
				del mymergelist[0]
1872
			validate_merge_list(mymergelist)
1873
		else:
1874
			myfavs = portage.grabfile(os.path.join(portage.root, portage.WORLD_FILE))
1875
			myfavdict=genericdict(myfavs)
1876
			for x in range(len(mylist)):
1877
				if mylist[x][3]!="nomerge":
1878
					# Add to the mergelist
1879
					mymergelist.append(mylist[x])
1880
				else:
1881
					myfavkey=portage.cpv_getkey(mylist[x][2])
1882
					if "--onlydeps" in myopts:
1883
						continue
1884
					# Add to the world file. Since we won't be able to later.
1885
					if (not "--fetchonly" in myopts) and (myfavkey in favorites):
1886
						#don't record if already in system profile or already recorded
1887
						if (not mysysdict.has_key(myfavkey)) and (not myfavdict.has_key(myfavkey)):
1888
							#we don't have a favorites entry for this package yet; add one
1889
							myfavdict[myfavkey]=myfavkey
1890
							print ">>> Recording",myfavkey,"in \"world\" favorites file..."
1891
			if not "--fetchonly" in myopts:
1892
				portage.write_atomic(
1893
					os.path.join(portage.root, portage.WORLD_FILE),
1894
					"\n".join(myfavdict.values()))
1895
1896
			portage.mtimedb["resume"]["mergelist"]=mymergelist[:]
1897
1898
		# We need to yank the harmful-to-new-builds settings from features.
1899
		myorigfeat=self.pkgsettings["FEATURES"]
1900
		myfeat=myorigfeat.split()
1901
		while ("keeptemp" in myfeat):
1902
			del myfeat[myfeat.index("keeptemp")]
1903
		while ("keepwork" in myfeat):
1904
			del myfeat[myfeat.index("keepwork")]
1905
1906
		self.pkgsettings["FEATURES"]=string.join(myfeat)
1907
1908
		if "parallel-fetch" in myfeat and not ("--ask" in myopts or "--pretend" in myopts or "--fetchonly" in myopts):
1909
			if "distlocks" not in myfeat:
1910
				print red("!!!")
1911
				print red("!!!")+" parallel-fetching requires the distlocks feature enabled"
1912
				print red("!!!")+" you have it disabled, thus parallel-fetching is being disabled"
1913
				print red("!!!")
1914
			elif len(mymergelist) > 1:
1915
				print ">>> starting parallel fetching"
1916
				pid = os.fork()
1917
				if not pid:
1918
					sys.stdin.close()
1919
					sys.stdout.close()
1920
					sys.stderr.close()
1921
					time.sleep(3) # allow the parent to have first fetch
1922
					sys.stdout = open("/dev/null","w")
1923
					sys.stderr = open("/dev/null","w")
1924
					os.dup2(sys.stdout.fileno(), 1)
1925
					os.dup2(sys.stdout.fileno(), 2)
1926
					# wipe the mtimedb so that portage doesn't attempt to flush it.
1927
					# do not convert this code away from a fork without correcting this.
1928
					portage.mtimedb = None
1929
					for x in ("autoaddcvs", "cvs"):
1930
						try:	myfeat.remove(x)
1931
						except ValueError: pass
1932
					self.pkgsettings["FEATURES"] = " ".join(myfeat)
1933
					ret = 0
1934
					for x in mymergelist:
1935
						if x[0] != "ebuild":
1936
							continue
1937
						try:
1938
							ret = portage.doebuild(portage.portdb.findname(x[2]), "fetch", x[1], self.pkgsettings,
1939
								cleanup=0, fetchonly=True, tree="porttree")
1940
						except SystemExit:
1941
							raise
1942
						except Exception:
1943
							ret = 1
1944
					sys.exit(0)
1945
				portage.portage_exec.spawned_pids.append(pid)
1946
1947
		mergecount=0
1948
		for x in mymergelist:
1949
			mergecount+=1
1950
			myroot=x[1]
1951
			pkgindex=2
1952
			if x[0]=="blocks":
1953
				pkgindex=3
1954
			y=portage.portdb.findname(x[pkgindex])
1955
			if not "--pretend" in myopts:
1956
				print ">>> Emerging ("+str(mergecount)+" of "+str(len(mymergelist))+")",x[pkgindex],"to",x[1]
1957
				emergelog(" >>> emerge ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" to "+x[1])
1958
1959
			self.pkgsettings["EMERGE_FROM"] = x[0][:]
1960
			self.pkgsettings.backup_changes("EMERGE_FROM")
1961
			self.pkgsettings.reset()
1962
1963
			#buildsyspkg: Check if we need to _force_ binary package creation
1964
			issyspkg = ("buildsyspkg" in myfeat) \
1965
					and x[0] != "blocks" \
1966
					and mysysdict.has_key(portage.cpv_getkey(x[2])) \
1967
					and not ("--buildpkg" in myopts)
1968
			if x[0] in ["ebuild","blocks"]:
1969
				if (x[0]=="blocks") and ("--fetchonly" not in myopts):
1970
					raise Exception, "Merging a blocker"
1971
				elif ("--fetchonly" in myopts) or ("--fetch-all-uri" in myopts):
1972
					if ("--fetch-all-uri" in myopts):
1973
						retval=portage.doebuild(y,"fetch",myroot,self.pkgsettings,edebug,("--pretend" in myopts),fetchonly=1,fetchall=1,tree="porttree")
1974
					else:
1975
						retval=portage.doebuild(y,"fetch",myroot,self.pkgsettings,edebug,("--pretend" in myopts),fetchonly=1,tree="porttree")
1976
					if (retval is None) or retval:
1977
						print
1978
						print "!!! Fetch for",y,"failed, continuing..."
1979
						print
1980
						returnme=1
1981
					continue
1982
				elif "--buildpkg" in myopts or issyspkg:
1983
					#buildsyspkg: Sounds useful to display something, but I don't know if we should also log it
1984
					if issyspkg:
1985
						print ">>> This is a system package, let's pack a rescue tarball."
1986
						#emergelog(">>> This is a system package, let's pack a rescue tarball.")
1987
					#create pkg, then merge pkg
1988
					short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Clean"
1989
					emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Cleaning ("+x[pkgindex]+"::"+y+")", short_msg=short_msg)
1990
					retval=portage.doebuild(y,"clean",myroot,self.pkgsettings,edebug,cleanup=1,tree="porttree")
1991
					if (retval is None):
1992
						portage_util.writemsg("Unable to run required binary.\n",
1993
							noiselevel=-1)
1994
						sys.exit(127)
1995
					if retval:
1996
						sys.exit(retval)
1997
					short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Compile"
1998
					emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Compiling/Packaging ("+x[pkgindex]+"::"+y+")", short_msg=short_msg)
1999
					retval=portage.doebuild(y,"package",myroot,self.pkgsettings,edebug,tree="porttree")
2000
					if (retval is None):
2001
						portage_util.writemsg("Unable to run required binary.\n",
2002
							noiselevel=-1)
2003
						sys.exit(127)
2004
					if retval:
2005
						sys.exit(retval)
2006
					#dynamically update our database
2007
					if "--buildpkgonly" not in myopts:
2008
						portage.db[portage.root]["bintree"].inject(x[2])
2009
						mytbz2=portage.db[portage.root]["bintree"].getname(x[2])
2010
						short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Merge"
2011
						emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Merging ("+x[pkgindex]+"::"+y+")", short_msg=short_msg)
2012
2013
						self.pkgsettings["EMERGE_FROM"] = "binary"
2014
						self.pkgsettings.backup_changes("EMERGE_FROM")
2015
2016
						retval=portage.pkgmerge(mytbz2,myroot,self.pkgsettings)
2017
						if retval is None:
2018
							sys.exit(1)
2019
					elif "noclean" not in self.pkgsettings.features:
2020
						portage.doebuild(y, "clean", myroot, self.pkgsettings,
2021
							edebug, tree="porttree")
2022
				else:
2023
					short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Clean"
2024
					emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Cleaning ("+x[pkgindex]+"::"+y+")", short_msg=short_msg)
2025
					retval=portage.doebuild(y,"clean",myroot,self.pkgsettings,edebug,cleanup=1,tree="porttree")
2026
					if (retval is None):
2027
						portage_util.writemsg("Unable to run required binary.\n",
2028
							noiselevel=-1)
2029
						sys.exit(127)
2030
					if retval:
2031
						sys.exit(retval)
2032
					short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Compile"
2033
					emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Compiling/Merging ("+x[pkgindex]+"::"+y+")", short_msg=short_msg)
2034
					retval=portage.doebuild(y,"merge",myroot,self.pkgsettings,edebug,tree="porttree")
2035
					if (retval is None):
2036
						portage_util.writemsg("Unable to run required binary.\n",
2037
							noiselevel=-1)
2038
						sys.exit(127)
2039
					if retval:
2040
						sys.exit(retval)
2041
					#dynamically update our database
2042
			elif x[0]=="binary":
2043
				#merge the tbz2
2044
				mytbz2=portage.db[portage.root]["bintree"].getname(x[2])
2045
				if portage.db[portage.root]["bintree"].isremote(x[2]):
2046
					short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Fetch"
2047
					emergelog(" --- ("+str(mergecount)+" of "+str(len(mymergelist))+") Fetching Binary ("+x[pkgindex]+"::"+mytbz2+")", short_msg=short_msg)
2048
					if not portage.db[portage.root]["bintree"].gettbz2(x[2]):
2049
						sys.exit(1)
2050
2051
				if ("--fetchonly" in myopts) or ("--fetch-all-uri" in myopts):
2052
					continue
2053
2054
				short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Merge Binary"
2055
				emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Merging Binary ("+x[pkgindex]+"::"+mytbz2+")", short_msg=short_msg)
2056
				retval=portage.pkgmerge(mytbz2,x[1],self.pkgsettings)
2057
				if retval is None:
2058
					sys.exit(1)
2059
				#need to check for errors
2060
			if "--buildpkgonly" not in myopts:
2061
				portage.db[x[1]]["vartree"].inject(x[2])
2062
				myfavkey=portage.cpv_getkey(x[2])
2063
				if "--fetchonly" not in myopts and "--fetch-all-uri" not in myopts and myfavkey in favorites:
2064
					myfavs = portage.grabfile(os.path.join(myroot, portage.WORLD_FILE))
2065
					myfavdict=genericdict(myfavs)
2066
					mysysdict=genericdict(syslist)
2067
					#don't record if already in system profile or already recorded
2068
					if (not mysysdict.has_key(myfavkey)) and (not myfavdict.has_key(myfavkey)):
2069
						#we don't have a favorites entry for this package yet; add one
2070
						myfavdict[myfavkey]=myfavkey
2071
						print ">>> Recording",myfavkey,"in \"world\" favorites file..."
2072
						emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Updating world file ("+x[pkgindex]+")")
2073
						portage.write_atomic(
2074
						os.path.join(myroot, portage.WORLD_FILE),
2075
						"\n".join(myfavdict.values()))
2076
2077
				if ("--pretend" not in myopts) and ("--fetchonly" not in myopts) and ("--fetch-all-uri" not in myopts):
2078
					# Clean the old package that we have merged over top of it.
2079
					if self.pkgsettings["AUTOCLEAN"]=="yes":
2080
						xsplit=portage.pkgsplit(x[2])
2081
						emergelog(" >>> AUTOCLEAN: "+xsplit[0])
2082
						if x[1] == portage.settings["ROOT"]:
2083
							# Compare against portage.settings["ROOT"] because
2084
							# the value of self.pkgsettings["ROOT"] does not
2085
							# match the original value!
2086
							retval = unmerge("clean", [xsplit[0]])
2087
						else:
2088
							retval = unmerge_overlapping(x[2], x[1],
2089
								self.pkgsettings, portage.db[x[1]]["vartree"])
2090
						if not retval:
2091
							emergelog(" --- AUTOCLEAN: Nothing unmerged.")
2092
					else:
2093
						portage.writemsg_stdout(colorize("WARN", "WARNING:")
2094
							+ " AUTOCLEAN is disabled.  This can cause serious"
2095
							+ " problems due to overlapping packages.\n")
2096
2097
					# Figure out if we need a restart.
2098
					mysplit=portage.pkgsplit(x[2])
2099
					if mysplit[0] == "sys-apps/portage" and x[1] == "/":
2100
						myver=mysplit[1]+"-"+mysplit[2]
2101
						if myver[-3:]=='-r0':
2102
							myver=myver[:-3]
2103
						if (myver != portage.VERSION) and \
2104
						   ("livecvsportage" not in portage.settings.features):
2105
							if len(mymergelist) > mergecount:
2106
								emergelog(" ::: completed emerge ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[2]+" to "+x[1])
2107
								emergelog(" *** RESTARTING emerge via exec() after change of portage version.")
2108
								del portage.mtimedb["resume"]["mergelist"][0]
2109
								portage.run_exitfuncs()
2110
								mynewargv=[sys.argv[0],"--resume"]
2111
								badlongopts = ("--ask","--tree","--changelog","--skipfirst","--resume")
2112
								for arg in myopts:
2113
									if arg in badlongopts:
2114
										continue
2115
									mynewargv.append(arg)
2116
								# priority only needs to be adjusted on the first run
2117
								os.environ["PORTAGE_NICENESS"] = "0"
2118
								os.execv(mynewargv[0], mynewargv)
2119
2120
			if ("--pretend" not in myopts) and ("--fetchonly" not in myopts) and ("--fetch-all-uri" not in myopts):
2121
				if "noclean" not in portage.settings.features:
2122
					short_msg = "emerge: (%s of %s) %s Clean Post" % \
2123
						(mergecount, len(mymergelist), x[pkgindex])
2124
					emergelog(" === (%s of %s) Post-Build Cleaning (%s::%s)" % \
2125
						(mergecount, len(mymergelist), x[pkgindex], y), short_msg=short_msg)
2126
				emergelog(" ::: completed emerge ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[2]+" to "+x[1])
2127
2128
			# Unsafe for parallel merges
2129
			del portage.mtimedb["resume"]["mergelist"][0]
2130
			# Commit after each merge so that --resume may still work in
2131
			# in the event that portage is not allowed to exit normally
2132
			# due to power failure, SIGKILL, etc...
2133
			portage.commit_mtimedb()
2134
2135
		emergelog(" *** Finished. Cleaning up...")
2136
2137
		# We're out of the loop... We're done. Delete the resume data.
2138
		if portage.mtimedb.has_key("resume"):
2139
			del portage.mtimedb["resume"]
2140
2141
		if ("--pretend" not in myopts):
2142
			if ("--fetchonly" not in myopts) and ("--fetch-all-uri" not in myopts):
2143
				if (mergecount>0):
2144
					if retval:
2145
						portage.env_update()
2146
2147
		#by doing an exit this way, --fetchonly can continue to try to
2148
		#fetch everything even if a particular download fails.
2149
		if "--fetchonly" in myopts or "--fetch-all-uri" in myopts:
2150
			if returnme:
2151
				print "\n\n!!! Some fetch errors were encountered.  Please see above for details.\n\n"
2152
				sys.exit(returnme)
2153
			else:
2154
				sys.exit(0)
2155
2156
def unmerge_overlapping(pkg_key, myroot, mysettings, vartree):
885
def unmerge_overlapping(pkg_key, myroot, mysettings, vartree):
2157
	"""Unmerge any packages that overlap with the given package (overlapping
886
	"""Unmerge any packages that overlap with the given package (overlapping
2158
	packages fill the same SLOT).  Unlike emerge's unmerge() function, this
887
	packages fill the same SLOT).  Unlike emerge's unmerge() function, this
Lines 2589-2594 Link Here
2589
			print red("!!!        the merge operation manually.")
1318
			print red("!!!        the merge operation manually.")
2590
			sys.exit(1)
1319
			sys.exit(1)
2591
1320
1321
import depgraph
1322
dg = depgraph
1323
depgraph = dg.depgraph
1324
dg.is_valid_package_atom = is_valid_package_atom
1325
dg.update_spinner = update_spinner
1326
dg.edebug = edebug
1327
dg.format_size = format_size
1328
dg.genericdict = genericdict
1329
dg.syslist = getlist("system")
1330
dg.emergelog = emergelog
1331
dg.unmerge = unmerge
1332
dg.EMERGE_WARNING_DELAY = EMERGE_WARNING_DELAY
1333
dg.countdown = countdown
1334
dg.validate_merge_list = validate_merge_list
1335
dg.unmerge_overlapping = unmerge_overlapping
1336
1337
2592
# general options that should be taken into account before any action
1338
# general options that should be taken into account before any action
2593
if "--debug" in myopts:
1339
if "--debug" in myopts:
2594
	edebug=1
1340
	edebug=1
Lines 3268-3278 Link Here
3268
	if not "--pretend" in myopts: #just check pretend, since --ask implies pretend
2014
	if not "--pretend" in myopts: #just check pretend, since --ask implies pretend
3269
		emergelog(" >>> depclean")
2015
		emergelog(" >>> depclean")
3270
	
2016
	
3271
	mydepgraph=depgraph(myaction,myopts)
2017
	mydepgraph=depgraph(myaction,myopts,myparams)
3272
2018
3273
	if not ("--quiet" in myopts):
2019
	if not ("--quiet" in myopts):
3274
		print "\nCalculating dependencies  ",
2020
		print "\nCalculating dependencies  ",
3275
	if not mydepgraph.xcreate("world"):
2021
	if not mydepgraph.xcreate(syslist,"world"):
3276
		print "\n!!! Failed to create deptree."
2022
		print "\n!!! Failed to create deptree."
3277
		sys.exit(1)
2023
		sys.exit(1)
3278
	if not ("--quiet" in myopts):
2024
	if not ("--quiet" in myopts):
Lines 3383-3389 Link Here
3383
			if myopt not in myresumeopts:
2129
			if myopt not in myresumeopts:
3384
				myresumeopts.append(myopt)
2130
				myresumeopts.append(myopt)
3385
		myopts=myresumeopts
2131
		myopts=myresumeopts
3386
		mydepgraph=depgraph("resume",myopts)
2132
		mydepgraph=depgraph("resume",myopts,myparams)
3387
		if "--resume" not in myopts:
2133
		if "--resume" not in myopts:
3388
			myopts+=["--resume"]
2134
			myopts+=["--resume"]
3389
	else:
2135
	else:
Lines 3392-3403 Link Here
3392
			print darkgreen("emerge: It seems we have nothing to resume...")
2138
			print darkgreen("emerge: It seems we have nothing to resume...")
3393
			sys.exit(0)
2139
			sys.exit(0)
3394
2140
3395
		mydepgraph=depgraph(myaction,myopts)
2141
		mydepgraph=depgraph(myaction,myopts,myparams)
3396
		if myaction in ["system","world"]:
2142
		if myaction in ["system","world"]:
3397
			if not ("--quiet" in myopts):
2143
			if not ("--quiet" in myopts):
3398
				print "Calculating",myaction,"dependencies  ",
2144
				print "Calculating",myaction,"dependencies  ",
3399
				sys.stdout.flush()
2145
				sys.stdout.flush()
3400
			if not mydepgraph.xcreate(myaction):
2146
			if not mydepgraph.xcreate(syslist, myaction):
3401
				print "!!! Depgraph creation failed."
2147
				print "!!! Depgraph creation failed."
3402
				sys.exit(1)
2148
				sys.exit(1)
3403
			if not ("--quiet" in myopts):
2149
			if not ("--quiet" in myopts):
Lines 3502-3508 Link Here
3502
						pkglist.append(pkg)
2248
						pkglist.append(pkg)
3503
			else:
2249
			else:
3504
				pkglist = mydepgraph.altlist()
2250
				pkglist = mydepgraph.altlist()
3505
			mydepgraph.merge(pkglist)
2251
			mydepgraph.merge(pkglist, favorites)
3506
2252
3507
		if portage.mtimedb.has_key("resume"):
2253
		if portage.mtimedb.has_key("resume"):
3508
			del portage.mtimedb["resume"]
2254
			del portage.mtimedb["resume"]
(-)depgraph.old (+1310 lines)
Line 0 Link Here
1
2
import portage
3
import os,sys
4
5
import xpak,string,re,commands,time
6
from stat import *
7
from output import *
8
9
import portage_util
10
import portage_exception
11
from portage_const import PROFILE_PATH
12
13
# Globals needed, which are overridden as we are imported!
14
# These globals will need to be modualarized before this script can be set free upon the world!!!
15
# -- Retrieved with pychecker --
16
update_spinner=lambda: None
17
is_valid_package_atom=lambda: None
18
format_size=lambda: None
19
emergelog=lambda: None
20
format_size=lambda: None
21
edebug=lambda: None
22
unmerge=lambda: None
23
genericdict=dict
24
25
EMERGE_WARNING_DELAY=5 
26
countdown=lambda: None 
27
getlist=lambda: None
28
validate_merge_list=lambda: None
29
unmerge_overlapping=lambda: None
30
# End list
31
32
olddbapi=None
33
class depgraph:
34
35
	def __init__(self,myaction,myopts,myparams):
36
		self.myopts = myopts
37
		self.myparams = myparams
38
		global olddbapi
39
		self.pkgsettings = portage.config(clone=portage.settings)
40
		if not self.pkgsettings["ARCH"]:
41
			portage.writemsg(red("\a!!! ARCH is not set... Are you missing the /etc/make.profile symlink?\n"),
42
				noiselevel=-1)
43
			portage.writemsg(red("\a!!! Is the symlink correct? Is your portage tree complete?\n\n"),
44
				noiselevel=-1)
45
			sys.exit(9)
46
		self.applied_useflags = {}
47
48
		self.missingbins=[]
49
		self.myaction=myaction
50
		self.digraph=portage.digraph()
51
		self.orderedkeys=[]
52
		self.outdatedpackages=[]
53
		self.mydbapi={}
54
		self.mydbapi["/"] = portage.fakedbapi()
55
		if "empty" not in self.myparams or portage.root != "/":
56
			for pkg in portage.db["/"]["vartree"].getallcpv():
57
				self.mydbapi["/"].cpv_inject(pkg)
58
		if portage.root != "/":
59
			self.mydbapi[portage.root] = portage.fakedbapi()
60
			if "empty" not in self.myparams:
61
				for pkg in portage.db[portage.root]["vartree"].getallcpv():
62
					self.mydbapi[portage.root].cpv_inject(pkg)
63
64
		if "--usepkg" in self.myopts:
65
			portage.db["/"]["bintree"].populate(("--getbinpkg" in self.myopts), ("--getbinpkgonly" in self.myopts))
66
67
	def create(self,mybigkey,myparent=None,addme=1,myuse=None):
68
		"""creates the actual digraph of packages to merge.  return 1 on success, 0 on failure
69
		mybigkey = specification of package to merge; myparent = parent package (one depending on me);
70
		addme = should I be added to the tree? (for the --onlydeps mode)"""
71
		#stuff to add:
72
		#SLOT-aware emerge
73
		#IUSE-aware emerge
74
		#"no downgrade" emerge
75
		#print "mybigkey:",mybigkey
76
77
		jbigkey=string.join(mybigkey)
78
		if self.digraph.hasnode(jbigkey+" merge") or self.digraph.hasnode(jbigkey+" nomerge"):
79
			#this conditional is needed to prevent infinite recursion on already-processed deps
80
			return 1
81
82
		update_spinner()
83
84
		mytype,myroot,mykey=mybigkey
85
		# select the correct /var database that we'll be checking against
86
		vardbapi=portage.db[myroot]["vartree"].dbapi
87
88
		# if the package is already on the system, we add a "nomerge"
89
		# directive, otherwise we add a "merge" directive.
90
		if mytype=="blocks":
91
			# we've encountered a "blocks" node.  We will totally ignore this
92
			# node and not add it to our digraph if it doesn't apply to us.
93
			if addme and "--buildpkgonly" not in self.myopts and myparent and (self.mydbapi[myroot].match(mykey) or vardbapi.match(mykey)):
94
				mybigkey.append(myparent.split()[2])
95
				self.digraph.addnode(string.join(mybigkey),myparent)
96
			return 1
97
98
		if myuse is None:
99
			self.pkgsettings.setcpv(mykey)
100
			myuse = self.pkgsettings["USE"].split()
101
		self.applied_useflags[mykey] = myuse
102
103
		merging=1
104
		if addme:
105
		# this is where we add the node to the list of packages to merge
106
			if not myparent:
107
				# command-line specified or part of a world list...
108
				if ("self" not in self.myparams) or (("selective" in self.myparams) and vardbapi.cpv_exists(mykey)):
109
					# the package is on the system, so don't merge it.
110
					merging=0
111
			elif ("selective" in self.myparams) and vardbapi.cpv_exists(mykey):
112
				merging=0
113
114
			if (merging==0 and "--newuse" in self.myopts and vardbapi.cpv_exists(mykey)):
115
				old_use = vardbapi.aux_get(mykey, ["USE"])[0].split()
116
				if mytype == "binary":
117
					iuses = portage.db["/"]["bintree"].dbapi.aux_get(mykey, ["IUSE"])[0].split()
118
				else:
119
					iuses = portage.db["/"]["porttree"].dbapi.aux_get(mykey, ["IUSE"])[0].split()
120
				for x in iuses:
121
					if (old_use.count(x) and not myuse.count(x)) or (not old_use.count(x) and myuse.count(x)):
122
						merging=1
123
						break
124
		else:
125
			#onlydeps mode; don't merge
126
			merging=2
127
		if merging==1:
128
			mybigkey.append("merge")
129
		else:
130
			mybigkey.append("nomerge")
131
132
		# whatever the case, we need to add the node to our digraph so
133
		# that children can depend upon it.
134
		self.digraph.addnode(string.join(mybigkey),myparent)
135
		if ("deep" not in self.myparams) and (not merging):
136
			return 1
137
		elif "recurse" not in self.myparams:
138
			return 1
139
140
		edepend={}
141
		if mytype=="binary":
142
			mypkgparts=portage.catpkgsplit(mykey)
143
			tbz2name = string.split(mykey, "/")[1]+".tbz2"
144
			if tbz2name in portage.db[portage.root]["bintree"].invalids:
145
				sys.stderr.write("\nINVALID PACKAGE (is required to continue): "+str(mykey)+"\n")
146
				sys.exit(1)
147
			if portage.db[portage.root]["bintree"].isremote(mykey):
148
				edepend = portage.db[portage.root]["bintree"].remotepkgs[tbz2name]
149
				edepend["DEPEND"] =""
150
				edepend["RDEPEND"]=string.join(string.split(edepend["RDEPEND"])," ")
151
				edepend["PDEPEND"]=string.join(string.split(edepend["PDEPEND"])," ")
152
				edepend["SLOT"]   =string.strip(edepend["SLOT"])
153
				#portage.db[portage.root]["bintree"].gettbz2(mykey)
154
			else: # It's local.
155
				mytbz2=xpak.tbz2(portage.db[portage.root]["bintree"].getname(mykey))
156
				edepend["DEPEND"] =""
157
				edepend["RDEPEND"]=string.join(mytbz2.getelements("RDEPEND")," ")
158
				edepend["PDEPEND"]=string.join(mytbz2.getelements("PDEPEND")," ")
159
				edepend["SLOT"]   =mytbz2.getfile("SLOT",mypkgparts[2])
160
		elif mytype=="ebuild":
161
			try:
162
				mymeta = ["DEPEND","RDEPEND","PDEPEND"]
163
				myfoo = portage.portdb.aux_get(mykey, mymeta)
164
				for index in range(0,len(mymeta)):
165
					edepend[mymeta[index]] = myfoo[index]
166
				if "--buildpkgonly" in self.myopts:
167
					edepend["RDEPEND"] = ""
168
					edepend["PDEPEND"] = ""
169
			except (KeyError,IOError):
170
				print "emerge: create(): aux_get() error on",mykey+"; aborting..."
171
				sys.exit(1)
172
		mydep={}
173
		mp=string.join(mybigkey)
174
175
		if myroot=="/":
176
			mydep["/"]=edepend["DEPEND"]+" "+edepend["RDEPEND"]
177
			if not self.select_dep("/",mydep["/"],myparent=mp,myuse=myuse):
178
				return 0
179
		else:
180
			mydep["/"]=edepend["DEPEND"]
181
			mydep[myroot]=edepend["RDEPEND"]
182
			if not self.select_dep("/",mydep["/"],myparent=mp,myuse=myuse):
183
				return 0
184
			if not self.select_dep(myroot,mydep[myroot],myparent=mp,myuse=myuse):
185
				return 0
186
187
		if edepend.has_key("PDEPEND") and edepend["PDEPEND"]:
188
			# Post Depend -- Add to the list without a parent, as it depends
189
			# on a package being present AND must be built after that package.
190
			if not self.select_dep(myroot,edepend["PDEPEND"],myuse=myuse):
191
				return 0
192
193
		return 1
194
195
	def select_files(self,myfiles):
196
		"given a list of .tbz2s, .ebuilds and deps, create the appropriate depgraph and return a favorite list"
197
		myfavorites=[]
198
		for x in myfiles:
199
			ext = os.path.splitext(x)[1]
200
			if ext==".tbz2":
201
				if not os.path.exists(x):
202
					if os.path.exists(self.pkgsettings["PKGDIR"]+"/All/"+x):
203
						x=self.pkgsettings["PKGDIR"]+"/All/"+x
204
					elif os.path.exists(self.pkgsettings["PKGDIR"]+"/"+x):
205
						x=self.pkgsettings["PKGDIR"]+"/"+x
206
					else:
207
						print "\n\n!!! Binary package '"+str(x)+"' does not exist."
208
						print "!!! Please ensure the tbz2 exists as specified.\n"
209
						sys.exit(1)
210
				mytbz2=xpak.tbz2(x)
211
				mykey=mytbz2.getelements("CATEGORY")[0]+"/"+os.path.splitext(os.path.basename(x))[0]
212
				if os.path.realpath(portage.db["/"]["bintree"].getname(mykey)) != os.path.realpath(x):
213
					print red("\n*** You need to adjust PKGDIR to emerge this package.\n")
214
					sys.exit(1)
215
				if not self.create(["binary",portage.root,mykey],None,"--onlydeps" not in self.myopts):
216
					return (0,myfavorites)
217
				elif not "--oneshot" in self.myopts:
218
					myfavorites.append(mykey)
219
			elif ext==".ebuild":
220
				x = os.path.realpath(x)
221
				mykey=os.path.basename(os.path.normpath(x+"/../.."))+"/"+os.path.splitext(os.path.basename(x))[0]
222
				ebuild_path = portage.db["/"]["porttree"].dbapi.findname(mykey)
223
				if ebuild_path:
224
					if os.path.realpath(ebuild_path) != x:
225
						print red("\n*** You need to adjust PORTDIR or PORTDIR_OVERLAY to emerge this package.\n")
226
						sys.exit(1)
227
					if mykey not in portage.db["/"]["porttree"].dbapi.xmatch("match-visible", portage.dep_getkey(mykey)):
228
						print red("\n*** You are emerging a masked package. It is MUCH better to use")
229
						print red("*** /etc/portage/package.* to accomplish this. See portage(5) man")
230
						print red("*** page for details.")
231
						countdown(EMERGE_WARNING_DELAY, "Continuing...")
232
				else:
233
					raise portage_exception.PackageNotFound(
234
						"%s is not in a valid portage tree hierarchy or does not exist" % x)
235
				if not self.create(["ebuild",portage.root,mykey],None,"--onlydeps" not in self.myopts):
236
					return (0,myfavorites)
237
				elif not "--oneshot" in self.myopts:
238
					myfavorites.append(mykey)
239
			else:
240
				if not is_valid_package_atom(x):
241
					portage.writemsg("\n\n!!! '%s' is not a valid package atom.\n" % x,
242
						noiselevel=-1)
243
					portage.writemsg("!!! Please check ebuild(5) for full details.\n")
244
					portage.writemsg("!!! (Did you specify a version but forget to prefix with '='?)\n")
245
					return (0,[])
246
				try:
247
					mykey=portage.dep_expand(x,mydb=portage.portdb)
248
				except ValueError, errpkgs:
249
					print "\n\n!!! The short ebuild name \"" + x + "\" is ambiguous.  Please specify"
250
					print "!!! one of the following fully-qualified ebuild names instead:\n"
251
					for i in errpkgs[0]:
252
						print "    " + green(i)
253
					print
254
					sys.exit(1)
255
256
				# select needs to return 0 on dep_check failure
257
258
				sys.stdout.flush()
259
				sys.stderr.flush()
260
261
				try:
262
					self.mysd = self.select_dep(portage.root,mykey,arg=x)
263
				except portage_exception.MissingSignature, e:
264
					portage.writemsg("\n\n!!! A missing gpg signature is preventing portage from calculating the\n")
265
					portage.writemsg("!!! required dependencies. This is a security feature enabled by the admin\n")
266
					portage.writemsg("!!! to aid in the detection of malicious intent.\n\n")
267
					portage.writemsg("!!! THIS IS A POSSIBLE INDICATION OF TAMPERED FILES -- CHECK CAREFULLY.\n")
268
					portage.writemsg("!!! Affected file: %s\n" % (e), noiselevel=-1)
269
					sys.exit(1)
270
				except portage_exception.InvalidSignature, e:
271
					portage.writemsg("\n\n!!! An invalid gpg signature is preventing portage from calculating the\n")
272
					portage.writemsg("!!! required dependencies. This is a security feature enabled by the admin\n")
273
					portage.writemsg("!!! to aid in the detection of malicious intent.\n\n")
274
					portage.writemsg("!!! THIS IS A POSSIBLE INDICATION OF TAMPERED FILES -- CHECK CAREFULLY.\n")
275
					portage.writemsg("!!! Affected file: %s\n" % (e), noiselevel=-1)
276
					sys.exit(1)
277
				except SystemExit, e:
278
					raise # Needed else can't exit
279
				except Exception, e:
280
					if "--debug" in self.myopts:
281
						raise
282
					print "\n\n!!! Problem in",mykey,"dependencies."
283
					print "!!!",str(e),e.__module__
284
					sys.exit(1)
285
286
				if not self.mysd:
287
					return (0,myfavorites)
288
				elif not "--oneshot" in self.myopts:
289
					myfavorites.append(portage.dep_getkey(mykey))
290
291
		missing=0
292
		if "--usepkgonly" in self.myopts:
293
			for x in self.digraph.dict.keys():
294
				xs=string.split(x," ")
295
				if (xs[0] != "binary") and (xs[3]=="merge"):
296
					if missing == 0:
297
						print
298
					missing += 1
299
					print "Missing binary for:",xs[2]
300
301
		# We're true here unless we are missing binaries.
302
		return (not missing,myfavorites)
303
304
	def is_newer_ver_installed(self,myroot,pkg,pkgver):
305
		"if there is a version of pkg installed newer than pkgver, return it"
306
		vardbapi=portage.db[myroot]["vartree"].dbapi # not used????
307
308
		matches=portage.db[myroot]["vartree"].dbapi.match(pkg)
309
		if matches:
310
			myslot=portage.db["/"]["porttree"].getslot(pkgver)
311
			for match in matches:
312
				if portage.pkgcmp(portage.catpkgsplit(pkgver)[1:], portage.catpkgsplit(match)[1:]) < 0:
313
					curslot=portage.db[myroot]["vartree"].getslot(match)
314
					if curslot == myslot:
315
						return match
316
		return None #explicitly return None, was implicit
317
318
	def select_dep(self,myroot,depstring,myparent=None,arg=None,myuse=None,raise_on_missing=False):
319
		"given a dependency string, create the appropriate depgraph and return 1 on success and 0 on failure"
320
		if "--debug" in self.myopts:
321
			print
322
			print "Parent:   ",myparent
323
			print "Depstring:",depstring
324
		if not arg:
325
			#processing dependencies
326
			mycheck=portage.dep_check(depstring,self.mydbapi[myroot],self.pkgsettings,myuse=myuse,use_binaries=("--usepkgonly" in self.myopts),myroot=myroot)
327
328
			if not mycheck[0]:
329
				mymerge=[]
330
			else:
331
				mymerge=mycheck[1]
332
333
		else:
334
			#we're processing a command-line argument; unconditionally merge it even if it's already merged
335
			mymerge=[depstring]
336
337
		# dep_check has been run so we can now add our parent to our
338
		# build state to update virtuals and other settings. This
339
		# happens after the package is added to the tree so that a
340
		# package can depend on a virtual which it satisfies.
341
		if myparent:
342
			myp = myparent.split()
343
			if myp[3]=="merge":
344
				self.mydbapi[myroot].cpv_inject(myp[2])
345
				if myp[0]=="binary":
346
					self.pkgsettings.setinst(myp[2],portage.db["/"]["bintree"].dbapi)
347
				else:
348
					self.pkgsettings.setinst(myp[2],portage.db[myroot]["porttree"].dbapi)
349
350
		if not mymerge:
351
			return 1
352
353
		if "--debug" in self.myopts:
354
			print "Candidates:",mymerge
355
		for x in mymerge:
356
			myk=None
357
			binpkguseflags=None
358
			if x[0]=="!":
359
				# if this package is myself, don't append it to block list.
360
				if "--debug" in self.myopts:
361
					print "Myparent",myparent
362
				if (myparent):
363
					if myparent.split()[2] in portage.portdb.xmatch("match-all", x[1:]):
364
						# myself, so exit.
365
						continue
366
				# adding block
367
				myk=["blocks",myroot,x[1:]]
368
			else:
369
				#We are not processing a blocker but a normal dependency
370
				myeb=None
371
				myeb_matches = portage.portdb.xmatch("match-visible",x)
372
				if ("--usepkgonly" not in self.myopts):
373
					myeb=portage.best(myeb_matches)
374
375
				myeb_pkg=None
376
				if ("--usepkg" in self.myopts):
377
					# The next line assumes the binarytree has been populated.
378
					# XXX: Need to work out how we use the binary tree with roots.
379
					myeb_pkg_matches=portage.db["/"]["bintree"].dbapi.match(x)
380
					if ("--usepkgonly" not in self.myopts):
381
						# Remove any binary package entries that are masked in the portage tree (#55871)
382
						for idx in range(len(myeb_pkg_matches)-1,-1,-1):
383
							if myeb_pkg_matches[idx] not in myeb_matches:
384
								del myeb_pkg_matches[idx]
385
					myeb_pkg = portage.best(myeb_pkg_matches)
386
387
				if not myeb_pkg:
388
					myeb_pkg = None
389
				elif ("--newuse" in self.myopts):
390
					iuses=string.split(portage.db["/"]["bintree"].dbapi.aux_get(myeb_pkg, ["IUSE"])[0])
391
					old_use=string.split(portage.db["/"]["bintree"].dbapi.aux_get(myeb_pkg, ["USE"])[0])
392
					self.pkgsettings.setcpv(myeb_pkg)
393
					now_use=string.split(self.pkgsettings["USE"])
394
					for x in iuses:
395
						if (old_use.count(x) and not now_use.count(x)) or (not old_use.count(x) and now_use.count(x)):
396
							myeb_pkg = None
397
							break
398
399
				if (not myeb) and (not myeb_pkg):
400
					if raise_on_missing:
401
						raise ValueError
402
					if not arg:
403
						xinfo='"'+x+'"'
404
					else:
405
						xinfo='"'+arg+'"'
406
					if myparent:
407
						xfrom = '(dependency required by '+green('"'+myparent.split()[2]+'"')+red(' ['+myparent.split()[0]+"]")+')'
408
					alleb=portage.portdb.xmatch("match-all",x)
409
					if alleb:
410
						if "--usepkgonly" not in self.myopts:
411
							print "\n!!! "+red("All ebuilds that could satisfy ")+green(xinfo)+red(" have been masked.")
412
							print "!!! One of the following masked packages is required to complete your request:"
413
							oldcomment = ""
414
							for p in alleb:
415
								mreasons = portage.getmaskingstatus(p)
416
								print "- "+p+" (masked by: "+string.join(mreasons, ", ")+")"
417
								comment = portage.getmaskingreason(p)
418
								if comment and comment != oldcomment:
419
									print comment
420
									oldcomment = comment
421
							print
422
							print "For more information, see MASKED PACKAGES section in the emerge man page or "
423
							print "refer to the Gentoo Handbook."
424
						else:
425
							print "\n!!! "+red("There are no packages available to satisfy: ")+green(xinfo)
426
							print "!!! Either add a suitable binary package or compile from an ebuild."
427
					else:
428
						print "\nemerge: there are no ebuilds to satisfy "+green(xinfo)+"."
429
					if myparent:
430
						print xfrom
431
					print
432
					return 0
433
434
				if "--debug" in self.myopts:
435
					print "ebuild:",myeb
436
					print "binpkg:",myeb_pkg
437
438
				if myeb and myeb_pkg:
439
					myeb_s     = portage.catpkgsplit(myeb)
440
					myeb_s     = [myeb_s[0]+"/"+myeb_s[1], myeb_s[2], myeb_s[3]]
441
					myeb_pkg_s = portage.catpkgsplit(myeb_pkg)
442
					myeb_pkg_s = [myeb_pkg_s[0]+"/"+myeb_pkg_s[1], myeb_pkg_s[2], myeb_pkg_s[3]]
443
444
					if portage.pkgcmp(myeb_s, myeb_pkg_s) == 0: # pkg is same version as ebuild
445
						myeb = None
446
					else:
447
						myeb_pkg = None
448
449
				if myeb:
450
					myk=["ebuild",myroot,myeb]
451
				elif myeb_pkg:
452
					binpkguseflags=portage.db[portage.root]["bintree"].get_use(myeb_pkg)
453
					myk=["binary",myroot,myeb_pkg]
454
				else:
455
					sys.stderr.write("!!! Confused... Don't know what's being used for dependency info. :(\n")
456
					sys.exit(1)
457
458
				#if "--usepkg" in self.myopts:
459
				#	#If we want to use packages, see if we have a pre-built one...
460
				#	mypk=portage.db["/"]["bintree"].dbapi.match(x)
461
				#	if myeb in mypk:
462
				#		#Use it only if it's exactly the version we want.
463
				#		myk=["binary",myroot,myeb]
464
				#	else:
465
				#		myk=["ebuild",myroot,myeb]
466
				#else:
467
				#	myk=["ebuild",myroot,myeb]
468
			if myparent:
469
				#we are a dependency, so we want to be unconditionally added
470
				if not self.create(myk,myparent,myuse=binpkguseflags):
471
					return 0
472
			else:
473
				#if mysource is not set, then we are a command-line dependency and should not be added
474
				#if --onlydeps is specified.
475
				if not self.create(myk,myparent,"--onlydeps" not in self.myopts,myuse=binpkguseflags):
476
					return 0
477
478
		if "--debug" in self.myopts:
479
			print "Exiting...",myparent
480
		return 1
481
482
483
	def altlist(self):
484
		mygraph=self.digraph.copy()
485
		dolist=["/"]
486
		retlist=[]
487
		for x in portage.db.keys():
488
			portage.db[x]["merge"]=[]
489
			if x not in dolist:
490
				dolist.append(x)
491
		while (not mygraph.empty()):
492
			mycurkey=mygraph.firstzero()
493
			if not mycurkey:
494
				print "!!! Error: circular dependencies:"
495
				print
496
				for x in mygraph.dict.keys():
497
					for y in mygraph.dict[x][1]:
498
						print y,"depends on",x
499
				print
500
				sys.exit(1)
501
			splitski=string.split(mycurkey)
502
			#I'm not sure of the significance of the following lines (vestigal?) so I'm commenting 'em out.
503
			#These lines remove already-merged things from our alt-list
504
			#if "--update" in self.myopts:
505
			#	if not portage.db["/"]["vartree"].exists_specific(splitski[2]):
506
			#		portage.db["/"]["merge"].append(splitski)
507
			#else:
508
			portage.db[splitski[1]]["merge"].append(splitski)
509
			mygraph.delnode(mycurkey)
510
		for x in dolist:
511
			for y in portage.db[x]["merge"]:
512
				retlist.append(y)
513
		return retlist
514
515
	def xcreate(self,sysl,mode="system"):
516
		global syslist
517
		syslist = sysl
518
		world_problems = False
519
		if mode=="system":
520
			mylist=syslist
521
		else:
522
			#world mode
523
			worldlist=getlist("world")
524
			sysdict=genericdict(syslist)
525
			worlddict=genericdict(worldlist)
526
527
			for x in worlddict.keys():
528
				if not portage.isvalidatom(x):
529
					world_problems = True
530
				elif not portage.db["/"]["vartree"].dbapi.match(x):
531
					world_problems = True
532
				else:
533
					sysdict[x]=worlddict[x]
534
535
			mylist = sysdict.keys()
536
537
		newlist = []
538
		for atom in mylist:
539
			if portage.dep_getkey(atom).split("/")[-1] == "portage":
540
				newlist.insert(0, atom)
541
			else:
542
				newlist.append(atom)
543
		mylist = newlist
544
		
545
		missing_atoms = []
546
		for mydep in mylist:
547
			try:
548
				if not self.select_dep(portage.root, mydep, raise_on_missing=True):
549
					print "\n\n!!! Problem resolving dependencies for", mydep
550
					return 0
551
			except ValueError:
552
				if "--debug" in self.myopts:
553
					raise
554
				missing_atoms.append(mydep)
555
556
		if world_problems:
557
			print "\n!!! Problems have been detected with your world file"
558
			print "!!! Please run "+green("emaint --check world")+"\n"
559
560
		if missing_atoms and "--verbose" in self.myopts:
561
			print "\n!!! Packages for the following atoms are either all"
562
			print "!!! masked or don't exist:"
563
			print " ".join(missing_atoms) + "\n"
564
565
		return 1
566
567
	def match(self,mydep,myroot=portage.root,mykey=None):
568
		# support mutual exclusive deps
569
		mydep2=mydep
570
		if mydep2[0]=="!":
571
			mydep2=mydep[1:]
572
573
		if mydep[0]=="!":
574
			#add our blocker; it will be ignored later if necessary (if we are remerging the same pkg, for example)
575
			myk="blocks "+myroot+" "+mydep2
576
		else:
577
			myeb=portage.db[portage.root]["porttree"].dep_bestmatch(mydep2)
578
			if not myeb:
579
				if not mykey:
580
					print "\n!!! Error: couldn't find match for",mydep
581
				else:
582
					print "\n!!! Error: couldn't find match for",mydep,"in",mykey
583
				print
584
				sys.exit(1)
585
586
			if "--usepkg" in self.myopts:
587
				mypk=portage.db[portage.root]["bintree"].dep_bestmatch(mydep)
588
				if myeb==mypk:
589
					myk="binary "+portage.root+" "+mypk
590
				else:
591
					myk="ebuild "+myroot+" "+myeb
592
			else:
593
				myk="ebuild "+myroot+" "+myeb
594
595
		return myk
596
597
	def display(self,mylist,verbosity=999):
598
		if verbosity == 999:
599
			verbosity = ("--quiet" in self.myopts and 1 or "--verbose" in self.myopts and 3 or 2 );
600
		changelogs=[]
601
		p=[]
602
		totalsize=0
603
604
		if verbosity == 1:
605
			def create_use_string(*args):
606
				return ""
607
		else:
608
			def create_use_string(name, cur_iuse, cur_use, old_iuse, old_use, is_new,
609
					all_flags=(verbosity == 3), alphabetical=("--alphabetical" in self.myopts)):
610
				enabled = []
611
				if alphabetical:
612
					disabled = enabled
613
				else:
614
					disabled = []
615
				for flag in cur_iuse:
616
					if flag in cur_use:
617
						if is_new or flag in old_use and all_flags:
618
							enabled.append(red(flag))
619
						elif flag not in old_iuse:
620
							enabled.append(yellow(flag)+"%")
621
						elif flag not in old_use:
622
							enabled.append(green(flag)+"*")
623
					else:
624
						if is_new or flag in old_iuse and flag not in old_use and all_flags:
625
							disabled.append(blue("-"+flag))
626
						elif flag not in old_iuse:
627
							disabled.append(yellow("-"+flag)+"%")
628
						elif flag in old_use:
629
							disabled.append(green("-"+flag)+"*")
630
631
				enabled = " ".join(enabled)
632
				if alphabetical:
633
					disabled = ""
634
				else:
635
					disabled = " ".join(disabled)
636
				if enabled and disabled:
637
					ret = enabled + " " + disabled
638
				elif enabled:
639
					ret = enabled
640
				else:
641
					ret = disabled
642
				if ret:
643
					ret = '%s="%s" ' % (name, ret)
644
				return ret
645
646
		if verbosity == 3:
647
			overlays = self.pkgsettings["PORTDIR_OVERLAY"].split()
648
			overlays_real = [os.path.realpath(t) \
649
				for t in self.pkgsettings["PORTDIR_OVERLAY"].split()]
650
651
		if "--tree" in self.myopts:
652
			mylist.reverse()
653
			mygraph=self.digraph.copy()
654
655
		i = 0
656
		while i < len(mylist):
657
			if mylist[i][-1]=="nomerge":
658
				if not ("--tree" in self.myopts):
659
					# we don't care about this elements
660
					mylist.pop(i)
661
					continue
662
				if (i == (len(mylist) - 1)) \
663
				   or (mygraph.depth(string.join(mylist[i])) \
664
				       >= mygraph.depth(string.join(mylist[i+1]))):
665
					# end of a useless branch (may be the last one)
666
					# -> delete the element and test the previous one
667
					mylist.pop(i)
668
					if i > 0:
669
						i -= 1
670
					continue
671
			# the branch continues, or we've found a good element.
672
			# -> let's see what's next, if anything
673
			i += 1
674
675
		display_overlays=False
676
		# files to fetch list - avoids counting a same file twice
677
		# in size display (verbose mode)
678
		myfetchlist=[]
679
		for x in mylist:
680
			pkg_type = x[0]
681
			pkg_key = x[2]
682
			if pkg_key not in self.applied_useflags:
683
				if "binary" == pkg_type:
684
					self.applied_useflags[pkg_key] = portage.db["/"]["bintree"].dbapi.aux_get(pkg_key, ["USE"])[0].split()
685
				elif "ebuild" == pkg_type:
686
					self.pkgsettings.setcpv(pkg_key)
687
					self.applied_useflags[pkg_key] = self.pkgsettings["USE"].split()
688
689
			fetch=" "
690
691
			if x[0]=="blocks":
692
				addl=""+red("B")+"  "+fetch+"  "
693
				resolved=portage.db[x[1]]["vartree"].resolve_key(x[2])
694
				print "["+x[0]+" "+addl+"]",red(resolved),
695
				if resolved!=x[2]:
696
					if x[3]:
697
						print red("(\""+x[2]+"\" is blocking "+x[3]+")")
698
					else:
699
						print red("(\""+x[2]+"\")")
700
				else:
701
					if x[3]:
702
						print red("(is blocking "+x[3]+")")
703
					else:
704
						print
705
			else:
706
				if (x[0]!="binary") and ("fetch" in string.split(portage.portdb.aux_get(x[2],["RESTRICT"])[0])):
707
					fetch = red("F")
708
					if portage.portdb.fetch_check(x[2], self.applied_useflags[x[2]]):
709
						fetch = green("f")
710
711
				#we need to use "--emptrytree" testing here rather than "empty" param testing because "empty"
712
				#param is used for -u, where you still *do* want to see when something is being upgraded.
713
				myoldbest=""
714
				if (not "--emptytree" in self.myopts) and portage.db[x[1]]["vartree"].exists_specific(x[2]):
715
					addl="  "+yellow("R")+fetch+"  "
716
				elif (not "--emptytree" in self.myopts) and portage.db[x[1]]["vartree"].exists_specific_cat(x[2]):
717
					if x[0] == "binary":
718
						mynewslot=portage.db["/"]["bintree"].getslot(x[2])
719
					elif x[0] == "ebuild":
720
						mynewslot=portage.db["/"]["porttree"].getslot(x[2])
721
					myoldlist=portage.db[x[1]]["vartree"].dbapi.match(portage.pkgsplit(x[2])[0])
722
					myinslotlist=filter((lambda p: portage.db[portage.root]["vartree"].getslot(p)==mynewslot),myoldlist)
723
					if myinslotlist:
724
						myoldbest=portage.best(myinslotlist)
725
						addl="   "+fetch
726
						if portage.pkgcmp(portage.pkgsplit(x[2]), portage.pkgsplit(myoldbest)) < 0:
727
							# Downgrade in slot
728
							addl+=turquoise("U")+blue("D")
729
						else:
730
							# Update in slot
731
							addl+=turquoise("U")+" "
732
					else:
733
						# New slot, mark it new.
734
						addl=" "+green("NS")+fetch+"  "
735
736
					if "--changelog" in self.myopts:
737
						changelogs.extend(self.calc_changelog(
738
							portage.portdb.findname(x[2]),
739
							portage.db[x[1]]["vartree"].dep_bestmatch('/'.join(portage.catpkgsplit(x[2])[:2])),
740
							x[2]
741
							))
742
				else:
743
					addl=" "+green("N")+" "+fetch+"  "
744
745
				verboseadd=""
746
				
747
				if x[2] in self.applied_useflags:
748
					# USE flag display
749
					if x[0] == "binary":
750
						cur_iuse = string.split(portage.db["/"]["bintree"].dbapi.aux_get(x[2],["IUSE"])[0])
751
					elif x[0] == "ebuild":
752
						cur_iuse = string.split(portage.portdb.aux_get(x[2],["IUSE"])[0])
753
					else:
754
						cur_iuse = []
755
756
					cur_iuse = portage.unique_array(cur_iuse)
757
					cur_iuse = [flag for flag in cur_iuse if flag not in portage.settings.usemask]
758
					cur_iuse.sort()
759
					cur_use = self.applied_useflags[x[2]]
760
					cur_use = [flag for flag in cur_use if flag in cur_iuse]
761
762
					if myoldbest:
763
						pkg = myoldbest
764
					else:
765
						pkg = x[2]
766
					if portage.db[x[1]]["vartree"].dbapi.cpv_exists(pkg):
767
						(old_iuse, old_use) = portage.db[x[1]]["vartree"].dbapi.aux_get(pkg, ["IUSE", "USE"])
768
						old_iuse = portage.unique_array(old_iuse.split())
769
						old_iuse.sort()
770
						old_use = old_use.split()
771
						is_new = False
772
					else:
773
						old_iuse = []
774
						old_use = []
775
						is_new = True
776
					old_iuse = [flag for flag in old_iuse if flag not in portage.settings.usemask]
777
					old_use = [flag for flag in old_use if flag in old_iuse]
778
779
					use_expand = portage.settings["USE_EXPAND"].lower().split()
780
					use_expand.sort()
781
					use_expand.reverse()
782
					use_expand_hidden = portage.settings["USE_EXPAND_HIDDEN"].lower().split()
783
784
					def map_to_use_expand(myvals):
785
						ret = {}
786
						for exp in use_expand:
787
							ret[exp] = []
788
							for val in myvals[:]:
789
								if val.startswith(exp.lower()+"_"):
790
									ret[exp].append(val[len(exp)+1:])
791
									myvals.remove(val)
792
						ret["USE"] = myvals
793
						for exp in use_expand_hidden:
794
							if exp in ret:
795
								del ret[exp]
796
						return ret
797
798
					cur_iuse_map = map_to_use_expand(cur_iuse)
799
					cur_use_map = map_to_use_expand(cur_use)
800
					old_iuse_map = map_to_use_expand(old_iuse)
801
					old_use_map = map_to_use_expand(old_use)
802
803
					use_expand.sort()
804
					use_expand.insert(0, "USE")
805
					
806
					for key in use_expand:
807
						if key in use_expand_hidden:
808
							continue
809
						verboseadd += create_use_string(key.upper(), cur_iuse_map[key], cur_use_map[key],
810
						                                old_iuse_map[key], old_use_map[key], is_new)
811
812
				if verbosity == 3:
813
					# size verbose
814
					mysize=0
815
					if x[0] == "ebuild" and x[-1]!="nomerge":
816
						myfilesdict=portage.portdb.getfetchsizes(x[2], useflags=self.applied_useflags[x[2]], debug=edebug)
817
						if myfilesdict is None:
818
							myfilesdict="[empty/missing/bad digest]"
819
						else:
820
							for myfetchfile in myfilesdict.keys():
821
								if myfetchfile not in myfetchlist:
822
									mysize+=myfilesdict[myfetchfile]
823
									myfetchlist.append(myfetchfile)
824
							totalsize+=mysize
825
						verboseadd+=format_size(mysize)+" "
826
827
					# overlay verbose
828
					# XXX: Invalid binaries have caused tracebacks here. 'if file_name'
829
					# x = ['binary', '/', 'sys-apps/pcmcia-cs-3.2.7.2.6', 'merge']
830
					file_name=portage.portdb.findname(x[2])
831
					if file_name: # It might not exist in the tree
832
						dir_name=os.path.abspath(os.path.dirname(file_name)+"/../..")
833
						if (overlays_real.count(dir_name)>0):
834
							verboseadd+=teal("["+str(overlays_real.index(
835
								os.path.normpath(dir_name))+1)+"]")+" "
836
							display_overlays=True
837
					else:
838
						verboseadd += "[No ebuild?]"
839
840
				xs=portage.pkgsplit(x[2])
841
				if xs[2]=="r0":
842
					xs[2]=""
843
				else:
844
					xs[2]="-"+xs[2]
845
846
				if self.pkgsettings.has_key("COLUMNWIDTH"):
847
					mywidth=int(self.pkgsettings.settings["COLUMNWIDTH"])
848
				else:
849
					mywidth=130
850
				oldlp=mywidth-30
851
				newlp=oldlp-30
852
853
				indent=""
854
				if ("--tree" in self.myopts):
855
					indent=" "*mygraph.depth(string.join(x))
856
857
				if myoldbest:
858
					myoldbest=portage.pkgsplit(myoldbest)[1]+"-"+portage.pkgsplit(myoldbest)[2]
859
					if myoldbest[-3:]=="-r0":
860
						myoldbest=myoldbest[:-3]
861
					myoldbest=blue("["+myoldbest+"]")
862
863
				if x[1]!="/":
864
					if myoldbest:
865
						myoldbest +=" "
866
					if "--columns" in self.myopts:
867
						if "--quiet" in self.myopts:
868
							myprint=addl+" "+indent+darkgreen(xs[0])
869
							myprint=myprint+darkblue(" "+xs[1]+xs[2])+" "
870
							myprint=myprint+myoldbest
871
							myprint=myprint+darkgreen("to "+x[1])
872
						else:
873
							myprint="["+x[0]+" "+addl+"] "+indent+darkgreen(xs[0])
874
							if (newlp-nc_len(myprint)) > 0:
875
								myprint=myprint+(" "*(newlp-nc_len(myprint)))
876
							myprint=myprint+"["+darkblue(xs[1]+xs[2])+"] "
877
							if (oldlp-nc_len(myprint)) > 0:
878
								myprint=myprint+" "*(oldlp-nc_len(myprint))
879
							myprint=myprint+myoldbest
880
							myprint=myprint+darkgreen("to "+x[1])+" "+verboseadd
881
					else:
882
						myprint="["+x[0]+" "+addl+"] "+darkgreen(x[2])+" "+myoldbest+darkgreen("to "+x[1])+" "+verboseadd
883
				else:
884
					if "--columns" in self.myopts:
885
						if "--quiet" in self.myopts:
886
							myprint=addl+" "+indent+darkgreen(xs[0])
887
							myprint=myprint+" "+green(xs[1]+xs[2])+" "
888
							myprint=myprint+myoldbest
889
						else:
890
							myprint="["+x[0]+" "+addl+"] "+indent+darkgreen(xs[0])
891
							if (newlp-nc_len(myprint)) > 0:
892
								myprint=myprint+(" "*(newlp-nc_len(myprint)))
893
							myprint=myprint+green(" ["+xs[1]+xs[2]+"] ")
894
							if (oldlp-nc_len(myprint)) > 0:
895
								myprint=myprint+(" "*(oldlp-nc_len(myprint)))
896
							myprint=myprint+myoldbest+"  "+verboseadd
897
					else:
898
						if x[3]=="nomerge":
899
							myprint=darkblue("[nomerge      ] "+indent+x[2]+" "+myoldbest+" ")+verboseadd
900
						else:
901
							myprint="["+x[0]+" "+addl+"] "+indent+darkgreen(x[2])+" "+myoldbest+" "+verboseadd
902
				p.append(myprint)
903
904
			mysplit = portage.pkgsplit(x[2])
905
			if "--tree" not in self.myopts and mysplit and len(mysplit) == 3 and \
906
				mysplit[0] == "sys-apps/portage" and x[1] == "/":
907
908
				if mysplit[2] == "r0":
909
					myversion = mysplit[1]
910
				else:
911
					myversion = "%s-%s" % (mysplit[1], mysplit[2])
912
913
				if myversion != portage.VERSION :
914
					if "--emptytree" in self.myopts:
915
						p.append(red("***")+" Please update portage to the above version before proceeding.")
916
						p.append("    Failure to do so may result in failed or improper merges.")
917
						p.append("    A simple '"+green("emerge portage")+"' is sufficient.")
918
						p.append("")
919
					elif mylist.index(x) < len(mylist) - 1 and \
920
						"livecvsportage" not in portage.settings.features:
921
						p.append(red("*** Portage will stop merging at this point and reload itself,"))
922
						p.append(red("    then resume the merge."))
923
						print
924
			del mysplit
925
926
		for x in p:
927
			print x
928
929
		if verbosity == 3:
930
			print
931
			print "Total size of downloads: "+format_size(totalsize)
932
			if overlays and display_overlays:
933
				print "Portage overlays:"
934
				y=0
935
				for x in overlays:
936
					y=y+1
937
					print " "+teal("["+str(y)+"]"),x
938
939
		if "--changelog" in self.myopts:
940
			print
941
			for revision,text in changelogs:
942
				print bold('*'+revision)
943
				sys.stdout.write(text)
944
945
	def calc_changelog(self,ebuildpath,current,next):
946
		current = '-'.join(portage.catpkgsplit(current)[1:])
947
		if current.endswith('-r0'): current = current[:-3]
948
		next = '-'.join(portage.catpkgsplit(next)[1:])
949
		if next.endswith('-r0'): next = next[:-3]
950
		changelogpath = os.path.join(os.path.split(ebuildpath)[0],'ChangeLog')
951
		try:
952
			changelog = open(changelogpath).read()
953
		except SystemExit, e:
954
			raise # Needed else can't exit
955
		except:
956
			return []
957
		divisions = self.find_changelog_tags(changelog)
958
		#print 'XX from',current,'to',next
959
		#for div,text in divisions: print 'XX',div
960
		# skip entries for all revisions above the one we are about to emerge
961
		for i in range(len(divisions)):
962
			if divisions[i][0]==next:
963
				divisions = divisions[i:]
964
				break
965
		# find out how many entries we are going to display
966
		for i in range(len(divisions)):
967
			if divisions[i][0]==current:
968
				divisions = divisions[:i]
969
				break
970
		else:
971
		    # couldnt find the current revision in the list. display nothing
972
			return []
973
		return divisions
974
975
	def find_changelog_tags(self,changelog):
976
		divs = []
977
		release = None
978
		while 1:
979
			match = re.search(r'^\*\ ?([-a-zA-Z0-9_.+]*)(?:\ .*)?\n',changelog,re.M)
980
			if match is None:
981
				if release is not None:
982
					divs.append((release,changelog))
983
				return divs
984
			if release is not None:
985
				divs.append((release,changelog[:match.start()]))
986
			changelog = changelog[match.end():]
987
			release = match.group(1)
988
			if release.endswith('.ebuild'):
989
				release = release[:-7]
990
			if release.endswith('-r0'):
991
				release = release[:-3]
992
993
	def outdated(self):
994
		return self.outdatedpackages
995
996
	def merge(self,mylist,fav):
997
		self.favorites=fav # XXX: HACK
998
		print "Favorites set to " + repr(fav)
999
		returnme=0
1000
		mymergelist=[]
1001
1002
		#check for blocking dependencies
1003
		if ("--fetchonly" not in self.myopts) and ("--buildpkgonly" not in self.myopts):
1004
			for x in mylist:
1005
				if x[0]=="blocks":
1006
					print "\n!!! Error: the "+x[2]+" package conflicts with another package;"
1007
					print   "!!!        the two packages cannot be installed on the same system together."
1008
					print   "!!!        Please use 'emerge --pretend' to determine blockers."
1009
					print
1010
					if ("--pretend" not in self.myopts):
1011
						try:
1012
							del portage.mtimedb["resume"]
1013
						except KeyError:
1014
							pass
1015
						sys.exit(1)
1016
1017
		#buildsyspkg: I need mysysdict also on resume (moved from the else block)
1018
		mysysdict=genericdict(syslist)
1019
		if ("--resume" in self.myopts):
1020
			# We're resuming.
1021
			print green("*** Resuming merge...")
1022
			emergelog(" *** Resuming merge...")
1023
			mymergelist=portage.mtimedb["resume"]["mergelist"][:]
1024
			if ("--skipfirst" in self.myopts) and mymergelist:
1025
				del portage.mtimedb["resume"]["mergelist"][0]
1026
				del mymergelist[0]
1027
			validate_merge_list(mymergelist)
1028
		else:
1029
			myfavs = portage.grabfile(os.path.join(portage.root, portage.WORLD_FILE))
1030
			myfavdict=genericdict(myfavs)
1031
			for x in range(len(mylist)):
1032
				if mylist[x][3]!="nomerge":
1033
					# Add to the mergelist
1034
					mymergelist.append(mylist[x])
1035
				else:
1036
					myfavkey=portage.cpv_getkey(mylist[x][2])
1037
					if "--onlydeps" in self.myopts:
1038
						continue
1039
					# Add to the world file. Since we won't be able to later.
1040
					if (not "--fetchonly" in self.myopts) and (myfavkey in self.favorites):
1041
						#don't record if already in system profile or already recorded
1042
						if (not mysysdict.has_key(myfavkey)) and (not myfavdict.has_key(myfavkey)):
1043
							#we don't have a favorites entry for this package yet; add one
1044
							myfavdict[myfavkey]=myfavkey
1045
							print ">>> Recording",myfavkey,"in \"world\" favorites file..."
1046
			if not "--fetchonly" in self.myopts:
1047
				portage.write_atomic(
1048
					os.path.join(portage.root, portage.WORLD_FILE),
1049
					"\n".join(myfavdict.values()))
1050
1051
			portage.mtimedb["resume"]["mergelist"]=mymergelist[:]
1052
1053
		# We need to yank the harmful-to-new-builds settings from features.
1054
		myorigfeat=self.pkgsettings["FEATURES"]
1055
		myfeat=myorigfeat.split()
1056
		while ("keeptemp" in myfeat):
1057
			del myfeat[myfeat.index("keeptemp")]
1058
		while ("keepwork" in myfeat):
1059
			del myfeat[myfeat.index("keepwork")]
1060
1061
		self.pkgsettings["FEATURES"]=string.join(myfeat)
1062
1063
		if "parallel-fetch" in myfeat and not ("--ask" in self.myopts or "--pretend" in self.myopts or "--fetchonly" in self.myopts):
1064
			if "distlocks" not in myfeat:
1065
				print red("!!!")
1066
				print red("!!!")+" parallel-fetching requires the distlocks feature enabled"
1067
				print red("!!!")+" you have it disabled, thus parallel-fetching is being disabled"
1068
				print red("!!!")
1069
			elif len(mymergelist) > 1:
1070
				print ">>> starting parallel fetching"
1071
				pid = os.fork()
1072
				if not pid:
1073
					sys.stdin.close()
1074
					sys.stdout.close()
1075
					sys.stderr.close()
1076
					time.sleep(3) # allow the parent to have first fetch
1077
					sys.stdout = open("/dev/null","w")
1078
					sys.stderr = open("/dev/null","w")
1079
					os.dup2(sys.stdout.fileno(), 1)
1080
					os.dup2(sys.stdout.fileno(), 2)
1081
					# wipe the mtimedb so that portage doesn't attempt to flush it.
1082
					# do not convert this code away from a fork without correcting this.
1083
					portage.mtimedb = None
1084
					for x in ("autoaddcvs", "cvs"):
1085
						try:	myfeat.remove(x)
1086
						except ValueError: pass
1087
					self.pkgsettings["FEATURES"] = " ".join(myfeat)
1088
					ret = 0
1089
					for x in mymergelist:
1090
						if x[0] != "ebuild":
1091
							continue
1092
						try:
1093
							ret = portage.doebuild(portage.portdb.findname(x[2]), "fetch", x[1], self.pkgsettings,
1094
								cleanup=0, fetchonly=True, tree="porttree")
1095
						except SystemExit:
1096
							raise
1097
						except Exception:
1098
							ret = 1
1099
					sys.exit(0)
1100
				portage.portage_exec.spawned_pids.append(pid)
1101
1102
		mergecount=0
1103
		for x in mymergelist:
1104
			mergecount+=1
1105
			myroot=x[1]
1106
			pkgindex=2
1107
			if x[0]=="blocks":
1108
				pkgindex=3
1109
			y=portage.portdb.findname(x[pkgindex])
1110
			if not "--pretend" in self.myopts:
1111
				print ">>> Emerging ("+str(mergecount)+" of "+str(len(mymergelist))+")",x[pkgindex],"to",x[1]
1112
				emergelog(" >>> emerge ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" to "+x[1])
1113
1114
			self.pkgsettings["EMERGE_FROM"] = x[0][:]
1115
			self.pkgsettings.backup_changes("EMERGE_FROM")
1116
			self.pkgsettings.reset()
1117
1118
			#buildsyspkg: Check if we need to _force_ binary package creation
1119
			issyspkg = ("buildsyspkg" in myfeat) \
1120
					and x[0] != "blocks" \
1121
					and mysysdict.has_key(portage.cpv_getkey(x[2])) \
1122
					and not ("--buildpkg" in self.myopts)
1123
			if x[0] in ["ebuild","blocks"]:
1124
				if (x[0]=="blocks") and ("--fetchonly" not in self.myopts):
1125
					raise Exception, "Merging a blocker"
1126
				elif ("--fetchonly" in self.myopts) or ("--fetch-all-uri" in self.myopts):
1127
					if ("--fetch-all-uri" in self.myopts):
1128
						retval=portage.doebuild(y,"fetch",myroot,self.pkgsettings,edebug,("--pretend" in self.myopts),fetchonly=1,fetchall=1,tree="porttree")
1129
					else:
1130
						retval=portage.doebuild(y,"fetch",myroot,self.pkgsettings,edebug,("--pretend" in self.myopts),fetchonly=1,tree="porttree")
1131
					if (retval is None) or retval:
1132
						print
1133
						print "!!! Fetch for",y,"failed, continuing..."
1134
						print
1135
						returnme=1
1136
					continue
1137
				elif "--buildpkg" in self.myopts or issyspkg:
1138
					#buildsyspkg: Sounds useful to display something, but I don't know if we should also log it
1139
					if issyspkg:
1140
						print ">>> This is a system package, let's pack a rescue tarball."
1141
						#emergelog(">>> This is a system package, let's pack a rescue tarball.")
1142
					#create pkg, then merge pkg
1143
					short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Clean"
1144
					emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Cleaning ("+x[pkgindex]+"::"+y+")", short_msg=short_msg)
1145
					retval=portage.doebuild(y,"clean",myroot,self.pkgsettings,edebug,cleanup=1,tree="porttree")
1146
					if (retval is None):
1147
						portage_util.writemsg("Unable to run required binary.\n",
1148
							noiselevel=-1)
1149
						sys.exit(127)
1150
					if retval:
1151
						sys.exit(retval)
1152
					short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Compile"
1153
					emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Compiling/Packaging ("+x[pkgindex]+"::"+y+")", short_msg=short_msg)
1154
					retval=portage.doebuild(y,"package",myroot,self.pkgsettings,edebug,tree="porttree")
1155
					if (retval is None):
1156
						portage_util.writemsg("Unable to run required binary.\n",
1157
							noiselevel=-1)
1158
						sys.exit(127)
1159
					if retval:
1160
						sys.exit(retval)
1161
					#dynamically update our database
1162
					if "--buildpkgonly" not in self.myopts:
1163
						portage.db[portage.root]["bintree"].inject(x[2])
1164
						mytbz2=portage.db[portage.root]["bintree"].getname(x[2])
1165
						short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Merge"
1166
						emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Merging ("+x[pkgindex]+"::"+y+")", short_msg=short_msg)
1167
1168
						self.pkgsettings["EMERGE_FROM"] = "binary"
1169
						self.pkgsettings.backup_changes("EMERGE_FROM")
1170
1171
						retval=portage.pkgmerge(mytbz2,myroot,self.pkgsettings)
1172
						if retval is None:
1173
							sys.exit(1)
1174
					elif "noclean" not in self.pkgsettings.features:
1175
						portage.doebuild(y, "clean", myroot, self.pkgsettings,
1176
							edebug, tree="porttree")
1177
				else:
1178
					short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Clean"
1179
					emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Cleaning ("+x[pkgindex]+"::"+y+")", short_msg=short_msg)
1180
					retval=portage.doebuild(y,"clean",myroot,self.pkgsettings,edebug,cleanup=1,tree="porttree")
1181
					if (retval is None):
1182
						portage_util.writemsg("Unable to run required binary.\n",
1183
							noiselevel=-1)
1184
						sys.exit(127)
1185
					if retval:
1186
						sys.exit(retval)
1187
					short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Compile"
1188
					emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Compiling/Merging ("+x[pkgindex]+"::"+y+")", short_msg=short_msg)
1189
					retval=portage.doebuild(y,"merge",myroot,self.pkgsettings,edebug,tree="porttree")
1190
					if (retval is None):
1191
						portage_util.writemsg("Unable to run required binary.\n",
1192
							noiselevel=-1)
1193
						sys.exit(127)
1194
					if retval:
1195
						sys.exit(retval)
1196
					#dynamically update our database
1197
			elif x[0]=="binary":
1198
				#merge the tbz2
1199
				mytbz2=portage.db[portage.root]["bintree"].getname(x[2])
1200
				if portage.db[portage.root]["bintree"].isremote(x[2]):
1201
					short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Fetch"
1202
					emergelog(" --- ("+str(mergecount)+" of "+str(len(mymergelist))+") Fetching Binary ("+x[pkgindex]+"::"+mytbz2+")", short_msg=short_msg)
1203
					if not portage.db[portage.root]["bintree"].gettbz2(x[2]):
1204
						sys.exit(1)
1205
1206
				if ("--fetchonly" in self.myopts) or ("--fetch-all-uri" in self.myopts):
1207
					continue
1208
1209
				short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Merge Binary"
1210
				emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Merging Binary ("+x[pkgindex]+"::"+mytbz2+")", short_msg=short_msg)
1211
				retval=portage.pkgmerge(mytbz2,x[1],self.pkgsettings)
1212
				if retval is None:
1213
					sys.exit(1)
1214
				#need to check for errors
1215
			if "--buildpkgonly" not in self.myopts:
1216
				portage.db[x[1]]["vartree"].inject(x[2])
1217
				myfavkey=portage.cpv_getkey(x[2])
1218
				if "--fetchonly" not in self.myopts and "--fetch-all-uri" not in self.myopts and myfavkey in self.favorites:
1219
					myfavs = portage.grabfile(os.path.join(myroot, portage.WORLD_FILE))
1220
					myfavdict=genericdict(myfavs)
1221
					mysysdict=genericdict(syslist)
1222
					#don't record if already in system profile or already recorded
1223
					if (not mysysdict.has_key(myfavkey)) and (not myfavdict.has_key(myfavkey)):
1224
						#we don't have a favorites entry for this package yet; add one
1225
						myfavdict[myfavkey]=myfavkey
1226
						print ">>> Recording",myfavkey,"in \"world\" favorites file..."
1227
						emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Updating world file ("+x[pkgindex]+")")
1228
						portage.write_atomic(
1229
						os.path.join(myroot, portage.WORLD_FILE),
1230
						"\n".join(myfavdict.values()))
1231
1232
				if ("--pretend" not in self.myopts) and ("--fetchonly" not in self.myopts) and ("--fetch-all-uri" not in self.myopts):
1233
					# Clean the old package that we have merged over top of it.
1234
					if self.pkgsettings["AUTOCLEAN"]=="yes":
1235
						xsplit=portage.pkgsplit(x[2])
1236
						emergelog(" >>> AUTOCLEAN: "+xsplit[0])
1237
						if x[1] == portage.settings["ROOT"]:
1238
							# Compare against portage.settings["ROOT"] because
1239
							# the value of self.pkgsettings["ROOT"] does not
1240
							# match the original value!
1241
							retval = unmerge("clean", [xsplit[0]])
1242
						else:
1243
							retval = unmerge_overlapping(x[2], x[1],
1244
								self.pkgsettings, portage.db[x[1]]["vartree"])
1245
						if not retval:
1246
							emergelog(" --- AUTOCLEAN: Nothing unmerged.")
1247
					else:
1248
						portage.writemsg_stdout(colorize("WARN", "WARNING:")
1249
							+ " AUTOCLEAN is disabled.  This can cause serious"
1250
							+ " problems due to overlapping packages.\n")
1251
1252
					# Figure out if we need a restart.
1253
					mysplit=portage.pkgsplit(x[2])
1254
					if mysplit[0] == "sys-apps/portage" and x[1] == "/":
1255
						myver=mysplit[1]+"-"+mysplit[2]
1256
						if myver[-3:]=='-r0':
1257
							myver=myver[:-3]
1258
						if (myver != portage.VERSION) and \
1259
						   ("livecvsportage" not in portage.settings.features):
1260
							if len(mymergelist) > mergecount:
1261
								emergelog(" ::: completed emerge ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[2]+" to "+x[1])
1262
								emergelog(" *** RESTARTING emerge via exec() after change of portage version.")
1263
								del portage.mtimedb["resume"]["mergelist"][0]
1264
								portage.run_exitfuncs()
1265
								mynewargv=[sys.argv[0],"--resume"]
1266
								badlongopts = ("--ask","--tree","--changelog","--skipfirst","--resume")
1267
								for arg in self.myopts:
1268
									if arg in badlongopts:
1269
										continue
1270
									mynewargv.append(arg)
1271
								# priority only needs to be adjusted on the first run
1272
								os.environ["PORTAGE_NICENESS"] = "0"
1273
								os.execv(mynewargv[0], mynewargv)
1274
1275
			if ("--pretend" not in self.myopts) and ("--fetchonly" not in self.myopts) and ("--fetch-all-uri" not in self.myopts):
1276
				if "noclean" not in portage.settings.features:
1277
					short_msg = "emerge: (%s of %s) %s Clean Post" % \
1278
						(mergecount, len(mymergelist), x[pkgindex])
1279
					emergelog(" === (%s of %s) Post-Build Cleaning (%s::%s)" % \
1280
						(mergecount, len(mymergelist), x[pkgindex], y), short_msg=short_msg)
1281
				emergelog(" ::: completed emerge ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[2]+" to "+x[1])
1282
1283
			# Unsafe for parallel merges
1284
			del portage.mtimedb["resume"]["mergelist"][0]
1285
			# Commit after each merge so that --resume may still work in
1286
			# in the event that portage is not allowed to exit normally
1287
			# due to power failure, SIGKILL, etc...
1288
			portage.commit_mtimedb()
1289
1290
		emergelog(" *** Finished. Cleaning up...")
1291
1292
		# We're out of the loop... We're done. Delete the resume data.
1293
		if portage.mtimedb.has_key("resume"):
1294
			del portage.mtimedb["resume"]
1295
1296
		if ("--pretend" not in self.myopts):
1297
			if ("--fetchonly" not in self.myopts) and ("--fetch-all-uri" not in self.myopts):
1298
				if (mergecount>0):
1299
					if retval:
1300
						portage.env_update()
1301
1302
		#by doing an exit this way, --fetchonly can continue to try to
1303
		#fetch everything even if a particular download fails.
1304
		if "--fetchonly" in self.myopts or "--fetch-all-uri" in self.myopts:
1305
			if returnme:
1306
				print "\n\n!!! Some fetch errors were encountered.  Please see above for details.\n\n"
1307
				sys.exit(returnme)
1308
			else:
1309
				sys.exit(0)
1310

Return to bug 136932