Ejemplo n.º 1
0
    def guess_existing_review_request_id(self, repository_info, api_root,
                                         api_client):
        """Try to guess the existing review request ID if it is available.

        The existing review request is guessed by comparing the existing
        summary and description to the current post's summary and description,
        respectively. The current post's summary and description are guessed if
        they are not provided.

        If the summary and description exactly match those of an existing
        review request, the ID for which is immediately returned. Otherwise,
        the user is prompted to select from a list of potential matches,
        sorted by the highest ranked match first.
        """
        user = get_user(api_client, api_root, auth_required=True)
        repository_id = get_repository_id(
            repository_info, api_root, self.options.repository_name)

        try:
            # Get only pending requests by the current user for this
            # repository.
            review_requests = api_root.get_review_requests(
                repository=repository_id, from_user=user.username,
                status='pending', expand='draft')

            if not review_requests:
                raise CommandError('No existing review requests to update for '
                                   'user %s.'
                                   % user.username)
        except APIError, e:
            raise CommandError('Error getting review requests for user '
                               '%s: %s' % (user.username, e))
Ejemplo n.º 2
0
    def guess_existing_review_request_id(self, repository_info, api_root,
                                         api_client):
        """Try to guess the existing review request ID if it is available.

        The existing review request is guessed by comparing the existing
        summary and description to the current post's summary and description,
        respectively. The current post's summary and description are guessed if
        they are not provided.

        If the summary and description exactly match those of an existing
        review request, the ID for which is immediately returned. Otherwise,
        the user is prompted to select from a list of potential matches,
        sorted by the highest ranked match first.
        """
        user = get_user(api_client, api_root, auth_required=True)
        repository_id = get_repository_id(
            repository_info, api_root, self.options.repository_name)

        try:
            # Get only pending requests by the current user for this
            # repository.
            review_requests = api_root.get_review_requests(
                repository=repository_id, from_user=user.username,
                status='pending', expand='draft')

            if not review_requests:
                raise CommandError('No existing review requests to update for '
                                   'user %s.'
                                   % user.username)
        except APIError, e:
            raise CommandError('Error getting review requests for user '
                               '%s: %s' % (user.username, e))
Ejemplo n.º 3
0
    def main(self):
        repository_info, tool = self.initialize_scm_tool(
            client_name=self.options.repository_type)
        server_url = self.get_server_url(repository_info, tool)
        api_client, api_root = self.get_api(server_url)
        self.setup_tool(tool, api_root=api_root)
        username = get_username(api_client, api_root, auth_required=True)

        # Check if repository info on reviewboard server match local ones.
        repository_info = repository_info.find_server_repository_info(api_root)

        query_args = {
            'from_user': username,
            'status': 'pending',
            'expand': 'draft',
        }

        if not self.options.all_repositories:
            repo_id = get_repository_id(
                repository_info,
                api_root,
                repository_name=self.options.repository_name)

            if repo_id:
                query_args['repository'] = repo_id
            else:
                logging.warning('The repository detected in the current '
                                'directory was not found on\n'
                                'the Review Board server. Displaying review '
                                'requests from all repositories.')

        requests = api_root.get_review_requests(**query_args)
        request_stats = self.get_data(requests)
        self.tabulate(request_stats)
Ejemplo n.º 4
0
    def main(self):
        repository_info, tool = self.initialize_scm_tool(
            client_name=self.options.repository_type)
        server_url = self.get_server_url(repository_info, tool)
        api_client, api_root = self.get_api(server_url)
        self.setup_tool(tool, api_root=api_root)
        username = get_username(api_client, api_root, auth_required=True)

        # Check if repository info on reviewboard server match local ones.
        repository_info = repository_info.find_server_repository_info(api_root)

        query_args = {
            'from_user': username,
            'status': 'pending',
            'expand': 'draft',
        }

        if not self.options.all_repositories:
            repo_id = get_repository_id(
                repository_info,
                api_root,
                repository_name=self.options.repository_name)

            if repo_id:
                query_args['repository'] = repo_id
            else:
                logging.warning('The repository detected in the current '
                                'directory was not found on\n'
                                'the Review Board server. Displaying review '
                                'requests from all repositories.')

        requests = api_root.get_review_requests(**query_args)
        request_stats = self.get_data(requests)
        self.tabulate(request_stats)
