Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@ $ uvx --from 'vcspull' --prerelease allow vcspull
_Notes on upcoming releases will be added here_
<!-- END PLACEHOLDER - ADD NEW CHANGELOG ENTRIES BELOW THIS LINE -->

### Documentation

#### Class fields describe themselves in the API reference (#567)

The configuration `TypedDict`s and the sync, status, and search types now
say what each field holds. They previously reached the rendered API
reference as "Alias for field number 0" or as a bare name carrying only its
type.

### Development

#### CI actions updated to current majors
Expand Down
99 changes: 95 additions & 4 deletions src/vcspull/cli/_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,51 @@ class PlanAction(Enum):

@dataclass
class PlanEntry:
"""Represents a single planned action for a repository."""
"""Represents a single planned action for a repository.

Attributes
----------
name : str
Repository name as keyed in the config file.
path : str
Checkout location on disk. Human and JSON output contract the home
directory to ``~``.
workspace_root : str
Workspace root the repository is grouped under; ``""`` when the config
entry carries none, which human output groups as ``(no workspace)``.
action : PlanAction
Action the plan resolved for this repository.
detail : str | None
Short explanation of the action, such as ``"missing"`` or
``"behind 2"``; ``None`` when no explanation applies.
url : str | None
VCS URL to clone or pull from; ``None`` when the entry carries no URL.
branch : str | None
Branch currently checked out; ``None`` when the checkout is absent or
the branch could not be read.
remote_branch : str | None
Upstream tracking branch, such as ``"origin/main"``; ``None`` when
unknown.
current_rev : str | None
Revision the checkout sits at; ``None`` when unknown.
target_rev : str | None
Revision a sync would move the checkout to; ``None`` when unknown.
ahead : int | None
Commits the local branch holds that the upstream lacks; ``None`` when
the comparison is unavailable, as for a missing or non-git checkout.
behind : int | None
Commits the upstream holds that the local branch lacks; ``None`` when
the comparison is unavailable.
dirty : bool | None
``True`` when the working tree has uncommitted changes; ``None`` when
cleanliness could not be determined.
error : str | None
Message describing why planning failed for this repository; ``None``
when planning succeeded.
diagnostics : list[str]
Extra messages carried into the serialised payload; empty when there
are none, and then omitted from the payload.
"""

name: str
path: str
Expand Down Expand Up @@ -102,7 +146,26 @@ def to_payload(self) -> dict[str, t.Any]:

@dataclass
class PlanSummary:
"""Aggregate summary for a synchronization plan."""
"""Aggregate summary for a synchronization plan.

Attributes
----------
clone : int
Repositories with no checkout yet, to be cloned.
update : int
Repositories with upstream work to pull.
unchanged : int
Repositories already up to date.
blocked : int
Repositories held back by local state: a dirty working tree,
local-only commits, or divergence from the upstream.
errors : int
Repositories that could not be planned, such as when refreshing
remotes failed.
duration_ms : int | None
Wall-clock time spent building the plan, in milliseconds; ``None``
when no timing was recorded, and then omitted from the payload.
"""

clone: int = 0
update: int = 0
Expand Down Expand Up @@ -151,7 +214,26 @@ def to_payload(self) -> dict[str, t.Any]:

@dataclass
class PlanRenderOptions:
"""Rendering options for human plan output."""
"""Rendering options for human plan output.

Attributes
----------
show_unchanged : bool
Keep repositories whose action is ``UNCHANGED`` in the rendered rows
(``--show-unchanged``); they are dropped otherwise.
summary_only : bool
Print the summary line alone and skip per-repository rows
(``--summary-only``).
long : bool
Show the extended block under each row with URL, ahead/behind counts,
and error text (``--long``).
verbosity : int
Repeated ``-v`` count, clamped to 0-2. At 1 or above, rows gain inline
detail extras; at 2 they gain the extended block.
relative_paths : bool
Render paths relative to the workspace root (``--relative-paths``)
instead of contracting the home directory to ``~``.
"""

show_unchanged: bool = False
summary_only: bool = False
Expand All @@ -162,7 +244,16 @@ class PlanRenderOptions:

@dataclass
class PlanResult:
"""Container for plan entries and their summary."""
"""Container for plan entries and their summary.

Attributes
----------
entries : list[PlanEntry]
One entry per repository the plan evaluated, in the order evaluation
finished; rendering sorts them by action and name.
summary : PlanSummary
Action counts tallied across ``entries``.
"""

entries: list[PlanEntry]
summary: PlanSummary
Expand Down
15 changes: 14 additions & 1 deletion src/vcspull/cli/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,20 @@ class SearchToken(t.NamedTuple):

@dataclass(frozen=True)
class SearchPattern:
"""Compiled search pattern tied to repository fields."""
"""Compiled search pattern tied to repository fields.

Attributes
----------
fields : tuple[str, ...]
Canonical field names the regex is applied to, carried over from the
token it was compiled from.
raw : str
Pattern text as typed, before ``--fixed-strings`` escaping or
``--word-regexp`` boundary wrapping.
regex : re.Pattern[str]
Matcher compiled from ``raw``, case-insensitive when ``--ignore-case``
was given or smart-case resolved that way.
"""

fields: tuple[str, ...]
raw: str
Expand Down
13 changes: 12 additions & 1 deletion src/vcspull/cli/status.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,18 @@

@dataclass
class StatusCheckConfig:
"""Configuration options for status checking."""
"""Configuration options for status checking.

Attributes
----------
max_concurrent : int
Ceiling on repositories inspected at once (``--max-concurrent``),
bounding the semaphore that guards the async checks.
detailed : bool
Collect the current branch and ahead/behind counts on top of the
existence, VCS, and cleanliness checks (``--detailed``). Each extra
field costs another git invocation per repository.
"""

max_concurrent: int
detailed: bool
Expand Down
13 changes: 12 additions & 1 deletion src/vcspull/cli/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,18 @@

@dataclass
class SyncPlanConfig:
"""Configuration options for building sync plans."""
"""Configuration options for building sync plans.

Attributes
----------
fetch : bool
Run ``git fetch --prune`` before reading status (``--fetch``), so
ahead/behind counts reflect current remote refs. Ignored when
``offline`` is set.
offline : bool
Plan without touching the network (``--offline``). Repositories whose
remote state cannot be compared are planned as updates.
"""

fetch: bool
offline: bool
Expand Down
22 changes: 21 additions & 1 deletion src/vcspull/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,27 @@ class RepoEntryDict(_RepoEntryDictRequired, _RepoEntryDictOptional):


class RawConfigDict(t.TypedDict):
"""Configuration dictionary without any type marshalling or variable resolution."""
"""Configuration dictionary without any type marshalling or variable resolution.

Counterpart to :class:`ConfigDict` in the shape a config file supplies:
paths stay as written and shorthand entries are not yet expanded.

Attributes
----------
vcs : VCSLiteral
Version control system backing the repository — ``"git"``, ``"hg"``,
or ``"svn"``.
name : str
Repository name, taken from the key it sits under within its
workspace root.
path : StrPath
Checkout location as written, still a :class:`str` or
:class:`os.PathLike` carrying any ``~`` or environment variable.
url : str
VCS URL in vcspull format, e.g. ``git+git@github.com:user/repo.git``.
remotes : GitSyncRemoteDict
Extra git remotes to keep in sync, keyed by remote name.
"""

vcs: VCSLiteral
name: str
Expand Down