Example #1
0
    def post_messages(self, messages, max_comments):
        # TODO: support non-PR runs
        if not self.github:
            print('Github connection is invalid.')
            return
        messages_to_post = 0
        messages_posted = 0
        paths = dict()

        # randomize message order to more evenly distribute messages across different files
        messages = list(messages)
        random.shuffle(messages)
        if self.out_of_date():
            print('This run is out of date because the PR has been updated.')
            messages = []
        start = time.time()
        print("Considering {} messages for posting.".format(len(messages)))
        for msg in messages:
            print('\nTrying to post a review comment.')
            print('{0}'.format(msg))
            if system.should_stop() or (time.time() - start > 10
                                        and self.out_of_date()):
                print('Stopping early.')
                break
            if not msg.comments:
                print("Skipping since there is no comment to post.")
                continue
            msg_position = self.position(msg)
            if not msg_position:
                print("Skipping since the comment is not part of this PR.")
                continue
            messages_to_post += 1
            if self.is_duplicate(msg, msg_position):
                print("Skipping since this comment already exists.")
                continue
            # skip this message if we already have too many comments on this file
            # max comments / 5 is an arbitrary number i totally made up. should maybe be configurable.
            if paths.setdefault(msg.path, 0) > max(max_comments // 5, 5):
                print(
                    "Skipping since we reached the maximum number of comments for this file."
                )
                continue
            if msg.path.split('/')[0] in self.ignore_paths:
                print("Skipping since the comment is on an ignored path.")
                continue
            try:
                self.pull_request.create_review_comment(
                    self.format_message(msg), self.last_sha, msg.path,
                    msg_position)
            except github3.GitHubError as err:
                print("Posting failed: {}".format(err))
                continue
            print("Comment posted successfully.")
            paths[msg.path] += 1
            messages_posted += 1
            if max_comments and messages_posted > max_comments:
                break
        print('\n{} messages posted to Github.'.format(messages_posted))
        return messages_to_post
Example #2
0
def lint(install=False,
         autorun=False,
         ignore_paths=None,
         config_dir=None,
         enabled_linters=None,
         disabled_linters=None,
         trusted=False):
    messages = message.Messages()
    cleanup()
    performance_hacks()
    if trusted and (install or autorun):
        install_trusted()
    for linter in linters_to_run(autorun, ignore_paths, enabled_linters,
                                 disabled_linters):
        if system.should_stop():
            return messages.get_messages()
        print('=' * 80)
        print('Running linter: {0}'.format(linter))
        sys.stdout.flush()
        start = time.time()
        output = ''
        config = LINTERS.get(linter)
        try:
            if (install or autorun) and config.get('install'):
                install_linter(config)
            if config.get('run_per_file'):
                output = run_per_file(config, ignore_paths, config_dir)
            else:
                cmd = run_config(config, config_dir)
                print(cmd)
                _, output = run_command(cmd)
                output = output.strip()
        except Exception:
            print('Running {0} failed:'.format(linter))
            print(traceback.format_exc())
            print('Failed {0} output: '.format(linter) +
                  str(output).encode('ascii', errors='replace'))
        print('Installation and running of {0} took {1} seconds'.format(
            linter, int(time.time() - start)))
        sys.stdout.flush()
        start = time.time()
        try:
            if output:
                linter_messages = config.get('parser')().parse(output)
                print('Found {0} messages from {1}'.format(
                    len(linter_messages), linter))
                # prepend linter name to message content
                linter_messages = {(msg[0], msg[1],
                                    '{0}: {1}'.format(linter, msg[2]))
                                   for msg in linter_messages}
                messages.add_messages(linter_messages)
        except Exception:
            print('Parsing {0} output failed:'.format(linter))
            print(traceback.format_exc())
            print(str(output).encode('ascii', errors='replace'))
        print('Parsing of {0} took {1} seconds'.format(
            linter, int(time.time() - start)))
    return messages.get_messages()
Example #3
0
def lint(install=False,
         autorun=False,
         ignore_paths=None,
         config_dir=None,
         enabled_linters=None,
         disabled_linters=None,
         trusted=False):
    messages = message.Messages()
    cleanup()
    performance_hacks()
    if trusted and (install or autorun):
        install_trusted()
    for linter in linters_to_run(install, autorun, ignore_paths,
                                 enabled_linters, disabled_linters):
        if system.should_stop():
            return messages.get_messages()
        print('Running linter: {0}'.format(linter))
        sys.stdout.flush()
        start = time.time()
        output = ''
        config = LINTERS.get(linter)
        try:
            if (install or autorun) and config.get('install'):
                install_linter(config)
            if config.get('run_per_file'):
                output = run_per_file(config, ignore_paths, config_dir)
            else:
                cmd = run_config(config, config_dir)
                print(cmd)
                _, output = run_command(cmd)
        except Exception:
            traceback.print_exc()
            print(str(output).encode('ascii', errors='replace'))
        print('Installation and running of {0} took {1} seconds'.format(
            linter, int(time.time() - start)))
        sys.stdout.flush()
        start = time.time()
        try:
            if output:
                linter_messages = config.get('parser')().parse(output)
                # prepend linter name to message content
                linter_messages = {
                    (msg[0], msg[1], '{0}: {1}'.format(linter, msg[2]))
                    for msg in linter_messages
                }
                messages.add_messages(linter_messages)
        except Exception:
            traceback.print_exc()
            print(str(output).encode('ascii', errors='replace'))
        print('Parsing of {0} took {1} seconds'.format(
            linter, int(time.time() - start)))
    return messages.get_messages()
Example #4
0
    def post_messages(self, messages, max_comments):
        # TODO: support non-PR runs
        if not self.github:
            print('Github connection is invalid.')
            return
        messages_to_post = 0
        messages_posted = 0
        paths = dict()

        # randomize message order to more evenly distribute messages across different files
        messages = list(messages)
        random.shuffle(messages)
        if self.out_of_date():
            print('This run is out of date because the PR has been updated.')
            messages = []
        start = time.time()
        for msg in messages:
            if system.should_stop() or (time.time() - start > 10
                                        and self.out_of_date()):
                print('Stopping early.')
                break
            if not msg.comments:
                continue
            msg_position = self.position(msg)
            if not msg_position:
                continue
            messages_to_post += 1
            if self.is_duplicate(msg, msg_position):
                continue
            # skip this message if we already have too many comments on this file
            # max comments / 5 is an arbitrary number i totally made up. should maybe be configurable.
            if paths.setdefault(msg.path, 0) > max_comments // 5:
                continue
            if msg.path.split('/')[0] in self.ignore_paths:
                continue
            try:
                print('Creating review comment: {0}'.format(msg))
                self.pull_request.create_review_comment(
                    self.format_message(msg), self.last_sha, msg.path,
                    msg_position)
            except github3.GitHubError:
                pass
            paths[msg.path] += 1
            messages_posted += 1
            if max_comments >= 0 and messages_posted > max_comments:
                break
        print('{} messages posted to Github.'.format(messages_posted))
        return messages_to_post
Example #5
0
    def post_messages(self, messages, max_comments):
        # TODO: support non-PR runs
        if not self.github:
            return
        messages_to_post = 0
        messages_posted = 0
        paths = dict()

        # randomize message order to more evenly distribute messages across different files
        messages = list(messages)
        random.shuffle(messages)
        if self.out_of_date():
            return messages_to_post
        start = time.time()
        for msg in messages:
            if system.should_stop() or (time.time() - start > 10 and self.out_of_date()):
                return messages_to_post
            if not msg.comments:
                continue
            msg_position = self.position(msg)
            if msg_position:
                messages_to_post += 1
                if not self.is_duplicate(msg, msg_position):
                    # skip this message if we already have too many comments on this file
                    # max comments / 5 is an arbitrary number i totally made up. should maybe be configurable.
                    if paths.setdefault(msg.path, 0) > max_comments // 5:
                        continue
                    try:
                        self.pull_request.create_review_comment(
                            self.format_message(msg),
                            self.last_sha,
                            msg.path,
                            msg_position
                        )
                    except github3.GitHubError:
                        pass
                    paths[msg.path] += 1
                    messages_posted += 1
                    if max_comments >= 0 and messages_posted > max_comments:
                        break
        print('{} messages posted to Github.'.format(messages_to_post))
        return messages_to_post
Example #6
0
    def post_messages(self, messages, max_comments):
        # TODO: support non-PR runs
        if not self.github:
            return
        messages_to_post = 0
        messages_posted = 0
        paths = dict()

        # randomize message order to more evenly distribute messages across different files
        messages = list(messages)
        random.shuffle(messages)
        if self.out_of_date():
            return messages_to_post
        start = time.time()
        for msg in messages:
            if system.should_stop() or (time.time() - start > 10 and self.out_of_date()):
                return messages_to_post
            if not msg.comments:
                continue
            msg_position = self.position(msg)
            if msg_position:
                messages_to_post += 1
                if not self.is_duplicate(msg, msg_position):
                    # skip this message if we already have too many comments on this file
                    # max comments / 5 is an arbitrary number i totally made up. should maybe be configurable.
                    if paths.setdefault(msg.path, 0) > max_comments // 5:
                        continue
                    try:
                        self.pull_request.create_review_comment(
                            self.format_message(msg),
                            self.last_sha,
                            msg.path,
                            msg_position
                        )
                    except github3.GitHubError:
                        pass
                    paths[msg.path] += 1
                    messages_posted += 1
                    if max_comments >= 0 and messages_posted > max_comments:
                        break
        return messages_to_post
Example #7
0
    def post_messages(self, messages, max_comments):
        if not self.github:
            print("Github connection is invalid.")
            return

        valid_errors = 0
        messages_posted = 0
        paths = dict()

        # randomize message order to more evenly distribute messages across different files
        messages = list(messages)
        random.shuffle(messages)
        if self.out_of_date():
            print("This run is out of date because the PR has been updated.")
            messages = []
        print("Considering {} messages for posting.".format(len(messages)))
        for msg in messages:
            # rate limit
            if system.should_stop() or self.out_of_date():
                print("Stopping early.")
                self.stopped_early = True
                break

            if not msg.comments:
                continue

            msg_position = self.position(msg)
            if not msg_position:
                continue

            if msg.path.split("/")[0] in self.ignore_paths:
                continue

            paths.setdefault(msg.path, 0)

            valid_errors += 1
            duplicate = self.is_duplicate(msg, msg_position)
            if duplicate:
                try:
                    duplicate.edit(self.format_message(msg))
                    self.messages_in_files.setdefault(msg.path, []).append(
                        (msg, msg_position))
                    print("Comment edited successfully: {0}".format(msg))
                    paths[msg.path] += 1
                    messages_posted += 1
                    time.sleep(.1)
                    continue

                except github3.GitHubError:
                    pass

            try:
                self.pull_request.create_review_comment(
                    self.format_message(msg), self.last_sha, msg.path,
                    msg_position)
                self.messages_in_files.setdefault(msg.path, []).append(
                    (msg, msg_position))
            except github3.GitHubError:
                # workaround for our diff not entirely matching up with github's diff
                # we can end up with a mismatched diff if the branch is old
                valid_errors -= 1
                continue

            print("Comment posted successfully: {0}".format(msg))
            paths[msg.path] += 1
            messages_posted += 1
            time.sleep(.1)
            if max_comments and messages_posted > max_comments:
                break

        print("\n{} messages posted to Github.".format(messages_posted))
        return valid_errors
Example #8
0
def lint(
    install=False,
    autorun=False,
    ignore_paths=None,
    config_dir=None,
    enabled_linters=None,
    disabled_linters=None,
    trusted=False,
):
    messages = message.Messages()
    cleanup()
    performance_hacks()
    if trusted and (install or autorun):
        install_trusted()
    for linter in linters_to_run(autorun, ignore_paths, enabled_linters,
                                 disabled_linters):
        if system.should_stop():
            return messages.get_messages()

        print("=" * 80)
        print("Running linter: {0}".format(linter))
        sys.stdout.flush()
        start = time.time()
        output = ""
        config = LINTERS.get(linter)
        try:
            if (install or autorun) and config.get("install"):
                install_linter(config)
            if config.get("run_per_file"):
                output = run_per_file(config, ignore_paths, config_dir)
            else:
                cmd = run_config(config, config_dir)
                _, output = run_command(cmd)
                output = output.strip()
        except Exception:
            print("Running {0} failed:".format(linter))
            print(traceback.format_exc())
            print("Failed {0} output: {1}".format(linter, output))
        print("Installation and running of {0} took {1} seconds".format(
            linter, int(time.time() - start)))
        sys.stdout.flush()
        start = time.time()
        try:
            if output:
                linter_messages = config.get("parser")().parse(output)
                # prepend linter name to message content
                linter_messages = {
                    (msg[0], msg[1], "{0}: {1}".format(linter, msg[2]))
                    for msg in linter_messages
                    if not should_ignore_path(msg[0], ignore_paths)
                }
                print("Found {0} messages from {1}".format(
                    len(linter_messages), linter))
                messages.add_messages(linter_messages)
        except Exception:
            print("Parsing {0} output failed:".format(linter))
            print(traceback.format_exc())
            print(output)
        print("Parsing of {0} took {1} seconds".format(
            linter, int(time.time() - start)))
    return messages.get_messages()