Ejemplo n.º 5
0
def find_review_request_by_change_id(api_client, api_root, repository_info,
                                     repository_name, revisions):
    """Ask ReviewBoard for the review request ID for the tip revision.

    Note that this function calls the ReviewBoard API with the only_fields
    paramater, thus the returned review request will contain only the fields
    specified by the only_fields variable.

    If no review request is found, None will be returned instead.
    """
    only_fields = 'id,commit_id,changenum,status,url,absolute_url'
    change_id = revisions['tip']
    logging.debug(
        'Attempting to find review request from tip revision ID: %s' %
        change_id)
    # Strip off any prefix that might have been added by the SCM.
    change_id = change_id.split(':', 1)[1]

    optional_args = {}

    if change_id.isdigit():
        # Populate integer-only changenum field also for compatibility
        # with older API versions
        optional_args['changenum'] = int(change_id)

    user = get_user(api_client, api_root, auth_required=True)
    repository_id = get_repository_id(repository_info, api_root,
                                      repository_name)

    # Don't limit query to only pending requests because it's okay to stamp a
    # submitted review.
    review_requests = api_root.get_review_requests(repository=repository_id,
                                                   from_user=user.username,
                                                   commit_id=change_id,
                                                   only_links='self',
                                                   only_fields=only_fields,
                                                   **optional_args)

    if review_requests:
        count = review_requests.total_results

        # Only one review can be associated with a specific commit ID.
        if count > 0:
            assert count == 1, '%d review requests were returned' % count
            review_request = review_requests[0]
            logging.debug('Found review request %s with status %s' %
                          (review_request.id, review_request.status))

            if review_request.status != 'discarded':
                return review_request

    return None
Ejemplo n.º 6
0
def find_review_request_by_change_id(api_client, api_root, repository_info,
                                     repository_name, revisions):
    """Ask ReviewBoard for the review request ID for the tip revision.

    Note that this function calls the ReviewBoard API with the only_fields
    paramater, thus the returned review request will contain only the fields
    specified by the only_fields variable.

    If no review request is found, None will be returned instead.
    """
    only_fields = 'id,commit_id,changenum,status,url,absolute_url'
    change_id = revisions['tip']
    logging.debug('Attempting to find review request from tip revision ID: %s',
                  change_id)
    # Strip off any prefix that might have been added by the SCM.
    change_id = change_id.split(':', 1)[1]

    optional_args = {}

    if change_id.isdigit():
        # Populate integer-only changenum field also for compatibility
        # with older API versions
        optional_args['changenum'] = int(change_id)

    user = get_user(api_client, api_root, auth_required=True)
    repository_id = get_repository_id(
        repository_info, api_root, repository_name)

    # Don't limit query to only pending requests because it's okay to stamp a
    # submitted review.
    review_requests = api_root.get_review_requests(repository=repository_id,
                                                   from_user=user.username,
                                                   commit_id=change_id,
                                                   only_links='self',
                                                   only_fields=only_fields,
                                                   **optional_args)

    if review_requests:
        count = review_requests.total_results

        # Only one review can be associated with a specific commit ID.
        if count > 0:
            assert count == 1, '%d review requests were returned' % count
            review_request = review_requests[0]
            logging.debug('Found review request %s with status %s',
                          review_request.id, review_request.status)

            if review_request.status != 'discarded':
                return review_request

    return None
Ejemplo n.º 7
0
    def main(self):
        repository_info, tool = self.initialize_scm_tool(
            client_name=self.options.repository_type)
        server_url = self.get_server_url(repository_info, tool)
        api_client, api_root = self.get_api(server_url)
        self.setup_tool(tool, api_root=api_root)
        user = get_user(api_client, api_root, auth_required=True)

        query_args = {
            'from_user': user.username,
            'status': 'pending',
            'expand': 'draft',
        }

        if not self.options.all_repositories:
            repo_id = get_repository_id(
                repository_info,
                api_root,
                repository_name=self.options.repository_name)

            if repo_id:
                query_args['repository'] = repo_id
            else:
                logging.warning('The repository detected in the current '
                                'directory was not found on\n'
                                'the Review Board server. Displaying review '
                                'requests from all repositories.')

        requests = api_root.get_review_requests(**query_args)

        try:
            while True:
                for request in requests:
                    if request.draft:
                        self.output_draft(request, request.draft[0])
                    else:
                        self.output_request(request)

                requests = requests.get_next(**query_args)
        except StopIteration:
            pass
