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

Collapse All | Expand All

(-)pym.orig/portage.py (-12 / +79 lines)
Lines 78-84 Link Here
78
	sys.stderr.write(red("*** Please add this user to the portage group if you wish to use portage.\n"))
78
	sys.stderr.write(red("*** Please add this user to the portage group if you wish to use portage.\n"))
79
	sys.stderr.write("\n")
79
	sys.stderr.write("\n")
80
80
81
incrementals=["USE","FEATURES","ACCEPT_KEYWORDS","ACCEPT_LICENSE","CONFIG_PROTECT_MASK","CONFIG_PROTECT","PRELINK_PATH","PRELINK_PATH_MASK"]
81
incrementals=["USE","FEATURES","ACCEPT_KEYWORDS","ACCEPT_LICENSE","CONFIG_PROTECT_MASK","CONFIG_PROTECT","CLEAN_PROTECT_MASK","CLEAN_PROTECT","PRELINK_PATH","PRELINK_PATH_MASK"]
82
stickies=["KEYWORDS_ACCEPT","USE","CFLAGS","CXXFLAGS","MAKEOPTS","EXTRA_ECONF","EXTRA_EMAKE"]
82
stickies=["KEYWORDS_ACCEPT","USE","CFLAGS","CXXFLAGS","MAKEOPTS","EXTRA_ECONF","EXTRA_EMAKE"]
83
83
84
def getcwd():
84
def getcwd():
Lines 437-443 Link Here
437
			continue
437
			continue
438
		pos=pos+1
438
		pos=pos+1
439
439
440
	specials={"KDEDIRS":[],"PATH":[],"CLASSPATH":[],"LDPATH":[],"MANPATH":[],"INFODIR":[],"INFOPATH":[],"ROOTPATH":[],"CONFIG_PROTECT":[],"CONFIG_PROTECT_MASK":[],"PRELINK_PATH":[],"PRELINK_PATH_MASK":[]}
440
	specials={"KDEDIRS":[],"PATH":[],"CLASSPATH":[],"LDPATH":[],"MANPATH":[],"INFODIR":[],"INFOPATH":[],"ROOTPATH":[],"CONFIG_PROTECT":[],"CONFIG_PROTECT_MASK":[],"CLEAN_PROTECT":[],"CLEAN_PROTECT_MASK":[],"PRELINK_PATH":[],"PRELINK_PATH_MASK":[]}
441
	env={}
441
	env={}
442
442
443
	for x in fns:
443
	for x in fns:
Lines 532-538 Link Here
532
		if len(specials[path])==0:
532
		if len(specials[path])==0:
533
			continue
533
			continue
534
		outstring="export "+path+"='"
534
		outstring="export "+path+"='"
535
		if path in ["CONFIG_PROTECT","CONFIG_PROTECT_MASK"]:
535
		if path in ["CONFIG_PROTECT","CONFIG_PROTECT_MASK","CLEAN_PROTECT","CLEAN_PROTECT_MASK"]:
536
			for x in specials[path][:-1]:
536
			for x in specials[path][:-1]:
537
				outstring += x+" "
537
				outstring += x+" "
538
		else:
538
		else:
Lines 1918-1928 Link Here
1918
		#shell error code
1918
		#shell error code
1919
	return mylink.merge(pkgloc,infloc,myroot,myebuild)
1919
	return mylink.merge(pkgloc,infloc,myroot,myebuild)
1920
	
1920
	
1921
def unmerge(cat,pkg,myroot,mytrimworld=1):
1921
def unmerge(cat,pkg,myroot,mytrimworld=1,protector=""):
1922
	# clnpro: Here, the protector is a cpv string, and we'll give an opened /db/c/pv/CONTENTS 
1923
	# file to the dblink.unmerge() call.
1924
	# If no protector is given, don't worry, it's not an error but a real unmerge 
1925
	# instead of a clean or prune.
1926
	myprotfile=None
1927
	if protector:
1928
		myprotcat=string.split(protector,"/")[0]
1929
		myprotpkg=string.split(protector,"/")[1]
