import logging import optparse import math import os from wizard import deploy from wizard.command import _base def main(argv, global_options): options, show = parse_args(argv) if not show: show = deploy.applications.keys() options.dispatch(parse_install_lines(show, options, global_options)) def parse_args(argv): usage = """usage: %prog summary [ARGS] APPS Scans all of the collected data from parallel-find.pl, and determines version histograms for our applications. You may optionally pass application parameters to filter the installs. Examples: %prog summary Basic usage %prog summary mediawiki Displays only MediaWiki statistics""" parser = _base.WizardOptionParser(usage) def addDispatch(flag, function, type, help): parser.add_option(flag, action="callback", callback=make_callback(function), type=type, help=help) addDispatch("--count-exists", summary_count_exists, "string", "Count deployments that contain a file") addDispatch("--list", summary_list, None, "Print locations of deployments that match APPS") parser.add_option("--warn-unrecognized", dest="warn_unrecognized", action="store_true", default=False, help="Emit warnings when unrecognized applications are found") options, show = parser.parse_all(argv) if not hasattr(options, "dispatch"): # default options.dispatch = summary_version return options, show def make_callback(f): def callback(option, opt_str, value, parser): if hasattr(parser.values, "dispatch"): # maybe make this more flexible raise optparse.OptionValueError("Cannot use multiple summary modes") parser.values.dispatch = lambda x: f(x, value) return callback def parse_install_lines(show, options, global_options): show = frozenset(show) for line in deploy.getInstallLines(global_options): # construction try: d = deploy.Deployment.parse(line) name = d.getApplication().name except deploy.NoSuchApplication: if options.warn_unrecognized: logging.warning("Unrecognized application with '%s'" % line.rstrip()) continue except deploy.Error: logging.warning("Error with '%s'" % line.rstrip()) continue # filter if name + "-" + str(d.getVersion()) in show or name in show: pass else: continue # yield yield d def print_summary(show, errors, unrecognized): for app in deploy.applications.values(): if app.name not in show: continue print app.report() print print "With %d errors and %d unrecognized applications" % (errors, unrecognized) def summary_list(deploys, value): for d in deploys: print d.location def summary_version(deploys, value): HISTOGRAM_WIDTH = 30 show = set() version_counts = {} application_counts = {} for d in deploys: version = d.getAppVersion() version_counts.setdefault(version, 0) application_counts.setdefault(version.application, 0) version_counts[version] += 1 application_counts[version.application] += 1 show.add(version.application) if not show: print "No applications found" for application in show: print "%-16s %3d installs" % (application.name, application_counts[application]) vmax = max(version_counts[x] for x in application.versions.values()) for version in sorted(application.versions.values()): v = version_counts[version] graph = '+' * int(math.ceil(float(v)/vmax * HISTOGRAM_WIDTH)) print " %-12s %3d %s" % (version.version, v, graph) print def summary_count_exists(deploys, value): for d in deploys: if os.path.exists(d.location + "/" + value): print d.location