Ejemplo n.º 8
0
    def main(self):
        repository_info, tool = self.initialize_scm_tool(
            client_name=self.options.repository_type)
        server_url = self.get_server_url(repository_info, tool)
        api_client, api_root = self.get_api(server_url)
        self.setup_tool(tool, api_root=api_root)
        username = get_username(api_client, api_root, auth_required=True)

        query_args = {
            'from_user': username,
            'status': 'pending',
            'expand': 'draft',
        }

        if not self.options.all_repositories:
            repo_id = get_repository_id(
                repository_info,
                api_root,
                repository_name=self.options.repository_name)

            if repo_id:
                query_args['repository'] = repo_id
            else:
                logging.warning('The repository detected in the current '
                                'directory was not found on\n'
                                'the Review Board server. Displaying review '
                                'requests from all repositories.')

        requests = api_root.get_review_requests(**query_args)

        try:
            while True:
                for request in requests:
                    if request.draft:
                        self.output_draft(request, request.draft[0])
                    else:
                        self.output_request(request)

                requests = requests.get_next(**query_args)
        except StopIteration:
            pass
Ejemplo n.º 9
0
def guess_existing_review_request(repository_info, repository_name,
                                  api_root, api_client, tool, revisions,
                                  guess_summary, guess_description,
                                  is_fuzzy_match_func=None,
                                  no_commit_error=None,
                                  submit_as=None, additional_fields=None):
    """Try to guess the existing review request ID if it is available.

    The existing review request is guessed by comparing the existing
    summary and description to the current post's summary and description,
    respectively. The current post's summary and description are guessed if
    they are not provided.

    If the summary and description exactly match those of an existing
    review request, that request is immediately returned. Otherwise,
    the user is prompted to select from a list of potential matches,
    sorted by the highest ranked match first.

    Note that this function calls the ReviewBoard API with the only_fields
    paramater, thus the returned review request will contain only the fields
    specified by the only_fields variable.
    """
    only_fields = [
        'id', 'summary', 'description', 'draft', 'url', 'absolute_url',
        'bugs_closed', 'status', 'public'
    ]

    if additional_fields:
        only_fields += additional_fields

    if submit_as:
        username = submit_as
    else:
        user = get_user(api_client, api_root, auth_required=True)
        username = user.username

    repository_id = get_repository_id(
        repository_info, api_root, repository_name)

    try:
        # Get only pending requests by the current user for this
        # repository.
        review_requests = api_root.get_review_requests(
            repository=repository_id,
            from_user=username,
            status='pending',
            expand='draft',
            only_fields=','.join(only_fields),
            only_links='diffs,draft',
            show_all_unpublished=True)

        if not review_requests:
            raise ValueError('No existing review requests to update for '
                             'user %s'
                             % username)
    except APIError as e:
        raise ValueError('Error getting review requests for user %s: %s'
                         % (username, e))

    summary = None
    description = None

    if not guess_summary or not guess_description:
        try:
            commit_message = tool.get_commit_message(revisions)

            if commit_message:
                if not guess_summary:
                    summary = commit_message['summary']

                if not guess_description:
                    description = commit_message['description']
            elif callable(no_commit_error):
                no_commit_error()
        except NotImplementedError:
            raise ValueError('--summary and --description are required.')

    if not summary and not description:
        return None

    possible_matches = get_possible_matches(review_requests, summary,
                                            description)
    exact_match_count = num_exact_matches(possible_matches)

    for score, review_request in possible_matches:
        # If the score is the only exact match, return the review request
        # ID without confirmation, otherwise prompt.
        if ((score.is_exact_match() and exact_match_count == 1) or
            (callable(is_fuzzy_match_func) and
             is_fuzzy_match_func(review_request))):
            return review_request

    return None
