feat(cli): sync folders with remote paths
Build and Push Docker Container / build-and-push (push) Successful in 1m36s
Build and Push Docker Container / build-and-push (push) Successful in 1m36s
- Store synced folder locations in file_path instead of embedding them in file names. - Add ignore rules from .nanoshareignore and repeatable sync --ignore flags. - Adopt existing remote files only after SHA-256 verification. - Move adopted remotes with metadata updates instead of uploading duplicates. - Bump NanoShare to 1.23.0 and the standalone CLI to 0.2.0.
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from fnmatch import fnmatch
|
||||
from pathlib import Path
|
||||
|
||||
IGNORE_FILE_NAME = '.nanoshareignore'
|
||||
|
||||
def load_ignore_patterns(root: Path, extra_patterns: list[str] | None = None) -> list[str]:
|
||||
patterns = [IGNORE_FILE_NAME]
|
||||
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
|
||||
continue
|
||||
if '/' in normalized:
|
||||
if fnmatch(path, normalized):
|
||||
return True
|
||||
elif any(fnmatch(part, normalized) for part in parts):
|
||||
return True
|
||||
return False
|
||||
Reference in New Issue
Block a user