Exemple #1
0
def check_common_patterns(file_path):
    """Checks for unwanted patterns in source files."""
    rel_path_from_peloton_dir = os.path.relpath(file_path, PELOTON_DIR)

    # Skip some files
    if rel_path_from_peloton_dir in SKIP_FILES_LIST:
        return True

    with open(file_path, 'r') as opened_file:
        file_status = True
        line_ctr = 1
        for line in opened_file:
            for validator_pattern in VALIDATOR_PATTERNS:
                # Check for patterns one at a time
                if validator_pattern.search(line):
                    if file_status:
                        LOG.info("Invalid pattern -- " +
                                 validator_pattern.pattern +
                                 " -- found in : " + file_path
                                )
                    LOG.info("Line %d: %s", line_ctr, line.strip())
                    file_status = False
            line_ctr += 1

    return file_status
Exemple #2
0
def check_includes(file_path):
    """Checks whether local includes are done via #include<...>"""
    with open(file_path, "r") as file:
        path_pattern = re.compile(r'^#include <(include/)?(.*?)>')
        linenum = 0
        file_status = True
        for line in file:
            linenum += 1
            res = path_pattern.match(line)
            if res:
                path = res.groups()[1]
                if path in PATHS:
                    if file_status:
                        LOG.info("Invalid include in %s", file_path)
                    file_status = False
                    LOG.info("Line %s: %s", linenum, line.strip())
        if not file_status:
            LOG.info('includes for peloton header files have must not have '
                     'brackets')
    return file_status
Exemple #3
0
def check_includes(file_path):
    """Checks whether local includes are done via #include<...>"""
    with open(file_path, "r") as file:
        path_pattern = re.compile(r'^#include <(include/)?(.*?)>')
        linenum = 0
        file_status = True
        for line in file:
            linenum += 1
            res = path_pattern.match(line)
            if res:
                path = res.groups()[1]
                if path in PATHS:
                    if file_status:
                        LOG.info("Invalid include in %s", file_path)
                    file_status = False
                    LOG.info("Line %s: %s", linenum, line.strip())
        if not file_status:
            LOG.info('includes for peloton header files have must not have '
                     'brackets'
                    )
    return file_status
Exemple #4
0
def format_file(file_path, update_header, clang_format_code):
    """Formats the file passed as argument."""
    file_name = os.path.basename(file_path)
    abs_path = os.path.abspath(file_path)
    rel_path_from_peloton_dir = os.path.relpath(abs_path, PELOTON_DIR)

    with open(file_path, "r+") as file:
        file_data = file.read()

        if update_header:
            # strip old header if it exists
            header_match = HEADER_REGEX.match(file_data)
            if not header_match is None:
                LOG.info("Strip header from %s", file_name)
                header_comment = header_match.group()
                LOG.debug("Header comment : %s", header_comment)
                file_data = file_data.replace(header_comment, "")

            # add new header
            LOG.info("Add header to %s", file_name)
            header_comment_2 = header_comment_line_3 + file_name + "\n"
            header_comment_4 = header_comment_line_5\
            + rel_path_from_peloton_dir + "\n"
            header_comment = header_comment_1 + header_comment_2 \
            + header_comment_3 + header_comment_4 \
            + header_comment_5
            #print header_comment

            file_data = header_comment + file_data

            file.seek(0, 0)
            file.truncate()
            file.write(file_data)

        elif clang_format_code:
            clang_format(file_path)
Exemple #5
0
def format_file(file_path, update_header, clang_format_code):
    """Formats the file passed as argument."""
    file_name = os.path.basename(file_path)
    abs_path = os.path.abspath(file_path)
    rel_path_from_peloton_dir = os.path.relpath(abs_path, PELOTON_DIR)

    with open(file_path, "r+") as file:
        file_data = file.read()

        if update_header:
            # strip old header if it exists
            header_match = HEADER_REGEX.match(file_data)
            if not header_match is None:
                LOG.info("Strip header from %s", file_name)
                header_comment = header_match.group()
                LOG.debug("Header comment : %s", header_comment)
                file_data = file_data.replace(header_comment,"")

            # add new header
            LOG.info("Add header to %s", file_name)
            header_comment_2 = header_comment_line_3 + file_name + "\n"
            header_comment_4 = header_comment_line_5\
            + rel_path_from_peloton_dir + "\n"
            header_comment = header_comment_1 + header_comment_2 \
            + header_comment_3 + header_comment_4 \
            + header_comment_5
            #print header_comment

            file_data = header_comment + file_data

            file.seek(0, 0)
            file.truncate()
            file.write(file_data)

        elif clang_format_code:
            clang_format(file_path)
