def update_in_review(conduit, branch):
    print "update_in_review"

    print "- 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)

    print "- updating revision " + 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()

    print "- commenting on revision " + 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)

    abdt_logging.on_review_event(
        'updaterev', '{} updated {}'.format(
            branch.review_branch_name(), review_id))
def update_in_review(conduit, branch):
    print "update_in_review"

    print "- creating diff"
    rawDiff = branch.make_raw_diff()

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

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

    print "- updating revision " + review_id_str
    conduit.update_revision(
        review_id,
        rawDiff,
        'update\n\n``` lang=text\n' + branch.describe_new_commits() + '```')

    branch.mark_ok_in_review()

    print "- commenting on revision " + review_id_str
    commenter = abdcmnt_commenter.Commenter(conduit, review_id)
    commenter.updatedReview(
        branch.review_branch_hash(),
        branch.review_branch_name())

    abdt_logging.on_review_event(
        'updaterev', '{} updated {}'.format(
            branch.review_branch_name(), review_id))
def land(conduit, branch):
    print "landing " + branch.review_branch_name()

    review_branch_name = branch.review_branch_name()
    base_branch_name = branch.base_branch_name()

    names_emails = branch.get_author_names_emails()
    if not names_emails:
        raise abdt_exception.LandingException(
            "no commits on branch", review_branch_name, base_branch_name)

    # pick the last author as the author for landing
    name, email = names_emails[-1]

    review_id = branch.review_id_or_none()

    # store the branch hash now, the branch will be invalid after landing
    review_branch_hash = branch.review_branch_hash()

    # compose the commit message
    message = conduit.get_commit_message(review_id)

    land_message = branch.land(name, email, message)

    print "- commenting on revision " + str(review_id)
    commenter = abdcmnt_commenter.Commenter(conduit, review_id)
    commenter.landedReview(
        review_branch_hash,
        review_branch_name,
        base_branch_name,
        land_message)

    conduit.close_revision(review_id)

    abdt_logging.on_review_event(
        'landrev', '{} landed {}, {}'.format(
            name, review_id, review_branch_name))
def create_review(conduit, branch, plugin_manager):
    plugin_manager.hook(
        "before_create_review",
        {"conduit": conduit, "branch": 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)

    print "- author: " + user

    user_warnings = []

    message = branch.get_commit_message_from_tip()
    parsed = conduit.parse_commit_message(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)

    plugin_manager.hook(
        "after_create_review",
        {"parsed": parsed, "conduit": conduit, "branch": branch,
            "rawDiff": raw_diff, "commenter": commenter}
    )

    abdt_logging.on_review_event(
        'createrev', '{} created {} from {}'.format(
            user, revisionid, branch.review_branch_name()))