svc-infra 0.1.619__py3-none-any.whl → 0.1.620__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of svc-infra might be problematic. Click here for more details.
- svc_infra/cli/cmds/docs/docs_cmds.py +54 -29
- {svc_infra-0.1.619.dist-info → svc_infra-0.1.620.dist-info}/METADATA +1 -1
- {svc_infra-0.1.619.dist-info → svc_infra-0.1.620.dist-info}/RECORD +5 -5
- {svc_infra-0.1.619.dist-info → svc_infra-0.1.620.dist-info}/WHEEL +0 -0
- {svc_infra-0.1.619.dist-info → svc_infra-0.1.620.dist-info}/entry_points.txt +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import importlib.util
|
|
3
4
|
import os
|
|
4
5
|
from importlib.metadata import PackageNotFoundError, distribution
|
|
5
6
|
from pathlib import Path
|
|
@@ -24,31 +25,50 @@ def _discover_fs_topics(docs_dir: Path) -> Dict[str, Path]:
|
|
|
24
25
|
def _discover_pkg_topics() -> Dict[str, Path]:
|
|
25
26
|
"""Discover docs packaged under 'docs/' in the installed distribution.
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
Works in external projects without a local docs/ by inspecting the wheel
|
|
29
|
+
metadata and, as a fallback, searching for a top-level docs/ next to the
|
|
30
|
+
installed package directory in site-packages.
|
|
29
31
|
"""
|
|
30
32
|
topics: Dict[str, Path] = {}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
files = getattr(dist, "files", None) or []
|
|
37
|
-
for f in files:
|
|
38
|
-
# f is a PackagePath; string form like 'docs/topic.md'
|
|
39
|
-
s = str(f)
|
|
40
|
-
if not s.startswith("docs/") or not s.endswith(".md"):
|
|
41
|
-
continue
|
|
42
|
-
name = Path(s).stem.replace(" ", "-")
|
|
33
|
+
|
|
34
|
+
# 1) Prefer distribution metadata (RECORD) for both hyphen/underscore names
|
|
35
|
+
dist = None
|
|
36
|
+
for name in ("svc-infra", "svc_infra"):
|
|
43
37
|
try:
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
38
|
+
dist = distribution(name)
|
|
39
|
+
break
|
|
40
|
+
except PackageNotFoundError:
|
|
41
|
+
dist = None
|
|
42
|
+
|
|
43
|
+
if dist is not None:
|
|
44
|
+
files = getattr(dist, "files", None) or []
|
|
45
|
+
for f in files:
|
|
46
|
+
s = str(f)
|
|
47
|
+
if not s.startswith("docs/") or not s.endswith(".md"):
|
|
48
|
+
continue
|
|
49
|
+
topic_name = Path(s).stem.replace(" ", "-")
|
|
50
|
+
try:
|
|
51
|
+
abs_path = Path(dist.locate_file(f))
|
|
52
|
+
if abs_path.exists() and abs_path.is_file():
|
|
53
|
+
topics[topic_name] = abs_path
|
|
54
|
+
except Exception:
|
|
55
|
+
# Best effort; continue to next
|
|
56
|
+
continue
|
|
57
|
+
|
|
58
|
+
# 2) Fallback: site-packages sibling 'docs/' directory
|
|
59
|
+
try:
|
|
60
|
+
spec = importlib.util.find_spec("svc_infra")
|
|
61
|
+
if spec and spec.submodule_search_locations:
|
|
62
|
+
pkg_dir = Path(next(iter(spec.submodule_search_locations)))
|
|
63
|
+
candidate = pkg_dir.parent / "docs"
|
|
64
|
+
if candidate.exists() and candidate.is_dir():
|
|
65
|
+
for p in sorted(candidate.glob("*.md")):
|
|
66
|
+
if p.is_file():
|
|
67
|
+
topics.setdefault(p.stem.replace(" ", "-"), p)
|
|
68
|
+
except Exception:
|
|
69
|
+
# Optional fallback only
|
|
70
|
+
pass
|
|
71
|
+
|
|
52
72
|
return topics
|
|
53
73
|
|
|
54
74
|
|
|
@@ -57,19 +77,21 @@ def _resolve_docs_dir(ctx: click.Context) -> Path | None:
|
|
|
57
77
|
# executes subcommands in child contexts that do not inherit params.
|
|
58
78
|
current: click.Context | None = ctx
|
|
59
79
|
while current is not None:
|
|
60
|
-
|
|
61
|
-
if
|
|
62
|
-
path =
|
|
80
|
+
docs_dir_opt = (current.params or {}).get("docs_dir")
|
|
81
|
+
if docs_dir_opt:
|
|
82
|
+
path = docs_dir_opt if isinstance(docs_dir_opt, Path) else Path(docs_dir_opt)
|
|
63
83
|
path = path.expanduser()
|
|
64
84
|
if path.exists():
|
|
65
85
|
return path
|
|
66
86
|
current = current.parent
|
|
87
|
+
|
|
67
88
|
# Env var next
|
|
68
89
|
env_dir = os.getenv("SVC_INFRA_DOCS_DIR")
|
|
69
90
|
if env_dir:
|
|
70
91
|
p = Path(env_dir).expanduser()
|
|
71
92
|
if p.exists():
|
|
72
93
|
return p
|
|
94
|
+
|
|
73
95
|
# Project docs
|
|
74
96
|
root = resolve_project_root()
|
|
75
97
|
proj_docs = root / "docs"
|
|
@@ -88,16 +110,15 @@ class DocsGroup(TyperGroup):
|
|
|
88
110
|
names.extend([k for k in fs.keys()])
|
|
89
111
|
names.extend([k for k in pkg.keys() if k not in fs])
|
|
90
112
|
# Deduplicate and sort
|
|
91
|
-
|
|
92
|
-
return uniq
|
|
113
|
+
return sorted({*names})
|
|
93
114
|
|
|
94
115
|
def get_command(self, ctx: click.Context, name: str) -> click.Command | None:
|
|
95
|
-
# Built-ins first (e.g., list)
|
|
116
|
+
# Built-ins first (e.g., list, show)
|
|
96
117
|
cmd = super().get_command(ctx, name)
|
|
97
118
|
if cmd is not None:
|
|
98
119
|
return cmd
|
|
99
120
|
|
|
100
|
-
# Dynamic topic resolution
|
|
121
|
+
# Dynamic topic resolution from FS
|
|
101
122
|
dir_to_use = _resolve_docs_dir(ctx)
|
|
102
123
|
fs = _discover_fs_topics(dir_to_use) if dir_to_use else {}
|
|
103
124
|
if name in fs:
|
|
@@ -145,6 +166,10 @@ def register(app: typer.Typer) -> None:
|
|
|
145
166
|
if topic in fs:
|
|
146
167
|
typer.echo(fs[topic].read_text(encoding="utf-8", errors="replace"))
|
|
147
168
|
raise typer.Exit(code=0)
|
|
169
|
+
pkg = _discover_pkg_topics()
|
|
170
|
+
if topic in pkg:
|
|
171
|
+
typer.echo(pkg[topic].read_text(encoding="utf-8", errors="replace"))
|
|
172
|
+
raise typer.Exit(code=0)
|
|
148
173
|
raise typer.BadParameter(f"Unknown topic: {topic}")
|
|
149
174
|
|
|
150
175
|
@docs_app.command("list", help="List available documentation topics")
|
|
@@ -142,7 +142,7 @@ svc_infra/cli/cmds/db/sql/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJW
|
|
|
142
142
|
svc_infra/cli/cmds/db/sql/alembic_cmds.py,sha256=uCreHg69Zf6B5gbv9Dm39jCRk6q2KQy_05A-75IP0Fg,9650
|
|
143
143
|
svc_infra/cli/cmds/db/sql/sql_export_cmds.py,sha256=YpkguUJFeFApMphVkhOJllTi25ejlsQaJarMe6vJD54,2685
|
|
144
144
|
svc_infra/cli/cmds/db/sql/sql_scaffold_cmds.py,sha256=MKc_T_tY1Y_wQl7XTlq8GhYWMMI1q1_vcFZVPOEcNUg,4601
|
|
145
|
-
svc_infra/cli/cmds/docs/docs_cmds.py,sha256=
|
|
145
|
+
svc_infra/cli/cmds/docs/docs_cmds.py,sha256=vRDhddel_X9MCfCVRvV7_Ns7sB3awfwSVWV0HqKLRKg,7653
|
|
146
146
|
svc_infra/cli/cmds/dx/__init__.py,sha256=wQtl3-kOgoESlpVkjl3YFtqkOnQSIvVsOdutiaZFejM,197
|
|
147
147
|
svc_infra/cli/cmds/dx/dx_cmds.py,sha256=XTKUJzS3UIYn6h3CHzDEWKYJaWn0TzGiUCq3OeW27E0,3326
|
|
148
148
|
svc_infra/cli/cmds/help.py,sha256=wGfZFMYaR2ZPwW2JwKDU7M3m4AtdCd8GRQ412AmEBUM,758
|
|
@@ -296,7 +296,7 @@ svc_infra/webhooks/fastapi.py,sha256=BCNvGNxukf6dC2a4i-6en-PrjBGV19YvCWOot5lXWsA
|
|
|
296
296
|
svc_infra/webhooks/router.py,sha256=6JvAVPMEth_xxHX-IsIOcyMgHX7g1H0OVxVXKLuMp9w,1596
|
|
297
297
|
svc_infra/webhooks/service.py,sha256=hWgiJRXKBwKunJOx91C7EcLUkotDtD3Xp0RT6vj2IC0,1797
|
|
298
298
|
svc_infra/webhooks/signing.py,sha256=NCwdZzmravUe7HVIK_uXK0qqf12FG-_MVsgPvOw6lsM,784
|
|
299
|
-
svc_infra-0.1.
|
|
300
|
-
svc_infra-0.1.
|
|
301
|
-
svc_infra-0.1.
|
|
302
|
-
svc_infra-0.1.
|
|
299
|
+
svc_infra-0.1.620.dist-info/METADATA,sha256=Ii8wzmysVqUARGfBUES-2TQIMzhyeAGvGimkSTMIpYg,8106
|
|
300
|
+
svc_infra-0.1.620.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
|
|
301
|
+
svc_infra-0.1.620.dist-info/entry_points.txt,sha256=6x_nZOsjvn6hRZsMgZLgTasaCSKCgAjsGhACe_CiP0U,48
|
|
302
|
+
svc_infra-0.1.620.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|