summaryrefslogtreecommitdiffstats
path: root/pym/portage/emaint/main.py
diff options
context:
space:
mode:
Diffstat (limited to 'pym/portage/emaint/main.py')
-rw-r--r--pym/portage/emaint/main.py218
1 files changed, 218 insertions, 0 deletions
diff --git a/pym/portage/emaint/main.py b/pym/portage/emaint/main.py
new file mode 100644
index 000000000..dbc5f18cc
--- /dev/null
+++ b/pym/portage/emaint/main.py
@@ -0,0 +1,218 @@
+# Copyright 2005-2012 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+from __future__ import print_function
+
+
+import sys
+import textwrap
+from optparse import OptionParser, OptionValueError
+
+
+import portage
+from portage import os
+from portage.emaint.module import Modules
+from portage.emaint.progress import ProgressBar
+from portage.emaint.defaults import DEFAULT_OPTIONS
+
+class OptionItem(object):
+ """class to hold module OptionParser options data
+ """
+
+ def __init__(self, opt, parser):
+ """
+ @type opt: dictionary
+ @param opt: options parser options
+ """
+ self.parser = parser
+ self.short = opt['short']
+ self.long = opt['long']
+ self.help = opt['help']
+ self.status = opt['status']
+ self.func = opt['func']
+ self.action = opt.get('action', "callback")
+ self.type = opt.get('type', None)
+ self.dest = opt.get('dest', None)
+ self.callback = opt.get('callback', self._exclusive)
+ self.callback_kwargs = opt.get('callback_kwargs', {"var":"action"})
+
+
+ def _exclusive(self, option, *args, **kw):
+ """Generic check for the 2 default options
+ """
+ var = kw.get("var", None)
+ if var is None:
+ raise ValueError("var not specified to exclusive()")
+ if getattr(self.parser, var, ""):
+ raise OptionValueError("%s and %s are exclusive options"
+ % (getattr(self.parser, var), option))
+ setattr(self.parser, var, str(option))
+
+ def check_action(self, action):
+ """Checks if 'action' is the same as this option
+
+ @type action: string
+ @param action: the action to compare
+ @rtype: boolean
+ """
+ if action == self.action:
+ return True
+ elif action == '/'.join([self.short, self.long]):
+ return True
+ return False
+
+
+def usage(module_controller):
+ _usage = "usage: emaint [options] COMMAND"
+
+ desc = "The emaint program provides an interface to system health " + \
+ "checks and maintenance. See the emaint(1) man page " + \
+ "for additional information about the following commands:"
+
+ _usage += "\n\n"
+ for line in textwrap.wrap(desc, 65):
+ _usage += "%s\n" % line
+ _usage += "\nCommands:\n"
+ _usage += " %s" % "all".ljust(15) + \
+ "Perform all supported commands\n"
+ textwrap.subsequent_indent = ' '.ljust(17)
+ for mod in module_controller.module_names:
+ desc = textwrap.wrap(module_controller.get_description(mod), 65)
+ _usage += " %s%s\n" % (mod.ljust(15), desc[0])
+ for d in desc[1:]:
+ _usage += " %s%s\n" % (' '.ljust(15), d)
+ return _usage
+
+
+def module_opts(module_controller, module):
+ _usage = " %s module options:\n" % module
+ opts = module_controller.get_func_descriptions(module)
+ if opts == {}:
+ opts = DEFAULT_OPTIONS
+ for opt in sorted(opts):
+ optd = opts[opt]
+ opto = " %s, %s" %(optd['short'], optd['long'])
+ _usage += '%s %s\n' % (opto.ljust(15),optd['help'])
+ _usage += '\n'
+ return _usage
+
+
+class TaskHandler(object):
+ """Handles the running of the tasks it is given
+ """
+
+ def __init__(self, show_progress_bar=True, verbose=True, callback=None):
+ self.show_progress_bar = show_progress_bar
+ self.verbose = verbose
+ self.callback = callback
+ self.isatty = os.environ.get('TERM') != 'dumb' and sys.stdout.isatty()
+ self.progress_bar = ProgressBar(self.isatty, title="Emaint", max_desc_length=27)
+
+
+ def run_tasks(self, tasks, func, status=None, verbose=True, options=None):
+ """Runs the module tasks"""
+ if tasks is None or func is None:
+ return
+ for task in tasks:
+ inst = task()
+ show_progress = self.show_progress_bar
+ # check if the function is capable of progressbar
+ # and possibly override it off
+ if show_progress and hasattr(inst, 'can_progressbar'):
+ show_progress = inst.can_progressbar(func)
+ if show_progress:
+ self.progress_bar.reset()
+ self.progress_bar.set_label(func + " " + inst.name())
+ onProgress = self.progress_bar.start()
+ else:
+ onProgress = None
+ kwargs = {
+ 'onProgress': onProgress,
+ # pass in a copy of the options so a module can not pollute or change
+ # them for other tasks if there is more to do.
+ 'options': options.copy()
+ }
+ result = getattr(inst, func)(**kwargs)
+ if self.isatty and show_progress:
+ # make sure the final progress is displayed
+ self.progress_bar.display()
+ print()
+ self.progress_bar.stop()
+ if self.callback:
+ self.callback(result)
+
+
+def print_results(results):
+ if results:
+ print()
+ print("\n".join(results))
+ print("\n")
+
+
+def emaint_main(myargv):
+
+ # Similar to emerge, emaint needs a default umask so that created
+ # files (such as the world file) have sane permissions.
+ os.umask(0o22)
+
+ module_controller = Modules(namepath="portage.emaint.modules")
+ module_names = module_controller.module_names[:]
+ module_names.insert(0, "all")
+
+
+ parser = OptionParser(usage=usage(module_controller), version=portage.VERSION)
+ # add default options
+ parser_options = []
+ for opt in DEFAULT_OPTIONS:
+ parser_options.append(OptionItem(DEFAULT_OPTIONS[opt], parser))
+ for mod in module_names[1:]:
+ desc = module_controller.get_func_descriptions(mod)
+ if desc:
+ for opt in desc:
+ parser_options.append(OptionItem(desc[opt], parser))
+ for opt in parser_options:
+ parser.add_option(opt.short, opt.long, help=opt.help, action=opt.action,
+ type=opt.type, dest=opt.dest,
+ callback=opt.callback, callback_kwargs=opt.callback_kwargs)
+
+ parser.action = None
+
+ (options, args) = parser.parse_args(args=myargv)
+ #print('options', options, '\nargs', args, '\naction', parser.action)
+ 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:
+ action = "-c/--check"
+ long_action = action.split('/')[1].lstrip('-')
+ #print("DEBUG: action = ", action, long_action)
+
+ if args[0] == "all":
+ tasks = []
+ for m in module_names[1:]:
+ #print("DEBUG: module: %s, functions: " %(m, str(module_controller.get_functions(m))))
+ if long_action in module_controller.get_functions(m):
+ tasks.append(module_controller.get_class(m))
+ elif long_action in module_controller.get_functions(args[0]):
+ tasks = [module_controller.get_class(args[0] )]
+ else:
+ print("\nERROR: module '%s' does not have option '%s'\n" %(args[0], action))
+ print(module_opts(module_controller, args[0]))
+ sys.exit(1)
+ func = status = None
+ for opt in parser_options:
+ if opt.check_action(action):
+ status = opt.status
+ func = opt.func
+ break
+
+ # need to pass the parser options dict to the modules
+ # so they are available if needed.
+ task_opts = options.__dict__
+ taskmaster = TaskHandler(callback=print_results)
+ taskmaster.run_tasks(tasks, func, status, options=task_opts)
+