Example #1
0
class Processor(object):
    def __init__(self, client, number, head, target_path):
        self._client = client
        self._number = number
        self._head = head
        self._target_path = target_path
        self._changes = None
        self._problems = Problems(target_path)
        self._review = Review(client, number)

    def load_changes(self):
        log.info('Loading pull request patches from github.')
        files = self._client.pull_requests.list_files(self._number)
        pull_request_patches = files.all()
        self._changes = DiffCollection(pull_request_patches)
        self._problems.set_changes(self._changes)

    def run_tools(self, repo_config):
        if not self._changes:
            raise RuntimeError('No loaded changes, cannot run tools. '
                               'Try calling load_changes first.')
        files_to_check = self._changes.get_files(append_base=self._target_path)
        tools.run(repo_config, self._problems, files_to_check,
                  self._target_path)

    def publish(self, wait_time=0):
        self._problems.limit_to_changes()
        self._review.publish(self._problems, self._head, wait_time)
Example #2
0
    def test_publish_empty_comment_add_ok_label(self):
        gh = Mock()
        problems = Problems(changes=[])
        review = Review(gh, 3)
        label = config.get('OK_LABEL', 'No lint errors')

        with add_ok_label(gh, 3, label):
            sha = 'abc123'
            review.publish(problems, sha)

        assert not gh.pull_requests.comments.create.called
        assert gh.issues.comments.create.called
        assert gh.issues.labels.remove_from_issue.called
        assert_add_to_issue(gh)

        calls = gh.issues.labels.remove_from_issue.call_args_list

        expected = call(3, label)
        eq_(calls, [expected])

        calls = gh.issues.comments.create.call_args_list

        msg = ('Could not review pull request. '
               'It may be too large, or contain no reviewable changes.')
        expected = call(3, msg)
        eq_(calls[0], expected)
Example #3
0
class Processor(object):

    def __init__(self, client, number, head, target_path):
        self._client = client
        self._number = number
        self._head = head
        self._target_path = target_path
        self._changes = None
        self._problems = Problems(target_path)
        self._review = Review(client, number)

    def load_changes(self):
        log.info('Loading pull request patches from github.')
        files = self._client.pull_requests.list_files(self._number)
        pull_request_patches = files.all()
        self._changes = DiffCollection(pull_request_patches)
        self._problems.set_changes(self._changes)

    def run_tools(self, review_config):
        if self._changes is None:
            raise RuntimeError('No loaded changes, cannot run tools. '
                               'Try calling load_changes first.')
        files_to_check = self._changes.get_files(
            append_base=self._target_path,
            ignore_patterns=review_config.ignore_patterns())
        tools.run(
            review_config,
            self._problems,
            files_to_check,
            self._target_path)

    def publish(self, wait_time=0):
        self._problems.limit_to_changes()
        self._review.publish(self._problems, self._head, wait_time)
Example #4
0
class Processor(object):

    _client = None
    _number = None
    _head = None
    _target_path = None
    _changes = None
    _problems = None
    _review = None
    _config = None

    def __init__(self, client, number, head, target_path, config=None):
        self._client = client
        self._number = number
        self._head = head
        self._target_path = target_path
        self._problems = Problems(target_path)
        self._review = Review(client, number)

        if config is None:
            config = {}
        self._config = config

    def load_changes(self):
        log.info('Loading pull request patches from github.')
        files = self._client.pull_requests.list_files(self._number)
        pull_request_patches = files.all()
        self._changes = DiffCollection(pull_request_patches)
        self._problems.set_changes(self._changes)

    def run_tools(self, review_config):
        if self._changes is None:
            raise RuntimeError('No loaded changes, cannot run tools. '
                               'Try calling load_changes first.')
        files_to_check = self._changes.get_files(
            append_base=self._target_path,
            ignore_patterns=review_config.ignore_patterns())
        commits_to_check = self.get_commits(self._number)
        tools.run(
            review_config,
            self._problems,
            files_to_check,
            commits_to_check,
            self._target_path)

    def publish(self):
        self._problems.limit_to_changes()
        self._review.publish(
            self._problems,
            self._head,
            self._config.get('SUMMARY_THRESHOLD'))

    def get_commits(self, number):
        return self._client.pull_requests.list_commits(number).all()
