Exemple #1
0
def main():
    for group in types:
        for ticket in sf.iter_tickets(group):
            if ticket.is_not_closed():
                bug = bz.create_bug(b, ticket)
                text = 'This ticket has been moved to ' \
                       'https://bugzilla.wikimedia.org/show_bug.cgi?id={0}'.format(bug.id)

                ticket.add_comment(text)
                bz.add_to_see_also(bug, ticket)
                bz.upload_attachments(bug, ticket)
Exemple #2
0
def main():
    for group in types:
        for ticket in sf.iter_tickets(group):
            if ticket.is_not_closed():
                bug = bz.create_bug(b, ticket)
                text = 'This ticket has been moved to ' \
                       'https://bugzilla.wikimedia.org/show_bug.cgi?id={0}'.format(bug.id)

                ticket.add_comment(text)
                bz.add_to_see_also(bug, ticket)
                bz.upload_attachments(bug, ticket)
def main():
    for group in types:
        for ticket in sf.iter_tickets(group):
            if ticket.is_not_closed():
                bug = bz.create_bug(b, ticket)
                text = 'This ticket has been moved to ' \
                       'https://bugzilla.wikimedia.org/show_bug.cgi?id={0}'.format(bug.id)

                ticket.add_comment(text)
                bz.add_to_see_also(bug, ticket)
                bz.upload_attachments(bug, ticket)
                if len(ticket.labels()) > 1:
                    logging.warn('Ticket: {0} (now bug {1}) had multiple labels'.format(ticket.human_url(), bug.id))
