Files
simple-nanoshare/cli/nanoshare_client/ignore.py
T
daniel156161 73fdeacbfe
Build and Push Docker Container / build-and-push (push) Successful in 2m25s
feat!: adopt Python 3.14 and 3.15 language features
- Require Python 3.15 for the server and Python 3.14 for the CLI.
- Match the server requirement to quart_common's Python 3.15 features.
- Replace future annotations with native deferred evaluation.
- Defer CLI command dependencies and QR imports on Python 3.15.
- Enable argparse suggestions for mistyped CLI commands.
- Remove the obsolete tomllib import fallback.
- Update my_helpers and quart_common submodule references.
- Lock test dependencies and exclude them from Docker installations.
- Add regression coverage for lazy imports and deferred annotations.
- Document runtime requirements and standalone CLI validation.
- Validate 276 tests on Python 3.15 and 18 CLI tests on Python 3.14.

BREAKING CHANGE: The server now requires Python 3.15+ and the standalone CLI requires Python 3.14+.
2026-10-26 14:47:29 +01:00

56 lines
1.5 KiB
Python

from fnmatch import fnmatch
from pathlib import Path
IGNORE_FILE_NAME = '.nanoshareignore'
DEFAULT_IGNORE_PATTERNS = [
IGNORE_FILE_NAME,
'.comments/',
'.env',
'.env.*',
'.venv/',
'venv/',
'__pycache__/',
'.pytest_cache/',
'.mypy_cache/',
'.ruff_cache/',
'.git/',
'.hg/',
'.svn/',
'.DS_Store',
'Thumbs.db',
'desktop.ini',
'$RECYCLE.BIN/',
'System Volume Information/',
]
def load_ignore_patterns(root: Path, extra_patterns: list[str] | None = None) -> list[str]:
patterns = list(DEFAULT_IGNORE_PATTERNS)
ignore_file = root / IGNORE_FILE_NAME
if ignore_file.is_file():
for line in ignore_file.read_text().splitlines():
pattern = line.strip()
if pattern and not pattern.startswith('#'):
patterns.append(pattern)
patterns.extend(pattern for pattern in extra_patterns or [] if pattern)
return patterns
def is_ignored(rel_path: str, patterns: list[str]) -> bool:
path = rel_path.strip('/')
parts = path.split('/')
for pattern in patterns:
normalized = pattern.strip().replace('\\', '/').strip('/')
if not normalized:
continue
if pattern.endswith('/'):
if path == normalized or path.startswith(f'{normalized}/'):
return True
if any(fnmatch(part, normalized) for part in parts):
return True
continue
if '/' in normalized:
if fnmatch(path, normalized):
return True
elif any(fnmatch(part, normalized) for part in parts):
return True
return False