def process_pull_request(user, repo, number, lintrc): """ Starts processing a pull request and running the various lint tools against it. """ log.info('Starting to process lint for %s/%s/%s', user, repo, number) log.debug("lintrc contents '%s'", lintrc) review_config = ReviewConfig(lintrc) if len(review_config.linters()) == 0: log.info('No configured linters, skipping processing.') return gh = github.get_client(config, user, repo) try: log.info('Loading pull request data from github.') pull_request = gh.pull_requests.get(number) head_repo = pull_request.head['repo']['git_url'] pr_head = pull_request.head['sha'] # Clone/Update repository target_path = git.get_repo_path(user, repo, number, config) git.clone_or_update(head_repo, target_path, pr_head) processor = Processor(gh, number, pr_head, target_path, config) processor.load_changes() processor.run_tools(review_config) processor.publish() log.info('Completed lint processing for %s/%s/%s' % (user, repo, number)) except BaseException, e: log.exception(e)
def process_pull_request(user, repo, number, lintrc): """ Starts processing a pull request and running the various lint tools against it. """ log.info('Starting to process lint for %s/%s/%s', user, repo, number) log.debug("lintrc contents '%s'", lintrc) review_config = ReviewConfig(lintrc) if len(review_config.linters()) == 0: log.info('No configured linters, skipping processing.') return gh = github.get_client(config, user, repo) try: log.info('Loading pull request data from github.') pull_request = gh.pull_requests.get(number) head_repo = pull_request.head['repo']['clone_url'] private_repo = pull_request.head['repo']['private'] pr_head = pull_request.head['sha'] # Clone/Update repository target_path = git.get_repo_path(user, repo, number, config) git.clone_or_update(config, head_repo, target_path, pr_head, private_repo) processor = Processor(gh, number, pr_head, target_path, config) processor.load_changes() processor.run_tools(review_config) processor.publish() log.info('Completed lint processing for %s/%s/%s' % ( user, repo, number)) except BaseException, e: log.exception(e)
def test_run_tools__execute_fixers(self): pull = self.get_pull_request() repo = Mock() self.tool_stub.factory.return_value = sentinel.tools self.fixer_stub.create_context.return_value = sentinel.context self.fixer_stub.run_fixers.return_value = sentinel.diff config = build_review_config(fixer_ini, app_config) subject = Processor(repo, pull, './tests', config) subject.load_changes() subject.run_tools() file_path = 'View/Helper/AssetCompressHelper.php' self.fixer_stub.create_context.assert_called_with( config, './tests', repo, pull ) self.fixer_stub.run_fixers.assert_called_with( sentinel.tools, './tests', [file_path] ) self.fixer_stub.apply_fixer_diff.assert_called_with( subject._changes, sentinel.diff, sentinel.context ) self.tool_stub.run.assert_called()
def _test_run_tools_fixer_error_scenario(self, error): pull = self.get_pull_request() repo = Mock() self.tool_stub.factory.return_value = sentinel.tools self.fixer_stub.create_context.return_value = sentinel.context self.fixer_stub.apply_fixer_diff.side_effect = error config = build_review_config(fixer_ini, app_config) subject = Processor(repo, pull, './tests', config) subject.load_changes() subject.run_tools() self.fixer_stub.create_context.assert_called() self.fixer_stub.run_fixers.assert_called() self.tool_stub.run.assert_called() self.fixer_stub.rollback_changes.assert_called_with( './tests', pull.head) assert 1 == len(subject.problems), 'strategy error adds pull comment' assert 0 == subject.problems.error_count( ), 'fixer failure should be info level' assert 'Unable to apply fixers. ' + str(error) == subject.problems.all( )[0].body assert 1 == len(subject.problems), 'strategy error adds pull comment'
def test_load_changes(self): gh = self.get_mock_client(fixture_data) subject = Processor(gh, 1, '123abc', './tests') subject.load_changes() eq_(1, len(subject._changes), 'File count is wrong') assert isinstance(subject._changes, DiffCollection)
def test_run_tools__execute_fixers(self, fixer_stub, tool_stub): pull = self.get_pull_request() repo = Mock() tool_stub.factory.return_value = sentinel.tools fixer_stub.create_context.return_value = sentinel.context fixer_stub.run_fixers.return_value = sentinel.diff config = build_review_config(fixer_ini, app_config) subject = Processor(repo, pull, './tests', config) subject.load_changes() subject.run_tools() file_path = 'View/Helper/AssetCompressHelper.php' fixer_stub.create_context.assert_called_with( config, './tests', repo, pull) fixer_stub.run_fixers.assert_called_with( sentinel.tools, './tests', [file_path]) fixer_stub.apply_fixer_diff.assert_called_with( subject._changes, sentinel.diff, sentinel.context) assert tool_stub.run.called, 'Should have ran'
def process_pull_request(self, user, repo_name, number, lintrc): """ Starts processing a pull request and running the various lint tools against it. """ log.info('Starting to process lint for %s/%s/%s', user, repo_name, number) log.debug("lintrc contents '%s'", lintrc) review_config = build_review_config(lintrc, deepcopy(config)) if len(review_config.linters()) == 0: log.info('No configured linters, skipping processing.') return try: log.info( 'Loading pull request data from github. user=%s ' 'repo=%s number=%s', user, repo_name, number) repo = GithubRepository(config, user, repo_name) pull_request = repo.pull_request(number) clone_url = pull_request.clone_url pr_head = pull_request.head target_branch = pull_request.target_branch if target_branch in review_config.ignore_branches(): log.info('Pull request into ignored branch %s, skipping review.', target_branch) return repo.create_status(pr_head, 'pending', 'Lintreview processing') # Clone/Update repository target_path = git.get_repo_path(user, repo_name, number, config) git.clone_or_update(config, clone_url, target_path, pr_head) processor = Processor(repo, pull_request, target_path, review_config) processor.load_changes() processor.run_tools() processor.publish() log.info('Completed lint processing for %s/%s/%s' % (user, repo_name, number)) except Exception as e: log.exception(e) except TimeoutError as e: log.exception(e) raise self.retry( countdown=5, # Pause for 5 seconds to clear things out max_retries=2, # only give it one more shot ) finally: try: git.destroy(target_path) log.info('Cleaned up pull request %s/%s/%s', user, repo_name, number) except Exception as e: log.exception(e)
def process_pull_request(self, user, repo_name, number, lintrc): """ Starts processing a pull request and running the various lint tools against it. """ log.info('Starting to process lint for %s/%s/%s', user, repo_name, number) log.debug("lintrc contents '%s'", lintrc) review_config = build_review_config(lintrc, deepcopy(config)) if len(review_config.linters()) == 0: log.info('No configured linters, skipping processing.') return try: log.info('Loading pull request data from github. user=%s ' 'repo=%s number=%s', user, repo_name, number) repo = GithubRepository(config, user, repo_name) pull_request = repo.pull_request(number) clone_url = pull_request.clone_url pr_head = pull_request.head target_branch = pull_request.target_branch if target_branch in review_config.ignore_branches(): log.info('Pull request into ignored branch %s, skipping review.', target_branch) return repo.create_status(pr_head, 'pending', 'Lintreview processing') # Clone/Update repository target_path = git.get_repo_path(user, repo_name, number, config) git.clone_or_update(config, clone_url, target_path, pr_head) processor = Processor(repo, pull_request, target_path, review_config) processor.load_changes() processor.run_tools() processor.publish() log.info('Completed lint processing for %s/%s/%s' % ( user, repo_name, number)) except Exception as e: log.exception(e) except TimeoutError as e: log.exception(e) raise self.retry( countdown=5, # Pause for 5 seconds to clear things out max_retries=2, # only give it one more shot ) finally: try: git.destroy(target_path) log.info('Cleaned up pull request %s/%s/%s', user, repo_name, number) except Exception as e: log.exception(e)
def test_load_changes(self): pull = self.get_pull_request() repo = Mock() subject = Processor(repo, pull, './tests', app_config) subject.load_changes() eq_(1, len(subject._changes), 'File count is wrong') assert isinstance(subject._changes, DiffCollection)
def test_load_changes(self): pull = self.get_pull_request(fixture_data) repo = Mock() subject = Processor(repo, pull, './tests') subject.load_changes() eq_(1, len(subject._changes), 'File count is wrong') assert isinstance(subject._changes, DiffCollection)
def test_load_changes(self): pull = self.get_pull_request() repo = Mock() config = build_review_config('', app_config) subject = Processor(repo, pull, './tests', config) subject.load_changes() self.assertEqual(1, len(subject._changes), 'File count is wrong') assert isinstance(subject._changes, DiffCollection)
def test_load_changes(self, http): gh = Github() response = Response() response._content = fixture_data http.return_value = response subject = Processor(gh, 1, '123abc', './tests') subject.load_changes() eq_(1, len(subject._changes), 'File count is wrong') assert isinstance(subject._changes, DiffCollection)
def test_run_tools__ignore_patterns(self, fixer_stub, tool_stub): pull = self.get_pull_request() repo = Mock() config = build_review_config(fixer_ini, app_config) config.ignore_patterns = lambda: ['View/Helper/*'] subject = Processor(repo, pull, './tests', config) subject.load_changes() subject.run_tools() tool_stub.run.assert_called_with(ANY, [], ANY)
def process_pull_request(user, repo_name, number, lintrc): """ Starts processing a pull request and running the various lint tools against it. """ log.info('Starting to process lint for %s/%s/%s', user, repo_name, number) log.debug("lintrc contents '%s'", lintrc) review_config = build_review_config(lintrc, config) if len(review_config.linters()) == 0: log.info('No configured linters, skipping processing.') return try: log.info('Loading pull request data from github. user=%s ' 'repo=%s number=%s', user, repo_name, number) repo = GithubRepository(config, user, repo_name) pull_request = repo.pull_request(number) clone_url = pull_request.clone_url pr_head = pull_request.head target_branch = pull_request.target_branch if target_branch in review_config.ignore_branches(): log.info('Pull request into ignored branch %s, skipping review.', target_branch) return status = config.get('PULLREQUEST_STATUS', True) if status: repo.create_status(pr_head, 'pending', 'Lintreview processing...') # Clone/Update repository target_path = git.get_repo_path(user, repo_name, number, config) git.clone_or_update(config, clone_url, target_path, pr_head) processor = Processor(repo, pull_request, target_path, config) processor.load_changes() processor.run_tools(review_config) processor.publish() log.info('Completed lint processing for %s/%s/%s' % ( user, repo, number)) git.destroy(target_path) log.info('Cleaned up pull request %s/%s/%s', user, repo, number) except BaseException as e: log.exception(e)
def process_pull_request(user, repo_name, number, lintrc): """ Starts processing a pull request and running the various lint tools against it. """ log.info('Starting to process lint for %s/%s/%s', user, repo_name, number) log.debug("lintrc contents '%s'", lintrc) review_config = build_review_config(lintrc, config) if len(review_config.linters()) == 0: log.info('No configured linters, skipping processing.') return try: log.info('Loading pull request data from github. user=%s ' 'repo=%s number=%s', user, repo_name, number) repo = GithubRepository(config, user, repo_name) pull_request = repo.pull_request(number) head_repo = pull_request.clone_url private_repo = pull_request.is_private pr_head = pull_request.head target_branch = pull_request.target_branch if target_branch in review_config.ignore_branches(): log.info('Pull request into ignored branch %s, skipping processing.' % target_branch) return status = config.get('PULLREQUEST_STATUS', True) if status: repo.create_status(pr_head, 'pending', 'Lintreview processing...') # Clone/Update repository target_path = git.get_repo_path(user, repo_name, number, config) git.clone_or_update(config, head_repo, target_path, pr_head, private_repo) processor = Processor(repo, pull_request, target_path, config) processor.load_changes() processor.run_tools(review_config) processor.publish() log.info('Completed lint processing for %s/%s/%s' % ( user, repo, number)) except BaseException, e: log.exception(e)
def process_pull_request(user, repo, number, lintrc): """ Starts processing a pull request and running the various lint tools against it. """ log.info('Starting to process lint for %s/%s/%s', user, repo, number) log.debug("lintrc contents '%s'", lintrc) review_config = build_review_config(lintrc, config) if len(review_config.linters()) == 0: log.info('No configured linters, skipping processing.') return try: log.info( 'Loading pull request data from github. user=%s ' 'repo=%s number=%s', user, repo, number) gh = github.get_repository(config, user, repo) pull_request = gh.pull_request(number) pr_dict = pull_request.as_dict() head_repo = pr_dict['head']['repo']['clone_url'] private_repo = pr_dict['head']['repo']['private'] pr_head = pr_dict['head']['sha'] target_branch = pr_dict['base']['ref'] if target_branch in review_config.ignore_branches(): log.info( 'Pull request into ignored branch %s, skipping processing.' % target_branch) return # Clone/Update repository target_path = git.get_repo_path(user, repo, number, config) git.clone_or_update(config, head_repo, target_path, pr_head, private_repo) processor = Processor(gh, number, pr_head, target_path, config) processor.load_changes() processor.run_tools(review_config) processor.publish() log.info('Completed lint processing for %s/%s/%s' % (user, repo, number)) except BaseException as e: log.exception(e)
def test_run_tools__ignore_patterns(self): pull = self.get_pull_request() repo = Mock() config = build_review_config(fixer_ini, app_config) config.ignore_patterns = lambda: [ 'View/Helper/*'] subject = Processor(repo, pull, './tests', config) subject.load_changes() subject.run_tools() self.tool_stub.run.assert_called_with( ANY, [], ANY )
def process_pull_request(user, repo, number, lintrc): """ Starts processing a pull request and running the various lint tools against it. """ log.info('Starting to process lint for %s/%s/%s', user, repo, number) log.debug("lintrc contents '%s'", lintrc) lintrc_defaults = get_lintrc_defaults(config) review_config = ReviewConfig(lintrc, lintrc_defaults) if len(review_config.linters()) == 0: log.info('No configured linters, skipping processing.') return try: log.info('Loading pull request data from github. user=%s ' 'repo=%s number=%s', user, repo, number) gh = github.get_repository(config, user, repo) pull_request = gh.pull_request(number) pr_dict = pull_request.as_dict() head_repo = pr_dict['head']['repo']['clone_url'] private_repo = pr_dict['head']['repo']['private'] pr_head = pr_dict['head']['sha'] target_branch = pr_dict['base']['ref'] if target_branch in review_config.ignore_branches(): log.info('Pull request into ignored branch %s, skipping processing.' % target_branch) return # Clone/Update repository target_path = git.get_repo_path(user, repo, number, config) git.clone_or_update(config, head_repo, target_path, pr_head, private_repo) processor = Processor(gh, number, pr_head, target_path, config) processor.load_changes() processor.run_tools(review_config) processor.publish() log.info('Completed lint processing for %s/%s/%s' % ( user, repo, number)) except BaseException, e: log.exception(e)
def test_run_tools__execute_fixers_fail(self): pull = self.get_pull_request() repo = Mock() self.tool_stub.factory.return_value = sentinel.tools self.fixer_stub.create_context.return_value = sentinel.context self.fixer_stub.run_fixers.side_effect = RuntimeError config = build_review_config(fixer_ini, app_config) subject = Processor(repo, pull, './tests', config) subject.load_changes() subject.run_tools() self.fixer_stub.create_context.assert_called() self.fixer_stub.run_fixers.assert_called() self.fixer_stub.apply_fixer_diff.assert_not_called() self.fixer_stub.rollback_changes.assert_called() self.tool_stub.run_assert_called()
def test_run_tools__import_error(self): self.tool_patcher.stop() pull = self.get_pull_request() repo = Mock() ini = """ [tools] linters = nope """ config = build_review_config(ini, app_config) subject = Processor(repo, pull, './tests', config) subject.load_changes() subject.run_tools() self.tool_patcher.start() problems = subject.problems.all() assert len(problems) == 1 assert 'could not load linters' in problems[0].body
def test_run_tools__execute_fixers_fail(self, fixer_stub, tool_stub): pull = self.get_pull_request() repo = Mock() tool_stub.factory.return_value = sentinel.tools fixer_stub.create_context.return_value = sentinel.context fixer_stub.run_fixers.side_effect = RuntimeError config = build_review_config(fixer_ini, app_config) subject = Processor(repo, pull, './tests', config) subject.load_changes() subject.run_tools() assert fixer_stub.create_context.called assert fixer_stub.run_fixers.called eq_(False, fixer_stub.apply_fixer_diff.called) eq_(True, fixer_stub.rollback_changes.called, 'Runtime error should trigger git reset.') assert tool_stub.run.called, 'Should have ran'
def _test_run_tools_fixer_error_scenario(self, error): pull = self.get_pull_request() repo = Mock() self.tool_stub.factory.return_value = sentinel.tools self.fixer_stub.create_context.return_value = sentinel.context self.fixer_stub.apply_fixer_diff.side_effect = error config = build_review_config(fixer_ini, app_config) subject = Processor(repo, pull, './tests', config) subject.load_changes() subject.run_tools() self.fixer_stub.create_context.assert_called() self.fixer_stub.run_fixers.assert_called() self.tool_stub.run.assert_called() self.fixer_stub.rollback_changes.assert_not_called() self.assertEqual(1, len(subject.problems), 'strategy error adds pull comment') self.assertEqual('Unable to apply fixers. ' + str(error), subject.problems.all()[0].body)
def _test_run_tools_fixer_error_scenario(self, error): pull = self.get_pull_request() repo = Mock() self.tool_stub.factory.return_value = sentinel.tools self.fixer_stub.create_context.return_value = sentinel.context self.fixer_stub.apply_fixer_diff.side_effect = error config = build_review_config(fixer_ini, app_config) subject = Processor(repo, pull, './tests', config) subject.load_changes() subject.run_tools() self.fixer_stub.create_context.assert_called() self.fixer_stub.run_fixers.assert_called() self.tool_stub.run.assert_called() self.fixer_stub.rollback_changes.assert_not_called() assert 1 == len(subject.problems), 'strategy error adds pull comment' assert 0 == subject.problems.error_count(), 'fixer failure should be info level' assert 'Unable to apply fixers. ' + str(error) == subject.problems.all()[0].body assert 1 == len(subject.problems), 'strategy error adds pull comment'
def _test_run_tools_fixer_error_scenario(self, error, fixer_stub, tool_stub): pull = self.get_pull_request() repo = Mock() tool_stub.factory.return_value = sentinel.tools fixer_stub.create_context.return_value = sentinel.context fixer_stub.apply_fixer_diff.side_effect = error config = build_review_config(fixer_ini, app_config) subject = Processor(repo, pull, './tests', config) subject.load_changes() subject.run_tools() assert fixer_stub.create_context.called assert fixer_stub.run_fixers.called assert tool_stub.run.called, 'Should have ran' eq_(False, fixer_stub.rollback_changes.called, 'No rollback on strategy failure') eq_(1, len(subject.problems), 'strategy error adds pull comment') eq_('Unable to apply fixers. ' + str(error), subject.problems.all()[0].body)