def bzexport(ui, repo, *args, **opts):
    """
    Export changesets to bugzilla attachments.

    The -e option may be used to bring up an editor that will allow editing all
    fields of the attachment and bug (if creating one).

    The --new option may be used to create a new bug rather than using an
    existing bug. See the newbug command for details.

    The -u (--update) option is equivalent to setting both 'update-patch'
    and 'rename-patch' to True in the [bzexport] section of your config file.
    """
    auth, api_server, bugzilla = bugzilla_info(ui, opts.get('ffprofile'))

    rev, bug = infer_arguments(ui, repo, args, opts)

    if not opts['new']:
        for o in ('cc', 'depends', 'blocks'):
            if opts[o]:
                ui.write("Warning: ignoring --%s option when not creating a bug\n" % o)

    contents = StringIO()
    diffopts = patch.diffopts(ui, opts)
    context = ui.config("bzexport", "unified", ui.config("diff", "unified", None))
    if context:
        diffopts.context = int(context)
    if rev in repo:
        description_from_patch = repo[rev].description().decode('utf-8')
        if hasattr(cmdutil, "export"):
            cmdutil.export(repo, [rev], fp=contents, opts=diffopts)
        else:
            # Support older hg versions
            patch.export(repo, [rev], fp=contents, opts=diffopts)
    else:
        q = repo.mq
        contents = q.opener(q.lookup(rev), "r")
        description_from_patch = '\n'.join(mq.patchheader(q.join(rev), q.plainmode).message)

    # Just always use the rev name as the patch name. Doesn't matter much,
    # unless you want to avoid obsoleting existing patches when uploading a
    # version that doesn't include whitespace changes.
    filename = rev
    if opts['ignore_all_space']:
        filename += "_ws"

    patch_comment = None
    reviewers = []
    orig_desc = opts['description'] or description_from_patch
    if not orig_desc or orig_desc.startswith('[mq]'):
        desc = '<required>'
    else:
        # Lightly reformat changeset messages into attachment descriptions.
        # Only use the first line of the provided description for our actual
        # description - use the rest for the patch/bug comment.
        parts = orig_desc.split('\n', 1)
        firstline = parts[0]
        if len(parts) == 2:
            patch_comment = parts[1].strip()

        # Attempt to split the firstline into a bug number, and strip()ed
        # description with that bug number string removed.
        desc_bug_number, desc = extract_bug_num_and_desc(firstline)

        # Failing that try looking in the commit description for a bug number,
        # since orig_desc could have come from the command line instead.
        if not desc_bug_number:
            commit_firstline = description_from_patch.split('\n', 1)[0]
            desc_bug_number, __ = extract_bug_num_and_desc(commit_firstline)

        if desc_bug_number:
            if bug and bug != desc_bug_number:
                ui.warn("Warning: Bug number %s from commandline doesn't match "
                        "bug number %s from changeset description\n"
                        % (bug, desc_bug_number))
            else:
                bug = desc_bug_number

        # Strip any remaining leading separator and whitespace,
        # if the original was something like "bug NNN - "
        if desc[0] in ['-', ':', '.']:
            desc = desc[1:].lstrip()

        # Next strip off review and approval annotations, grabbing the
        # reviewers from the patch comments only if -r auto was given
        def grab_reviewer(m):
            if opts['review'] == 'auto':
                reviewers.append(m.group(1))
            return ''
        desc = review_re.sub(grab_reviewer, desc).rstrip()

        # Strip any trailing separators, if the original was something like:
        # "Desc; r=foo" or "Desc. r=foo"
        if desc and desc[-1] in (';', '.'):
            desc = desc[:-1].rstrip()

        if len(reviewers) > 0:
            opts['review'] = ''

    attachment_comment = opts['comment']
    bug_comment = opts['bug_description']

    if not attachment_comment:
        # New bugs get first shot at the patch comment
        if not opts['new'] or bug_comment:
            attachment_comment = patch_comment

    if not bug_comment and opts['new']:
        bug_comment = patch_comment

    if opts["review"]:
        search_strings = opts["review"].split(",")
        valid_users = validate_users(ui, api_server, auth, search_strings, multi_user_prompt, 'reviewer')
        reviewers = select_users(valid_users, search_strings)
    elif len(reviewers) > 0:
        # Pulled reviewers out of commit message
        valid_users = validate_users(ui, api_server, auth, reviewers, multi_user_prompt, 'reviewer')
        reviewers = select_users(valid_users, reviewers)

    if reviewers is None:
        raise util.Abort(_("Invalid reviewers"))

    feedback = []
    if opts["feedback"]:
        search_strings = opts["feedback"].split(",")
        valid_users = validate_users(ui, api_server, auth, search_strings, multi_user_prompt, 'feedback from')
        feedback = select_users(valid_users, search_strings)

    values = {'BUGNUM': bug,
              'ATTACHMENT_FILENAME': filename,
              'ATTACHMENT_DESCRIPTION': desc,
              'ATTACHCOMMENT': attachment_comment,
              'REVIEWERS': reviewers,
              'FEEDBACK': feedback,
              }

    cc = []
    depends = opts["depends"].split(",")
    blocks = opts["blocks"].split(",")
    if opts['new']:
        if opts["cc"]:
            search_strings = opts["cc"].split(",")
            valid_users = validate_users(ui, api_server, auth, search_strings, multi_user_prompt, 'CC')
            cc = select_users(valid_users, search_strings)

        values['BUGTITLE'] = opts['title'] or desc
        values['PRODUCT'] = opts.get('product', '') or ui.config("bzexport", "product", '<choose-from-menu>')
        values['COMPONENT'] = opts.get('component', '') or ui.config("bzexport", "component", '<choose-from-menu>')
        values['PRODVERSION'] = opts.get('prodversion', '') or ui.config("bzexport", "prodversion", '<default>')
        values['BUGCOMMENT0'] = bug_comment
        values['CC'] = cc
        values['BLOCKS'] = blocks
        values['DEPENDS'] = depends

    values = fill_values(values, ui, api_server, finalize=False)

    if opts['edit']:
        if opts['new']:
            values = edit_form(ui, repo, values, 'new_both_template')
        else:
            values = edit_form(ui, repo, values, 'existing_bug_template')
            bug = values['BUGNUM']

        search_strings = []
        for key in ('REVIEWERS', 'CC', 'FEEDBACK'):
            # TODO: Handle <choose-from-menu>
            search_strings.extend(values.get(key, []))
        users = validate_users(ui, api_server, auth, search_strings, multi_user_prompt, 'reviewer')
        if users is None:
            raise util.Abort("Invalid users")

        if 'REVIEWERS' in values:  # Always true
            reviewers = select_users(users, values['REVIEWERS'])
        if 'CC' in values:         # Only when opts['new']
            cc = select_users(users, values['CC'])
        if 'BLOCKS' in values:     # Only when opts['new']
            blocks = values['BLOCKS']
        if 'DEPENDS' in values:    # Only when opts['new']
            depends = values['DEPENDS']
        if 'FEEDBACK' in values:   # Always true
            feedback = select_users(users, values['FEEDBACK'])
        if 'ATTACHMENT_FILENAME' in values:
            filename = values['ATTACHMENT_FILENAME']

    values = fill_values(values, ui, api_server, finalize=True)

    if opts["new"]:
        if bug is not None:
            raise util.Abort("Bug %s given but creation of new bug requested!" % bug)

        if opts['interactive'] and ui.prompt(_("Create bug in '%s' :: '%s' (y/n)?") %
                                             (values['PRODUCT'], values['COMPONENT'])) != 'y':
            ui.write(_("Exiting without creating bug\n"))
            return

        try:
            create_opts = {}
            if not opts['no_take_bug']:
                create_opts['assign_to'] = auth.username(api_server)
            result = bz.create_bug(auth,
                                product=values['PRODUCT'],
                                component=values['COMPONENT'],
                                version=values['PRODVERSION'],
                                title=values['BUGTITLE'],
                                description=values['BUGCOMMENT0'],
                                cc=cc,
                                depends=depends,
                                blocks=blocks,
                                **create_opts)
            bug = result['id']
            ui.write("Created bug %s at %sshow_bug.cgi?id=%s\n" % (bug, bugzilla, bug))
        except Exception, e:
            raise util.Abort(_("Error creating bug: %s\n" % str(e)))