1930
		myprotfilename=myroot+"///var/db/pkg/"+myprotcat+"/"+myprotpkg+"/CONTENTS"
1931
		if not os.path.exists(myprotfilename) or (cat==myprotcat and pkg==myprotpkg):
1932
			print "!!! Wrong protector. This shouldn't happen."
1933
		else:
1934
			myprotfile=open(myprotfilename,"a")
1922
	mylink=dblink(cat,pkg,myroot)
1935
	mylink=dblink(cat,pkg,myroot)
1923
	if mylink.exists():
1936
	if mylink.exists():
1924
		mylink.unmerge(trimworld=mytrimworld)
1937
		mylink.unmerge(trimworld=mytrimworld,protectfile=myprotfile)
1925
	mylink.delete()
1938
	mylink.delete()
1939
	if (myprotfile != None):
1940
		myprotfile.close()
1926
1941
1927
def relparse(myver):
1942
def relparse(myver):
1928
	"converts last version part into three components"
1943
	"converts last version part into three components"
Lines 4306-4311 Link Here
4306
			if os.path.isdir(ppath):
4321
			if os.path.isdir(ppath):
4307
				self.protectmask.append(ppath)
4322
				self.protectmask.append(ppath)
4308
			#if it doesn't exist, silently skip it
4323
			#if it doesn't exist, silently skip it
4324
		
4325
		#clnpro: update protection path
4326
		self.cleanprotect=[]
4327
		for x in string.split(settings["CLEAN_PROTECT"]):
4328
			ppath=os.path.normpath(self.myroot+"/"+x)+"/"
4329
			if os.path.isdir(ppath):
4330
				self.cleanprotect.append(ppath)
4331
			#if it doesn't exist, silently skip it
4332
		#clnpro: is a masked relly needed?
4333
		self.cleanprotectmask=[]
4334
		for x in string.split(settings["CLEAN_PROTECT_MASK"]):
4335
			ppath=os.path.normpath(self.myroot+"/"+x)+"/"
4336
			if os.path.isdir(ppath):
4337
				self.cleanprotectmask.append(ppath)
4338
			#if it doesn't exist, silently skip it
4309
4339
4310
	def isprotected(self,obj):
4340
	def isprotected(self,obj):
4311
		"""Checks if obj is in the current protect/mask directories. Returns
4341
		"""Checks if obj is in the current protect/mask directories. Returns
Lines 4322-4328 Link Here
4322
						masked=len(pmpath)
4352
						masked=len(pmpath)
4323
		return (protected > masked)
4353
		return (protected > masked)
4324
4354
4325
	def unmerge(self,pkgfiles=None,trimworld=1):
4355
        def iscleanprotected(self,obj):
4356
                """Checks if obj is in the current clean protect/mask directories. Returns
4357
                0 on unprotected/masked, and 1 on protected."""
4358
                masked=0
4359
                protected=0
4360
                for ppath in self.cleanprotect:
4361
                        if (len(ppath) > masked) and (obj[0:len(ppath)]==ppath):
4362
                                protected=len(ppath)
4363
                                #clnpro file management
4364
                                for pmpath in self.cleanprotectmask:
4365
                                        if (len(pmpath) >= protected) and (obj[0:len(pmpath)]==pmpath):
4366
                                                #skip, it's in the mask
4367
                                                masked=len(pmpath)
4368
                return (protected > masked)
4369
 
4370
        def unmerge(self,pkgfiles=None,trimworld=1,protectfile=None):
4371
                # clnpro: Here, protectfile is an opened /db/c/pv/CONTENTS file.
4372
                # If a file to unmerge is protected, then it will instead be recorded in protectfile.
4373
                # If protectfile=None, it means that we are doing a real unmerge, not just a clean/prune.
4326
		global dircache
4374
		global dircache
4327
		dircache={}
4375
		dircache={}
4328
		
4376
		
Lines 4393-4398 Link Here
4393
				if mymd5 != string.lower(pkgfiles[obj][2]):
4441
				if mymd5 != string.lower(pkgfiles[obj][2]):
