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

Collapse All | Expand All

(-)pym/portage_sets.py (+89 lines)
Line 0 Link Here
1
# portage_sets.py - Portage Sets functionality
2
# Copyright 2006 Gentoo Foundation
3
# Distributed under the terms of the GNU General Public License v2
4
# $Id: $
5
6
import os
7
8
from portage_dep import isvalidatom
9
from portage_const import SET_PATH, WORLD_FILE
10
11
class PackageSet(list):
12
	""" Abstract PackageSet Class 
13
	Ironically this is a python list and NOT a set, as we need to preserve
14
	order here.
15
	"""
16
	
17
	def __init__( self ):
18
		""" All PackageSet classes have items """
19
		self.items = None
20
21
def PackageSetFactory( set_name, root="/", settings=None ):
22
	""" Give me a valid set_name and I'll make you the right one.
23
	    (settings,root) are require for certain types of Sets (glsa,all,system)  """
24
25
	if os.path.exists( SET_PATH + os.sep + set_name ):
26
		return PackageSetFile( SET_PATH + os.sep + set_name )
27
	elif set_name in "world":
28
		return WorldSet( root )
29
	elif not settings:
30
		raise ValueError( "Settings is require for sets: %s" % ["system","all","glsa"] )
31
	elif set_name in "system":
32
		return SystemSet( settings )
33
	elif set_name in "all":
34
		return AllSet( root, settings )
35
	elif set_name in "glsa":
36
		return GLSASet( settings )
37
	else:
38
		return PackageSetFile( set_name )
39
40
class AllSet(PackageSet):
41
	""" Returns a set of all installed packages (CPs) """
42
	
43
	def __init__( self, root, settings ):
44
		""" Pass me a config to work with. """
45
		from portage import vartree
46
		vartree = vartree( root=root, settings=settings )
47
		self.items = vartree.dbapi.cp_all()
48
49
class SystemSet(PackageSet):
50
	""" Returns a set of all packages in 'system' """
51
	
52
	def __init__( self, settings ):
53
		""" I need a config object to inspect.  """
54
		# settings.packages all start with "*", so we strip it here.
55
		self.items = [item[1:] for item in settings.packages 
56
					if item.startswith("*")]
57
58
class PackageSetList(PackageSet):
59
	""" Represents a set of packages """
60
61
	def __init__( self, cpvs ):
62
		""" Create a new object given a list of atoms (cps or cpvs) """
63
		self.items = cpvs
64
65
class WorldSet(PackageSet):
66
	""" Represents everything in "world", aka installed manually by the user. """
67
	
68
	def __init__( self, root ):
69
		""" Create a new object given a root to pull from. """
70
		self.items = PackageSetFile( root + WORLD_FILE ).items
71
72
class GLSASet(PackageSet):
73
	""" Represents a set of packages worth upgrading for security reasons """
74
	
75
	def __init__( self, root ):
76
		raise NotImplementedError("GLSA Set is not written yet")
77
78
class PackageSetFile(PackageSet):
79
	""" Represents a set of packages loaded from a file"""
80
	
81
	def __init__( self, filename ):
82
		""" Create a new object given a filename to load a set from """
83
		handle = open(filename, "r")	
84
		items = handle.readlines()
85
		items = [l for l in items if not l.startswith("#")]
86
		items = [item.rstrip() for item in items]
87
		items = [pkg for pkg in items if isvalidatom(pkg)]
88
		self.items = items
89
		self.filename = filename
(-)pym/portage_const.py (+1 lines)
Lines 14-19 Link Here
14
DEPCACHE_PATH           = CACHE_PATH+"/dep"
14
DEPCACHE_PATH           = CACHE_PATH+"/dep"
15
15
16
USER_CONFIG_PATH        = "/etc/portage"
16
USER_CONFIG_PATH        = "/etc/portage"
17
SET_PATH 		= USER_CONFIG_PATH+"/sets"
17
MODULES_FILE_PATH       = USER_CONFIG_PATH+"/modules"
18
MODULES_FILE_PATH       = USER_CONFIG_PATH+"/modules"
18
CUSTOM_PROFILE_PATH     = USER_CONFIG_PATH+"/profile"
19
CUSTOM_PROFILE_PATH     = USER_CONFIG_PATH+"/profile"
19
20
(-)bin/emerge (-71 / +123 lines)
Lines 40-45 Link Here
40
import portage_locks
40
import portage_locks
41
import portage_exception
41
import portage_exception
42
from portage_data import secpass
42
from portage_data import secpass
43
from portage_const import SET_PATH
44
from portage_sets import PackageSetFactory
43
45
44
if not hasattr(__builtins__, "set"):
46
if not hasattr(__builtins__, "set"):
45
	from sets import Set as set
