| #!/usr/bin/python -O |
| |
| import sys |
| from copy import copy |
| from optparse import OptionParser, OptionValueError |
| |
| |
| |
| import os, portage, portage_const |
| class WorldHandler(object): |
| |
| def name(): |
| return "world" |
| name = staticmethod(name) |
| |
| def __init__(self): |
| self.invalid = [] |
| self.not_installed = [] |
| self.unavailable = [] |
| self.okay = [] |
| self.found = os.access(portage_const.WORLD_FILE, os.R_OK) |
| |
| for atom in open(portage_const.WORLD_FILE).read().split(): |
| if not portage.isvalidatom(atom): |
| self.invalid.append(atom) |
| elif not portage.db["/"]["vartree"].dbapi.match(atom): |
| self.not_installed.append(atom) |
| elif not portage.db["/"]["porttree"].dbapi.match(atom): |
| self.unavailable.append(atom) |
| else: |
| self.okay.append(atom) |
| |
| def check(self): |
| errors = [] |
| if self.found: |
| errors += map(lambda x: "'%s' is not a valid atom" % x, self.invalid) |
| errors += map(lambda x: "'%s' is not installed" % x, self.not_installed) |
| errors += map(lambda x: "'%s' has no ebuilds available" % x, self.unavailable) |
| else: |
| errors.append(portage_const.WORLD_FILE + " could not be opened for reading") |
| return errors |
| |
| def fix(self): |
| errors = [] |
| try: |
| open(portage_const.WORLD_FILE, "w").write("\n".join(self.okay)) |
| except OSError: |
| errors.append(portage_const.WORLD_FILE + " could not be opened for writing") |
| return errors |
| |
| |
| modules = {"world" : WorldHandler} |
| |
| |
| module_names = modules.keys() |
| module_names.sort() |
| module_names.insert(0, "all") |
| |
| |
| def exclusive(option, unused1, unused2, unused3, var=None): |
| if not var: |
| raise ValueError("var not specified to exclusive()") |
| if getattr(parser, var, ""): |
| raise OptionValueError("%s and %s are exclusive options" % (getattr(parser, var), value)) |
| setattr(parser, var, option) |
| |
| |
| usage = "usage: emaint [options] " + " | ".join(module_names) |
| parser = OptionParser(usage=usage) |
| parser.add_option("-c", "--check", help="check for problems", |
| action="callback", callback=exclusive, callback_kwargs={"var":"action"}) |
| parser.add_option("-f", "--fix", help="attempt to fix problems", |
| action="callback", callback=exclusive, callback_kwargs={"var":"action"}) |
| parser.action = None |
| |
| |
| (options, args) = parser.parse_args() |
| if len(args) != 1: |
| parser.error("Incorrect number of arguments") |
| if args[0] not in module_names: |
| parser.error("%s target is not a known target" % args[0]) |
| |
| if parser.action: |
| action = parser.action |
| else: |
| print "Defaulting to --check" |
| action = "-c/--check" |
| |
| if args[0] == "all": |
| tasks = modules.values() |
| else: |
| tasks = [modules[args[0]]] |
| |
| |
| if action == "-c/--check": |
| status = "Checking %s for problems" |
| func = "check" |
| else: |
| status = "Attempting to fix %s" |
| func = "fix" |
| |
| |
| for task in tasks: |
| print status % task.name() |
| inst = task() |
| result = getattr(inst, func)() |
| if result: |
| print |
| print "\n".join(result) |
| print "\n" |
| |