Example #5
0
    def test_publish_empty_comment(self):
        problems = Problems(changes=[])
        review = Review(self.gh, 3)

        sha = 'abc123'
        review.publish(problems, sha)

        assert self.issue.create_comment.called, 'Should create a comment'

        msg = ('Could not review pull request. '
               'It may be too large, or contain no reviewable changes.')
        self.issue.create_comment.assert_called_with(msg)
Example #6
0
    def test_publish_empty_comment(self):
        problems = Problems(changes=[])
        review = Review(self.repo, self.pr, self.config)

        sha = 'abc123'
        review.publish(problems, sha)

        assert self.pr.create_comment.called, 'Should create a comment'

        msg = ('Could not review pull request. '
               'It may be too large, or contain no reviewable changes.')
        self.pr.create_comment.assert_called_with(msg)
Example #7
0
class Processor(object):

    _repository = None
    _pull_request = None
    _target_path = None
    _changes = None
    _problems = None
    _review = None
    _config = None

    def __init__(self, repository, pull_request, target_path, config=None):
        config = config if config else {}
        self._config = config
        self._repository = repository
        self._pull_request = pull_request
        self._target_path = target_path
        self._problems = Problems(target_path)
        self._review = Review(repository, pull_request, config)

    def load_changes(self):
        log.info('Loading pull request patches from github.')
        files = self._pull_request.files()
        self._changes = DiffCollection(files)
        self._problems.set_changes(self._changes)

    def run_tools(self, review_config):
        if self._changes is None:
            raise RuntimeError('No loaded changes, cannot run tools. '
                               'Try calling load_changes first.')
        files_to_check = self._changes.get_files(
            append_base=self._target_path,
            ignore_patterns=review_config.ignore_patterns())
        commits_to_check = self._pull_request.commits()
        log.debug("_problems before tools: %s" % len(self._problems))
        self._problems = tools.run(
            review_config,
            self._problems,
            files_to_check,
            commits_to_check,
            self._target_path)
        log.debug("_problems after tools: %s" % len(self._problems))


    def publish(self):
        self._problems.limit_to_changes()
        self._review.publish(
            self._problems,
            self._pull_request.head,
            self._config.get('SUMMARY_THRESHOLD'))
Example #8
0
    def test_publish_empty_comment_add_ok_label(self):
        problems = Problems(changes=[])
        config = build_review_config(fixer_ini, {'OK_LABEL': 'No lint'})
        review = Review(self.repo, self.pr, config)

        sha = 'abc123'
        review.publish(problems, sha)

        assert self.pr.create_comment.called, 'ok comment should be added.'
        assert self.pr.remove_label.called, 'label should be removed.'
        self.pr.remove_label.assert_called_with(config['OK_LABEL'])

        msg = ('Could not review pull request. '
               'It may be too large, or contain no reviewable changes.')
        self.pr.create_comment.assert_called_with(msg)
Example #9
0
    def test_publish_empty_comment_add_ok_label(self):
        problems = Problems(changes=[])
        config = {'OK_LABEL': 'No lint'}
        review = Review(self.repo, self.pr, config)

        sha = 'abc123'
        review.publish(problems, sha)

        assert self.pr.create_comment.called, 'ok comment should be added.'
        assert self.pr.remove_label.called, 'label should be removed.'
        self.pr.remove_label.assert_called_with(config['OK_LABEL'])

        msg = ('Could not review pull request. '
               'It may be too large, or contain no reviewable changes.')
        self.pr.create_comment.assert_called_with(msg)
Example #10
0
    def test_publish_ok_comment(self):
        gh = Mock()
        problems = Problems(changes=[1])
        review = Review(gh, 3)

        sha = 'abc123'
        review.publish(problems, sha)

        assert not (gh.pull_requests.comments.create.called)
        assert gh.issues.comments.create.called

        calls = gh.issues.comments.create.call_args_list

        expected = call(3, ':+1: No lint errors found.')
        eq_(calls[0], expected)
Example #11
0
    def test_publish_ok_comment(self):
        gh = Mock()
        problems = Problems()
        review = Review(gh, 3)

        sha = 'abc123'
        review.publish(problems, sha)

        assert not(gh.pull_requests.comments.create.called)
        assert gh.issues.comments.create.called

        calls = gh.issues.comments.create.call_args_list

        expected = call(3, ':+1: No lint errors found.')
        eq_(calls[0], expected)