Ejemplo n.º 10
0
def guess_existing_review_request(repository_info,
                                  repository_name,
                                  api_root,
                                  api_client,
                                  tool,
                                  revisions,
                                  guess_summary,
                                  guess_description,
                                  is_fuzzy_match_func=None,
                                  no_commit_error=None,
                                  submit_as=None,
                                  additional_fields=None):
    """Try to guess the existing review request ID if it is available.

    The existing review request is guessed by comparing the existing
    summary and description to the current post's summary and description,
    respectively. The current post's summary and description are guessed if
    they are not provided.

    If the summary and description exactly match those of an existing
    review request, that request is immediately returned. Otherwise,
    the user is prompted to select from a list of potential matches,
    sorted by the highest ranked match first.

    Note that this function calls the ReviewBoard API with the only_fields
    paramater, thus the returned review request will contain only the fields
    specified by the only_fields variable.
    """
    only_fields = [
        'id', 'summary', 'description', 'draft', 'url', 'absolute_url',
        'bugs_closed', 'status', 'public'
    ]

    if additional_fields:
        only_fields += additional_fields

    if submit_as:
        username = submit_as
    else:
        user = get_user(api_client, api_root, auth_required=True)
        username = user.username

    repository_id = get_repository_id(repository_info, api_root,
                                      repository_name)

    try:
        # Get only pending requests by the current user for this
        # repository.
        review_requests = api_root.get_review_requests(
            repository=repository_id,
            from_user=username,
            status='pending',
            expand='draft',
            only_fields=','.join(only_fields),
            only_links='diffs,draft',
            show_all_unpublished=True)

        if not review_requests:
            raise ValueError('No existing review requests to update for '
                             'user %s' % username)
    except APIError as e:
        raise ValueError('Error getting review requests for user %s: %s' %
                         (username, e))

    summary = None
    description = None

    if not guess_summary or not guess_description:
        try:
            commit_message = tool.get_commit_message(revisions)

            if commit_message:
                if not guess_summary:
                    summary = commit_message['summary']

                if not guess_description:
                    description = commit_message['description']
            elif callable(no_commit_error):
                no_commit_error()
        except NotImplementedError:
            raise ValueError('--summary and --description are required.')

    if not summary and not description:
        return None

    possible_matches = get_possible_matches(review_requests, summary,
                                            description)
    exact_match_count = num_exact_matches(possible_matches)

    for score, review_request in possible_matches:
        # If the score is the only exact match, return the review request
        # ID without confirmation, otherwise prompt.
        if ((score.is_exact_match() and exact_match_count == 1)
                or (callable(is_fuzzy_match_func)
                    and is_fuzzy_match_func(review_request))):
            return review_request

    return None
Ejemplo n.º 11
0
def guess_existing_review_request_id(repository_info,
                                     repository_name,
                                     api_root,
                                     api_client,
                                     tool,
                                     revisions,
                                     guess_summary,
                                     guess_description,
                                     is_fuzzy_match_func=None,
                                     no_commit_error=None):
    """Try to guess the existing review request ID if it is available.

    The existing review request is guessed by comparing the existing
    summary and description to the current post's summary and description,
    respectively. The current post's summary and description are guessed if
    they are not provided.

    If the summary and description exactly match those of an existing
    review request, the ID for which is immediately returned. Otherwise,
    the user is prompted to select from a list of potential matches,
    sorted by the highest ranked match first.
    """
    user = get_user(api_client, api_root, auth_required=True)
    repository_id = get_repository_id(repository_info, api_root,
                                      repository_name)

    try:
        # Get only pending requests by the current user for this
        # repository.
        review_requests = api_root.get_review_requests(
            repository=repository_id,
            from_user=user.username,
            status='pending',
            expand='draft')

        if not review_requests:
            raise CommandError('No existing review requests to update for '
                               'user %s.' % user.username)
    except APIError as e:
        raise CommandError('Error getting review requests for user '
                           '%s: %s' % (user.username, e))

    summary = None
    description = None

    if not guess_summary or not guess_description:
        try:
            commit_message = tool.get_commit_message(revisions)

            if commit_message:
                if not guess_summary:
                    summary = commit_message['summary']

                if not guess_description:
                    description = commit_message['description']
            elif callable(no_commit_error):
                no_commit_error()
        except NotImplementedError:
            raise CommandError('--summary and --description are required.')

    if not summary and not description:
        return None

    possible_matches = get_possible_matches(review_requests, summary,
                                            description)
    exact_match_count = num_exact_matches(possible_matches)

    for score, review_request in possible_matches:
        # If the score is the only exact match, return the review request
        # ID without confirmation, otherwise prompt.
        if ((score.is_exact_match() and exact_match_count == 1)
                or (callable(is_fuzzy_match_func)
                    and is_fuzzy_match_func(review_request))):
            return review_request.id

    return None