def newbug(ui, repo, *args, **opts):
    """
    Create a new bug in bugzilla

    A menu will be displayed for the product and component unless a default has
    been set in the [bzexport] section of the config file (keys are 'product'
    and 'component'), or if something has been specified on the command line.

    The -e option brings up an editor that will allow editing all handled
    fields of the bug.

    The product and/or component given on the command line or the edited form
    may be case-insensitive substrings rather than exact matches of valid
    values. Ambiguous matches will be resolved with a menu. The -C
    (--component) option may be used to set both the product and component by
    separating them with a double colon ('::'), though usually just giving the
    component should be sufficient.
    """
    auth, api_server, bugzilla = bugzilla_info(ui, opts.get('ffprofile'))

    if args:
        args = list(args)

    if args and not opts['title']:
        opts['title'] = args.pop(0)
    if args and not opts['comment']:
        opts['comment'] = args.pop(0)
    if args:
        raise util.Abort(_("Too many arguments to newbug command (only title and comment may be given)"))

    bug_comment = opts['comment'] or '<required>'

    values = {'BUGTITLE': opts['title'] or '<required>',
              'PRODUCT': opts.get('product', '') or ui.config("bzexport", "product", '<choose-from-menu>'),
              'COMPONENT': opts.get('component', '') or ui.config("bzexport", "component", '<choose-from-menu>'),
              'PRODVERSION': opts.get('prodversion', '') or ui.config("bzexport", "prodversion", '<default>'),
              'BUGCOMMENT0': bug_comment,
              'CC': [cc for cc in opts.get('cc', '').split(',') if cc],
              'DEPENDS': opts["depends"].split(","),
              'BLOCKS': opts["blocks"].split(","),
              }

    fill_values(values, ui, api_server, finalize=False)

    if opts['edit']:
        values = edit_form(ui, repo, values, 'new_bug_template')

    fill_values(values, ui, api_server, finalize=True)

    cc = validate_users(ui, api_server, auth, values['CC'], multi_user_prompt, 'reviewer')
    if cc is None:
        raise util.Abort("Invalid users")
    cc = select_users(cc, values['CC'])

    if opts['interactive'] and ui.prompt(_("Create bug in '%s' :: '%s' (y/n)?") %
                                         (values['PRODUCT'], values['COMPONENT'])) != 'y':
        ui.write(_("Exiting without creating bug\n"))
        return

    create_opts = {}
    if opts['take_bug']:
        create_opts['assign_to'] = auth.username(api_server)

    try:
        result = bz.create_bug(auth,
                            product=values['PRODUCT'],
                            component=values['COMPONENT'],
                            version=values['PRODVERSION'],
                            title=values['BUGTITLE'],
                            description=values['BUGCOMMENT0'],
                            cc=cc,
                            depends=values['DEPENDS'],
                            blocks=values['BLOCKS'],
                            **create_opts)
    except Exception as e:
        raise util.Abort('error creating bug: %s' % e.message)

    bug = result['id']
    ui.write("Created bug %s at %sshow_bug.cgi?id=%s\n" % (bug, bugzilla, bug))
