Example #1
0
    def diffstat(self):
        class patchbuf(object):
            def __init__(self):
                self.lines = []
                # diffstat is stupid
                self.name = 'cia'
            def write(self, data):
                self.lines.append(data)
            def close(self):
                pass

        n = self.ctx.node()
        pbuf = patchbuf()
        patch.export(self.cia.repo, [n], fp=pbuf)
        return patch.diffstat(pbuf.lines) or ''
Example #2
0
    def diffstat(self):
        class patchbuf(object):
            def __init__(self):
                self.lines = []
                # diffstat is stupid
                self.name = 'cia'
            def write(self, data):
                self.lines.append(data)
            def close(self):
                pass

        n = self.ctx.node()
        pbuf = patchbuf()
        patch.export(self.cia.repo, [n], fp=pbuf)
        return patch.diffstat(pbuf.lines) or ''
Example #3
0
def export(repo, revs, template='hg-%h.patch', fp=None, switch_parent=False,
           opts=None):
    '''
    export changesets as hg patches.

    Mercurial moved patch.export to cmdutil.export after version 1.5
    (change e764f24a45ee in mercurial).
    '''

    try:
        return cmdutil.export(repo, revs, template, fp, switch_parent, opts)
    except AttributeError:
        from mercurial import patch
        return patch.export(repo, revs, template, fp, switch_parent, opts)
Example #4
0
def export(repo,
           revs,
           template='hg-%h.patch',
           fp=None,
           switch_parent=False,
           opts=None):
    '''
    export changesets as hg patches.

    Mercurial moved patch.export to cmdutil.export after version 1.5
    (change e764f24a45ee in mercurial).
    '''

    try:
        return cmdutil.export(repo, revs, template, fp, switch_parent, opts)
    except AttributeError:
        from mercurial import patch
        return patch.export(repo, revs, template, fp, switch_parent, opts)
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)))
Example #6
0
 def getpatches(revs):
     for r in cmdutil.revrange(repo, revs):
         output = cStringIO.StringIO()
         patch.export(repo, [r], fp=output,
                      opts=patch.diffopts(ui, opts))
         yield output.getvalue().split('\n')
Example #7
0
 def getpatches(revs):
     for r in cmdutil.revrange(repo, revs):
         output = cStringIO.StringIO()
         patch.export(repo, [r], fp=output, opts=patch.diffopts(ui, opts))
         yield output.getvalue().split('\n')
Example #8
0
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)))