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

(-)emergeold (-1274 / +9 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
dg.is_valid_package_atom = is_valid_package_atom
1324
dg.update_spinner = update_spinner
1325
depgraph = depgraph.depgraph
1326
2592
# general options that should be taken into account before any action
1327
# general options that should be taken into account before any action
2593
if "--debug" in myopts:
1328
if "--debug" in myopts:
2594
	edebug=1
1329
	edebug=1
Lines 3268-3274 Link Here
3268
	if not "--pretend" in myopts: #just check pretend, since --ask implies pretend
2003
	if not "--pretend" in myopts: #just check pretend, since --ask implies pretend
3269
		emergelog(" >>> depclean")
2004
		emergelog(" >>> depclean")
3270
	
2005
	
3271
	mydepgraph=depgraph(myaction,myopts)
2006
	mydepgraph=depgraph(myaction,myopts,myparams)
3272
2007
3273
	if not ("--quiet" in myopts):
2008
	if not ("--quiet" in myopts):
3274
		print "\nCalculating dependencies  ",
2009
		print "\nCalculating dependencies  ",
Lines 3383-3389 Link Here
3383
			if myopt not in myresumeopts:
2118
			if myopt not in myresumeopts:
3384
				myresumeopts.append(myopt)
2119
				myresumeopts.append(myopt)
3385
		myopts=myresumeopts
2120
		myopts=myresumeopts
3386
		mydepgraph=depgraph("resume",myopts)
2121
		mydepgraph=depgraph("resume",myopts,myparams)
3387
		if "--resume" not in myopts:
2122
		if "--resume" not in myopts:
3388
			myopts+=["--resume"]
2123
			myopts+=["--resume"]
3389
	else:
2124
	else:
Lines 3392-3398 Link Here
3392
			print darkgreen("emerge: It seems we have nothing to resume...")
2127
			print darkgreen("emerge: It seems we have nothing to resume...")
3393
			sys.exit(0)
2128
			sys.exit(0)
3394
2129
3395
		mydepgraph=depgraph(myaction,myopts)
2130
		mydepgraph=depgraph(myaction,myopts,myparams)
3396
		if myaction in ["system","world"]:
2131
		if myaction in ["system","world"]:
3397
			if not ("--quiet" in myopts):
2132
			if not ("--quiet" in myopts):
3398
				print "Calculating",myaction,"dependencies  ",
2133
				print "Calculating",myaction,"dependencies  ",
(-)depgraph.old (+1288 lines)
Line 0 Link Here
1
2
import portage
3
import os,sys
4
5
import emergehelp,xpak,string,re,commands,time,shutil,traceback,signal,socket,types
6
from stat import *
7
from output import *
8
9
import portage_util
10
import portage_locks
11
import portage_exception
12
from portage_const import PROFILE_PATH
13
14
olddbapi=None
15
class depgraph:
16
17
	def __init__(self,myaction,myopts,myparams):
18
		self.myopts = myopts
19
		self.myparams = myparams
20
		global olddbapi
21
		self.pkgsettings = portage.config(clone=portage.settings)
22
		if not self.pkgsettings["ARCH"]:
23
			portage.writemsg(red("\a!!! ARCH is not set... Are you missing the /etc/make.profile symlink?\n"),
24
				noiselevel=-1)
25
			portage.writemsg(red("\a!!! Is the symlink correct? Is your portage tree complete?\n\n"),
26
				noiselevel=-1)
27
			sys.exit(9)
28
		self.applied_useflags = {}
29
30
		self.missingbins=[]
31
		self.myaction=myaction
32
		self.digraph=portage.digraph()
33
		self.orderedkeys=[]
34
		self.outdatedpackages=[]
35
		self.mydbapi={}
36
		self.mydbapi["/"] = portage.fakedbapi()
37
		if "empty" not in self.myparams or portage.root != "/":
38
			for pkg in portage.db["/"]["vartree"].getallcpv():
39
				self.mydbapi["/"].cpv_inject(pkg)
40
		if portage.root != "/":
41
			self.mydbapi[portage.root] = portage.fakedbapi()
42
			if "empty" not in self.myparams:
43
				for pkg in portage.db[portage.root]["vartree"].getallcpv():
44
					self.mydbapi[portage.root].cpv_inject(pkg)
45
46
		if "--usepkg" in self.myopts:
47
			portage.db["/"]["bintree"].populate(("--getbinpkg" in self.myopts), ("--getbinpkgonly" in self.myopts))
48
49
	def create(self,mybigkey,myparent=None,addme=1,myuse=None):
50
		"""creates the actual digraph of packages to merge.  return 1 on success, 0 on failure
51
		mybigkey = specification of package to merge; myparent = parent package (one depending on me);
52
		addme = should I be added to the tree? (for the --onlydeps mode)"""
53
		#stuff to add:
54
		#SLOT-aware emerge
55
		#IUSE-aware emerge
56
		#"no downgrade" emerge
57
		#print "mybigkey:",mybigkey
58
59
		jbigkey=string.join(mybigkey)
60
		if self.digraph.hasnode(jbigkey+" merge") or self.digraph.hasnode(jbigkey+" nomerge"):
61
			#this conditional is needed to prevent infinite recursion on already-processed deps
62
			return 1
63
64
		update_spinner()
65
66
		mytype,myroot,mykey=mybigkey
67
		# select the correct /var database that we'll be checking against
68
		vardbapi=portage.db[myroot]["vartree"].dbapi
69
70
		# if the package is already on the system, we add a "nomerge"
71
		# directive, otherwise we add a "merge" directive.
72
		if mytype=="blocks":
73
			# we've encountered a "blocks" node.  We will totally ignore this
74
			# node and not add it to our digraph if it doesn't apply to us.
75
			if addme and "--buildpkgonly" not in self.myopts and myparent and (self.mydbapi[myroot].match(mykey) or vardbapi.match(mykey)):
76
				mybigkey.append(myparent.split()[2])
77
				self.digraph.addnode(string.join(mybigkey),myparent)
78
			return 1
79
80
		if myuse is None:
81
			self.pkgsettings.setcpv(mykey)
82
			myuse = self.pkgsettings["USE"].split()
83
		self.applied_useflags[mykey] = myuse
84
85
		merging=1
86
		if addme:
87
		# this is where we add the node to the list of packages to merge
88
			if not myparent:
89
				# command-line specified or part of a world list...
90
				if ("self" not in self.myparams) or (("selective" in self.myparams) and vardbapi.cpv_exists(mykey)):
91
					# the package is on the system, so don't merge it.
92
					merging=0
93
			elif ("selective" in self.myparams) and vardbapi.cpv_exists(mykey):
94
				merging=0
95
96
			if (merging==0 and "--newuse" in self.myopts and vardbapi.cpv_exists(mykey)):
97
				old_use = vardbapi.aux_get(mykey, ["USE"])[0].split()
98
				if mytype == "binary":
99
					iuses = portage.db["/"]["bintree"].dbapi.aux_get(mykey, ["IUSE"])[0].split()
100
				else:
101
					iuses = portage.db["/"]["porttree"].dbapi.aux_get(mykey, ["IUSE"])[0].split()
102
				for x in iuses:
103
					if (old_use.count(x) and not myuse.count(x)) or (not old_use.count(x) and myuse.count(x)):
104
						merging=1
105
						break
106
		else:
107
			#onlydeps mode; don't merge
108
			merging=2
109
		if merging==1:
110
			mybigkey.append("merge")
111
		else:
112
			mybigkey.append("nomerge")
113
114
		# whatever the case, we need to add the node to our digraph so
115
		# that children can depend upon it.
116
		self.digraph.addnode(string.join(mybigkey),myparent)
117
		if ("deep" not in self.myparams) and (not merging):
118
			return 1
119
		elif "recurse" not in self.myparams:
120
			return 1
121
122
		edepend={}
123
		if mytype=="binary":
124
			mypkgparts=portage.catpkgsplit(mykey)
125
			tbz2name = string.split(mykey, "/")[1]+".tbz2"
126
			if tbz2name in portage.db[portage.root]["bintree"].invalids:
127
				sys.stderr.write("\nINVALID PACKAGE (is required to continue): "+str(mykey)+"\n")
128
				sys.exit(1)
129
			if portage.db[portage.root]["bintree"].isremote(mykey):
130
				edepend = portage.db[portage.root]["bintree"].remotepkgs[tbz2name]
131
				edepend["DEPEND"] =""
132
				edepend["RDEPEND"]=string.join(string.split(edepend["RDEPEND"])," ")
133
				edepend["PDEPEND"]=string.join(string.split(edepend["PDEPEND"])," ")
134
				edepend["SLOT"]   =string.strip(edepend["SLOT"])
135
				#portage.db[portage.root]["bintree"].gettbz2(mykey)
136
			else: # It's local.
137
				mytbz2=xpak.tbz2(portage.db[portage.root]["bintree"].getname(mykey))
138
				edepend["DEPEND"] =""
139
				edepend["RDEPEND"]=string.join(mytbz2.getelements("RDEPEND")," ")
140
				edepend["PDEPEND"]=string.join(mytbz2.getelements("PDEPEND")," ")
141
				edepend["SLOT"]   =mytbz2.getfile("SLOT",mypkgparts[2])
142
		elif mytype=="ebuild":
143
			try:
144
				mymeta = ["DEPEND","RDEPEND","PDEPEND"]
145
				myfoo = portage.portdb.aux_get(mykey, mymeta)
146
				for index in range(0,len(mymeta)):
147
					edepend[mymeta[index]] = myfoo[index]
148
				if "--buildpkgonly" in self.myopts:
149
					edepend["RDEPEND"] = ""
150
					edepend["PDEPEND"] = ""
151
			except (KeyError,IOError):
152
				print "emerge: create(): aux_get() error on",mykey+"; aborting..."
153
				sys.exit(1)
154
		mydep={}
155
		mp=string.join(mybigkey)
156
157
		if myroot=="/":
158
			mydep["/"]=edepend["DEPEND"]+" "+edepend["RDEPEND"]
159
			if not self.select_dep("/",mydep["/"],myparent=mp,myuse=myuse):
160
				return 0
161
		else:
162
			mydep["/"]=edepend["DEPEND"]
163
			mydep[myroot]=edepend["RDEPEND"]
164
			if not self.select_dep("/",mydep["/"],myparent=mp,myuse=myuse):
165
				return 0
166
			if not self.select_dep(myroot,mydep[myroot],myparent=mp,myuse=myuse):
167
				return 0
168
169
		if edepend.has_key("PDEPEND") and edepend["PDEPEND"]:
170
			# Post Depend -- Add to the list without a parent, as it depends
171
			# on a package being present AND must be built after that package.
172
			if not self.select_dep(myroot,edepend["PDEPEND"],myuse=myuse):
173
				return 0
174
175
		return 1
176
177
	def select_files(self,myfiles):
178
		"given a list of .tbz2s, .ebuilds and deps, create the appropriate depgraph and return a favorite list"
179
		myfavorites=[]
180
		for x in myfiles:
181
			ext = os.path.splitext(x)[1]
182
			if ext==".tbz2":
183
				if not os.path.exists(x):
184
					if os.path.exists(self.pkgsettings["PKGDIR"]+"/All/"+x):
185
						x=self.pkgsettings["PKGDIR"]+"/All/"+x
186
					elif os.path.exists(self.pkgsettings["PKGDIR"]+"/"+x):
187
						x=self.pkgsettings["PKGDIR"]+"/"+x
188
					else:
189
						print "\n\n!!! Binary package '"+str(x)+"' does not exist."
190
						print "!!! Please ensure the tbz2 exists as specified.\n"
191
						sys.exit(1)
192
				mytbz2=xpak.tbz2(x)
193
				mykey=mytbz2.getelements("CATEGORY")[0]+"/"+os.path.splitext(os.path.basename(x))[0]
194
				if os.path.realpath(portage.db["/"]["bintree"].getname(mykey)) != os.path.realpath(x):
195
					print red("\n*** You need to adjust PKGDIR to emerge this package.\n")
196
					sys.exit(1)
197
				if not self.create(["binary",portage.root,mykey],None,"--onlydeps" not in self.myopts):
198
					return (0,myfavorites)
199
				elif not "--oneshot" in self.myopts:
200
					myfavorites.append(mykey)
201
			elif ext==".ebuild":
202
				x = os.path.realpath(x)
203
				mykey=os.path.basename(os.path.normpath(x+"/../.."))+"/"+os.path.splitext(os.path.basename(x))[0]
204
				ebuild_path = portage.db["/"]["porttree"].dbapi.findname(mykey)
205
				if ebuild_path:
206
					if os.path.realpath(ebuild_path) != x:
207
						print red("\n*** You need to adjust PORTDIR or PORTDIR_OVERLAY to emerge this package.\n")
208
						sys.exit(1)
209
					if mykey not in portage.db["/"]["porttree"].dbapi.xmatch("match-visible", portage.dep_getkey(mykey)):
210
						print red("\n*** You are emerging a masked package. It is MUCH better to use")
211
						print red("*** /etc/portage/package.* to accomplish this. See portage(5) man")
212
						print red("*** page for details.")
213
						countdown(EMERGE_WARNING_DELAY, "Continuing...")
214
				else:
215
					raise portage_exception.PackageNotFound(
216
						"%s is not in a valid portage tree hierarchy or does not exist" % x)
217
				if not self.create(["ebuild",portage.root,mykey],None,"--onlydeps" not in self.myopts):
218
					return (0,myfavorites)
219
				elif not "--oneshot" in self.myopts:
220
					myfavorites.append(mykey)
221
			else:
222
				if not is_valid_package_atom(x):
223
					portage.writemsg("\n\n!!! '%s' is not a valid package atom.\n" % x,
224
						noiselevel=-1)
225
					portage.writemsg("!!! Please check ebuild(5) for full details.\n")
226
					portage.writemsg("!!! (Did you specify a version but forget to prefix with '='?)\n")
227
					return (0,[])
228
				try:
229
					mykey=portage.dep_expand(x,mydb=portage.portdb)
230
				except ValueError, errpkgs:
231
					print "\n\n!!! The short ebuild name \"" + x + "\" is ambiguous.  Please specify"
232
					print "!!! one of the following fully-qualified ebuild names instead:\n"
233
					for i in errpkgs[0]:
234
						print "    " + green(i)
235
					print
236
					sys.exit(1)
237
238
				# select needs to return 0 on dep_check failure
239
240
				sys.stdout.flush()
241
				sys.stderr.flush()
242
243
				try:
244
					self.mysd = self.select_dep(portage.root,mykey,arg=x)
245
				except portage_exception.MissingSignature, e:
246
					portage.writemsg("\n\n!!! A missing gpg signature is preventing portage from calculating the\n")
247
					portage.writemsg("!!! required dependencies. This is a security feature enabled by the admin\n")
248
					portage.writemsg("!!! to aid in the detection of malicious intent.\n\n")
249
					portage.writemsg("!!! THIS IS A POSSIBLE INDICATION OF TAMPERED FILES -- CHECK CAREFULLY.\n")
250
					portage.writemsg("!!! Affected file: %s\n" % (e), noiselevel=-1)
251
					sys.exit(1)
252
				except portage_exception.InvalidSignature, e:
253
					portage.writemsg("\n\n!!! An invalid gpg signature is preventing portage from calculating the\n")
254
					portage.writemsg("!!! required dependencies. This is a security feature enabled by the admin\n")
255
					portage.writemsg("!!! to aid in the detection of malicious intent.\n\n")
256
					portage.writemsg("!!! THIS IS A POSSIBLE INDICATION OF TAMPERED FILES -- CHECK CAREFULLY.\n")
257
					portage.writemsg("!!! Affected file: %s\n" % (e), noiselevel=-1)
258
					sys.exit(1)
259
				except SystemExit, e:
260
					raise # Needed else can't exit
261
				except Exception, e:
262
					if "--debug" in self.myopts:
263
						raise
264
					print "\n\n!!! Problem in",mykey,"dependencies."
265
					print "!!!",str(e),e.__module__
266
					sys.exit(1)
267
268
				if not self.mysd:
269
					return (0,myfavorites)
270
				elif not "--oneshot" in self.myopts:
271
					myfavorites.append(portage.dep_getkey(mykey))
272
273
		missing=0
274
		if "--usepkgonly" in self.myopts:
275
			for x in self.digraph.dict.keys():
276
				xs=string.split(x," ")
277
				if (xs[0] != "binary") and (xs[3]=="merge"):
278
					if missing == 0:
279
						print
280
					missing += 1
281
					print "Missing binary for:",xs[2]
282
283
		# We're true here unless we are missing binaries.
284
		return (not missing,myfavorites)
285
286
	def is_newer_ver_installed(self,myroot,pkg,pkgver):
287
		"if there is a version of pkg installed newer than pkgver, return it"
288
		vardbapi=portage.db[myroot]["vartree"].dbapi
289
290
		matches=portage.db[myroot]["vartree"].dbapi.match(pkg)
291
		if matches:
292
			myslot=portage.db["/"]["porttree"].getslot(pkgver)
293
			for match in matches:
294
				if portage.pkgcmp(portage.catpkgsplit(pkgver)[1:], portage.catpkgsplit(match)[1:]) < 0:
295
					curslot=portage.db[myroot]["vartree"].getslot(match)
296
					if curslot == myslot:
297
						return match
298
299
	def select_dep(self,myroot,depstring,myparent=None,arg=None,myuse=None,raise_on_missing=False):
300
		"given a dependency string, create the appropriate depgraph and return 1 on success and 0 on failure"
301
		if "--debug" in self.myopts:
302
			print
303
			print "Parent:   ",myparent
304
			print "Depstring:",depstring
305
		if not arg:
306
			#processing dependencies
307
			mycheck=portage.dep_check(depstring,self.mydbapi[myroot],self.pkgsettings,myuse=myuse,use_binaries=("--usepkgonly" in self.myopts),myroot=myroot)
308
309
			if not mycheck[0]:
310
				mymerge=[]
311
			else:
312
				mymerge=mycheck[1]
313
314
		else:
315
			#we're processing a command-line argument; unconditionally merge it even if it's already merged
316
			mymerge=[depstring]
317
318
		# dep_check has been run so we can now add our parent to our
319
		# build state to update virtuals and other settings. This
320
		# happens after the package is added to the tree so that a
321
		# package can depend on a virtual which it satisfies.
322
		if myparent:
323
			myp = myparent.split()
324
			if myp[3]=="merge":
325
				self.mydbapi[myroot].cpv_inject(myp[2])
326
				if myp[0]=="binary":
327
					self.pkgsettings.setinst(myp[2],portage.db["/"]["bintree"].dbapi)
328
				else:
329
					self.pkgsettings.setinst(myp[2],portage.db[myroot]["porttree"].dbapi)
330
331
		if not mymerge:
332
			return 1
333
334
		if "--debug" in self.myopts:
335
			print "Candidates:",mymerge
336
		for x in mymerge:
337
			myk=None
338
			binpkguseflags=None
339
			if x[0]=="!":
340
				# if this package is myself, don't append it to block list.
341
				if "--debug" in self.myopts:
342
					print "Myparent",myparent
343
				if (myparent):
344
					if myparent.split()[2] in portage.portdb.xmatch("match-all", x[1:]):
345
						# myself, so exit.
346
						continue
347
				# adding block
348
				myk=["blocks",myroot,x[1:]]
349
			else:
350
				#We are not processing a blocker but a normal dependency
351
				myeb=None
352
				myeb_matches = portage.portdb.xmatch("match-visible",x)
353
				if ("--usepkgonly" not in self.myopts):
354
					myeb=portage.best(myeb_matches)
355
356
				myeb_pkg=None
357
				if ("--usepkg" in self.myopts):
358
					# The next line assumes the binarytree has been populated.
359
					# XXX: Need to work out how we use the binary tree with roots.
360
					myeb_pkg_matches=portage.db["/"]["bintree"].dbapi.match(x)
361
					if ("--usepkgonly" not in self.myopts):
362
						# Remove any binary package entries that are masked in the portage tree (#55871)
363
						for idx in range(len(myeb_pkg_matches)-1,-1,-1):
364
							if myeb_pkg_matches[idx] not in myeb_matches:
365
								del myeb_pkg_matches[idx]
366
					myeb_pkg = portage.best(myeb_pkg_matches)
367
368
				if not myeb_pkg:
369
					myeb_pkg = None
370
				elif ("--newuse" in self.myopts):
371
					iuses=string.split(portage.db["/"]["bintree"].dbapi.aux_get(myeb_pkg, ["IUSE"])[0])
372
					old_use=string.split(portage.db["/"]["bintree"].dbapi.aux_get(myeb_pkg, ["USE"])[0])
373
					self.pkgsettings.setcpv(myeb_pkg)
374
					now_use=string.split(self.pkgsettings["USE"])
375
					for x in iuses:
376
						if (old_use.count(x) and not now_use.count(x)) or (not old_use.count(x) and now_use.count(x)):
377
							myeb_pkg = None
378
							break
379
380
				if (not myeb) and (not myeb_pkg):
381
					if raise_on_missing:
382
						raise ValueError
383
					if not arg:
384
						xinfo='"'+x+'"'
385
					else:
386
						xinfo='"'+arg+'"'
387
					if myparent:
388
						xfrom = '(dependency required by '+green('"'+myparent.split()[2]+'"')+red(' ['+myparent.split()[0]+"]")+')'
389
					alleb=portage.portdb.xmatch("match-all",x)
390
					if alleb:
391
						if "--usepkgonly" not in self.myopts:
392
							print "\n!!! "+red("All ebuilds that could satisfy ")+green(xinfo)+red(" have been masked.")
393
							print "!!! One of the following masked packages is required to complete your request:"
394
							oldcomment = ""
395
							for p in alleb:
396
								mreasons = portage.getmaskingstatus(p)
397
								print "- "+p+" (masked by: "+string.join(mreasons, ", ")+")"
398
								comment = portage.getmaskingreason(p)
399
								if comment and comment != oldcomment:
400
									print comment
401
									oldcomment = comment
402
							print
403
							print "For more information, see MASKED PACKAGES section in the emerge man page or "
404
							print "refer to the Gentoo Handbook."
405
						else:
406
							print "\n!!! "+red("There are no packages available to satisfy: ")+green(xinfo)
407
							print "!!! Either add a suitable binary package or compile from an ebuild."
408
					else:
409
						print "\nemerge: there are no ebuilds to satisfy "+green(xinfo)+"."
410
					if myparent:
411
						print xfrom
412
					print
413
					return 0
414
415
				if "--debug" in self.myopts:
416
					print "ebuild:",myeb
417
					print "binpkg:",myeb_pkg
418
419
				if myeb and myeb_pkg:
420
					myeb_s     = portage.catpkgsplit(myeb)
421
					myeb_s     = [myeb_s[0]+"/"+myeb_s[1], myeb_s[2], myeb_s[3]]
422
					myeb_pkg_s = portage.catpkgsplit(myeb_pkg)
423
					myeb_pkg_s = [myeb_pkg_s[0]+"/"+myeb_pkg_s[1], myeb_pkg_s[2], myeb_pkg_s[3]]
424
425
					if portage.pkgcmp(myeb_s, myeb_pkg_s) == 0: # pkg is same version as ebuild
426
						myeb = None
427
					else:
428
						myeb_pkg = None
429
430
				if myeb:
431
					myk=["ebuild",myroot,myeb]
432
				elif myeb_pkg:
433
					binpkguseflags=portage.db[portage.root]["bintree"].get_use(myeb_pkg)
434
					myk=["binary",myroot,myeb_pkg]
435
				else:
436
					sys.stderr.write("!!! Confused... Don't know what's being used for dependency info. :(\n")
437
					sys.exit(1)
438
439
				#if "--usepkg" in self.myopts:
440
				#	#If we want to use packages, see if we have a pre-built one...
441
				#	mypk=portage.db["/"]["bintree"].dbapi.match(x)
442
				#	if myeb in mypk:
443
				#		#Use it only if it's exactly the version we want.
444
				#		myk=["binary",myroot,myeb]
445
				#	else:
446
				#		myk=["ebuild",myroot,myeb]
447
				#else:
448
				#	myk=["ebuild",myroot,myeb]
449
			if myparent:
450
				#we are a dependency, so we want to be unconditionally added
451
				if not self.create(myk,myparent,myuse=binpkguseflags):
452
					return 0
453
			else:
454
				#if mysource is not set, then we are a command-line dependency and should not be added
455
				#if --onlydeps is specified.
456
				if not self.create(myk,myparent,"--onlydeps" not in self.myopts,myuse=binpkguseflags):
457
					return 0
458
459
		if "--debug" in self.myopts:
460
			print "Exiting...",myparent
461
		return 1
462
463
464
	def altlist(self):
465
		mygraph=self.digraph.copy()
466
		dolist=["/"]
467
		retlist=[]
468
		for x in portage.db.keys():
469
			portage.db[x]["merge"]=[]
470
			if x not in dolist:
471
				dolist.append(x)
472
		while (not mygraph.empty()):
473
			mycurkey=mygraph.firstzero()
474
			if not mycurkey:
475
				print "!!! Error: circular dependencies:"
476
				print
477
				for x in mygraph.dict.keys():
478
					for y in mygraph.dict[x][1]:
479
						print y,"depends on",x
480
				print
481
				sys.exit(1)
482
			splitski=string.split(mycurkey)
483
			#I'm not sure of the significance of the following lines (vestigal?) so I'm commenting 'em out.
484
			#These lines remove already-merged things from our alt-list
485
			#if "--update" in self.myopts:
486
			#	if not portage.db["/"]["vartree"].exists_specific(splitski[2]):
487
			#		portage.db["/"]["merge"].append(splitski)
488
			#else:
489
			portage.db[splitski[1]]["merge"].append(splitski)
490
			mygraph.delnode(mycurkey)
491
		for x in dolist:
492
			for y in portage.db[x]["merge"]:
493
				retlist.append(y)
494
		return retlist
495
496
	def xcreate(self,mode="system"):
497
		global syslist
498
		world_problems = False
499
		if mode=="system":
500
			mylist=syslist
501
		else:
502
			#world mode
503
			worldlist=getlist("world")
504
			sysdict=genericdict(syslist)
505
			worlddict=genericdict(worldlist)
506
507
			for x in worlddict.keys():
508
				if not portage.isvalidatom(x):
509
					world_problems = True
510
				elif not portage.db["/"]["vartree"].dbapi.match(x):
511
					world_problems = True
512
				else:
513
					sysdict[x]=worlddict[x]
514
515
			mylist = sysdict.keys()
516
517
		newlist = []
518
		for atom in mylist:
519
			if portage.dep_getkey(atom).split("/")[-1] == "portage":
520
				newlist.insert(0, atom)
521
			else:
522
				newlist.append(atom)
523
		mylist = newlist
524
		
525
		missing_atoms = []
526
		for mydep in mylist:
527
			try:
528
				if not self.select_dep(portage.root, mydep, raise_on_missing=True):
529
					print "\n\n!!! Problem resolving dependencies for", mydep
530
					return 0
531
			except ValueError:
532
				if "--debug" in self.myopts:
533
					raise
534
				missing_atoms.append(mydep)
535
536
		if world_problems:
537
			print "\n!!! Problems have been detected with your world file"
538
			print "!!! Please run "+green("emaint --check world")+"\n"
539
540
		if missing_atoms and "--verbose" in self.myopts:
541
			print "\n!!! Packages for the following atoms are either all"
542
			print "!!! masked or don't exist:"
543
			print " ".join(missing_atoms) + "\n"
544
545
		return 1
546
547
	def match(self,mydep,myroot=portage.root,mykey=None):
548
		# support mutual exclusive deps
549
		mydep2=mydep
550
		if mydep2[0]=="!":
551
			mydep2=mydep[1:]
552
553
		if mydep[0]=="!":
554
			#add our blocker; it will be ignored later if necessary (if we are remerging the same pkg, for example)
555
			myk="blocks "+myroot+" "+mydep2
556
		else:
557
			myeb=portage.db[portage.root]["porttree"].dep_bestmatch(mydep2)
558
			if not myeb:
559
				if not mykey:
560
					print "\n!!! Error: couldn't find match for",mydep
561
				else:
562
					print "\n!!! Error: couldn't find match for",mydep,"in",mykey
563
				print
564
				sys.exit(1)
565
566
			if "--usepkg" in self.myopts:
567
				mypk=portage.db[portage.root]["bintree"].dep_bestmatch(mydep)
568
				if myeb==mypk:
569
					myk="binary "+portage.root+" "+mypk
570
				else:
571
					myk="ebuild "+myroot+" "+myeb
572
			else:
573
				myk="ebuild "+myroot+" "+myeb
574
575
		return myk
576
577
	def display(self,mylist,verbosity=999):
578
		if verbosity == 999:
579
			verbosity = ("--quiet" in self.myopts and 1 or "--verbose" in self.myopts and 3 or 2 );
580
		changelogs=[]
581
		p=[]
582
		totalsize=0
583
584
		if verbosity == 1:
585
			def create_use_string(*args):
586
				return ""
587
		else:
588
			def create_use_string(name, cur_iuse, cur_use, old_iuse, old_use, is_new,
589
					all_flags=(verbosity == 3), alphabetical=("--alphabetical" in self.myopts)):
590
				enabled = []
591
				if alphabetical:
592
					disabled = enabled
593
				else:
594
					disabled = []
595
				for flag in cur_iuse:
596
					if flag in cur_use:
597
						if is_new or flag in old_use and all_flags:
598
							enabled.append(red(flag))
599
						elif flag not in old_iuse:
600
							enabled.append(yellow(flag)+"%")
601
						elif flag not in old_use:
602
							enabled.append(green(flag)+"*")
603
					else:
604
						if is_new or flag in old_iuse and flag not in old_use and all_flags:
605
							disabled.append(blue("-"+flag))
606
						elif flag not in old_iuse:
607
							disabled.append(yellow("-"+flag)+"%")
608
						elif flag in old_use:
609
							disabled.append(green("-"+flag)+"*")
610
611
				enabled = " ".join(enabled)
612
				if alphabetical:
613
					disabled = ""
614
				else:
615
					disabled = " ".join(disabled)
616
				if enabled and disabled:
617
					ret = enabled + " " + disabled
618
				elif enabled:
619
					ret = enabled
620
				else:
621
					ret = disabled
622
				if ret:
623
					ret = '%s="%s" ' % (name, ret)
624
				return ret
625
626
		if verbosity == 3:
627
			overlays = self.pkgsettings["PORTDIR_OVERLAY"].split()
628
			overlays_real = [os.path.realpath(t) \
629
				for t in self.pkgsettings["PORTDIR_OVERLAY"].split()]
630
631
		if "--tree" in self.myopts:
632
			mylist.reverse()
633
			mygraph=self.digraph.copy()
634
635
		i = 0
636
		while i < len(mylist):
637
			if mylist[i][-1]=="nomerge":
638
				if not ("--tree" in self.myopts):
639
					# we don't care about this elements
640
					mylist.pop(i)
641
					continue
642
				if (i == (len(mylist) - 1)) \
643
				   or (mygraph.depth(string.join(mylist[i])) \
644
				       >= mygraph.depth(string.join(mylist[i+1]))):
645
					# end of a useless branch (may be the last one)
646
					# -> delete the element and test the previous one
647
					mylist.pop(i)
648
					if i > 0:
649
						i -= 1
650
					continue
651
			# the branch continues, or we've found a good element.
652
			# -> let's see what's next, if anything
653
			i += 1
654
655
		display_overlays=False
656
		# files to fetch list - avoids counting a same file twice
657
		# in size display (verbose mode)
658
		myfetchlist=[]
659
		for x in mylist:
660
			pkg_type = x[0]
661
			pkg_key = x[2]
662
			if pkg_key not in self.applied_useflags:
663
				if "binary" == pkg_type:
664
					self.applied_useflags[pkg_key] = portage.db["/"]["bintree"].dbapi.aux_get(pkg_key, ["USE"])[0].split()
665
				elif "ebuild" == pkg_type:
666
					self.pkgsettings.setcpv(pkg_key)
667
					self.applied_useflags[pkg_key] = self.pkgsettings["USE"].split()
668
669
			fetch=" "
670
671
			if x[0]=="blocks":
672
				addl=""+red("B")+"  "+fetch+"  "
673
				resolved=portage.db[x[1]]["vartree"].resolve_key(x[2])
674
				print "["+x[0]+" "+addl+"]",red(resolved),
675
				if resolved!=x[2]:
676
					if x[3]:
677
						print red("(\""+x[2]+"\" is blocking "+x[3]+")")
678
					else:
679
						print red("(\""+x[2]+"\")")
680
				else:
681
					if x[3]:
682
						print red("(is blocking "+x[3]+")")
683
					else:
684
						print
685
			else:
686
				if (x[0]!="binary") and ("fetch" in string.split(portage.portdb.aux_get(x[2],["RESTRICT"])[0])):
687
					fetch = red("F")
688
					if portage.portdb.fetch_check(x[2], self.applied_useflags[x[2]]):
689
						fetch = green("f")
690
691
				#we need to use "--emptrytree" testing here rather than "empty" param testing because "empty"
692
				#param is used for -u, where you still *do* want to see when something is being upgraded.
693
				myoldbest=""
694
				if (not "--emptytree" in self.myopts) and portage.db[x[1]]["vartree"].exists_specific(x[2]):
695
					addl="  "+yellow("R")+fetch+"  "
696
				elif (not "--emptytree" in self.myopts) and portage.db[x[1]]["vartree"].exists_specific_cat(x[2]):
697
					if x[0] == "binary":
698
						mynewslot=portage.db["/"]["bintree"].getslot(x[2])
699
					elif x[0] == "ebuild":
700
						mynewslot=portage.db["/"]["porttree"].getslot(x[2])
701
					myoldlist=portage.db[x[1]]["vartree"].dbapi.match(portage.pkgsplit(x[2])[0])
702
					myinslotlist=filter((lambda p: portage.db[portage.root]["vartree"].getslot(p)==mynewslot),myoldlist)
703
					if myinslotlist:
704
						myoldbest=portage.best(myinslotlist)
705
						addl="   "+fetch
706
						if portage.pkgcmp(portage.pkgsplit(x[2]), portage.pkgsplit(myoldbest)) < 0:
707
							# Downgrade in slot
708
							addl+=turquoise("U")+blue("D")
709
						else:
710
							# Update in slot
711
							addl+=turquoise("U")+" "
712
					else:
713
						# New slot, mark it new.
714
						addl=" "+green("NS")+fetch+"  "
715
716
					if "--changelog" in self.myopts:
717
						changelogs.extend(self.calc_changelog(
718
							portage.portdb.findname(x[2]),
719
							portage.db[x[1]]["vartree"].dep_bestmatch('/'.join(portage.catpkgsplit(x[2])[:2])),
720
							x[2]
721
							))
722
				else:
723
					addl=" "+green("N")+" "+fetch+"  "
724
725
				verboseadd=""
726
				
727
				if x[2] in self.applied_useflags:
728
					# USE flag display
729
					if x[0] == "binary":
730
						cur_iuse = string.split(portage.db["/"]["bintree"].dbapi.aux_get(x[2],["IUSE"])[0])
731
					elif x[0] == "ebuild":
732
						cur_iuse = string.split(portage.portdb.aux_get(x[2],["IUSE"])[0])
733
					else:
734
						cur_iuse = []
735
736
					cur_iuse = portage.unique_array(cur_iuse)
737
					cur_iuse = [flag for flag in cur_iuse if flag not in portage.settings.usemask]
738
					cur_iuse.sort()
739
					cur_use = self.applied_useflags[x[2]]
740
					cur_use = [flag for flag in cur_use if flag in cur_iuse]
741
742
					if myoldbest:
743
						pkg = myoldbest
744
					else:
745
						pkg = x[2]
746
					if portage.db[x[1]]["vartree"].dbapi.cpv_exists(pkg):
747
						(old_iuse, old_use) = portage.db[x[1]]["vartree"].dbapi.aux_get(pkg, ["IUSE", "USE"])
748
						old_iuse = portage.unique_array(old_iuse.split())
749
						old_iuse.sort()
750
						old_use = old_use.split()
751
						is_new = False
752
					else:
753
						old_iuse = []
754
						old_use = []
755
						is_new = True
756
					old_iuse = [flag for flag in old_iuse if flag not in portage.settings.usemask]
757
					old_use = [flag for flag in old_use if flag in old_iuse]
758
759
					use_expand = portage.settings["USE_EXPAND"].lower().split()
760
					use_expand.sort()
761
					use_expand.reverse()
762
					use_expand_hidden = portage.settings["USE_EXPAND_HIDDEN"].lower().split()
763
764
					def map_to_use_expand(myvals):
765
						ret = {}
766
						for exp in use_expand:
767
							ret[exp] = []
768
							for val in myvals[:]:
769
								if val.startswith(exp.lower()+"_"):
770
									ret[exp].append(val[len(exp)+1:])
771
									myvals.remove(val)
772
						ret["USE"] = myvals
773
						for exp in use_expand_hidden:
774
							if exp in ret:
775
								del ret[exp]
776
						return ret
777
778
					cur_iuse_map = map_to_use_expand(cur_iuse)
779
					cur_use_map = map_to_use_expand(cur_use)
780
					old_iuse_map = map_to_use_expand(old_iuse)
781
					old_use_map = map_to_use_expand(old_use)
782
783
					use_expand.sort()
784
					use_expand.insert(0, "USE")
785
					
786
					for key in use_expand:
787
						if key in use_expand_hidden:
788
							continue
789
						verboseadd += create_use_string(key.upper(), cur_iuse_map[key], cur_use_map[key],
790
						                                old_iuse_map[key], old_use_map[key], is_new)
791
792
				if verbosity == 3:
793
					# size verbose
794
					mysize=0
795
					if x[0] == "ebuild" and x[-1]!="nomerge":
796
						myfilesdict=portage.portdb.getfetchsizes(x[2], useflags=self.applied_useflags[x[2]], debug=edebug)
797
						if myfilesdict is None:
798
							myfilesdict="[empty/missing/bad digest]"
799
						else:
800
							for myfetchfile in myfilesdict.keys():
801
								if myfetchfile not in myfetchlist:
802
									mysize+=myfilesdict[myfetchfile]
803
									myfetchlist.append(myfetchfile)
804
							totalsize+=mysize
805
						verboseadd+=format_size(mysize)+" "
806
807
					# overlay verbose
808
					# XXX: Invalid binaries have caused tracebacks here. 'if file_name'
809
					# x = ['binary', '/', 'sys-apps/pcmcia-cs-3.2.7.2.6', 'merge']
810
					file_name=portage.portdb.findname(x[2])
811
					if file_name: # It might not exist in the tree
812
						dir_name=os.path.abspath(os.path.dirname(file_name)+"/../..")
813
						if (overlays_real.count(dir_name)>0):
814
							verboseadd+=teal("["+str(overlays_real.index(
815
								os.path.normpath(dir_name))+1)+"]")+" "
816
							display_overlays=True
817
					else:
818
						verboseadd += "[No ebuild?]"
819
820
				xs=portage.pkgsplit(x[2])
821
				if xs[2]=="r0":
822
					xs[2]=""
823
				else:
824
					xs[2]="-"+xs[2]
825
826
				if self.pkgsettings.has_key("COLUMNWIDTH"):
827
					mywidth=int(self.pkgsettings.settings["COLUMNWIDTH"])
828
				else:
829
					mywidth=130
830
				oldlp=mywidth-30
831
				newlp=oldlp-30
832
833
				indent=""
834
				if ("--tree" in self.myopts):
835
					indent=" "*mygraph.depth(string.join(x))
836
837
				if myoldbest:
838
					myoldbest=portage.pkgsplit(myoldbest)[1]+"-"+portage.pkgsplit(myoldbest)[2]
839
					if myoldbest[-3:]=="-r0":
840
						myoldbest=myoldbest[:-3]
841
					myoldbest=blue("["+myoldbest+"]")
842
843
				if x[1]!="/":
844
					if myoldbest:
845
						myoldbest +=" "
846
					if "--columns" in self.myopts:
847
						if "--quiet" in self.myopts:
848
							myprint=addl+" "+indent+darkgreen(xs[0])
849
							myprint=myprint+darkblue(" "+xs[1]+xs[2])+" "
850
							myprint=myprint+myoldbest
851
							myprint=myprint+darkgreen("to "+x[1])
852
						else:
853
							myprint="["+x[0]+" "+addl+"] "+indent+darkgreen(xs[0])
854
							if (newlp-nc_len(myprint)) > 0:
855
								myprint=myprint+(" "*(newlp-nc_len(myprint)))
856
							myprint=myprint+"["+darkblue(xs[1]+xs[2])+"] "
857
							if (oldlp-nc_len(myprint)) > 0:
858
								myprint=myprint+" "*(oldlp-nc_len(myprint))
859
							myprint=myprint+myoldbest
860
							myprint=myprint+darkgreen("to "+x[1])+" "+verboseadd
861
					else:
862
						myprint="["+x[0]+" "+addl+"] "+darkgreen(x[2])+" "+myoldbest+darkgreen("to "+x[1])+" "+verboseadd
863
				else:
864
					if "--columns" in self.myopts:
865
						if "--quiet" in self.myopts:
866
							myprint=addl+" "+indent+darkgreen(xs[0])
867
							myprint=myprint+" "+green(xs[1]+xs[2])+" "
868
							myprint=myprint+myoldbest
869
						else:
870
							myprint="["+x[0]+" "+addl+"] "+indent+darkgreen(xs[0])
871
							if (newlp-nc_len(myprint)) > 0:
872
								myprint=myprint+(" "*(newlp-nc_len(myprint)))
873
							myprint=myprint+green(" ["+xs[1]+xs[2]+"] ")
874
							if (oldlp-nc_len(myprint)) > 0:
875
								myprint=myprint+(" "*(oldlp-nc_len(myprint)))
876
							myprint=myprint+myoldbest+"  "+verboseadd
877
					else:
878
						if x[3]=="nomerge":
879
							myprint=darkblue("[nomerge      ] "+indent+x[2]+" "+myoldbest+" ")+verboseadd
880
						else:
881
							myprint="["+x[0]+" "+addl+"] "+indent+darkgreen(x[2])+" "+myoldbest+" "+verboseadd
882
				p.append(myprint)
883
884
			mysplit = portage.pkgsplit(x[2])
885
			if "--tree" not in self.myopts and mysplit and len(mysplit) == 3 and \
886
				mysplit[0] == "sys-apps/portage" and x[1] == "/":
887
888
				if mysplit[2] == "r0":
889
					myversion = mysplit[1]
890
				else:
891
					myversion = "%s-%s" % (mysplit[1], mysplit[2])
892
893
				if myversion != portage.VERSION :
894
					if "--emptytree" in self.myopts:
895
						p.append(red("***")+" Please update portage to the above version before proceeding.")
896
						p.append("    Failure to do so may result in failed or improper merges.")
897
						p.append("    A simple '"+green("emerge portage")+"' is sufficient.")
898
						p.append("")
899
					elif mylist.index(x) < len(mylist) - 1 and \
900
						"livecvsportage" not in portage.settings.features:
901
						p.append(red("*** Portage will stop merging at this point and reload itself,"))
902
						p.append(red("    then resume the merge."))
903
						print
904
			del mysplit
905
906
		for x in p:
907
			print x
908
909
		if verbosity == 3:
910
			print
911
			print "Total size of downloads: "+format_size(totalsize)
912
			if overlays and display_overlays:
913
				print "Portage overlays:"
914
				y=0
915
				for x in overlays:
916
					y=y+1
917
					print " "+teal("["+str(y)+"]"),x
918
919
		if "--changelog" in self.myopts:
920
			print
921
			for revision,text in changelogs:
922
				print bold('*'+revision)
923
				sys.stdout.write(text)
924
925
	def calc_changelog(self,ebuildpath,current,next):
926
		current = '-'.join(portage.catpkgsplit(current)[1:])
927
		if current.endswith('-r0'): current = current[:-3]
928
		next = '-'.join(portage.catpkgsplit(next)[1:])
929
		if next.endswith('-r0'): next = next[:-3]
930
		changelogpath = os.path.join(os.path.split(ebuildpath)[0],'ChangeLog')
931
		try:
932
			changelog = open(changelogpath).read()
933
		except SystemExit, e:
934
			raise # Needed else can't exit
935
		except:
936
			return []
937
		divisions = self.find_changelog_tags(changelog)
938
		#print 'XX from',current,'to',next
939
		#for div,text in divisions: print 'XX',div
940
		# skip entries for all revisions above the one we are about to emerge
941
		for i in range(len(divisions)):
942
			if divisions[i][0]==next:
943
				divisions = divisions[i:]
944
				break
945
		# find out how many entries we are going to display
946
		for i in range(len(divisions)):
947
			if divisions[i][0]==current:
948
				divisions = divisions[:i]
949
				break
950
		else:
951
		    # couldnt find the current revision in the list. display nothing
952
			return []
953
		return divisions
954
955
	def find_changelog_tags(self,changelog):
956
		divs = []
957
		release = None
958
		while 1:
959
			match = re.search(r'^\*\ ?([-a-zA-Z0-9_.+]*)(?:\ .*)?\n',changelog,re.M)
960
			if match is None:
961
				if release is not None:
962
					divs.append((release,changelog))
963
				return divs
964
			if release is not None:
965
				divs.append((release,changelog[:match.start()]))
966
			changelog = changelog[match.end():]
967
			release = match.group(1)
968
			if release.endswith('.ebuild'):
969
				release = release[:-7]
970
			if release.endswith('-r0'):
971
				release = release[:-3]
972
973
	def outdated(self):
974
		return self.outdatedpackages
975
976
	def merge(self,mylist):
977
		returnme=0
978
		mymergelist=[]
979
980
		#check for blocking dependencies
981
		if ("--fetchonly" not in self.myopts) and ("--buildpkgonly" not in self.myopts):
982
			for x in mylist:
983
				if x[0]=="blocks":
984
					print "\n!!! Error: the "+x[2]+" package conflicts with another package;"
985
					print   "!!!        the two packages cannot be installed on the same system together."
986
					print   "!!!        Please use 'emerge --pretend' to determine blockers."
987
					print
988
					if ("--pretend" not in self.myopts):
989
						try:
990
							del portage.mtimedb["resume"]
991
						except KeyError:
992
							pass
993
						sys.exit(1)
994
995
		#buildsyspkg: I need mysysdict also on resume (moved from the else block)
996
		mysysdict=genericdict(syslist)
997
		if ("--resume" in self.myopts):
998
			# We're resuming.
999
			print green("*** Resuming merge...")
1000
			emergelog(" *** Resuming merge...")
1001
			mymergelist=portage.mtimedb["resume"]["mergelist"][:]
1002
			if ("--skipfirst" in self.myopts) and mymergelist:
1003
				del portage.mtimedb["resume"]["mergelist"][0]
1004
				del mymergelist[0]
1005
			validate_merge_list(mymergelist)
1006
		else:
1007
			myfavs = portage.grabfile(os.path.join(portage.root, portage.WORLD_FILE))
1008
			myfavdict=genericdict(myfavs)
1009
			for x in range(len(mylist)):
1010
				if mylist[x][3]!="nomerge":
1011
					# Add to the mergelist
1012
					mymergelist.append(mylist[x])
1013
				else:
1014
					myfavkey=portage.cpv_getkey(mylist[x][2])
1015
					if "--onlydeps" in self.myopts:
1016
						continue
1017
					# Add to the world file. Since we won't be able to later.
1018
					if (not "--fetchonly" in self.myopts) and (myfavkey in favorites):
1019
						#don't record if already in system profile or already recorded
1020
						if (not mysysdict.has_key(myfavkey)) and (not myfavdict.has_key(myfavkey)):
1021
							#we don't have a favorites entry for this package yet; add one
1022
							myfavdict[myfavkey]=myfavkey
1023
							print ">>> Recording",myfavkey,"in \"world\" favorites file..."
1024
			if not "--fetchonly" in self.myopts:
1025
				portage.write_atomic(
1026
					os.path.join(portage.root, portage.WORLD_FILE),
1027
					"\n".join(myfavdict.values()))
1028
1029
			portage.mtimedb["resume"]["mergelist"]=mymergelist[:]
1030
1031
		# We need to yank the harmful-to-new-builds settings from features.
1032
		myorigfeat=self.pkgsettings["FEATURES"]
1033
		myfeat=myorigfeat.split()
1034
		while ("keeptemp" in myfeat):
1035
			del myfeat[myfeat.index("keeptemp")]
1036
		while ("keepwork" in myfeat):
1037
			del myfeat[myfeat.index("keepwork")]
1038
1039
		self.pkgsettings["FEATURES"]=string.join(myfeat)
1040
1041
		if "parallel-fetch" in myfeat and not ("--ask" in self.myopts or "--pretend" in self.myopts or "--fetchonly" in self.myopts):
1042
			if "distlocks" not in myfeat:
1043
				print red("!!!")
1044
				print red("!!!")+" parallel-fetching requires the distlocks feature enabled"
1045
				print red("!!!")+" you have it disabled, thus parallel-fetching is being disabled"
1046
				print red("!!!")
1047
			elif len(mymergelist) > 1:
1048
				print ">>> starting parallel fetching"
1049
				pid = os.fork()
1050
				if not pid:
1051
					sys.stdin.close()
1052
					sys.stdout.close()
1053
					sys.stderr.close()
1054
					time.sleep(3) # allow the parent to have first fetch
1055
					sys.stdout = open("/dev/null","w")
1056
					sys.stderr = open("/dev/null","w")
1057
					os.dup2(sys.stdout.fileno(), 1)
1058
					os.dup2(sys.stdout.fileno(), 2)
1059
					# wipe the mtimedb so that portage doesn't attempt to flush it.
1060
					# do not convert this code away from a fork without correcting this.
1061
					portage.mtimedb = None
1062
					for x in ("autoaddcvs", "cvs"):
1063
						try:	myfeat.remove(x)
1064
						except ValueError: pass
1065
					self.pkgsettings["FEATURES"] = " ".join(myfeat)
1066
					ret = 0
1067
					for x in mymergelist:
1068
						if x[0] != "ebuild":
1069
							continue
1070
						try:
1071
							ret = portage.doebuild(portage.portdb.findname(x[2]), "fetch", x[1], self.pkgsettings,
1072
								cleanup=0, fetchonly=True, tree="porttree")
1073
						except SystemExit:
1074
							raise
1075
						except Exception:
1076
							ret = 1
1077
					sys.exit(0)
1078
				portage.portage_exec.spawned_pids.append(pid)
1079
1080
		mergecount=0
1081
		for x in mymergelist:
1082
			mergecount+=1
1083
			myroot=x[1]
1084
			pkgindex=2
1085
			if x[0]=="blocks":
1086
				pkgindex=3
1087
			y=portage.portdb.findname(x[pkgindex])
1088
			if not "--pretend" in self.myopts:
1089
				print ">>> Emerging ("+str(mergecount)+" of "+str(len(mymergelist))+")",x[pkgindex],"to",x[1]
1090
				emergelog(" >>> emerge ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" to "+x[1])
1091
1092
			self.pkgsettings["EMERGE_FROM"] = x[0][:]
1093
			self.pkgsettings.backup_changes("EMERGE_FROM")
1094
			self.pkgsettings.reset()
1095
1096
			#buildsyspkg: Check if we need to _force_ binary package creation
1097
			issyspkg = ("buildsyspkg" in myfeat) \
1098
					and x[0] != "blocks" \
1099
					and mysysdict.has_key(portage.cpv_getkey(x[2])) \
1100
					and not ("--buildpkg" in self.myopts)
1101
			if x[0] in ["ebuild","blocks"]:
1102
				if (x[0]=="blocks") and ("--fetchonly" not in self.myopts):
1103
					raise Exception, "Merging a blocker"
1104
				elif ("--fetchonly" in self.myopts) or ("--fetch-all-uri" in self.myopts):
1105
					if ("--fetch-all-uri" in self.myopts):
1106
						retval=portage.doebuild(y,"fetch",myroot,self.pkgsettings,edebug,("--pretend" in self.myopts),fetchonly=1,fetchall=1,tree="porttree")
1107
					else:
1108
						retval=portage.doebuild(y,"fetch",myroot,self.pkgsettings,edebug,("--pretend" in self.myopts),fetchonly=1,tree="porttree")
1109
					if (retval is None) or retval:
1110
						print
1111
						print "!!! Fetch for",y,"failed, continuing..."
1112
						print
1113
						returnme=1
1114
					continue
1115
				elif "--buildpkg" in self.myopts or issyspkg:
1116
					#buildsyspkg: Sounds useful to display something, but I don't know if we should also log it
1117
					if issyspkg:
1118
						print ">>> This is a system package, let's pack a rescue tarball."
1119
						#emergelog(">>> This is a system package, let's pack a rescue tarball.")
1120
					#create pkg, then merge pkg
1121
					short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Clean"
1122
					emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Cleaning ("+x[pkgindex]+"::"+y+")", short_msg=short_msg)
1123
					retval=portage.doebuild(y,"clean",myroot,self.pkgsettings,edebug,cleanup=1,tree="porttree")
1124
					if (retval is None):
1125
						portage_util.writemsg("Unable to run required binary.\n",
1126
							noiselevel=-1)
1127
						sys.exit(127)
1128
					if retval:
1129
						sys.exit(retval)
1130
					short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Compile"
1131
					emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Compiling/Packaging ("+x[pkgindex]+"::"+y+")", short_msg=short_msg)
1132
					retval=portage.doebuild(y,"package",myroot,self.pkgsettings,edebug,tree="porttree")
1133
					if (retval is None):
1134
						portage_util.writemsg("Unable to run required binary.\n",
1135
							noiselevel=-1)
1136
						sys.exit(127)
1137
					if retval:
1138
						sys.exit(retval)
1139
					#dynamically update our database
1140
					if "--buildpkgonly" not in self.myopts:
1141
						portage.db[portage.root]["bintree"].inject(x[2])
1142
						mytbz2=portage.db[portage.root]["bintree"].getname(x[2])
1143
						short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Merge"
1144
						emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Merging ("+x[pkgindex]+"::"+y+")", short_msg=short_msg)
1145
1146
						self.pkgsettings["EMERGE_FROM"] = "binary"
1147
						self.pkgsettings.backup_changes("EMERGE_FROM")
1148
1149
						retval=portage.pkgmerge(mytbz2,myroot,self.pkgsettings)
1150
						if retval is None:
1151
							sys.exit(1)
1152
					elif "noclean" not in self.pkgsettings.features:
1153
						portage.doebuild(y, "clean", myroot, self.pkgsettings,
1154
							edebug, tree="porttree")
1155
				else:
1156
					short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Clean"
1157
					emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Cleaning ("+x[pkgindex]+"::"+y+")", short_msg=short_msg)
1158
					retval=portage.doebuild(y,"clean",myroot,self.pkgsettings,edebug,cleanup=1,tree="porttree")
1159
					if (retval is None):
1160
						portage_util.writemsg("Unable to run required binary.\n",
1161
							noiselevel=-1)
1162
						sys.exit(127)
1163
					if retval:
1164
						sys.exit(retval)
1165
					short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Compile"
1166
					emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Compiling/Merging ("+x[pkgindex]+"::"+y+")", short_msg=short_msg)
1167
					retval=portage.doebuild(y,"merge",myroot,self.pkgsettings,edebug,tree="porttree")
1168
					if (retval is None):
1169
						portage_util.writemsg("Unable to run required binary.\n",
1170
							noiselevel=-1)
1171
						sys.exit(127)
1172
					if retval:
1173
						sys.exit(retval)
1174
					#dynamically update our database
1175
			elif x[0]=="binary":
1176
				#merge the tbz2
1177
				mytbz2=portage.db[portage.root]["bintree"].getname(x[2])
1178
				if portage.db[portage.root]["bintree"].isremote(x[2]):
1179
					short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Fetch"
1180
					emergelog(" --- ("+str(mergecount)+" of "+str(len(mymergelist))+") Fetching Binary ("+x[pkgindex]+"::"+mytbz2+")", short_msg=short_msg)
1181
					if not portage.db[portage.root]["bintree"].gettbz2(x[2]):
1182
						sys.exit(1)
1183
1184
				if ("--fetchonly" in self.myopts) or ("--fetch-all-uri" in self.myopts):
1185
					continue
1186
1187
				short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Merge Binary"
1188
				emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Merging Binary ("+x[pkgindex]+"::"+mytbz2+")", short_msg=short_msg)
1189
				retval=portage.pkgmerge(mytbz2,x[1],self.pkgsettings)
1190
				if retval is None:
1191
					sys.exit(1)
1192
				#need to check for errors
1193
			if "--buildpkgonly" not in self.myopts:
1194
				portage.db[x[1]]["vartree"].inject(x[2])
1195
				myfavkey=portage.cpv_getkey(x[2])
1196
				if "--fetchonly" not in self.myopts and "--fetch-all-uri" not in self.myopts and myfavkey in favorites:
1197
					myfavs = portage.grabfile(os.path.join(myroot, portage.WORLD_FILE))
1198
					myfavdict=genericdict(myfavs)
1199
					mysysdict=genericdict(syslist)
1200
					#don't record if already in system profile or already recorded
1201
					if (not mysysdict.has_key(myfavkey)) and (not myfavdict.has_key(myfavkey)):
1202
						#we don't have a favorites entry for this package yet; add one
1203
						myfavdict[myfavkey]=myfavkey
1204
						print ">>> Recording",myfavkey,"in \"world\" favorites file..."
1205
						emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Updating world file ("+x[pkgindex]+")")
1206
						portage.write_atomic(
1207
						os.path.join(myroot, portage.WORLD_FILE),
1208
						"\n".join(myfavdict.values()))
1209
1210
				if ("--pretend" not in self.myopts) and ("--fetchonly" not in self.myopts) and ("--fetch-all-uri" not in self.myopts):
1211
					# Clean the old package that we have merged over top of it.
1212
					if self.pkgsettings["AUTOCLEAN"]=="yes":
1213
						xsplit=portage.pkgsplit(x[2])
1214
						emergelog(" >>> AUTOCLEAN: "+xsplit[0])
1215
						if x[1] == portage.settings["ROOT"]:
1216
							# Compare against portage.settings["ROOT"] because
1217
							# the value of self.pkgsettings["ROOT"] does not
1218
							# match the original value!
1219
							retval = unmerge("clean", [xsplit[0]])
1220
						else:
1221
							retval = unmerge_overlapping(x[2], x[1],
1222
								self.pkgsettings, portage.db[x[1]]["vartree"])
1223
						if not retval:
1224
							emergelog(" --- AUTOCLEAN: Nothing unmerged.")
1225
					else:
1226
						portage.writemsg_stdout(colorize("WARN", "WARNING:")
1227
							+ " AUTOCLEAN is disabled.  This can cause serious"
1228
							+ " problems due to overlapping packages.\n")
1229
1230
					# Figure out if we need a restart.
1231
					mysplit=portage.pkgsplit(x[2])
1232
					if mysplit[0] == "sys-apps/portage" and x[1] == "/":
1233
						myver=mysplit[1]+"-"+mysplit[2]
1234
						if myver[-3:]=='-r0':
1235
							myver=myver[:-3]
1236
						if (myver != portage.VERSION) and \
1237
						   ("livecvsportage" not in portage.settings.features):
1238
							if len(mymergelist) > mergecount:
1239
								emergelog(" ::: completed emerge ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[2]+" to "+x[1])
1240
								emergelog(" *** RESTARTING emerge via exec() after change of portage version.")
1241
								del portage.mtimedb["resume"]["mergelist"][0]
1242
								portage.run_exitfuncs()
1243
								mynewargv=[sys.argv[0],"--resume"]
1244
								badlongopts = ("--ask","--tree","--changelog","--skipfirst","--resume")
1245
								for arg in self.myopts:
1246
									if arg in badlongopts:
1247
										continue
1248
									mynewargv.append(arg)
1249
								# priority only needs to be adjusted on the first run
1250
								os.environ["PORTAGE_NICENESS"] = "0"
1251
								os.execv(mynewargv[0], mynewargv)
1252
1253
			if ("--pretend" not in self.myopts) and ("--fetchonly" not in self.myopts) and ("--fetch-all-uri" not in self.myopts):
1254
				if "noclean" not in portage.settings.features:
1255
					short_msg = "emerge: (%s of %s) %s Clean Post" % \
1256
						(mergecount, len(mymergelist), x[pkgindex])
1257
					emergelog(" === (%s of %s) Post-Build Cleaning (%s::%s)" % \
1258
						(mergecount, len(mymergelist), x[pkgindex], y), short_msg=short_msg)
1259
				emergelog(" ::: completed emerge ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[2]+" to "+x[1])
1260
1261
			# Unsafe for parallel merges
1262
			del portage.mtimedb["resume"]["mergelist"][0]
1263
			# Commit after each merge so that --resume may still work in
1264
			# in the event that portage is not allowed to exit normally
1265
			# due to power failure, SIGKILL, etc...
1266
			portage.commit_mtimedb()
1267
1268
		emergelog(" *** Finished. Cleaning up...")
1269
1270
		# We're out of the loop... We're done. Delete the resume data.
1271
		if portage.mtimedb.has_key("resume"):
1272
			del portage.mtimedb["resume"]
1273
1274
		if ("--pretend" not in self.myopts):
1275
			if ("--fetchonly" not in self.myopts) and ("--fetch-all-uri" not in self.myopts):
1276
				if (mergecount>0):
1277
					if retval:
1278
						portage.env_update()
1279
1280
		#by doing an exit this way, --fetchonly can continue to try to
1281
		#fetch everything even if a particular download fails.
1282
		if "--fetchonly" in self.myopts or "--fetch-all-uri" in self.myopts:
1283
			if returnme:
1284
				print "\n\n!!! Some fetch errors were encountered.  Please see above for details.\n\n"
1285
				sys.exit(returnme)
1286
			else:
1287
				sys.exit(0)
1288

Return to bug 136932