Example #12
0
    def test_publish_empty_comment_add_ok_label(self):
        problems = Problems(changes=[])
        review = Review(self.gh, 3)
        label = 'No lint errors'

        with add_ok_label(self.gh, 3, review, label):
            sha = 'abc123'
            review.publish(problems, sha)

        assert self.issue.create_comment.called, 'ok comment should be added.'
        assert self.issue.remove_label.called, 'label should be removed.'
        self.issue.remove_label.assert_called_with(label)

        msg = ('Could not review pull request. '
               'It may be too large, or contain no reviewable changes.')
        self.issue.create_comment.assert_called_with(msg)
Example #13
0
    def test_publish_empty_comment(self):
        gh = Mock()
        problems = Problems(changes=[])
        review = Review(gh, 3)

        sha = 'abc123'
        review.publish(problems, sha)

        assert not (gh.pull_requests.comments.create.called)
        assert gh.issues.comments.create.called

        calls = gh.issues.comments.create.call_args_list

        msg = ('Could not review pull request. '
               'It may be too large, or contain no reviewable changes.')
        expected = call(3, msg)
        eq_(calls[0], expected)
Example #14
0
    def test_publish_empty_comment(self):
        gh = Mock()
        problems = Problems(changes=[])
        review = Review(gh, 3)

        sha = 'abc123'
        review.publish(problems, sha)

        assert not(gh.pull_requests.comments.create.called)
        assert gh.issues.comments.create.called

        calls = gh.issues.comments.create.call_args_list

        msg = ('Could not review pull request. '
               'It may be too large, or contain no reviewable changes.')
        expected = call(3, msg)
        eq_(calls[0], expected)
Example #15
0
    def test_publish_empty_comment_with_comment_status(self):
        config = build_review_config(fixer_ini, {'PULLREQUEST_STATUS': True})

        problems = Problems(changes=[])
        review = Review(self.repo, self.pr, config)

        sha = 'abc123'
        review.publish(problems, sha)

        assert self.pr.create_comment.called, 'Should create a comment'

        msg = ('Could not review pull request. '
               'It may be too large, or contain no reviewable changes.')

        self.repo.create_status.assert_called_with(self.pr.head, 'success',
                                                   msg)

        self.pr.create_comment.assert_called_with(msg)
Example #16
0
    def test_publish_comment_threshold_checks(self):
        fixture = load_fixture('comments_current.json')
        self.pr.review_comments.return_value = [GhIssueComment(f) for f in json.loads(fixture)]

        problems = Problems()

        filename_1 = 'Console/Command/Task/AssetBuildTask.php'
        errors = (
            (filename_1, 117, 'Something bad'),
            (filename_1, 119, 'Something bad'),
        )
        problems.add_many(errors)
        problems.set_changes([1])
        sha = 'abc123'

        review = Review(self.gh, 3)
        review.publish_summary = Mock()
        review.publish(problems, sha, 1)

        assert review.publish_summary.called, 'Should have been called.'
Example #17
0
    def test_publish_ok_comment_add_ok_label(self):
        gh = Mock()
        problems = Problems(changes=[1])
        review = Review(gh, 3)
        label = config.get('OK_LABEL', 'No lint errors')

        with add_ok_label(gh, 3, label, create=True):
            sha = 'abc123'
            review.publish(problems, sha)

        assert not gh.pull_requests.comments.create.called
        assert not gh.issues.comments.create.called
        assert gh.issues.labels.remove_from_issue.called

        calls = gh.issues.labels.remove_from_issue.call_args_list

        expected = call(3, label)
        eq_(calls, [expected])

        assert_add_to_issue(gh, 3, label, create=True)
        assert not(gh.pull_requests.comments.create.called)
Example #18
0
class Processor(object):

    _repository = None
    _pull_request = None
    _target_path = None
    _changes = None
    _problems = None
    _review = None
    _config = None

    def __init__(self, repository, pull_request, target_path, config=None):
        config = config if config else {}
        self._config = config
        self._repository = repository
        self._pull_request = pull_request
        self._target_path = target_path
        self._problems = Problems(target_path)
        self._review = Review(repository, pull_request, config)

    def load_changes(self):
        log.info('Loading pull request patches from github.')
        files = self._pull_request.files()
        self._changes = DiffCollection(files)
        self._problems.set_changes(self._changes)

    def run_tools(self, review_config):
        if self._changes is None:
            raise RuntimeError('No loaded changes, cannot run tools. '
                               'Try calling load_changes first.')
        files_to_check = self._changes.get_files(
            append_base=self._target_path,
            ignore_patterns=review_config.ignore_patterns())
        commits_to_check = self._pull_request.commits()
        tools.run(review_config, self._problems, files_to_check,
                  commits_to_check, self._target_path)

    def publish(self):
        self._problems.limit_to_changes()
        self._review.publish(self._problems, self._pull_request.head,
                             self._config.get('SUMMARY_THRESHOLD'))