47
	from sets import Set as set
Lines 178-184 Link Here
178
"clean", "config", "depclean",
180
"clean", "config", "depclean",
179
"info", "metadata",
181
"info", "metadata",
180
"prune", "regen",  "search",
182
"prune", "regen",  "search",
181
"sync",  "system", "unmerge",  "world",
183
"sync", "unmerge", 
182
]
184
]
183
options=[
185
options=[
184
"--ask",          "--alphabetical",
186
"--ask",          "--alphabetical",
Lines 348-362 Link Here
348
	#configure emerge engine parameters
350
	#configure emerge engine parameters
349
	#
351
	#
350
	# self:      include _this_ package regardless of if it is merged.
352
	# self:      include _this_ package regardless of if it is merged.
351
	# selective: exclude the package if it is merged
353
	# selective: exclude the package if it is merged.
352
	# recurse:   go into the dependencies
354
	# recurse:   go into the dependencies
353
	# deep:      go into the dependencies of already merged packages
355
	# deep:      go into the dependencies of already merged packages
354
	# empty:     pretend nothing is merged
356
	# empty:     pretend nothing is merged
355
	myparams=["self","recurse"]
357
	myparams=["self","recurse"]
356
	add=[]
358
	add=[]
357
	sub=[]
359
	sub=[]
358
	if "--update" in myopts or myaction in ("system", "world"):
360
	if "--update" in myopts:
359
		add.extend(["selective","empty"])
361
		add.extend(["selective","empty"])
362
	if "--package-set" in myopts:
363
		add.extend(["selective"])
360
	if "--emptytree" in myopts:
364
	if "--emptytree" in myopts:
361
		add.extend(["empty"])
365
		add.extend(["empty"])
362
		sub.extend(["selective"])
366
		sub.extend(["selective"])
Lines 368-375 Link Here
368
		add.extend(["deep"])
372
		add.extend(["deep"])
369
	if "--selective" in myopts:
373
	if "--selective" in myopts:
370
		add.extend(["selective"])
374
		add.extend(["selective"])
371
	if myaction in ["world","system"]:
372
		add.extend(["selective"])
373
	elif myaction in ["depclean"]:
375
	elif myaction in ["depclean"]:
374
		add.extend(["empty"])
376
		add.extend(["empty"])
375
		sub.extend(["selective"])
377
		sub.extend(["selective"])
Lines 1226-1281 Link Here
1226
				retlist.append(y)
1228
				retlist.append(y)
1227
		return retlist
1229
		return retlist
1228
1230
1229
	def xcreate(self,mode="system"):
1231
	def setCreate( self, set_name ):
1230
		world_problems = False
1232
		""" 
1231
		if mode=="system":
1233
		Checks dependencies on all sets (system + world)
1232
			mylist = getlist(self.settings, "system")
1234
		Replaces xcreate()
1233
		else:
1234
			#world mode
1235
			worldlist = getlist(self.settings, "world")
1236
			sysdict = genericdict(getlist(self.settings, "system"))
1237
			worlddict=genericdict(worldlist)
1238
1235
1239
			for x in worlddict.keys():
1236
		@param set_name: Name of item to merge.
1240
				if not portage.isvalidatom(x):
1237
		@type set_name: String
1241
					world_problems = True
1238
		@rtype: bool
1242
				elif not self.trees[self.target_root]["vartree"].dbapi.match(x):
1239
		@returns: True if set exists and has proper deps, false if improper deps
1243
					world_problems = True
1240
		and raises ParseError if set_name is not a set.
1244
				else:
1245
					sysdict[x]=worlddict[x]
1246
1241
1247
			mylist = sysdict.keys()
1242
		"""
1248
1243
1249
		newlist = []
1244
		try:
1250
		for atom in mylist:
1245
			_set = PackageSetFactory( set_name, self.target_root, self.settings )
1251
			if portage.dep_getkey(atom).split("/")[-1] == "portage":
1246
		except IOError:
1252
				newlist.insert(0, atom)
1247
			error = portage_exception.ParseError("%s is not a set" % set_name)
1253
			else:
1248
			error.pkg = set_name
1254
				newlist.append(atom)
1249
			raise error
1255
		mylist = newlist
1250
1256
		
1257
		missing_atoms = []
1251
		missing_atoms = []
1258
		for mydep in mylist:
1252
		for pkg in _set.items:
1259
			try:
1253
			try:
1260
				if not self.select_dep(
1254
				if not self.select_dep(
1261
					self.target_root, mydep, raise_on_missing=True):
1255
					self.target_root, pkg, raise_on_missing=True):
1262
					print "\n\n!!! Problem resolving dependencies for", mydep
1256
					portage.writemsg_stdout( "\n!!! Problem resolving dependencies for %s" % mydep ) 
1263
					return 0
1257
					return 0
1264
			except ValueError:
1258
			except ValueError:
1265
				missing_atoms.append(mydep)
1259
				""" Atom is missing from PORTTREE; so we quickly
1266
1260
				    check for it in the VDB; if it's there we don't bitch
1267
		if world_problems:
1261
				"""
1268
			print "\n!!! Problems have been detected with your world file"
1262
				if not self.trees[self.target_root]["vartree"].dbapi.match(pkg):
1269
			print "!!! Please run "+green("emaint --check world")+"\n"
1263
					missing_atoms.append( pkg )
1270
1271
		if missing_atoms:
1264
		if missing_atoms:
1272
			print "\n" + colorize("BAD", "!!!") + \
1265
			portage.writemsg_stdout( "\n" + colorize("BAD", "!!!") + \
1273
				" Ebuilds for the following packages are either all"
1266
 				" Ebuilds for the following packages are either all\n")
1274
			print colorize("BAD", "!!!") + " masked or don't exist:"
1267
			portage.writemsg_stdout( colorize("BAD", "!!!") + " masked or don't exist:")
1275
			print " ".join(missing_atoms) + "\n"
1268
			portage.writemsg_stdout( colorize("BAD", "\n!!!").join( missing_atoms) + "\n")
1276
1269
1277
		return 1
1270
		return 1
1278
1271
1272
	def xcreate(self,mode="system"):
1273
1274
		if False:
1275
			world_problems = False
1276
			if mode=="system":
1277
				mylist = getlist(self.settings, "system")
1278
			else:
1279
				#world mode
1280
				worldlist = getlist(self.settings, "world")
1281
				sysdict = genericdict(getlist(self.settings, "system"))
1282
				worlddict=genericdict(worldlist)
1283
	
1284
				for x in worlddict.keys():
1285
					if not portage.isvalidatom(x):
1286
						world_problems = True
1287
					elif not self.trees[self.target_root]["vartree"].dbapi.match(x):
1288
						world_problems = True
1289
					else:
1290
						sysdict[x]=worlddict[x]
1291
	
1292
				mylist = sysdict.keys()
1293
1294
			newlist = []
1295
			for atom in mylist:
1296
				if portage.dep_getkey(atom).split("/")[-1] == "portage":
1297
					newlist.insert(0, atom)
1298
				else:
1299
					newlist.append(atom)
1300
			mylist = newlist
1301
			
1302
			missing_atoms = []
1303
			for mydep in mylist:
1304
				try:
1305
					if not self.select_dep(
1306
						self.target_root, mydep, raise_on_missing=True):
1307
						print "\n\n!!! Problem resolving dependencies for", mydep
1308
						return 0
1309
				except ValueError:
1310
					missing_atoms.append(mydep)
1311
	
1312
			if world_problems:
1313
				print "\n!!! Problems have been detected with your world file"
1314
				print "!!! Please run "+green("emaint --check world")+"\n"
1315
	
1316
			if missing_atoms:
1317
				print "\n" + colorize("BAD", "!!!") + \
1318
					" Ebuilds for the following packages are either all"
1319
				print colorize("BAD", "!!!") + " masked or don't exist:"
1320
				print " ".join(missing_atoms) + "\n"
1321
			
1322
			return 1
1323
		else:
1324
			raise NotImplementedError("Xcreate is depreated")
1325
1279
	def match(self, mydep, myroot=None, mykey=None):
1326
	def match(self, mydep, myroot=None, mykey=None):
1280
		# support mutual exclusive deps
1327
		# support mutual exclusive deps
1281
		if myroot is None:
1328
		if myroot is None:
Lines 2208-2213 Link Here
2208
2255
2209
	mysettings = portage.config(clone=settings)
2256
	mysettings = portage.config(clone=settings)
2210
2257
2258
	### XXX Fix unmerge logic to work with sets ?
2259
2211
	if not unmerge_files or "world" in unmerge_files or "system" in unmerge_files:
2260
	if not unmerge_files or "world" in unmerge_files or "system" in unmerge_files:
2212
		if "unmerge"==unmerge_action:
2261
		if "unmerge"==unmerge_action:
2213
			print
2262
			print
Lines 3047-3052 Link Here
3047
				print "\n  error processing %(cpv)s, continuing... (%(e)s)" % {"cpv":y,"e":str(e)}
3096
				print "\n  error processing %(cpv)s, continuing... (%(e)s)" % {"cpv":y,"e":str(e)}
3048
	print "done!"
3097
	print "done!"
3049
3098
3099
### XXX Fix config to not take sets 
3100
3050
def action_config(settings, trees, myopts, myfiles):
3101
def action_config(settings, trees, myopts, myfiles):
3051
	if len(myfiles) != 1 or "system" in myfiles or "world" in myfiles:
3102
	if len(myfiles) != 1 or "system" in myfiles or "world" in myfiles:
3052
		print red("!!! config can only take a single package atom at this time\n")
3103
		print red("!!! config can only take a single package atom at this time\n")
Lines 3308-3316 Link Here
3308
	myvarlist = vardb.cpv_all()
3359
	myvarlist = vardb.cpv_all()
3309
3360
3310
	if not syslist:
3361
	if not syslist:
3311
		print "\n!!! You have no system list.",
3362
		print "\n!!! You have no system set.",
3312
	if not worldlist:
3363
	if not worldlist:
3313
		print "\n!!! You have no world file.",
3364
		print "\n!!! You have no world set.",
3314
	if not myvarlist:
3365
	if not myvarlist:
3315
		print "\n!!! You have no installed package database (%s)." % portage.VDB_PATH,
3366
		print "\n!!! You have no installed package database (%s)." % portage.VDB_PATH,
3316
3367
Lines 3447-3485 Link Here
3447
			print darkgreen("emerge: It seems we have nothing to resume...")
3498
			print darkgreen("emerge: It seems we have nothing to resume...")
3448
			sys.exit(0)
3499
			sys.exit(0)
3449
3500
3501
3502
		""" Here we parse the command line args, we try sets first, then
3503
		    normal packages.
3504
		"""
3505
3450
		myparams = create_depgraph_params(myopts, myaction)
3506
		myparams = create_depgraph_params(myopts, myaction)
3451
		mydepgraph = depgraph(settings, trees,
3507
		mydepgraph = depgraph(settings, trees,
3452
			myopts, myparams, spinner)
3508
			myopts, myparams, spinner)
3453
		if myaction in ["system","world"]:
3509
3454
			if not ("--quiet" in myopts):
3510
		mypackages = []
3455
				print "Calculating",myaction,"dependencies  ",
3511
		unfulfilled_sets = []
3456
				sys.stdout.flush()
3512
		sets = myfiles
3457
			if not mydepgraph.xcreate(myaction):
3513
		portage.writemsg_stdout( "\nCalculating dependencies:   " )
3458
				print "!!! Depgraph creation failed."
3514
3459
				sys.exit(1)
3515
		for p_set in sets:
3460
			if not ("--quiet" in myopts):
3461
				print "\b\b... done!"
3462
		else:
3463
			if not ("--quiet" in myopts):
3464
				print "Calculating dependencies  ",
3465
				sys.stdout.flush()
3466
			try:
3516
			try:
3467
				retval, favorites = mydepgraph.select_files(myfiles)
3517
				if not mydepgraph.setCreate(p_set):
3518
					unfulfilled_sets.append(p_set)
3519
			except portage_exception.ParseError, pe:
3520
				mypackages.append( pe.pkg )
3521
		if unfulfilled_sets:
3522
			raise Exception( "Depgraph creation failed for: %s" % unfulfilled_sets )
3523
		elif mypackages:
3524
			try:
3525
				retval, favorites = mydepgraph.select_files(mypackages)
3468
			except portage_exception.PackageNotFound, e:
3526
			except portage_exception.PackageNotFound, e:
3469
				portage.writemsg("\n!!! %s\n" % str(e), noiselevel=-1)
3527
				portage.writemsg("\n!!! %s\n" % str(e), noiselevel=-1)
3470
				sys.exit(1)
3528
				sys.exit(1)
3471
			if not retval:
3529
			if not retval:
3472
				sys.exit(1)
3530
				sys.exit(1)
3473
			if not ("--quiet" in myopts):
3531
			if not ("--quiet" in myopts):
3474
				print "\b\b... done!"
3532
				portage.writemsg( "\b\b... done!" )
3475
3533
3476
			if ("--usepkgonly" in myopts) and mydepgraph.missingbins:
3534
			if ("--usepkgonly" in myopts) and mydepgraph.missingbins:
3477
				sys.stderr.write(red("The following binaries are not available for merging...\n"))
3535
				portage.writemsg_stderr(red("The following binaries are not available for merging...\n"))
3478
3536
3479
		if mydepgraph.missingbins:
3537
		if mydepgraph.missingbins:
3480
			for x in mydepgraph.missingbins:
3538
			for x in mydepgraph.missingbins:
3481
				sys.stderr.write("   "+str(x)+"\n")
3539
				portage.writemsg_stderr("   "+str(x)+"\n")
3482
			sys.stderr.write("\nThese are required by '--usepkgonly' -- Terminating.\n\n")
3540
			portage.writemsg_stderr("\nThese are required by '--usepkgonly' -- Terminating.\n\n")
3483
			sys.exit(1)
3541
			sys.exit(1)
3484
3542
3485
	if "--ask" in myopts:
3543
	if "--ask" in myopts:
Lines 3631-3638 Link Here
3631
					myopts.append(x)
3689
					myopts.append(x)
3632
			elif x[2:] in actions:
3690
			elif x[2:] in actions:
3633
				if myaction:
3691
				if myaction:
3634
					if myaction not in ["system", "world"]:
3692
					myaction="--"+myaction
3635
						myaction="--"+myaction
3636
					print
3693
					print
3637
					print red("!!!")+green(" Multiple actions requested... Please choose one only.")
3694
					print red("!!!")+green(" Multiple actions requested... Please choose one only.")
3638
					print red("!!!")+" '"+darkgreen(myaction)+"' "+red("or")+" '"+darkgreen(x)+"'"
3695
					print red("!!!")+" '"+darkgreen(myaction)+"' "+red("or")+" '"+darkgreen(x)+"'"
Lines 3643-3650 Link Here
3643
				print "!!! Error:",x,"is an invalid option."
3700
				print "!!! Error:",x,"is an invalid option."
3644
				sys.exit(1)
3701
				sys.exit(1)
3645
		elif (not myaction) and (x in actions):
3702
		elif (not myaction) and (x in actions):
3646
			if x not in ["system", "world"]:
3703
			print red("*** Deprecated use of action '%s', use '--%s' instead" % (x,x))
3647
				print red("*** Deprecated use of action '%s', use '--%s' instead" % (x,x))
3648
			if myaction:
3704
			if myaction:
3649
				print
3705
				print
3650
				print red("!!!")+green(" Multiple actions requested... Please choose one only.")
3706
				print red("!!!")+green(" Multiple actions requested... Please choose one only.")
Lines 3833-3842 Link Here
3833
3889
3834
"""
3890
"""
3835
3891
3836
	if (myaction in ["world", "system"]) and myfiles:
3837
		print "emerge: please specify a package class (\"world\" or \"system\") or individual packages, but not both."
3838
		sys.exit(1)
3839
3840
	for x in myfiles:
3892
	for x in myfiles:
3841
		ext = os.path.splitext(x)[1]
3893
		ext = os.path.splitext(x)[1]
3842
		if (ext == ".ebuild" or ext == ".tbz2") and os.path.exists(os.path.abspath(x)):
3894
		if (ext == ".ebuild" or ext == ".tbz2") and os.path.exists(os.path.abspath(x)):
3843
+ac592a22-f3fe-0310-977e-98394eae9e84:/main/trunk:4434
3895
+ac592a22-f3fe-0310-977e-98394eae9e84:/main/trunk:4434

Return to bug 6411