Esempio n. 1
0
    def update_revision(self, revisionid, raw_diff, message):
        """Update an existing Differential revision with a new diff.

        :revisionid: id of the Differential revision to update
        :raw_diff: raw output string from e.g. 'git diff master...'
        :message: string message to annotate the update event with
        :returns: None

        """
        # do some sanity checks before committing to the expensive operation
        # of storing a diff in Differential
        state = self._reviewstate_cache.get_state(revisionid)
        if state.status == phlcon_differential.ReviewStates.closed:
            raise abdt_exception.AbdUserException(
                "can't update a closed revision")

        author_user = self._get_author_user(revisionid)
        as_user_conduit = self._make_as_user_conduit(author_user)

        with self._log_context(
                'conduit-updaterev',
                'update {} as {}'.format(revisionid, author_user)):

            diffid = phlcon_differential.create_raw_diff(
                as_user_conduit, raw_diff).id
            try:
                phlcon_differential.update_revision(as_user_conduit,
                                                    revisionid, diffid, [],
                                                    message)
            except phlcon_differential.UpdateClosedRevisionError:
                raise abdt_exception.AbdUserException(
                    "CONDUIT: can't update a closed revision")
def getPrimaryUserDetailsFromBranch(conduit, branch):
    """Return a tuple representing the primary user on the supplied 'branch'.

    The primary user is currently determined from the latest user to commit
    on the branch but this may change later.

    :conduit: an abdt_conduit
    :branch: an abdt_branch
    :returns: a (name, email, username, phid) tuple

    """
    names_emails = branch.get_author_names_emails()
    if not names_emails:
        raise abdt_exception.NoHistoryException(
            branch.review_branch_name(),
            branch.base_branch_name())
    committer = names_emails[-1]
    name = committer[0]
    email = committer[1]
    found_user = conduit.query_name_and_phid_from_email(email)
    if found_user is None:
        raise abdt_exception.AbdUserException(
            "first committer is not a Phabricator user")
    user, phid = found_user
    return name, email, user, phid
    def update_revision(self, revisionid, raw_diff, message):
        """Update an existing Differential revision with a new diff.

        :revisionid: id of the Differential revision to update
        :raw_diff: raw output string from e.g. 'git diff master...'
        :message: string message to annotate the update event with
        :returns: None

        """
        revision = self._data.get_revision(revisionid)

        assert raw_diff
        assert message

        # match the behaviour asserted by phlcon_differential__t,
        # we can't update a closed review, that's an error
        if revision.is_closed():
            raise abdt_exception.AbdUserException(
                "can't update a closed revision")

        # match the behaviour asserted by phlcon_differential__t, 'accepted' is
        # a sticky state as far as updating the review is concerned
        if not revision.is_accepted():
            revision.set_in_review()

        self._data.set_changed()
Esempio n. 4
0
def update_in_review(conduit, branch):
    _LOGGER.debug("update_in_review")

    _LOGGER.debug("- creating diff")
    diff_result = branch.make_raw_diff()

    if not diff_result.diff:
        raise abdt_exception.AbdUserException("no difference to review")

    user_warnings = []
    if diff_result.reduction_list:
        user_warnings.append(abdt_userwarning.LargeDiff(diff_result))

    review_id = branch.review_id_or_none()
    review_id_str = str(review_id)

    _LOGGER.debug("- updating revision {}".format(review_id_str))
    conduit.update_revision(
        review_id, diff_result.diff,
        'update\n\n``` lang=text\n' + branch.describe_new_commits() + '```')

    branch.mark_ok_in_review()

    _LOGGER.debug("- commenting on revision {}".format(review_id_str))
    commenter = abdcmnt_commenter.Commenter(conduit, review_id)
    commenter.updatedReview(branch.review_branch_hash(),
                            branch.review_branch_name())
    if user_warnings:
        commenter.userWarnings(user_warnings)
Esempio n. 5
0
 def verify_review_branch_base(self):
     """Raise exception if review branch has invalid base."""
     if self._review_branch.base not in self._repo.get_remote_branches():
         raise abdt_exception.MissingBaseException(
             self._review_branch.branch, self._review_branch.description,
             self._review_branch.base)
     if not self._is_based_on(self._review_branch.branch,
                              self._review_branch.base):
         raise abdt_exception.AbdUserException("'" +
                                               self._review_branch.branch +
                                               "' is not based on '" +
                                               self._review_branch.base +
                                               "'")
Esempio n. 6
0
def create_review(conduit, branch):
    branch.verify_review_branch_base()

    # TODO: we should also cc other users on the branch
    # TODO: if there are emails that don't match up to users then we should
    #       note that on the review and perhaps use the mailer to notify them
    name, email, user, phid = abdt_conduitgit.getPrimaryUserDetailsFromBranch(
        conduit, branch)

    _LOGGER.debug("- author: {}".format(user))

    user_warnings = []

    message = branch.get_commit_message_from_tip()

    try:
        parsed = conduit.parse_commit_message(message)
    except phlcon_differential.UnknownParseCommitMessageResponseError as e:
        raise abdt_exception.CommitMessageParseException(errors=[e],
                                                         fields=[],
                                                         digest=message)

    d = phlcon_differential
    if parsed.errors:
        error_list = phlcon_differential.parse_commit_message_errors(
            parsed.errors)
        for error in error_list:
            if isinstance(error, d.ParseCommitMessageNoTestPlanFail):
                parsed.fields["testPlan"] = _DEFAULT_TEST_PLAN
                user_warnings.append(
                    abdt_userwarning.UsedDefaultTestPlan(_DEFAULT_TEST_PLAN))
            elif isinstance(error, d.ParseCommitMessageUnknownReviewerFail):
                user_warnings.append(
                    abdt_userwarning.UnknownReviewers(error.user_list,
                                                      message))
            else:
                raise abdt_exception.CommitMessageParseException(
                    errors=parsed.errors,
                    fields=parsed.fields,
                    digest=branch.make_message_digest())

    # remove the author from reviewer list if present
    reviewer_phids_key = phlcon_differential.MessageFields.reviewer_phids
    if reviewer_phids_key in parsed.fields:
        reviewer_phids = parsed.fields[reviewer_phids_key]
        if phid in reviewer_phids:
            reviewer_phids.remove(phid)
            user_warnings.append(abdt_userwarning.SelfReviewer(user, message))

    diff_result = branch.make_raw_diff()
    raw_diff = diff_result.diff

    if not raw_diff:
        raise abdt_exception.AbdUserException("no difference to review")

    if diff_result.reduction_list:
        user_warnings.append(abdt_userwarning.LargeDiff(diff_result))

    revisionid = create_differential_review(conduit, user, parsed, branch,
                                            raw_diff)

    commenter = abdcmnt_commenter.Commenter(conduit, revisionid)

    if user_warnings:
        commenter.userWarnings(user_warnings)