Example #19
0
    def test_publish_empty_comment_with_comment_status(self):
        config = {
            'PULLREQUEST_STATUS': True,
        }

        problems = Problems(changes=[])
        review = Review(self.repo, self.pr, config)

        sha = 'abc123'
        review.publish(problems, sha)

        assert self.pr.create_comment.called, 'Should create a comment'

        msg = ('Could not review pull request. '
               'It may be too large, or contain no reviewable changes.')

        self.repo.create_status.assert_called_with(
            self.pr.head,
            'error',
            msg)

        self.pr.create_comment.assert_called_with(msg)
Example #20
0
    def test_publish_comment_threshold_checks(self, http):
        fixture_data = load_fixture('comments_current.json')
        response = Response()
        response._content = fixture_data
        http.return_value = response

        gh = Github()
        problems = Problems()

        filename_1 = 'Console/Command/Task/AssetBuildTask.php'
        errors = (
            (filename_1, 117, 'Something bad'),
            (filename_1, 119, 'Something bad'),
        )
        problems.add_many(errors)
        problems.set_changes([1])
        sha = 'abc123'

        review = Review(gh, 3)
        review.publish_summary = Mock()
        review.publish(problems, sha, 1)

        assert review.publish_summary.called, 'Should have been called.'
Example #21
0
    def test_publish_comment_threshold_checks(self, http):
        fixture_data = load_fixture('comments_current.json')
        response = Response()
        response._content = fixture_data
        http.return_value = response

        gh = Github()
        problems = Problems()

        filename_1 = 'Console/Command/Task/AssetBuildTask.php'
        errors = (
            (filename_1, 117, 'Something bad'),
            (filename_1, 119, 'Something bad'),
        )
        problems.add_many(errors)
        problems.set_changes([1])
        sha = 'abc123'

        review = Review(gh, 3)
        review.publish_summary = Mock()
        review.publish(problems, sha, 1)

        assert review.publish_summary.called, 'Should have been called.'
Example #22
0
class Processor(object):

    _repository = None
    _pull_request = None
    _target_path = None
    _changes = None
    _review = None
    _config = None
    problems = None

    def __init__(self, repository, pull_request, target_path, config):
        config = config if config else {}
        self._config = config
        self._repository = repository
        self._pull_request = pull_request
        self._target_path = target_path
        self.problems = Problems()
        self._review = Review(repository, pull_request, config)

    def load_changes(self):
        log.info('Loading pull request patches from github.')
        files = self._pull_request.files()
        self._changes = DiffCollection(files)
        self.problems.set_changes(self._changes)

    def run_tools(self, review_config):
        if self._changes is None:
            raise RuntimeError('No loaded changes, cannot run tools. '
                               'Try calling load_changes first.')
        files_to_check = self._changes.get_files(
            ignore_patterns=review_config.ignore_patterns())
        commits_to_check = self._pull_request.commits()

        tool_list = tools.factory(review_config, self.problems,
                                  self._target_path)

        if review_config.fixers_enabled():
            self.apply_fixers(review_config, tool_list, files_to_check)

        tools.run(tool_list, files_to_check, commits_to_check)

    def apply_fixers(self, review_config, tool_list, files_to_check):
        try:
            fixer_context = fixers.create_context(
                review_config,
                self._config,
                self._target_path,
                self._repository,
                self._pull_request,
            )
            fixer_diff = fixers.run_fixers(tool_list, self._target_path,
                                           files_to_check)
            fixers.apply_fixer_diff(self._changes, fixer_diff, fixer_context)
        except (ConfigurationError, WorkflowError) as e:
            log.warn('Fixer application failed. Got %s', e)
            message = u'Unable to apply fixers. {}'.format(e)
            self.problems.add(IssueComment(message))
        except Exception as e:
            log.warn(
                'Fixer application failed, '
                'rolling back working tree. Got %s', e)
            fixers.rollback_changes(self._target_path)

    def publish(self):
        self.problems.limit_to_changes()
        self._review.publish(self.problems, self._pull_request.head,
                             self._config.get('SUMMARY_THRESHOLD'))