mirror of
https://github.com/kuhyx/utils.git
synced 2026-11-10 22:27:13 +01:00
The hook entry was an absolute /home/kuhy/utils path, copied from a config written for ~/.claude where it only ever ran locally. On an Actions runner that is exit code 127 — "No such file or directory" — so gatelock-precommit and crdt-sync-precommit failed on every commit of this refactor while the hook silently checked nothing. Now repo-relative, matching the sibling hooks (`entry: scripts/check_subproject_scope.sh`): pre-commit always runs from the git root, so it resolves the same in both places. Fixing that made the CI configs runnable locally, and `--all-files` then found what per-file runs had missed — ruff pruning imports that exist *for* their re-export. `import crdt_sync` was broken three separate ways (FileSyncStateStore, encode_key, FileCredentialStore). Each affected module now states an explicit __all__ so the autofixer cannot take them again, and the two files that pushed past the cap once __all__ was added are split further: _firebase.py 260 -> 247 + _fberrors 25 _sync.py 257 -> 188 + _syncargs 91 Test patch targets followed the code they patch: gatelock._outputs.shutil -> _xrandr.shutil, gatelock._arbiter.Path -> _claims.Path. gatelock and crdt-sync both pass `pre-commit run --all-files` in full; 389 and 259 tests at 100% branch coverage; the root gate exits 0. 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, field
|
|
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
|