Ejemplo n.º 12
0
def find_review_request_by_change_id(api_client,
                                     api_root,
                                     repository_info=None,
                                     repository_name=None,
                                     revisions=None,
                                     repository_id=None):
    """Ask ReviewBoard for the review request ID for the tip revision.

    Note that this function calls the ReviewBoard API with the only_fields
    paramater, thus the returned review request will contain only the fields
    specified by the only_fields variable.

    If no review request is found, None will be returned instead.

    Version Changed:
        3.0:
        The ``repository_info`` and ``repository_name`` arguments were
        deprecated in favor of adding the new ``repository_id`` argument.

    Args:
        api_client (rbtools.api.client.RBClient):
            The API client.

        api_root (rbtools.api.resource.RootResource):
            The root resource of the Review Board server.

        repository_info (rbtools.clients.RepositoryInfo, deprecated):
            The repository info object.

        repository_name (unicode, deprecated):
            The repository name.

        revisions (dict):
            The parsed revision information, including the ``tip`` key.

        repository_id (int, optional):
            The repository ID to use.
    """
    assert api_client is not None
    assert api_root is not None
    assert revisions is not None

    only_fields = 'id,commit_id,changenum,status,url,absolute_url'
    change_id = revisions['tip']
    logging.debug('Attempting to find review request from tip revision ID: %s',
                  change_id)
    # Strip off any prefix that might have been added by the SCM.
    change_id = change_id.split(':', 1)[1]

    optional_args = {}

    if change_id.isdigit():
        # Populate integer-only changenum field also for compatibility
        # with older API versions
        optional_args['changenum'] = int(change_id)

    user = get_user(api_client, api_root, auth_required=True)

    if repository_info or repository_name:
        RemovedInRBTools40Warning.warn(
            'The repository_info and repository_name arguments to '
            'find_review_request_by_change_id are deprecated and will be '
            'removed in RBTools 4.0. Please change your command to use the '
            'needs_repository attribute and pass in the repository ID '
            'directly.')
        repository_id = get_repository_id(repository_info, api_root,
                                          repository_name)

    # Don't limit query to only pending requests because it's okay to stamp a
    # submitted review.
    review_requests = api_root.get_review_requests(repository=repository_id,
                                                   from_user=user.username,
                                                   commit_id=change_id,
                                                   only_links='self',
                                                   only_fields=only_fields,
                                                   **optional_args)

    if review_requests:
        count = review_requests.total_results

        # Only one review can be associated with a specific commit ID.
        if count > 0:
            assert count == 1, '%d review requests were returned' % count
            review_request = review_requests[0]
            logging.debug('Found review request %s with status %s',
                          review_request.id, review_request.status)

            if review_request.status != 'discarded':
                return review_request

    return None
