Add a sync-project-tree workflow that regenerates this repo's tracked-file tree and opens (or force-updates) a PR against RunicGateway/docs whenever the layout on main changes. Never writes to the docs repo's main directly. Reuses the existing REGISTRY_USER / REGISTRY_TOKEN secrets. Tree rendering lives in .gitea/scripts/gen_tree.py (deterministic, dirs-first ordering). Co-Authored-By: Claude <noreply@anthropic.com>
55 lines
1.7 KiB
Python
55 lines
1.7 KiB
Python
#!/usr/bin/env python3
|
|
"""Render an ASCII tree of tracked files, read from stdin (one path per line).
|
|
|
|
Used by the `sync-project-tree` workflow to regenerate this repo's PROJECT_TREE.md
|
|
snapshot in the RunicGateway/docs repo. Feed it `git ls-files`:
|
|
|
|
git ls-files | python3 .gitea/scripts/gen_tree.py <root-label>
|
|
|
|
Deterministic ordering: directories before files, each group sorted
|
|
case-insensitively with the raw name as a tiebreak. Output uses the classic
|
|
`tree(1)` box-drawing style so the result is stable across runs and platforms.
|
|
"""
|
|
import sys
|
|
|
|
|
|
def build(paths):
|
|
root = {}
|
|
for p in paths:
|
|
p = p.strip().replace("\\", "/")
|
|
if not p:
|
|
continue
|
|
node = root
|
|
for part in p.split("/"):
|
|
node = node.setdefault(part, {})
|
|
return root
|
|
|
|
|
|
def render(node, prefix, lines):
|
|
entries = list(node.items())
|
|
# directories (non-empty children dict) before files, then case-insensitive name
|
|
entries.sort(key=lambda kv: (0 if kv[1] else 1, kv[0].lower(), kv[0]))
|
|
for i, (name, child) in enumerate(entries):
|
|
last = i == len(entries) - 1
|
|
branch = "└── " if last else "├── "
|
|
suffix = "/" if child else ""
|
|
lines.append(f"{prefix}{branch}{name}{suffix}")
|
|
if child:
|
|
render(child, prefix + (" " if last else "│ "), lines)
|
|
|
|
|
|
def main():
|
|
try:
|
|
sys.stdout.reconfigure(encoding="utf-8", newline="\n")
|
|
except AttributeError:
|
|
pass
|
|
root_label = sys.argv[1] if len(sys.argv) > 1 else "."
|
|
tree = build(sys.stdin.read().splitlines())
|
|
lines = [f"{root_label}/"]
|
|
render(tree, "", lines)
|
|
sys.stdout.write("\n".join(lines) + "\n")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|