Build and Push Docker Container / build-and-push (push) Successful in 2m25s
- 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+.
56 lines
1.5 KiB
Python
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
|