Skip to content

Commit aa0b18c

Browse files
authored
docs(api): Describe class fields (#567)
`NamedTuple`, dataclass, and `TypedDict` fields now describe what they hold, so the rendered API reference no longer shows "Alias for field number 0" or a bare name carrying only its type. - **Docstrings**: every field-bearing class documents each field in a NumPy `Attributes` section. - **Changelog**: a Documentation entry records the change.
2 parents a04a50d + 5f91b2e commit aa0b18c

6 files changed

Lines changed: 163 additions & 8 deletions

File tree

CHANGES

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,15 @@ $ uvx --from 'vcspull' --prerelease allow vcspull
3838
_Notes on upcoming releases will be added here_
3939
<!-- END PLACEHOLDER - ADD NEW CHANGELOG ENTRIES BELOW THIS LINE -->
4040

41+
### Documentation
42+
43+
#### Class fields describe themselves in the API reference (#567)
44+
45+
The configuration `TypedDict`s and the sync, status, and search types now
46+
say what each field holds. They previously reached the rendered API
47+
reference as "Alias for field number 0" or as a bare name carrying only its
48+
type.
49+
4150
### Development
4251

4352
#### CI actions updated to current majors

src/vcspull/cli/_output.py

Lines changed: 95 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,51 @@ class PlanAction(Enum):
2929

3030
@dataclass
3131
class PlanEntry:
32-
"""Represents a single planned action for a repository."""
32+
"""Represents a single planned action for a repository.
33+
34+
Attributes
35+
----------
36+
name : str
37+
Repository name as keyed in the config file.
38+
path : str
39+
Checkout location on disk. Human and JSON output contract the home
40+
directory to ``~``.
41+
workspace_root : str
42+
Workspace root the repository is grouped under; ``""`` when the config
43+
entry carries none, which human output groups as ``(no workspace)``.
44+
action : PlanAction
45+
Action the plan resolved for this repository.
46+
detail : str | None
47+
Short explanation of the action, such as ``"missing"`` or
48+
``"behind 2"``; ``None`` when no explanation applies.
49+
url : str | None
50+
VCS URL to clone or pull from; ``None`` when the entry carries no URL.
51+
branch : str | None
52+
Branch currently checked out; ``None`` when the checkout is absent or
53+
the branch could not be read.
54+
remote_branch : str | None
55+
Upstream tracking branch, such as ``"origin/main"``; ``None`` when
56+
unknown.
57+
current_rev : str | None
58+
Revision the checkout sits at; ``None`` when unknown.
59+
target_rev : str | None
60+
Revision a sync would move the checkout to; ``None`` when unknown.
61+
ahead : int | None
62+
Commits the local branch holds that the upstream lacks; ``None`` when
63+
the comparison is unavailable, as for a missing or non-git checkout.
64+
behind : int | None
65+
Commits the upstream holds that the local branch lacks; ``None`` when
66+
the comparison is unavailable.
67+
dirty : bool | None
68+
``True`` when the working tree has uncommitted changes; ``None`` when
69+
cleanliness could not be determined.
70+
error : str | None
71+
Message describing why planning failed for this repository; ``None``
72+
when planning succeeded.
73+
diagnostics : list[str]
74+
Extra messages carried into the serialised payload; empty when there
75+
are none, and then omitted from the payload.
76+
"""
3377

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

103147
@dataclass
104148
class PlanSummary:
105-
"""Aggregate summary for a synchronization plan."""
149+
"""Aggregate summary for a synchronization plan.
150+
151+
Attributes
152+
----------
153+
clone : int
154+
Repositories with no checkout yet, to be cloned.
155+
update : int
156+
Repositories with upstream work to pull.
157+
unchanged : int
158+
Repositories already up to date.
159+
blocked : int
160+
Repositories held back by local state: a dirty working tree,
161+
local-only commits, or divergence from the upstream.
162+
errors : int
163+
Repositories that could not be planned, such as when refreshing
164+
remotes failed.
165+
duration_ms : int | None
166+
Wall-clock time spent building the plan, in milliseconds; ``None``
167+
when no timing was recorded, and then omitted from the payload.
168+
"""
106169

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

152215
@dataclass
153216
class PlanRenderOptions:
154-
"""Rendering options for human plan output."""
217+
"""Rendering options for human plan output.
218+
219+
Attributes
220+
----------
221+
show_unchanged : bool
222+
Keep repositories whose action is ``UNCHANGED`` in the rendered rows
223+
(``--show-unchanged``); they are dropped otherwise.
224+
summary_only : bool
225+
Print the summary line alone and skip per-repository rows
226+
(``--summary-only``).
227+
long : bool
228+
Show the extended block under each row with URL, ahead/behind counts,
229+
and error text (``--long``).
230+
verbosity : int
231+
Repeated ``-v`` count, clamped to 0-2. At 1 or above, rows gain inline
232+
detail extras; at 2 they gain the extended block.
233+
relative_paths : bool
234+
Render paths relative to the workspace root (``--relative-paths``)
235+
instead of contracting the home directory to ``~``.
236+
"""
155237

156238
show_unchanged: bool = False
157239
summary_only: bool = False
@@ -162,7 +244,16 @@ class PlanRenderOptions:
162244

163245
@dataclass
164246
class PlanResult:
165-
"""Container for plan entries and their summary."""
247+
"""Container for plan entries and their summary.
248+
249+
Attributes
250+
----------
251+
entries : list[PlanEntry]
252+
One entry per repository the plan evaluated, in the order evaluation
253+
finished; rendering sorts them by action and name.
254+
summary : PlanSummary
255+
Action counts tallied across ``entries``.
256+
"""
166257

167258
entries: list[PlanEntry]
168259
summary: PlanSummary

src/vcspull/cli/search.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,20 @@ class SearchToken(t.NamedTuple):
4848

4949
@dataclass(frozen=True)
5050
class SearchPattern:
51-
"""Compiled search pattern tied to repository fields."""
51+
"""Compiled search pattern tied to repository fields.
52+
53+
Attributes
54+
----------
55+
fields : tuple[str, ...]
56+
Canonical field names the regex is applied to, carried over from the
57+
token it was compiled from.
58+
raw : str
59+
Pattern text as typed, before ``--fixed-strings`` escaping or
60+
``--word-regexp`` boundary wrapping.
61+
regex : re.Pattern[str]
62+
Matcher compiled from ``raw``, case-insensitive when ``--ignore-case``
63+
was given or smart-case resolved that way.
64+
"""
5265

5366
fields: tuple[str, ...]
5467
raw: str

src/vcspull/cli/status.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,18 @@
3030

3131
@dataclass
3232
class StatusCheckConfig:
33-
"""Configuration options for status checking."""
33+
"""Configuration options for status checking.
34+
35+
Attributes
36+
----------
37+
max_concurrent : int
38+
Ceiling on repositories inspected at once (``--max-concurrent``),
39+
bounding the semaphore that guards the async checks.
40+
detailed : bool
41+
Collect the current branch and ahead/behind counts on top of the
42+
existence, VCS, and cleanliness checks (``--detailed``). Each extra
43+
field costs another git invocation per repository.
44+
"""
3445

3546
max_concurrent: int
3647
detailed: bool

src/vcspull/cli/sync.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,18 @@
8686

8787
@dataclass
8888
class SyncPlanConfig:
89-
"""Configuration options for building sync plans."""
89+
"""Configuration options for building sync plans.
90+
91+
Attributes
92+
----------
93+
fetch : bool
94+
Run ``git fetch --prune`` before reading status (``--fetch``), so
95+
ahead/behind counts reflect current remote refs. Ignored when
96+
``offline`` is set.
97+
offline : bool
98+
Plan without touching the network (``--offline``). Repositories whose
99+
remote state cannot be compared are planned as updates.
100+
"""
90101

91102
fetch: bool
92103
offline: bool

src/vcspull/types.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,27 @@ class RepoEntryDict(_RepoEntryDictRequired, _RepoEntryDictOptional):
257257

258258

259259
class RawConfigDict(t.TypedDict):
260-
"""Configuration dictionary without any type marshalling or variable resolution."""
260+
"""Configuration dictionary without any type marshalling or variable resolution.
261+
262+
Counterpart to :class:`ConfigDict` in the shape a config file supplies:
263+
paths stay as written and shorthand entries are not yet expanded.
264+
265+
Attributes
266+
----------
267+
vcs : VCSLiteral
268+
Version control system backing the repository — ``"git"``, ``"hg"``,
269+
or ``"svn"``.
270+
name : str
271+
Repository name, taken from the key it sits under within its
272+
workspace root.
273+
path : StrPath
274+
Checkout location as written, still a :class:`str` or
275+
:class:`os.PathLike` carrying any ``~`` or environment variable.
276+
url : str
277+
VCS URL in vcspull format, e.g. ``git+git@github.com:user/repo.git``.
278+
remotes : GitSyncRemoteDict
279+
Extra git remotes to keep in sync, keyed by remote name.
280+
"""
261281

262282
vcs: VCSLiteral
263283
name: str

0 commit comments

Comments
 (0)