1. Lukas Linhart
  2. django-triager-bot

Source

django-triager-bot / djangotriager / main.py

"""Main "entry point" module for package"""
import os
import sys

from argparse import ArgumentParser

from djangotriager.config import Configuration
from djangotriager.trac.tickets import Ticket
from djangotriager.exceptions import InvalidOptions

__all__ = ('main', )

def get_parser():
    """
    Construct command-line argument parser with all allowed options.
    """
    parser = ArgumentParser(description='Trac Triager')
    parser.add_argument("--config", type=unicode,
                        help=(u"Configuration file you'd like to use "
                               "(will overwrite options given through "
                              "CLI)"))
    parser.add_argument("--ticket", type=int,
                        help=u"Ticket number you want to operate on")
    parser.add_argument("--send_report", type=bool,
                        help=(u"If the processing result must be sent "
                              "to the ticket's page on Trac"))
    parser.add_argument("--query", type=unicode,
                        help=(u"Trac query string to use when searching "
                              "for tickets"))
    parser.add_argument("--n_patches", type=int,
                        help=(u"Limit the number of the patches to "
                              "check, most recent first."))
    parser.add_argument("--trac", type=unicode,
                        help=(u"URL of the trac instance to use for "
                              "retrieving tickets"))
    parser.add_argument("command", type=unicode, choices=ACTIONS_MAP,
                        help=(u"Operation to perform with the ticket(s) "
                              "retrieved"))
    parser.add_argument('--working_copy', type=unicode,
                        help=(u"The SVN working copy directory to "
                              "use when trying tickets"))
    return parser

def main(argv=None, config=None, do_exit=True):
    """
    Main entry point for console script
    """
    parser = get_parser()
    namespace = parser.parse_args(argv or sys.argv[1:])

    config = config or Configuration()
    config.command = namespace.command

    if namespace.config:
        if (os.path.exists(namespace.config) 
            and os.path.isfile(namespace.config)):
            config.read_config(namespace.config)
        else:
            parser.error("The configuration file specified "
                         "doesn't exists or isn't a file.")
    config.merge_with_cmd(namespace)
    try:
        code = ACTIONS_MAP[config.command](config=config)
    except InvalidOptions, error:
        parser.error(error.message)

    if do_exit:
        sys.exit(code or 0)
    else:
        return code

def _process_tickets(config, func):
    config.ensure_one("ticket", "query")
    config.ensure_all("working_copy")
    if config.get("ticket"):
        tickets = [Ticket(config.get("ticket")), ]
    else:
        tickets = Ticket.get_by_query(config, config.get("query"))

    patches_limit = config.get("n_patches")
    patches_limit = patches_limit and int(patches_limit) or None

    for ticket in tickets:
        func(ticket, patches_limit)
        if not config.get("send_report"):
            print ticket.get_report()
        else:
            # TODO: send report to the ticket's page
            pass

def try_ticket(config):
    func = lambda ticket, limit: \
        ticket.try_patches(config, limit=limit)
    _process_tickets(config, func)

def apply_ticket(config):
    func = lambda ticket, limit: \
        ticket.apply_patches(config, limit=limit)
    _process_tickets(config, func)

ACTIONS_MAP = {
    'try': try_ticket,
    'apply': apply_ticket,
}