mirror of
https://github.com/kuhyx/utils.git
synced 2026-11-10 21:27:14 +01:00
My local pre-commit cache holds three ruff versions and I had been resolving `ls ... | head -1`, which picks 0.14.5 — CI pins 0.15.2, and the newer version flags eight things the older one does not (unused imports left behind in _syncargs.py and tool/_oauth_callback.py, import ordering, an empty TYPE_CHECKING block). Re-ran against the pinned binary; `ruff check` is now "All checks passed!" under the same version CI uses. 259 tests at 100% branch coverage, `pre-commit run --all-files` clean for this config, and `python3 -m tool.google_id_token --help` still runs. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CFSGeWxHPY5rHUGrPqhcmG
93 lines
3.0 KiB
Python
93 lines
3.0 KiB
Python
"""The three argument bundles :func:`crdt_sync.sync_log` takes.
|
|
|
|
Split from :mod:`crdt_sync._sync` for the 250-line cap. Grouping sync_log's
|
|
arguments into what/how/whether bundles is what keeps its signature readable;
|
|
the bundles themselves carry no behaviour.
|
|
|
|
Re-exported from :mod:`crdt_sync._sync`, so existing imports keep working.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
from typing import TYPE_CHECKING
|
|
|
|
if TYPE_CHECKING:
|
|
from collections.abc import Callable
|
|
|
|
from crdt_sync._log import Log
|
|
from crdt_sync._remote import RemoteStore
|
|
from crdt_sync._syncstate import SyncStateStore
|
|
|
|
|
|
_DEFAULT_FILENAME = "log.json"
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class SyncTarget:
|
|
"""Which remote, which device, and where its logs live.
|
|
|
|
Args:
|
|
client: An authenticated :class:`RemoteStore` -- a
|
|
:class:`crdt_sync.GitHubSyncClient`, a
|
|
:class:`crdt_sync.FirebaseSyncClient`, or a mirror of both.
|
|
device_id: This device's identifier; also the directory name its own
|
|
log is pushed under.
|
|
path_prefix: The directory holding one subdirectory per device
|
|
(e.g. ``"devices"``).
|
|
legacy_device_id: The id this device pushed under before migrating to
|
|
a persisted uuid. Treated as this device's own for skip-own
|
|
purposes, so its pre-migration log is not pulled back and
|
|
re-merged as a peer's. Pass ``None`` once the old path has been
|
|
reclaimed.
|
|
"""
|
|
|
|
client: RemoteStore
|
|
device_id: str
|
|
path_prefix: str
|
|
legacy_device_id: str | None = None
|
|
|
|
@property
|
|
def own_ids(self) -> frozenset[str]:
|
|
"""Every id whose pushed log belongs to this device."""
|
|
if self.legacy_device_id is None:
|
|
return frozenset({self.device_id})
|
|
return frozenset({self.device_id, self.legacy_device_id})
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class LogCodec:
|
|
"""How a log is turned into pushed text and back.
|
|
|
|
Args:
|
|
encode: Serializes a merged log for pushing.
|
|
decode: Parses a remote device's pushed text back into a log.
|
|
Raising ``ValueError``, ``KeyError``, or ``TypeError`` is treated
|
|
as a corrupt/unparsable push, and that device is skipped for
|
|
this tick rather than aborting the whole sync.
|
|
filename: The file name each device pushes its log as.
|
|
commit_message: The commit message used for this device's push.
|
|
"""
|
|
|
|
encode: Callable[[Log], str]
|
|
decode: Callable[[str], Log]
|
|
filename: str = _DEFAULT_FILENAME
|
|
commit_message: str = "crdt_sync: update log"
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class RevisionTracking:
|
|
"""Optional skip-unchanged behaviour for a tick.
|
|
|
|
Omit it entirely and the tick behaves exactly as it always did: fetch
|
|
everything, push unconditionally.
|
|
|
|
Args:
|
|
state_store: Persists what this device last pushed and last merged.
|
|
revs_path: Where revisions live; defaults to
|
|
:func:`default_revs_path`.
|
|
"""
|
|
|
|
state_store: SyncStateStore | None = None
|
|
revs_path: str | None = None
|