Exemple #6
0
def check_namespaces(file_path):
    """Scans namespace openings and closings."""
    # only check for src files
    if not file_path.startswith(DEFAULT_DIRS[0]):
        return True

    # get required namespaces from path
    required_namespaces = ['peloton'] + file_path.replace(DEFAULT_DIRS[0] + "/", "").split("/")

    # for the include files, remove the include item in the list
    if 'include' in required_namespaces:
        required_namespaces.remove('include')

    # cut off the file name at the end of the list
    required_namespaces = required_namespaces[:-1]

    with open(file_path, 'r') as file:
        data = mmap.mmap(file.fileno(), 0, prot=mmap.PROT_READ)

        # scan for all namespace openings and closings
        matches = re.findall(
            r'^ *namespace ([a-z_-]+) {$|^ *} +\/\/ namespace ([a-z_-]+)$',
            data,
            flags=re.MULTILINE
        )

        open_namespaces = list()
        namespace_errors = list()

        for match in matches:
            # assert the match is either an opening or a closing
            assert match[0] or match[1]

            # 1. namespace opening
            if match[0]:
                # add to list of open namespaces
                open_namespaces.append(match[0])

                # remove from list of required namespaces
                if required_namespaces and required_namespaces[0] == match[0]:
                    required_namespaces.pop(0)

            # 2. namespace closing
            else:
                # check if correct order
                if open_namespaces and open_namespaces[-1] != match[1]:
                    namespace_errors.append(
                        "This namespace was closed in wrong order: '" +
                        match[1] +
                        "' -- in " + file_path
                    )
                # check if present at all
                if not match[1] in open_namespaces:
                    namespace_errors.append(
                        "This namespace was closed, but is missing a correct "
                        "opening: '" + match[1] + "' -- in " + file_path
                        )
                else:
                    # remove from open list
                    open_namespaces.remove(match[1])

        if required_namespaces:
            namespace_errors.append(
                "Required namespaces are missing or in wrong order: " +
                str(required_namespaces) + " -- in " + file_path
                )

        if open_namespaces:
            namespace_errors.append(
                "These namespaces were not closed properly: " +
                str(open_namespaces) + " -- in " + file_path
                )

        if namespace_errors:
            LOG.info("Invalid namespace style -- in " + file_path)
            for error in namespace_errors:
                LOG.info("  " + error)
            return False
        return True
Exemple #7
0
## ==============================================
##                 Main Function
## ==============================================

if __name__ == '__main__':

    PARSER = argparse.ArgumentParser(
        description='Perform source code validation on Peloton source'
        )
    PARSER.add_argument("-f", "--files", nargs='*',
                        help="A list of files to validate"
                       )
    ARGS = PARSER.parse_args()

    LOG.info("Running source validator ...")
    LOG.info("Peloton root : " + PELOTON_DIR)


    if ARGS.files:
        # Validate just the provided files.

        # In this mode, we perform explicit clang-format checks
        VALIDATORS.append(clang_check)
        for each_file in ARGS.files:
            each_file = os.path.abspath(each_file.lower())

            # Fail if the file isn't really a file
            if not os.path.isfile(each_file):
                LOG.info("ERROR: " + each_file + " isn't a file")
                sys.exit(EXIT_FAILURE)
Exemple #8
0
        help='Files or directories to (recursively) apply the actions to')

    ARGS = PARSER.parse_args()

    if ARGS.staged_files:
        PELOTON_DIR_bytes = bytes(PELOTON_DIR, 'utf-8')
        TARGETS = [
            str(os.path.abspath(os.path.join(PELOTON_DIR_bytes, f)), 'utf-8') \
            for f in subprocess.check_output(
                ["git", "diff", "--name-only", "HEAD", "--cached",
                 "--diff-filter=d"
                ]
            ).split()]

        if not TARGETS:
            LOG.error(
                "no staged files or not calling from a repository -- exiting")
            sys.exit("no staged files or not calling from a repository")
    elif not ARGS.paths:
        LOG.error("no files or directories given -- exiting")
        sys.exit("no files or directories given")
    else:
        TARGETS = ARGS.paths

    for x in TARGETS:
        if os.path.isfile(x):
            LOG.info("Scanning file: %s", x)
            format_file(x, ARGS.update_header, ARGS.clang_format_code)
        elif os.path.isdir(x):
            LOG.info("Scanning directory %s", x)
            format_dir(x, ARGS.update_header, ARGS.clang_format_code)
    ## FOR
Exemple #9
0
        metavar='PATH',
        type=str,
        nargs='*',
        help='Files or directories to (recursively) apply the actions to')

    ARGS = PARSER.parse_args()

    # TARGETS is a list of files with an optional list of hunks, represented as
    # pair (start, end) of line numbers, 1 based.
    # element of TARGETS: (filename, None) or (filename, [(start,end)])

    if ARGS.staged_files:
        TARGETS = hunks_from_staged_files()

        if not TARGETS:
            LOG.error(
                "no staged files or not calling from a repository -- exiting")
            sys.exit("no staged files or not calling from a repository")

    elif ARGS.number_commits > 0:
        TARGETS = hunks_from_last_commits(ARGS.number_commits)

        if not TARGETS:
            LOG.error(
                "no changes could be extracted for formatting -- exiting")
            sys.exit("no changes could be extracted for formatting")

    elif not ARGS.paths:
        LOG.error("no files or directories given -- exiting")
        sys.exit("no files or directories given")

    else:
Exemple #10
0
    ARGS = PARSER.parse_args()

    if ARGS.staged_files:
        PELOTON_DIR_bytes = bytes(PELOTON_DIR, 'utf-8')
        TARGETS = [
            str(os.path.abspath(os.path.join(PELOTON_DIR_bytes, f)), 'utf-8') \
            for f in subprocess.check_output(
                ["git", "diff", "--name-only", "HEAD", "--cached",
                 "--diff-filter=d"
                ]
            ).split()]

        if not TARGETS:
            LOG.error(
                "no staged files or not calling from a repository -- exiting"
                )
            sys.exit("no staged files or not calling from a repository")
    elif not ARGS.paths:
        LOG.error("no files or directories given -- exiting")
        sys.exit("no files or directories given")
    else:
        TARGETS = ARGS.paths

    for x in TARGETS:
        if os.path.isfile(x):
            LOG.info("Scanning file: %s", x)
            format_file(x, ARGS.update_header, ARGS.clang_format_code)
        elif os.path.isdir(x):
            LOG.info("Scanning directory %s", x)
            format_dir(x, ARGS.update_header, ARGS.clang_format_code)