4394
					print "--- !md5  ","obj", obj
4442
					print "--- !md5  ","obj", obj
4395
					continue
4443
					continue
4444
				if self.iscleanprotected(obj) and (protectfile != None):
4445
					#clnpro: this object must be protected
4446
					print "--- clnpro "+str(pkgfiles[obj][0]), obj
4447
					contentsentry="obj "+obj+" "+pkgfiles[obj][2]+" "+pkgfiles[obj][1]+"\n"
4448
					#print contentsentry
4449
					protectfile.write(contentsentry)
4450
					continue
4396
				try:
4451
				try:
4397
					os.unlink(obj)
4452
					os.unlink(obj)
4398
				except (OSError,IOError),e:
4453
				except (OSError,IOError),e:
Lines 4402-4407 Link Here
4402
				if not S_ISFIFO(lstatobj[ST_MODE]):
4457
				if not S_ISFIFO(lstatobj[ST_MODE]):
4403
					print "--- !fif  ","fif", obj
4458
					print "--- !fif  ","fif", obj
4404
					continue
4459
					continue
4460
				#if self.iscleanprotected(obj) and (protectfile != None):
4461
				#	#clnpro: should a fifo be protected? 
4462
				#	#this may introduce duplicates, because they lacks mtime/md5.
4463
				#       #have to check existing CONTENTS
4464
				#	print "--- clnpro "+str(pkgfiles[obj][0]), obj
4465
				#	contentsentry="fif "+obj+"\n"
4466
				#       print contentsentry
4467
				#       #protectfile.write(contentsentry)
4468
				#	continue
4405
				try:
4469
				try:
4406
					os.unlink(obj)
4470
					os.unlink(obj)
4407
				except (OSError,IOError),e:
4471
				except (OSError,IOError),e:
Lines 4409-4414 Link Here
4409
				print "<<<       ","fif",obj
4473
				print "<<<       ","fif",obj
4410
			elif pkgfiles[obj][0]=="dev":
4474
			elif pkgfiles[obj][0]=="dev":
4411
				print "---       ","dev",obj
4475
				print "---       ","dev",obj
4476
				#clnpro: since devs never get cleaned, no need to protect them.
4412
4477
4413
		#Now, we need to remove symlinks and directories.  We'll repeatedly
4478
		#Now, we need to remove symlinks and directories.  We'll repeatedly
4414
		#remove dead symlinks, then directories until we stop making progress.
4479
		#remove dead symlinks, then directories until we stop making progress.
Lines 4425-4431 Link Here
4425
			progress=0
4490
			progress=0
4426
4491
4427
			#step 1: remove all the dead symlinks we can...
4492
			#step 1: remove all the dead symlinks we can...
4428
4493
			#clnpro:symlinks protection not yet implemented.
4494
			#(what if target does not match? keep or forget?)
4429
			pos = 0
4495
			pos = 0
4430
			while pos<len(mysyms):
4496
			while pos<len(mysyms):
4431
				obj=mysyms[pos]
4497
				obj=mysyms[pos]
Lines 4445-4451 Link Here
4445
						pass
4511
						pass
4446
	
4512
	
4447
			#step 2: remove all the empty directories we can...
4513
			#step 2: remove all the empty directories we can...
4448
	
4514
			#clnpro: should dirs be protected? 
4515
			#(may introduce duplicates if we don't check existing CONTENTS)
4449
			pos = 0
4516
			pos = 0
4450
			while pos<len(mydirs):
4517
			while pos<len(mydirs):
4451
				obj=mydirs[pos]
4518
				obj=mydirs[pos]
Lines 4609-4621 Link Here
4609
		
4676
		
4610
		#restore umask
4677
		#restore umask
4611
		os.umask(prevmask)
4678
		os.umask(prevmask)
4612
		#if we opened it, close it	
4613
		outfile.close()
4614
		print
4679
		print
4615
		if (oldcontents):
4680
		if (oldcontents):
4616
			print ">>> Safely unmerging already-installed instance..."
4681
			print ">>> Safely unmerging already-installed instance..."