def bzexport(ui, repo, *args, **opts):
    """
    Export changesets to bugzilla attachments.

    The -e option may be used to bring up an editor that will allow editing all
    fields of the attachment and bug (if creating one).

    The --new option may be used to create a new bug rather than using an
    existing bug. See the newbug command for details.

    The -u (--update) option is equivalent to setting both 'update-patch'
    and 'rename-patch' to True in the [bzexport] section of your config file.
    """
    auth, api_server, bugzilla = bugzilla_info(ui, opts.get('ffprofile'))

    rev, bug = infer_arguments(ui, repo, args, opts)

    if not opts['new']:
        for o in ('cc', 'depends', 'blocks'):
            if opts[o]:
                ui.write(
                    "Warning: ignoring --%s option when not creating a bug\n" %
                    o)

    contents = StringIO()
    diffopts = patch.diffopts(ui, opts)
    context = ui.config("bzexport", "unified",
                        ui.config("diff", "unified", None))
    if context:
        diffopts.context = int(context)
    if rev in repo:
        description_from_patch = repo[rev].description().decode('utf-8')
        if hasattr(cmdutil, "export"):
            cmdutil.export(repo, [rev], fp=contents, opts=diffopts)
        else:
            # Support older hg versions
            patch.export(repo, [rev], fp=contents, opts=diffopts)
    else:
        q = repo.mq
        contents = q.opener(q.lookup(rev), "r")
        description_from_patch = '\n'.join(
            mq.patchheader(q.join(rev), q.plainmode).message)

    # Just always use the rev name as the patch name. Doesn't matter much,
    # unless you want to avoid obsoleting existing patches when uploading a
    # version that doesn't include whitespace changes.
    filename = rev
    if opts['ignore_all_space']:
        filename += "_ws"

    patch_comment = None
    reviewers = []
    orig_desc = opts['description'] or description_from_patch
    if not orig_desc or orig_desc.startswith('[mq]'):
        desc = '<required>'
    else:
        # Lightly reformat changeset messages into attachment descriptions.
        # Only use the first line of the provided description for our actual
        # description - use the rest for the patch/bug comment.
        parts = orig_desc.split('\n', 1)
        firstline = parts[0]
        if len(parts) == 2:
            patch_comment = parts[1].strip()

        # Attempt to split the firstline into a bug number, and strip()ed
        # description with that bug number string removed.
        desc_bug_number, desc = extract_bug_num_and_desc(firstline)

        # Failing that try looking in the commit description for a bug number,
        # since orig_desc could have come from the command line instead.
        if not desc_bug_number:
            commit_firstline = description_from_patch.split('\n', 1)[0]
            desc_bug_number, __ = extract_bug_num_and_desc(commit_firstline)

        if desc_bug_number:
            if bug and bug != desc_bug_number:
                ui.warn(
                    "Warning: Bug number %s from commandline doesn't match "
                    "bug number %s from changeset description\n" %
                    (bug, desc_bug_number))
            else:
                bug = desc_bug_number

        # Strip any remaining leading separator and whitespace,
        # if the original was something like "bug NNN - "
        if desc[0] in ['-', ':', '.']:
            desc = desc[1:].lstrip()

        # Next strip off review and approval annotations, grabbing the
        # reviewers from the patch comments only if -r auto was given
        def grab_reviewer(m):
            if opts['review'] == 'auto':
                reviewers.append(m.group(1))
            return ''

        desc = review_re.sub(grab_reviewer, desc).rstrip()

        # Strip any trailing separators, if the original was something like:
        # "Desc; r=foo" or "Desc. r=foo"
        if desc and desc[-1] in (';', '.'):
            desc = desc[:-1].rstrip()

        if len(reviewers) > 0:
            opts['review'] = ''

    attachment_comment = opts['comment']
    bug_comment = opts['bug_description']

    if not attachment_comment:
        # New bugs get first shot at the patch comment
        if not opts['new'] or bug_comment:
            attachment_comment = patch_comment

    if not bug_comment and opts['new']:
        bug_comment = patch_comment

    if opts["review"]:
        search_strings = opts["review"].split(",")
        valid_users = validate_users(ui, api_server, auth, search_strings,
                                     multi_user_prompt, 'reviewer')
        reviewers = select_users(valid_users, search_strings)
    elif len(reviewers) > 0:
        # Pulled reviewers out of commit message
        valid_users = validate_users(ui, api_server, auth, reviewers,
                                     multi_user_prompt, 'reviewer')
        reviewers = select_users(valid_users, reviewers)

    if reviewers is None:
        raise util.Abort(_("Invalid reviewers"))

    feedback = []
    if opts["feedback"]:
        search_strings = opts["feedback"].split(",")
        valid_users = validate_users(ui, api_server, auth, search_strings,
                                     multi_user_prompt, 'feedback from')
        feedback = select_users(valid_users, search_strings)

    values = {
        'BUGNUM': bug,
        'ATTACHMENT_FILENAME': filename,
        'ATTACHMENT_DESCRIPTION': desc,
        'ATTACHCOMMENT': attachment_comment,
        'REVIEWERS': reviewers,
        'FEEDBACK': feedback,
    }

    cc = []
    depends = opts["depends"].split(",")
    blocks = opts["blocks"].split(",")
    if opts['new']:
        if opts["cc"]:
            search_strings = opts["cc"].split(",")
            valid_users = validate_users(ui, api_server, auth, search_strings,
                                         multi_user_prompt, 'CC')
            cc = select_users(valid_users, search_strings)

        values['BUGTITLE'] = opts['title'] or desc
        values['PRODUCT'] = opts.get('product', '') or ui.config(
            "bzexport", "product", '<choose-from-menu>')
        values['COMPONENT'] = opts.get('component', '') or ui.config(
            "bzexport", "component", '<choose-from-menu>')
        values['PRODVERSION'] = opts.get('prodversion', '') or ui.config(
            "bzexport", "prodversion", '<default>')
        values['BUGCOMMENT0'] = bug_comment
        values['CC'] = cc
        values['BLOCKS'] = blocks
        values['DEPENDS'] = depends

    values = fill_values(values, ui, api_server, finalize=False)

    if opts['edit']:
        if opts['new']:
            values = edit_form(ui, repo, values, 'new_both_template')
        else:
            values = edit_form(ui, repo, values, 'existing_bug_template')
            bug = values['BUGNUM']

        search_strings = []
        for key in ('REVIEWERS', 'CC', 'FEEDBACK'):
            # TODO: Handle <choose-from-menu>
            search_strings.extend(values.get(key, []))
        users = validate_users(ui, api_server, auth, search_strings,
                               multi_user_prompt, 'reviewer')
        if users is None:
            raise util.Abort("Invalid users")

        if 'REVIEWERS' in values:  # Always true
            reviewers = select_users(users, values['REVIEWERS'])
        if 'CC' in values:  # Only when opts['new']
            cc = select_users(users, values['CC'])
        if 'BLOCKS' in values:  # Only when opts['new']
            blocks = values['BLOCKS']
        if 'DEPENDS' in values:  # Only when opts['new']
            depends = values['DEPENDS']
        if 'FEEDBACK' in values:  # Always true
            feedback = select_users(users, values['FEEDBACK'])
        if 'ATTACHMENT_FILENAME' in values:
            filename = values['ATTACHMENT_FILENAME']

    values = fill_values(values, ui, api_server, finalize=True)

    if opts["new"]:
        if bug is not None:
            raise util.Abort(
                "Bug %s given but creation of new bug requested!" % bug)

        if opts['interactive'] and ui.prompt(
                _("Create bug in '%s' :: '%s' (y/n)?") %
            (values['PRODUCT'], values['COMPONENT'])) != 'y':
            ui.write(_("Exiting without creating bug\n"))
            return

        try:
            create_opts = {}
            if not opts['no_take_bug']:
                create_opts['assign_to'] = auth.username(api_server)
            result = bz.create_bug(auth,
                                   product=values['PRODUCT'],
                                   component=values['COMPONENT'],
                                   version=values['PRODVERSION'],
                                   title=values['BUGTITLE'],
                                   description=values['BUGCOMMENT0'],
                                   cc=cc,
                                   depends=depends,
                                   blocks=blocks,
                                   **create_opts)
            bug = result['id']
            ui.write("Created bug %s at %sshow_bug.cgi?id=%s\n" %
                     (bug, bugzilla, bug))
        except Exception, e:
            raise util.Abort(_("Error creating bug: %s\n" % str(e)))
