Files
nx_post_support/server/libs/tclint/cli/utils.py
T
2026-06-18 17:21:58 +02:00

57 lines
1.9 KiB
Python

import codecs
import os
import re
from collections import defaultdict
from pathlib import Path
from typing import Callable
import pathspec
from tclint.config import ExcludePattern
def register_codec_warning(name):
def replace_with_warning_handler(e):
# TODO: formal warning mechanism, include path
print("Warning: non-unicode characters in file, replacing with ")
return codecs.replace_errors(e)
codecs.register_error(name, replace_with_warning_handler)
def make_exclude_filter(
exclude_patterns: list[ExcludePattern],
) -> Callable[[Path], bool]:
# Transform patterns into a data structure keyed on root.
patterns_by_root = defaultdict(list)
for pattern, root in exclude_patterns:
# I think this is escaping #, which would otherwise be treated like a comment.
# Not 100% sure though, I originally wrote this a while ago.
pattern = re.sub(r"^\s*#", r"\#", pattern)
patterns_by_root[root.resolve()].append(pattern)
compiled_patterns = {}
for root in patterns_by_root.keys():
patterns = patterns_by_root[root]
spec = pathspec.PathSpec.from_lines("gitwildmatch", patterns)
compiled_patterns[root] = spec
def is_excluded(path: Path) -> bool:
abspath = path.resolve()
for root, exclude_spec in compiled_patterns.items():
try:
relpath = Path(os.path.relpath(abspath, start=root))
except ValueError:
# We get here if path and exclude_root are on different drives (on
# Windows).Things should still behave roughly as expected without
# using a relative path. See
# test_cli_utils.py::test_exclude_filter_windows for test cases.
relpath = abspath
if exclude_spec.match_file(relpath):
return True
return False
return is_excluded