fix: network property means any network reach, not only HTTP (#144)
Files changed: - CHANGES.md - VERSION - tools/CONTRACT.md - tools/chemenu/cli_contract.py - tools/chemenu/commands/git_publish.py - tools/chemenu/commands/upstream_cmd.py - tools/chemenu/commands/version_cmd.py - tools/chemenu/tests/test_cli.py - tools/chemenu/version.py
This commit is contained in:
1 parent
16c911fca5
commit
906d63fae2
9 files changed
+86
-24
No files matched your search
+25
-1
@@ -59,7 +59,7 @@ concern - readable here, never shipped as something to parse.
|
||||
|
||||
---
|
||||
|
||||
## 7.1.0-beta.22 - 2026-09-26 - fail() prints the command's ON FAILURE lines on stderr
|
||||
## 7.1.0-beta.23 - 2026-09-26 - network: property defined; sync, publish and upstream merge marked networked
|
||||
|
||||
**Author:** Torben Nehmer
|
||||
|
||||
@@ -91,6 +91,7 @@ concern - readable here, never shipped as something to parse.
|
||||
- Command records, Private instances group: one line per cause, examples, prohibitions
|
||||
- Command records, Instance health group: one bullet per check, examples
|
||||
- Command records: NOTES is always a tuple of bullets; every record's examples are tested
|
||||
- network: property defined; sync, publish and upstream merge marked networked
|
||||
<!-- /wikitool:bumps -->
|
||||
|
||||
### CalDAV task-tracker provider (Nextcloud Tasks, iOS Reminders); review reports unknown-value findings instead of skipping them
|
||||
@@ -358,6 +359,29 @@ byte-identical to before. `cli.py`'s and `_util.py`'s lookup of the running comm
|
||||
`cli_contract` path is now one shared function, `cli_contract.path_of`, in place of a private
|
||||
copy that used to live only in `cli.py`.
|
||||
|
||||
### network: Eigenschaft definiert; sync, publish und upstream merge als netzwerkend markiert
|
||||
|
||||
Gitea #144: `network:` blieb undefiniert und stand mit dem Code sowie mit sich selbst im
|
||||
Widerspruch. `sync` und `publish` (`git_publish.py`) sowie `upstream merge` (`upstream_cmd.py`)
|
||||
sprechen ein Git-Remote an (`fetch`, `ls-remote`, `push`), trugen aber `network: no`; `upstream
|
||||
verify` liest nur bereits geholte Refs und bleibt zu Recht bei `no`. Gleichzeitig behauptete
|
||||
`version check`s Datensatz, mit `version notes` eines von nur zwei netzwerkenden Kommandos in
|
||||
`wikitool` zu sein - während `review`, `task new`/`task list`/`task close` und `doctor` seit
|
||||
Gitea #121 ebenfalls `network: yes` tragen. Drei weitere Docstrings wiederholten dieselbe
|
||||
Ausschließlichkeit: der Modul- und der Befehls-Docstring von `version_cmd.py` sowie
|
||||
`fetch_latest`s Docstring in `version.py`, dessen Behauptung „the one place that talks to a
|
||||
remote host" auch unter der bisherigen, engen Lesart falsch war, da `tasks/caldav.py` und
|
||||
`tasks/superproductivity.py` ebenfalls per `urllib` sprechen.
|
||||
|
||||
Entschieden (Operator, 2026-09-26): `network:` meint jeden Netzzugriff, gleich ob per HTTP aus
|
||||
`wikitool` selbst oder per Git-Operation gegen ein Remote - maßgeblich ist, was möglich ist,
|
||||
nicht was im Normalfall passiert, und ein Git-Aufruf, der nur lokale Refs liest, zählt nicht.
|
||||
Diese Bedeutung steht jetzt im Docstring von `cli_contract.Network`. `sync`, `publish` und
|
||||
`upstream merge` tragen `network: yes`; alle vier überzähligen bzw. falschen Textstellen sind
|
||||
korrigiert, ohne eine neue Zahl zu behaupten. Ein neuer Test schreibt die Menge der `network:
|
||||
yes`-Pfade explizit fest, damit ein künftiger Wechsel eine bewusste Teständerung ist statt
|
||||
stillen Auseinanderlaufens.
|
||||
|
||||
---
|
||||
|
||||
## 7.0.0 - 2026-09-22 - Task-Tracker-Anbindung: Vorhaben als Seitenart, Verpflichtungsschicht, Weekly Review als Read-Time-Join
|
||||
|
||||
+4
-4
@@ -1611,7 +1611,7 @@ Fetch `<remote>/<branch>` and bring the local branch up to date with it.
|
||||
- idempotent: yes
|
||||
- atomic: No - fetch, then at most one merge/rebase attempt, aborted cleanly on failure
|
||||
- budget: counted
|
||||
- network: no
|
||||
- network: yes
|
||||
- gates: rebase-review
|
||||
|
||||
**EXAMPLES**
|
||||
@@ -1664,7 +1664,7 @@ Reconcile with `<remote>/<branch>`, then stage all changes, commit, and push.
|
||||
- idempotent: no
|
||||
- atomic: No - sequential git operations, but every gate runs before staging
|
||||
- budget: counted
|
||||
- network: no
|
||||
- network: yes
|
||||
- gates: mass-update, publish-remote, rebase-review
|
||||
|
||||
**EXAMPLES**
|
||||
@@ -2566,7 +2566,7 @@ Ask the origin's release feed whether a newer stack exists.
|
||||
**NOTES**
|
||||
|
||||
- Asks the release feed for its latest release and compares it with `VERSION`: `state` is `current`, `update`, `migration` (the step crosses a compatibility boundary) or `ahead`.
|
||||
- One of the **two** commands in `wikitool` that make a network call, and the only one whose whole job it is - `version notes` is the other, and only on a distributed instance.
|
||||
- The only command whose whole job is the network call - `version notes` reaches the same feed too, but only as a fallback on a distributed instance.
|
||||
- Never reached implicitly from another command, needs no key, and times out after `--timeout` seconds (default 10).
|
||||
- The feed is `--url`, else `$WIKITOOL_UPDATE_URL`, else the release stamp's, else the built-in origin. `$WIKITOOL_UPDATE_TOKEN` is only needed if that feed is not readable anonymously.
|
||||
- For `update` or `migration` it prints that applying the release is a separate, manual step (`INSTALL.md` § "Eine Instanz aktualisieren").
|
||||
@@ -3042,7 +3042,7 @@ Take a stack update into a private instance's branch, machinery only.
|
||||
- idempotent: no
|
||||
- atomic: **No** - can leave an open, uncommitted merge behind on refusal after fetching
|
||||
- budget: counted
|
||||
- network: no
|
||||
- network: yes
|
||||
|
||||
**EXAMPLES**
|
||||
|
||||
|
||||
@@ -51,6 +51,15 @@ class Budget(str, Enum):
|
||||
|
||||
|
||||
class Network(str, Enum):
|
||||
"""Whether at least one path through this command can reach an endpoint outside this
|
||||
checkout - an HTTP call `wikitool` makes itself (release feed, task tracker), or a git
|
||||
operation against a remote (`fetch`, `ls-remote`, `push`). `YES` if either kind is
|
||||
possible, not only if it is the usual case: a flag that avoids it (`--offline`,
|
||||
`--no-fetch`) or a configuration with no remote endpoint (a markdown tracker, a remote
|
||||
pointed at a local path) does not turn the value back to `NO` - what matters is whether the
|
||||
command can stall or fail on an unreachable network, not what it does on a good day. A git
|
||||
call that only reads refs already on disk (`rev-parse`, `rev-list`, `remote get-url`) is not
|
||||
a network access on its own."""
|
||||
YES = "yes"
|
||||
NO = "no"
|
||||
|
||||
|
||||
@@ -1010,6 +1010,7 @@ def apply_reconcile(outcome: ReconcileOutcome, remote: str, branch: str, command
|
||||
idempotent=cli_contract.Idempotent.YES,
|
||||
atomic="No - fetch, then at most one merge/rebase attempt, aborted cleanly on failure",
|
||||
budget=cli_contract.Budget.COUNTED,
|
||||
network=cli_contract.Network.YES,
|
||||
gates=("rebase-review",),
|
||||
),
|
||||
notes=(
|
||||
@@ -1089,6 +1090,7 @@ def sync_command(
|
||||
idempotent=cli_contract.Idempotent.NO,
|
||||
atomic="No - sequential git operations, but every gate runs before staging",
|
||||
budget=cli_contract.Budget.COUNTED,
|
||||
network=cli_contract.Network.YES,
|
||||
gates=("mass-update", "publish-remote", "rebase-review"),
|
||||
),
|
||||
notes=(
|
||||
|
||||
@@ -249,6 +249,7 @@ def _merge_success_message(
|
||||
idempotent=cli_contract.Idempotent.NO,
|
||||
atomic="**No** - can leave an open, uncommitted merge behind on refusal after fetching",
|
||||
budget=cli_contract.Budget.COUNTED,
|
||||
network=cli_contract.Network.YES,
|
||||
),
|
||||
notes=(
|
||||
"Refuses on a dirty working tree, a merge already in progress, or a remote that does "
|
||||
|
||||
@@ -24,11 +24,11 @@ number means, and `instructions/dev/version-parts.md` for the candidate model):
|
||||
*distributed* instance, whose `CHANGES.md` is a stub `dist upgrade` never
|
||||
overwrites, it falls back to the release feed, because otherwise the command
|
||||
can never answer there - not today and not after any future release.
|
||||
- `version check` and that fallback are the only two network calls in
|
||||
`wikitool`, and neither is implicit: `check` exists for the call, `notes`
|
||||
announces the URL on stderr before asking and takes `--offline`. Both need
|
||||
no key, both time out, and a feed that cannot be reached is reported as an
|
||||
error rather than silently answered as "up to date" or "no notes".
|
||||
- `version check` and that fallback both reach the release feed, and neither
|
||||
is implicit: `check` exists for the call, `notes` announces the URL on
|
||||
stderr before asking and takes `--offline`. Both need no key, both time
|
||||
out, and a feed that cannot be reached is reported as an error rather than
|
||||
silently answered as "up to date" or "no notes".
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -157,9 +157,8 @@ def show_command(
|
||||
"Asks the release feed for its latest release and compares it with `VERSION`: `state` "
|
||||
"is `current`, `update`, `migration` (the step crosses a compatibility boundary) or "
|
||||
"`ahead`.",
|
||||
"One of the **two** commands in `wikitool` that make a network call, and the only one "
|
||||
"whose whole job it is - `version notes` is the other, and only on a distributed "
|
||||
"instance.",
|
||||
"The only command whose whole job is the network call - `version notes` reaches the "
|
||||
"same feed too, but only as a fallback on a distributed instance.",
|
||||
"Never reached implicitly from another command, needs no key, and times out after "
|
||||
"`--timeout` seconds (default 10).",
|
||||
"The feed is `--url`, else `$WIKITOOL_UPDATE_URL`, else the release stamp's, else the "
|
||||
@@ -205,9 +204,10 @@ def check_command(
|
||||
):
|
||||
"""Ask the origin's release feed whether a newer stack exists.
|
||||
|
||||
The only networked command in `wikitool`. Exits 1 if the feed cannot be
|
||||
reached or does not answer with a release - an unreachable feed is not the
|
||||
same answer as "up to date", and must never be reported as one."""
|
||||
The only command whose whole job is the network call. Exits 1 if the feed
|
||||
cannot be reached or does not answer with a release - an unreachable feed
|
||||
is not the same answer as "up to date", and must never be reported as
|
||||
one."""
|
||||
import os
|
||||
|
||||
try:
|
||||
|
||||
@@ -285,6 +285,32 @@ def test_every_gated_record_shows_its_re_run_after_exit_42():
|
||||
assert missing == []
|
||||
|
||||
|
||||
def test_network_yes_is_exactly_the_commands_that_can_reach_outside_this_checkout():
|
||||
"""Gitea #144: `network:` means *any* reach outside this checkout - an HTTP call
|
||||
`wikitool` makes itself, or a git operation against a remote (fetch/ls-remote/push) -
|
||||
not only the two `version_cmd.py` used to claim exclusivity for. Pinned as an explicit
|
||||
set so a command gaining or losing that reach is a deliberate edit here, not a silent
|
||||
drift between the property and what the command actually does."""
|
||||
expected = {
|
||||
"sync",
|
||||
"publish",
|
||||
"upstream merge",
|
||||
"version check",
|
||||
"version notes",
|
||||
"review",
|
||||
"task new",
|
||||
"task list",
|
||||
"task close",
|
||||
"doctor",
|
||||
}
|
||||
actual = {
|
||||
path
|
||||
for path, rec in cli_contract.all_records().items()
|
||||
if rec.properties.network is cli_contract.Network.YES
|
||||
}
|
||||
assert actual == expected
|
||||
|
||||
|
||||
# --- fail()'s ON FAILURE hint, through two real commands (Gitea #143) ---
|
||||
|
||||
|
||||
|
||||
@@ -348,13 +348,13 @@ def fetch_latest(
|
||||
"""The version the release feed reports as latest.
|
||||
|
||||
The network call sits behind `fetcher` so every caller above this line -
|
||||
and every test - can run without a network. This is the one place in
|
||||
`wikitool` that talks to a remote host, and only two commands reach it:
|
||||
`version check`, whose whole job it is, and `version notes` on a
|
||||
*distributed* instance, whose local `CHANGES.md` is a stub with no entry to
|
||||
print (see `fetch_latest_notes`). Neither is implicit - `check` exists for
|
||||
the call, and `notes` announces the URL it is asking before it asks, on
|
||||
stderr, and takes `--offline` for a caller that wants none of it.
|
||||
and every test - can run without a network. This is the one place that
|
||||
talks to the **release feed**, and only two commands reach it: `version
|
||||
check`, whose whole job it is, and `version notes` on a *distributed*
|
||||
instance, whose local `CHANGES.md` is a stub with no entry to print (see
|
||||
`fetch_latest_notes`). Neither is implicit - `check` exists for the call,
|
||||
and `notes` announces the URL it is asking before it asks, on stderr, and
|
||||
takes `--offline` for a caller that wants none of it.
|
||||
"""
|
||||
fetch = fetcher or _urlopen_fetch
|
||||
try:
|
||||
|
||||
Reference in new issue
Block a user