Ejemplo n.º 13
0
def guess_existing_review_request(repository_info=None,
                                  repository_name=None,
                                  api_root=None,
                                  api_client=None,
                                  tool=None,
                                  revisions=None,
                                  guess_summary=None,
                                  guess_description=None,
                                  is_fuzzy_match_func=None,
                                  no_commit_error=None,
                                  submit_as=None,
                                  additional_fields=None,
                                  repository_id=None):
    """Try to guess the existing review request ID if it is available.

    The existing review request is guessed by comparing the existing
    summary and description to the current post's summary and description,
    respectively. The current post's summary and description are guessed if
    they are not provided.

    If the summary and description exactly match those of an existing
    review request, that request is immediately returned. Otherwise,
    the user is prompted to select from a list of potential matches,
    sorted by the highest ranked match first.

    Note that this function calls the ReviewBoard API with the only_fields
    paramater, thus the returned review request will contain only the fields
    specified by the only_fields variable.

    Version Changed:
        3.0:
        The ``repository_info`` and ``repository_name`` arguments were
        deprecated in favor of adding the new ``repository_id`` argument.

    Args:
        repository_info (rbtools.clients.RepositoryInfo, deprecated):
            The repository info object.

        repository_name (unicode, deprecated):
            The repository name.

        api_root (rbtools.api.resource.RootResource):
            The root resource of the Review Board server.

        api_client (rbtools.api.client.RBClient):
            The API client.

        tool (rbtools.clients.SCMClient):
            The SCM client.

        revisions (dict):
            The parsed revisions object.

        guess_summary (bool):
            Whether to attempt to guess the summary for comparison.

        guess_description (bool):
            Whether to attempt to guess the description for comparison.

        is_fuzzy_match_func (callable, optional):
            A function which can check if a review request is a match for the
            data being posted.

        no_commit_error (callable, optional):
            A function to be called when there's no local commit.

        submit_as (unicode, optional):
            A username on the server which is used for posting review requests.
            If provided, review requests owned by this user will be matched.

        additional_fields (list of unicode, optional):
            A list of additional fields to include in the fetched review
            request resource.

        repository_id (int, optional):
            The ID of the repository to match.
    """
    assert api_root is not None
    assert api_client is not None
    assert tool is not None
    assert revisions is not None

    only_fields = [
        'id', 'summary', 'description', 'draft', 'url', 'absolute_url',
        'bugs_closed', 'status', 'public'
    ]

    if additional_fields:
        only_fields += additional_fields

    if submit_as:
        username = submit_as
    else:
        user = get_user(api_client, api_root, auth_required=True)
        username = user.username

    if repository_info or repository_name:
        RemovedInRBTools40Warning.warn(
            'The repository_info and repository_name arguments to '
            'find_review_request_by_change_id are deprecated and will be '
            'removed in RBTools 4.0. Please change your command to use the '
            'needs_repository attribute and pass in the repository ID '
            'directly.')
        repository_id = get_repository_id(repository_info, api_root,
                                          repository_name)

    try:
        # Get only pending requests by the current user for this
        # repository.
        review_requests = api_root.get_review_requests(
            repository=repository_id,
            from_user=username,
            status='pending',
            expand='draft',
            only_fields=','.join(only_fields),
            only_links='diffs,draft',
            show_all_unpublished=True)

        if not review_requests:
            raise ValueError('No existing review requests to update for '
                             'user %s' % username)
    except APIError as e:
        raise ValueError('Error getting review requests for user %s: %s' %
                         (username, e))

    summary = None
    description = None

    if not guess_summary or not guess_description:
        try:
            commit_message = tool.get_commit_message(revisions)

            if commit_message:
                if not guess_summary:
                    summary = commit_message['summary']

                if not guess_description:
                    description = commit_message['description']
            elif callable(no_commit_error):
                no_commit_error()
        except NotImplementedError:
            raise ValueError('--summary and --description are required.')

    if not summary and not description:
        return None

    possible_matches = get_possible_matches(review_requests, summary,
                                            description)
    exact_match_count = num_exact_matches(possible_matches)

    for score, review_request in possible_matches:
        # If the score is the only exact match, return the review request
        # ID without confirmation, otherwise prompt.
        if ((score.is_exact_match() and exact_match_count == 1)
                or (callable(is_fuzzy_match_func)
                    and is_fuzzy_match_func(review_request))):
            return review_request

    return None
Ejemplo n.º 14
0
def guess_existing_review_request_id(repository_info, repository_name,
                                     api_root, api_client, tool, revisions,
                                     guess_summary, guess_description,
                                     is_fuzzy_match_func=None,
                                     no_commit_error=None):
    """Try to guess the existing review request ID if it is available.

    The existing review request is guessed by comparing the existing
    summary and description to the current post's summary and description,
    respectively. The current post's summary and description are guessed if
    they are not provided.

    If the summary and description exactly match those of an existing
    review request, the ID for which is immediately returned. Otherwise,
    the user is prompted to select from a list of potential matches,
    sorted by the highest ranked match first.
    """
    user = get_user(api_client, api_root, auth_required=True)
    repository_id = get_repository_id(
        repository_info, api_root, repository_name)

    try:
        # Get only pending requests by the current user for this
        # repository.
        review_requests = api_root.get_review_requests(
            repository=repository_id, from_user=user.username,
            status='pending', expand='draft',
            only_fields='id,summary,description,draft',
            only_links='draft')

        if not review_requests:
            raise CommandError('No existing review requests to update for '
                               'user %s.'
                               % user.username)
    except APIError as e:
        raise CommandError('Error getting review requests for user '
                           '%s: %s' % (user.username, e))

    summary = None
    description = None

    if not guess_summary or not guess_description:
        try:
            commit_message = tool.get_commit_message(revisions)

            if commit_message:
                if not guess_summary:
                    summary = commit_message['summary']

                if not guess_description:
                    description = commit_message['description']
            elif callable(no_commit_error):
                no_commit_error()
        except NotImplementedError:
            raise CommandError('--summary and --description are required.')

    if not summary and not description:
        return None

    possible_matches = get_possible_matches(review_requests, summary,
                                            description)
    exact_match_count = num_exact_matches(possible_matches)

    for score, review_request in possible_matches:
        # If the score is the only exact match, return the review request
        # ID without confirmation, otherwise prompt.
        if ((score.is_exact_match() and exact_match_count == 1) or
            (callable(is_fuzzy_match_func) and
             is_fuzzy_match_func(review_request))):
            return review_request.id

    return None