Skip to content

Commit 4a348dd

Browse files
committed
Expose more details about Crystal in template strings
1 parent 4c7f1a0 commit 4a348dd

1 file changed

Lines changed: 32 additions & 8 deletions

File tree

mkdocstrings/handlers/crystal/collector.py

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def __init__(
4848
]
4949
if source_locations:
5050
command.append("--source-refname=master")
51-
command += crystal_docs_flags
51+
command += (s.format_map(_crystal_info) for s in crystal_docs_flags)
5252
log.debug("Running `%s`", " ".join(shlex.quote(arg) for arg in command))
5353

5454
self._proc = subprocess.Popen(command, stdout=subprocess.PIPE)
@@ -129,18 +129,12 @@ class _SourceDestination:
129129
def substitute(self, location: DocLocation) -> str:
130130
data = {"file": location.filename[len(self.src_path) :], "line": location.line}
131131
try:
132-
return self.dest_url.format_map(collections.ChainMap(data, self)) # type: ignore
132+
return self.dest_url.format_map(collections.ChainMap(data, _DictAccess(self), _crystal_info)) # type: ignore
133133
except KeyError as e:
134134
raise PluginError(
135135
f"The source_locations template {self.dest_url!r} did not resolve correctly: {e}"
136136
)
137137

138-
def __getitem__(self, key):
139-
try:
140-
return getattr(self, key)
141-
except AttributeError as e:
142-
raise KeyError(str(e))
143-
144138
@property
145139
def shard_version(self):
146140
return self._shard_version(os.path.dirname(self.src_path))
@@ -165,6 +159,36 @@ def _find_above(path: str, filename: str) -> str:
165159
raise PluginError(f"{filename!r} not found anywhere above {os.path.abspath(orig_path)!r}")
166160

167161

162+
class _CrystalInfo:
163+
@cached_property
164+
def crystal_version(self) -> str:
165+
return subprocess.check_output(
166+
["crystal", "env", "CRYSTAL_VERSION"], encoding="ascii"
167+
).rstrip()
168+
169+
@cached_property
170+
def crystal_src(self):
171+
out = subprocess.check_output(["crystal", "env", "CRYSTAL_PATH"], text=True).rstrip()
172+
for path in out.split(os.pathsep):
173+
if os.path.isfile(os.path.join(path, "prelude.cr")):
174+
return os.path.relpath(path)
175+
raise PluginError(f"Crystal sources not found anywhere in CRYSTAL_PATH={out!r}")
176+
177+
178+
class _DictAccess:
179+
def __init__(self, obj):
180+
self.obj = obj
181+
182+
def __getitem__(self, key):
183+
try:
184+
return getattr(self.obj, key)
185+
except AttributeError as e:
186+
raise KeyError(f"Missing key: {e}")
187+
188+
189+
_crystal_info = _DictAccess(_CrystalInfo())
190+
191+
168192
class DocRoot(DocModule):
169193
source_locations: List[_SourceDestination]
170194

0 commit comments

Comments
 (0)