nested_pages: Katalogtiefe 1 durchgesetzt, layout:-dir validiert, move raeumt geleerte Verzeichnisse - die drei #57-Seiten hochgezogen (schliesst #57)
CI / verify (push) Successful in 1m0s
Release / release (push) Successful in 37s

Files changed:
- CHANGES.md
- VERSION
- kb/CONTRACT.md
- kb/entities/projects/kfchou/wiki-skills.md
- kb/entities/projects/llm-wiki-skills.md
- kb/entities/projects/vanillaflava/wiki-skills-vanillaflava.md
- kb/entities/projects/wiki-skills-vanillaflava.md
- kb/entities/projects/wiki-skills.md
- kb/entities/projects/yugasun/llm-wiki-skills.md
- kb/log.md
- tools/CONTRACT.md
- tools/chemenu/commands/index_build.py
- tools/chemenu/commands/page_ops.py
- tools/chemenu/kb_scan.py
- tools/chemenu/lint_core.py
- tools/chemenu/tests/test_index_build.py
- tools/chemenu/tests/test_kb_scan.py
- tools/chemenu/tests/test_lint.py
- tools/chemenu/tests/test_page_ops.py
- tools/chemenu/tests/test_type_resolver.py
- tools/chemenu/type_resolver.py
This commit is contained in:
torben committed 2026-09-04 23:19:30 +02:00
1 parent 9e414319b8
commit 251e597c63
18 files changed
+331 -10

No files matched your search

+12 -1
View File
@@ -28,7 +28,7 @@ from chemenu import config
from chemenu.commands._util import rel_path, success
from chemenu.kb_collections import iter_kb_collections
from chemenu.page import Page
from chemenu.kb_scan import GENERATED_INDEX, load_kb_pages
from chemenu.kb_scan import GENERATED_INDEX, find_nested_pages, load_kb_pages
from chemenu.type_resolver import resolver
app = typer.Typer(help="Manage the generated wiki catalog (kb/index.md + per-collection INDEX.md).")
@@ -302,6 +302,17 @@ def index_rebuild(
False, "--dry-run", help="Print what would be written instead of writing it"
),
):
# Reported, not refused (#57 decision): a nested page still gets a catalog
# written for it, just a wrong one (folded into its area, no distinct
# location of its own) - `wikitool lint`'s `nested_pages` is the hard
# finding this warning previews.
for title, page, depth in find_nested_pages(config.KB_DIR, load_kb_pages(config.KB_DIR)):
typer.echo(
f"WARNING: [[{title}]] is {depth} directories below its collection "
f"({rel_path(page.path.parent)}) - the catalog folds it into the area silently. "
"See `wikitool lint`'s Nested Pages finding."
)
plan = plan_index(config.KB_DIR)
stale = stale_shards(config.KB_DIR, plan)
+30 -2
View File
@@ -381,6 +381,24 @@ def rm_command(
)
def _rmdir_if_emptied(directory: Path) -> bool:
"""Remove `directory` if the move that just vacated it left it empty.
Symmetric with the `target_dir.mkdir(parents=True, exist_ok=True)` a move
does on the way in: without this, a hand-nested directory (#57) survives
its own fix, and a directory-shape test would still find it after every
page under it moved out. Never touches `kb/` itself, and only ever a
directory this move just emptied - never a pre-existing empty one it
happens to pass through.
"""
if directory.resolve() == config.KB_DIR.resolve():
return False
if not directory.is_dir() or any(directory.iterdir()):
return False
directory.rmdir()
return True
def move_command(
page_title: Optional[str] = typer.Option(
None, "--page", help="Exact title of the page to move to its computed location"
@@ -431,7 +449,9 @@ def move_command(
moved: list[str] = []
failed: list[str] = list(collisions)
removed_dirs = 0
for title, page, target_dir, new_path in planned:
old_dir = page.path.parent
try:
target_dir.mkdir(parents=True, exist_ok=True)
page.path.rename(new_path)
@@ -440,13 +460,17 @@ def move_command(
continue
moved.append(title)
typer.echo(f" moved '{title}' -> {rel_path(new_path)}")
if _rmdir_if_emptied(old_dir):
removed_dirs += 1
typer.echo(f" removed empty {rel_path(old_dir)}")
if failed:
fail(
f"Moved {len(moved)}/{len(candidates)} page(s) before a failure: {', '.join(failed)}. "
"Safe to retry - `move --reconcile` only re-moves what is still misplaced."
)
success(f"Moved {len(moved)} page(s). Run `wikitool index rebuild` next.")
removed_note = f", removed {removed_dirs} emptied dir(s)" if removed_dirs else ""
success(f"Moved {len(moved)} page(s){removed_note}. Run `wikitool index rebuild` next.")
return
target = pages.get(page_title)
@@ -473,6 +497,10 @@ def move_command(
typer.echo(f"[dry-run] would move {rel_path(target.path)} -> {rel_path(new_path)}")
return
old_dir = target.path.parent
target_dir.mkdir(parents=True, exist_ok=True)
target.path.rename(new_path)
success(f"Moved '{page_title}' -> {rel_path(new_path)}. Run `wikitool index rebuild` next.")
removed_note = ""
if _rmdir_if_emptied(old_dir):
removed_note = f" Removed emptied {rel_path(old_dir)}."
success(f"Moved '{page_title}' -> {rel_path(new_path)}.{removed_note} Run `wikitool index rebuild` next.")