def newbug(ui, repo, *args, **opts):
    """
    Create a new bug in bugzilla

    A menu will be displayed for the product and component unless a default has
    been set in the [bzexport] section of the config file (keys are 'product'
    and 'component'), or if something has been specified on the command line.

    The -e option brings up an editor that will allow editing all handled
    fields of the bug.

    The product and/or component given on the command line or the edited form
    may be case-insensitive substrings rather than exact matches of valid
    values. Ambiguous matches will be resolved with a menu. The -C
    (--component) option may be used to set both the product and component by
    separating them with a double colon ('::'), though usually just giving the
    component should be sufficient.
    """
    auth, api_server, bugzilla = bugzilla_info(ui, opts.get('ffprofile'))

    if args:
        args = list(args)

    if args and not opts['title']:
        opts['title'] = args.pop(0)
    if args and not opts['comment']:
        opts['comment'] = args.pop(0)
    if args:
        raise util.Abort(
            _("Too many arguments to newbug command (only title and comment may be given)"
              ))

    bug_comment = opts['comment'] or '<required>'

    values = {
        'BUGTITLE':
        opts['title'] or '<required>',
        'PRODUCT':
        opts.get('product', '')
        or ui.config("bzexport", "product", '<choose-from-menu>'),
        'COMPONENT':
        opts.get('component', '')
        or ui.config("bzexport", "component", '<choose-from-menu>'),
        'PRODVERSION':
        opts.get('prodversion', '')
        or ui.config("bzexport", "prodversion", '<default>'),
        'BUGCOMMENT0':
        bug_comment,
        'CC': [cc for cc in opts.get('cc', '').split(',') if cc],
        'DEPENDS':
        opts["depends"].split(","),
        'BLOCKS':
        opts["blocks"].split(","),
    }

    fill_values(values, ui, api_server, finalize=False)

    if opts['edit']:
        values = edit_form(ui, repo, values, 'new_bug_template')

    fill_values(values, ui, api_server, finalize=True)

    cc = validate_users(ui, api_server, auth, values['CC'], multi_user_prompt,
                        'reviewer')
    if cc is None:
        raise util.Abort("Invalid users")
    cc = select_users(cc, values['CC'])

    if opts['interactive'] and ui.prompt(
            _("Create bug in '%s' :: '%s' (y/n)?") %
        (values['PRODUCT'], values['COMPONENT'])) != 'y':
        ui.write(_("Exiting without creating bug\n"))
        return

    create_opts = {}
    if opts['take_bug']:
        create_opts['assign_to'] = auth.username(api_server)

    try:
        result = bz.create_bug(auth,
                               product=values['PRODUCT'],
                               component=values['COMPONENT'],
                               version=values['PRODVERSION'],
                               title=values['BUGTITLE'],
                               description=values['BUGCOMMENT0'],
                               cc=cc,
                               depends=values['DEPENDS'],
                               blocks=values['BLOCKS'],
                               **create_opts)
    except Exception as e:
        raise util.Abort('error creating bug: %s' % e.message)

    bug = result['id']
    ui.write("Created bug %s at %sshow_bug.cgi?id=%s\n" % (bug, bugzilla, bug))