예제 #1
0
def autoformat(filename, git_stage, abort, effective_filename=None):
    """ Format source code with external tools

    Args:
        filename: filename to work on
        git_stage: indicate if this is to be done on staged content
        abort: error exit in case a tool shows a problem
        effective_filename: derive type of file from this name

    Notes:
        The effective filename can be used in case this is already a
        temporary filename intended to replace another.

    Returns:
        None
    """

    # This does a lot of distinctions, pylint: disable=too-many-branches,too-many-statements

    if effective_filename is None:
        effective_filename = filename

    if os.path.isdir(effective_filename):
        return

    filename = os.path.normpath(filename)
    effective_filename = os.path.normpath(effective_filename)

    my_print("Consider", filename, end=": ")

    is_python = _isPythonFile(effective_filename)

    is_c = effective_filename.endswith((".c", ".h"))

    is_txt = effective_filename.endswith((
        ".patch",
        ".txt",
        ".rst",
        ".sh",
        ".in",
        ".md",
        ".yml",
        ".stylesheet",
        ".j2",
        ".gitignore",
        ".json",
        ".spec",
        "-rpmlintrc",
    )) or os.path.basename(filename) in (
        "changelog",
        "compat",
        "control",
        "lintian-overrides",
    )

    # Some parts of Nuitka must not be re-formatted with black or clang-format
    # as they have different intentions.
    if not (is_python or is_c or is_txt):
        my_print("Ignored file type.")
        return

    # Work on a temporary copy
    tmp_filename = filename + ".tmp"

    if git_stage:
        old_code = getFileHashContent(git_stage["dst_hash"])
    else:
        old_code = getFileContents(filename, "rb")

    with open(tmp_filename, "wb") as output_file:
        output_file.write(old_code)

    try:
        if is_python:
            cleanupWindowsNewlines(tmp_filename)

            if not _shouldNotFormatCode(effective_filename):
                _cleanupImportSortOrder(tmp_filename)
                _cleanupPyLintComments(tmp_filename, abort)

                black_call = _getPythonBinaryCall("black")

                subprocess.call(black_call + ["-q", "--fast", tmp_filename])
                cleanupWindowsNewlines(tmp_filename)

        elif is_c:
            cleanupWindowsNewlines(tmp_filename)
            _cleanupClangFormat(filename)
            cleanupWindowsNewlines(tmp_filename)
        elif is_txt:
            cleanupWindowsNewlines(tmp_filename)
            _cleanupTrailingWhitespace(tmp_filename)
            cleanupWindowsNewlines(tmp_filename)

        _transferBOM(filename, tmp_filename)

        changed = False
        if old_code != getFileContents(tmp_filename, "rb"):
            my_print("Updated.")

            with withPreserveFileMode(filename):
                if git_stage:
                    new_hash_value = putFileHashContent(tmp_filename)
                    updateFileIndex(git_stage, new_hash_value)
                    updateWorkingFile(filename, git_stage["dst_hash"],
                                      new_hash_value)
                else:
                    renameFile(tmp_filename, filename)

            changed = True
        else:
            my_print("OK.")

        return changed
    finally:
        if os.path.exists(tmp_filename):
            os.unlink(tmp_filename)
예제 #2
0
def autoformat(filename, git_stage, abort):
    # This does a lot of distinctions, pylint: disable=too-many-branches

    if os.path.isdir(filename):
        return

    filename = os.path.normpath(filename)

    my_print("Consider", filename, end=": ")

    is_python = _isPythonFile(filename)

    is_c = filename.endswith((".c", ".h"))

    is_txt = filename.endswith((
        ".patch",
        ".txt",
        ".rst",
        ".sh",
        ".in",
        ".md",
        ".yml",
        ".stylesheet",
        ".j2",
        ".gitignore",
        ".json",
        ".spec",
        "-rpmlintrc",
    )) or os.path.basename(filename) in (
        "changelog",
        "compat",
        "control",
        "lintian-overrides",
    )

    # Some parts of Nuitka must not be re-formatted with black or clang-format
    # as they have different intentions.
    if not (is_python or is_c or is_txt):
        my_print("Ignored file type")
        return

    # Work on a temporary copy
    tmp_filename = filename + ".tmp"

    if git_stage:
        old_code = getFileHashContent(git_stage["dst_hash"])
    else:
        old_code = getFileContents(filename, "rb")

    with open(tmp_filename, "wb") as output_file:
        output_file.write(old_code)

    try:
        if is_python:
            _cleanupWindowsNewlines(tmp_filename)

            if not _shouldNotFormatCode(filename):
                _cleanupImportSortOrder(tmp_filename)
                _cleanupPyLintComments(tmp_filename, abort)

                black_call = _getPythonBinaryCall("black")

                subprocess.call(black_call + ["-q", "--fast", tmp_filename])
                _cleanupWindowsNewlines(tmp_filename)

        elif is_c:
            _cleanupWindowsNewlines(tmp_filename)
            _cleanupClangFormat(filename)
            _cleanupWindowsNewlines(tmp_filename)
        elif is_txt:
            _cleanupWindowsNewlines(tmp_filename)
            _cleanupTrailingWhitespace(tmp_filename)
            _cleanupWindowsNewlines(tmp_filename)

        transferBOM(filename, tmp_filename)

        changed = False
        if old_code != getFileContents(tmp_filename, "rb"):
            my_print("Updated.")

            with withPreserveFileMode(filename):
                if git_stage:
                    new_hash_value = putFileHashContent(tmp_filename)
                    updateFileIndex(git_stage, new_hash_value)
                    updateWorkingFile(filename, git_stage["dst_hash"],
                                      new_hash_value)
                else:
                    renameFile(tmp_filename, filename)

            changed = True
        else:
            my_print("OK.")

        return changed
    finally:
        if os.path.exists(tmp_filename):
            os.unlink(tmp_filename)