Lines 5199-5205
Link Here
|
5199 |
searchinstance.output() |
5225 |
searchinstance.output() |
5200 |
|
5226 |
|
5201 |
def action_depclean(settings, trees, ldpath_mtimes, |
5227 |
def action_depclean(settings, trees, ldpath_mtimes, |
5202 |
myopts, spinner): |
5228 |
myopts, action, myfiles, spinner): |
5203 |
# Kill packages that aren't explicitly merged or are required as a |
5229 |
# Kill packages that aren't explicitly merged or are required as a |
5204 |
# dependency of another package. World file is explicit. |
5230 |
# dependency of another package. World file is explicit. |
5205 |
|
5231 |
|
Lines 5220-5228
Link Here
|
5220 |
msg.append("consequence, it is often necessary to run\n") |
5246 |
msg.append("consequence, it is often necessary to run\n") |
5221 |
msg.append(good("`emerge --update --newuse --deep world`") + " prior to depclean.\n") |
5247 |
msg.append(good("`emerge --update --newuse --deep world`") + " prior to depclean.\n") |
5222 |
|
5248 |
|
5223 |
portage.writemsg_stdout("\n") |
5249 |
if action == "depclean" and "--quiet" not in myopts and not myfiles: |
5224 |
for x in msg: |
5250 |
portage.writemsg_stdout("\n") |
5225 |
portage.writemsg_stdout(colorize("BAD", "*** WARNING *** ") + x) |
5251 |
for x in msg: |
|
|
5252 |
portage.writemsg_stdout(colorize("BAD", "*** WARNING *** ") + x) |
5226 |
|
5253 |
|
5227 |
xterm_titles = "notitles" not in settings.features |
5254 |
xterm_titles = "notitles" not in settings.features |
5228 |
myroot = settings["ROOT"] |
5255 |
myroot = settings["ROOT"] |
Lines 5239-5244
Link Here
|
5239 |
world_set = WorldSet(settings) |
5266 |
world_set = WorldSet(settings) |
5240 |
world_set.load() |
5267 |
world_set.load() |
5241 |
worldlist = list(world_set) |
5268 |
worldlist = list(world_set) |
|
|
5269 |
args_set = AtomSet() |
5242 |
fakedb = portage.fakedbapi(settings=settings) |
5270 |
fakedb = portage.fakedbapi(settings=settings) |
5243 |
myvarlist = vardb.cpv_all() |
5271 |
myvarlist = vardb.cpv_all() |
5244 |
|
5272 |
|
Lines 5255-5273
Link Here
|
5255 |
if "--pretend" not in myopts: |
5283 |
if "--pretend" not in myopts: |
5256 |
countdown(int(settings["EMERGE_WARNING_DELAY"]), ">>> Depclean") |
5284 |
countdown(int(settings["EMERGE_WARNING_DELAY"]), ">>> Depclean") |
5257 |
|
5285 |
|
5258 |
if not "--pretend" in myopts: #just check pretend, since --ask implies pretend |
5286 |
if action == "depclean": |
5259 |
emergelog(xterm_titles, " >>> depclean") |
5287 |
emergelog(xterm_titles, " >>> depclean") |
|
|
5288 |
if myfiles: |
5289 |
for x in myfiles: |
5290 |
if not is_valid_package_atom(x): |
5291 |
portage.writemsg("!!! '%s' is not a valid package atom.\n" % x, |
5292 |
noiselevel=-1) |
5293 |
portage.writemsg("!!! Please check ebuild(5) for full details.\n") |
5294 |
return |
5295 |
try: |
5296 |
atom = portage.dep_expand(x, mydb=vardb, settings=settings) |
5297 |
except ValueError, e: |
5298 |
print "!!! The short ebuild name \"" + x + "\" is ambiguous. Please specify" |
5299 |
print "!!! one of the following fully-qualified ebuild names instead:\n" |
5300 |
for i in e[0]: |
5301 |
print " " + colorize("INFORM", i) |
5302 |
print |
5303 |
return |
5304 |
args_set.add(atom) |
5260 |
|
5305 |
|
5261 |
if "--quiet" not in myopts: |
5306 |
if "--quiet" not in myopts: |
5262 |
print "\nCalculating dependencies ", |
5307 |
print "\nCalculating dependencies ", |
5263 |
|
5308 |
|
5264 |
soft = 0 |
5309 |
soft = 0 |
5265 |
hard = 1 |
5310 |
hard = 1 |
5266 |
remaining_atoms = [(atom, 'world', hard) for atom in worldlist if vardb.match(atom)] |
5311 |
remaining_atoms = [] |
5267 |
remaining_atoms += [(atom, 'system', hard) for atom in syslist if vardb.match(atom)] |
5312 |
if action == "depclean": |
|
|
5313 |
for atom in worldlist: |
5314 |
if vardb.match(atom): |
5315 |
remaining_atoms.append((atom, 'world', hard)) |
5316 |
for atom in syslist: |
5317 |
if vardb.match(atom): |
5318 |
remaining_atoms.append((atom, 'system', hard)) |
5319 |
elif action == "prune": |
5320 |
# Pull in everything that's installed since we don't want to prune a |
5321 |
# package if something depends on it. |
5322 |
remaining_atoms.extend((atom, 'world', hard) for atom in vardb.cp_all()) |
5323 |
if not myfiles: |
5324 |
# Try to prune everything that's slotted. |
5325 |
for cp in vardb.cp_all(): |
5326 |
if len(vardb.cp_list(cp)) > 1: |
5327 |
args_set.add(cp) |
5328 |
|
5268 |
unresolveable = {} |
5329 |
unresolveable = {} |
5269 |
aux_keys = ["DEPEND", "RDEPEND", "PDEPEND"] |
5330 |
aux_keys = ["DEPEND", "RDEPEND", "PDEPEND"] |
5270 |
metadata_keys = ["PROVIDE", "SLOT", "USE"] |
5331 |
metadata_keys = ["PROVIDE", "SLOT", "USE"] |
|
|
5332 |
graph = digraph() |
5271 |
|
5333 |
|
5272 |
while remaining_atoms: |
5334 |
while remaining_atoms: |
5273 |
atom, parent, priority = remaining_atoms.pop() |
5335 |
atom, parent, priority = remaining_atoms.pop() |
Lines 5276-5282
Link Here
|
5276 |
if not atom.startswith("!") and priority == hard: |
5338 |
if not atom.startswith("!") and priority == hard: |
5277 |
unresolveable.setdefault(atom, []).append(parent) |
5339 |
unresolveable.setdefault(atom, []).append(parent) |
5278 |
continue |
5340 |
continue |
5279 |
if len(pkgs) > 1 and parent != "world": |
5341 |
if action == "depclean" and parent == "world" and myfiles: |
|
|
5342 |
# Filter out packages given as arguments since the user wants |
5343 |
# to remove those. |
5344 |
filtered_pkgs = [] |
5345 |
for pkg in pkgs: |
5346 |
metadata = dict(izip(metadata_keys, |
5347 |
vardb.aux_get(pkg, metadata_keys))) |
5348 |
arg_atom = None |
5349 |
try: |
5350 |
arg_atom = args_set.findAtomForPackage(pkg, metadata) |
5351 |
except portage_exception.InvalidDependString, e: |
5352 |
file_path = os.path.join(myroot, VDB_PATH, pkg, "PROVIDE") |
5353 |
portage.writemsg("\n\nInvalid PROVIDE: %s\n" % str(s), |
5354 |
noiselevel=-1) |
5355 |
portage.writemsg("See '%s'\n" % file_path, |
5356 |
noiselevel=-1) |
5357 |
del e |
5358 |
if not arg_atom: |
5359 |
filtered_pkgs.append(pkg) |
5360 |
pkgs = filtered_pkgs |
5361 |
prune_this = False |
5362 |
if action == "prune": |
5363 |
for pkg in pkgs: |
5364 |
metadata = dict(izip(metadata_keys, |
5365 |
vardb.aux_get(pkg, metadata_keys))) |
5366 |
try: |
5367 |
arg_atom = args_set.findAtomForPackage(pkg, metadata) |
5368 |
except portage_exception.InvalidDependString, e: |
5369 |
file_path = os.path.join(myroot, VDB_PATH, pkg, "PROVIDE") |
5370 |
portage.writemsg("\n\nInvalid PROVIDE: %s\n" % str(s), |
5371 |
noiselevel=-1) |
5372 |
portage.writemsg("See '%s'\n" % file_path, |
5373 |
noiselevel=-1) |
5374 |
del e |
5375 |
continue |
5376 |
if arg_atom: |
5377 |
prune_this = True |
5378 |
break |
5379 |
if len(pkgs) > 1 and (parent != "world" or prune_this): |
5280 |
# Prune all but the best matching slot, since that's all that a |
5380 |
# Prune all but the best matching slot, since that's all that a |
5281 |
# deep world update would pull in. Don't prune if this atom comes |
5381 |
# deep world update would pull in. Don't prune if this atom comes |
5282 |
# directly from world though, since world atoms are greedy when |
5382 |
# directly from world though, since world atoms are greedy when |
Lines 5289-5294
Link Here
|
5289 |
pkgs = visible_in_portdb |
5389 |
pkgs = visible_in_portdb |
5290 |
pkgs = [portage.best(pkgs)] |
5390 |
pkgs = [portage.best(pkgs)] |
5291 |
for pkg in pkgs: |
5391 |
for pkg in pkgs: |
|
|
5392 |
graph.add(pkg, parent) |
5292 |
if fakedb.cpv_exists(pkg): |
5393 |
if fakedb.cpv_exists(pkg): |
5293 |
continue |
5394 |
continue |
5294 |
spinner.update() |
5395 |
spinner.update() |
Lines 5342-5362
Link Here
|
5342 |
print |
5443 |
print |
5343 |
for atom in unresolveable: |
5444 |
for atom in unresolveable: |
5344 |
print atom, "required by", " ".join(unresolveable[atom]) |
5445 |
print atom, "required by", " ".join(unresolveable[atom]) |
|
|
5446 |
if unresolveable: |
5345 |
print |
5447 |
print |
5346 |
print "Have you forgotten to run " + good("`emerge --update --newuse --deep world`") + " prior to" |
5448 |
print "Have you forgotten to run " + good("`emerge --update --newuse --deep world`") + " prior to" |
5347 |
print "depclean? It may be necessary to manually uninstall packages that no longer" |
5449 |
print "%s? It may be necessary to manually uninstall packages that no longer" % action |
5348 |
print "exist in the portage tree since it may not be possible to satisfy their" |
5450 |
print "exist in the portage tree since it may not be possible to satisfy their" |
5349 |
print "dependencies. Also, be aware of the --with-bdeps option that is documented" |
5451 |
print "dependencies. Also, be aware of the --with-bdeps option that is documented" |
5350 |
print "in " + good("`man emerge`") + "." |
5452 |
print "in " + good("`man emerge`") + "." |
5351 |
print |
5453 |
print |
|
|
5454 |
if action == "prune": |
5455 |
print "If you would like to ignore dependencies then use %s." % \ |
5456 |
good("--nodeps") |
5352 |
return |
5457 |
return |
5353 |
|
5458 |
|
5354 |
cleanlist = [pkg for pkg in vardb.cpv_all() if not fakedb.cpv_exists(pkg)] |
5459 |
def show_parents(child_node): |
|
|
5460 |
parent_nodes = graph.parent_nodes(child_node) |
5461 |
parent_nodes.sort() |
5462 |
msg = [] |
5463 |
msg.append(" %s pulled in by:\n" % str(child_node)) |
5464 |
for parent_node in parent_nodes: |
5465 |
msg.append(" %s\n" % str(parent_node)) |
5466 |
msg.append("\n") |
5467 |
portage.writemsg_stdout("".join(msg), noiselevel=-1) |
5355 |
|
5468 |
|
|
|
5469 |
cleanlist = [] |
5470 |
if action == "depclean": |
5471 |
if myfiles: |
5472 |
for pkg in vardb.cpv_all(): |
5473 |
metadata = dict(izip(metadata_keys, |
5474 |
vardb.aux_get(pkg, metadata_keys))) |
5475 |
arg_atom = None |
5476 |
try: |
5477 |
arg_atom = args_set.findAtomForPackage(pkg, metadata) |
5478 |
except portage_exception.InvalidDependString: |
5479 |
# this error has already been displayed by now |
5480 |
continue |
5481 |
if arg_atom: |
5482 |
if not fakedb.cpv_exists(pkg): |
5483 |
cleanlist.append(pkg) |
5484 |
elif "--verbose" in myopts: |
5485 |
show_parents(pkg) |
5486 |
else: |
5487 |
for pkg in vardb.cpv_all(): |
5488 |
if not fakedb.cpv_exists(pkg): |
5489 |
cleanlist.append(pkg) |
5490 |
elif "--verbose" in myopts: |
5491 |
show_parents(pkg) |
5492 |
elif action == "prune": |
5493 |
for atom in args_set: |
5494 |
for pkg in vardb.match(atom): |
5495 |
if not fakedb.cpv_exists(pkg): |
5496 |
cleanlist.append(pkg) |
5497 |
elif "--verbose" in myopts: |
5498 |
show_parents(pkg) |
5499 |
|
5500 |
if not cleanlist: |
5501 |
portage.writemsg_stdout( |
5502 |
">>> No packages selected for removal by %s\n" % action) |
5503 |
if "--verbose" not in myopts: |
5504 |
portage.writemsg_stdout( |
5505 |
">>> To see reverse dependencies, use %s\n" % \ |
5506 |
good("--verbose")) |
5507 |
if action == "prune": |
5508 |
portage.writemsg_stdout( |
5509 |
">>> To ignore dependencies, use %s\n" % \ |
5510 |
good("--nodeps")) |
5511 |
|
5356 |
if len(cleanlist): |
5512 |
if len(cleanlist): |
5357 |
unmerge(settings, myopts, trees[settings["ROOT"]]["vartree"], |
5513 |
unmerge(settings, myopts, trees[settings["ROOT"]]["vartree"], |
5358 |
"unmerge", cleanlist, ldpath_mtimes) |
5514 |
"unmerge", cleanlist, ldpath_mtimes) |
5359 |
|
5515 |
|
|
|
5516 |
if action == "prune": |
5517 |
return |
5518 |
|
5360 |
print "Packages installed: "+str(len(myvarlist)) |
5519 |
print "Packages installed: "+str(len(myvarlist)) |
5361 |
print "Packages in world: "+str(len(worldlist)) |
5520 |
print "Packages in world: "+str(len(worldlist)) |
5362 |
print "Packages in system: "+str(len(syslist)) |
5521 |
print "Packages in system: "+str(len(syslist)) |
Lines 6147-6153
Link Here
|
6147 |
validate_ebuild_environment(trees) |
6306 |
validate_ebuild_environment(trees) |
6148 |
action_search(settings, portdb, trees["/"]["vartree"], |
6307 |
action_search(settings, portdb, trees["/"]["vartree"], |
6149 |
myopts, myfiles, spinner) |
6308 |
myopts, myfiles, spinner) |
6150 |
elif "unmerge"==myaction or "prune"==myaction or "clean"==myaction: |
6309 |
elif myaction in ("clean", "unmerge") or \ |
|
|
6310 |
(myaction == "prune" and "--nodeps" in myopts): |
6151 |
validate_ebuild_environment(trees) |
6311 |
validate_ebuild_environment(trees) |
6152 |
vartree = trees[settings["ROOT"]]["vartree"] |
6312 |
vartree = trees[settings["ROOT"]]["vartree"] |
6153 |
if 1 == unmerge(settings, myopts, vartree, myaction, myfiles, |
6313 |
if 1 == unmerge(settings, myopts, vartree, myaction, myfiles, |
Lines 6155-6164
Link Here
|
6155 |
if "--pretend" not in myopts: |
6315 |
if "--pretend" not in myopts: |
6156 |
post_emerge(settings, mtimedb, 0) |
6316 |
post_emerge(settings, mtimedb, 0) |
6157 |
|
6317 |
|
6158 |
elif "depclean"==myaction: |
6318 |
elif myaction in ("depclean", "prune"): |
6159 |
validate_ebuild_environment(trees) |
6319 |
validate_ebuild_environment(trees) |
6160 |
action_depclean(settings, trees, mtimedb["ldpath"], |
6320 |
action_depclean(settings, trees, mtimedb["ldpath"], |
6161 |
myopts, spinner) |
6321 |
myopts, myaction, myfiles, spinner) |
6162 |
if "--pretend" not in myopts: |
6322 |
if "--pretend" not in myopts: |
6163 |
post_emerge(settings, mtimedb, 0) |
6323 |
post_emerge(settings, mtimedb, 0) |
6164 |
# "update", "system", or just process files: |
6324 |
# "update", "system", or just process files: |