4617
			self.unmerge(oldcontents,trimworld=0)
4682
			self.unmerge(oldcontents,trimworld=0,protectfile=outfile)
4618
			print ">>> original instance of package unmerged safely."	
4683
			print ">>> original instance of package unmerged safely."
4684
		#if we opened it, close it	
4685
		outfile.close()
4619
		# copy "info" files (like SLOT, CFLAGS, etc.) into the database
4686
		# copy "info" files (like SLOT, CFLAGS, etc.) into the database
4620
		for x in listdir(inforoot):
4687
		for x in listdir(inforoot):
4621
			self.copyfile(inforoot+"/"+x)
4688
			self.copyfile(inforoot+"/"+x)
(-)bin.orig/emerge (-1 / +10 lines)
Lines 1480-1485 Link Here
1480
		print darkgreen("\n>>> These are the packages that I would unmerge:")
1480
		print darkgreen("\n>>> These are the packages that I would unmerge:")
1481
	
1481
	
1482
	pkgmap={}
1482
	pkgmap={}
1483
	cleanprotmap={}
1483
	numselected=0
1484
	numselected=0
1484
	for x in candidate_catpkgs:
1485
	for x in candidate_catpkgs:
1485
		#cycle through all our candidate deps and determine what will and will not get unmerged
1486
		#cycle through all our candidate deps and determine what will and will not get unmerged
Lines 1517-1528 Link Here
1517
					continue
1518
					continue
1518
				counterkeys.sort()
1519
				counterkeys.sort()
1519
				pkgmap[mykey]["protected"].append(slotmap[myslot][counterkeys[-1]])
1520
				pkgmap[mykey]["protected"].append(slotmap[myslot][counterkeys[-1]])
1521
				protpkg=slotmap[myslot][counterkeys[-1]]
1520
				del counterkeys[-1]
1522
				del counterkeys[-1]
1521
				#be pretty and get them in order of merge:
1523
				#be pretty and get them in order of merge:
1522
				for ckey in counterkeys:
1524
				for ckey in counterkeys:
1523
					pkgmap[mykey]["selected"].append(slotmap[myslot][ckey])
1525
					pkgmap[mykey]["selected"].append(slotmap[myslot][ckey])
1526
					cleanprotmap[slotmap[myslot][ckey]]=protpkg
1524
					numselected=numselected+1
1527
					numselected=numselected+1
1525
				#ok, now the last-merged package is protected, and the rest are selected
1528
				#ok, now the last-merged package is protected, and the rest are selected
1529
			# clnpro: now, cleanprotmap should contain selected_cpv:protected_cpv entries for 
1530
			# each selected pkg. 
1526
	if global_unmerge and not numselected:
1531
	if global_unmerge and not numselected:
1527
		print "\n>>> No outdated packages were found on your system.\n"
1532
		print "\n>>> No outdated packages were found on your system.\n"
1528
		return 0
1533
		return 0
Lines 1581-1587 Link Here
1581
			emergelog("=== Unmerging... ("+y+")")
1586
			emergelog("=== Unmerging... ("+y+")")
1582
			mysplit=string.split(y,"/")
1587
			mysplit=string.split(y,"/")
1583
			#unmerge...
1588
			#unmerge...
1584
			retval=portage.unmerge(mysplit[0],mysplit[1],portage.root,unmerge_action not in ["clean","prune"])
1589
			#clnpro: we add the protecting cpv to the unmerge call
1590
			if cleanprotmap.has_key(y):
1591
				retval=portage.unmerge(mysplit[0],mysplit[1],portage.root,unmerge_action not in ["clean","prune"],protector=cleanprotmap[y])
1592
			else:
1593
				retval=portage.unmerge(mysplit[0],mysplit[1],portage.root,unmerge_action not in ["clean","prune"])
1585
			if retval:
1594
			if retval:
1586
				emergelog(" !!! unmerge FAILURE: "+y)
1595
				emergelog(" !!! unmerge FAILURE: "+y)
1587
			else:
1596
			else:

Return to bug 24990