julee 0.1.3__py3-none-any.whl → 0.1.4__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.
- julee/api/tests/routers/test_documents.py +6 -6
- julee/docs/sphinx_hcd/__init__.py +4 -10
- julee/docs/sphinx_hcd/accelerators.py +277 -180
- julee/docs/sphinx_hcd/apps.py +78 -59
- julee/docs/sphinx_hcd/config.py +16 -16
- julee/docs/sphinx_hcd/epics.py +47 -42
- julee/docs/sphinx_hcd/integrations.py +53 -49
- julee/docs/sphinx_hcd/journeys.py +124 -110
- julee/docs/sphinx_hcd/personas.py +75 -53
- julee/docs/sphinx_hcd/stories.py +99 -71
- julee/docs/sphinx_hcd/utils.py +23 -18
- julee/domain/models/document/document.py +12 -21
- julee/domain/models/document/tests/test_document.py +14 -34
- julee/domain/use_cases/extract_assemble_data.py +1 -1
- julee/domain/use_cases/initialize_system_data.py +75 -21
- julee/fixtures/documents.yaml +4 -43
- julee/fixtures/knowledge_service_queries.yaml +9 -0
- julee/maintenance/release.py +85 -30
- julee/repositories/memory/document.py +19 -13
- julee/repositories/memory/tests/test_document.py +18 -18
- julee/repositories/minio/document.py +25 -22
- julee/repositories/minio/tests/test_document.py +16 -16
- {julee-0.1.3.dist-info → julee-0.1.4.dist-info}/METADATA +2 -3
- {julee-0.1.3.dist-info → julee-0.1.4.dist-info}/RECORD +27 -28
- julee/fixtures/assembly_specifications.yaml +0 -70
- {julee-0.1.3.dist-info → julee-0.1.4.dist-info}/WHEEL +0 -0
- {julee-0.1.3.dist-info → julee-0.1.4.dist-info}/licenses/LICENSE +0 -0
- {julee-0.1.3.dist-info → julee-0.1.4.dist-info}/top_level.txt +0 -0
|
@@ -19,17 +19,20 @@ Provides directives:
|
|
|
19
19
|
|
|
20
20
|
import ast
|
|
21
21
|
import os
|
|
22
|
-
import re
|
|
23
22
|
from pathlib import Path
|
|
23
|
+
|
|
24
24
|
from docutils import nodes
|
|
25
25
|
from docutils.parsers.rst import directives
|
|
26
|
-
from sphinx.util.docutils import SphinxDirective
|
|
27
26
|
from sphinx.util import logging
|
|
27
|
+
from sphinx.util.docutils import SphinxDirective
|
|
28
28
|
|
|
29
29
|
from .config import get_config
|
|
30
30
|
from .utils import (
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
kebab_to_snake,
|
|
32
|
+
normalize_name,
|
|
33
|
+
parse_integration_options,
|
|
34
|
+
parse_list_option,
|
|
35
|
+
path_to_root,
|
|
33
36
|
)
|
|
34
37
|
|
|
35
38
|
logger = logging.getLogger(__name__)
|
|
@@ -40,14 +43,14 @@ _code_registry: dict = {}
|
|
|
40
43
|
|
|
41
44
|
def get_accelerator_registry(env):
|
|
42
45
|
"""Get the accelerator registry from env, creating if needed."""
|
|
43
|
-
if not hasattr(env,
|
|
46
|
+
if not hasattr(env, "accelerator_registry"):
|
|
44
47
|
env.accelerator_registry = {}
|
|
45
48
|
return env.accelerator_registry
|
|
46
49
|
|
|
47
50
|
|
|
48
51
|
def get_documented_accelerators(env):
|
|
49
52
|
"""Get the set of documented accelerators from env, creating if needed."""
|
|
50
|
-
if not hasattr(env,
|
|
53
|
+
if not hasattr(env, "documented_accelerators"):
|
|
51
54
|
env.documented_accelerators = set()
|
|
52
55
|
return env.documented_accelerators
|
|
53
56
|
|
|
@@ -69,16 +72,18 @@ def scan_python_classes(directory: Path) -> list[dict]:
|
|
|
69
72
|
for node in ast.walk(tree):
|
|
70
73
|
if isinstance(node, ast.ClassDef):
|
|
71
74
|
docstring = ast.get_docstring(node) or ""
|
|
72
|
-
first_line = docstring.split(
|
|
73
|
-
classes.append(
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
75
|
+
first_line = docstring.split("\n")[0].strip() if docstring else ""
|
|
76
|
+
classes.append(
|
|
77
|
+
{
|
|
78
|
+
"name": node.name,
|
|
79
|
+
"docstring": first_line,
|
|
80
|
+
"file": py_file.name,
|
|
81
|
+
}
|
|
82
|
+
)
|
|
78
83
|
except Exception as e:
|
|
79
84
|
logger.warning(f"Could not parse {py_file}: {e}")
|
|
80
85
|
|
|
81
|
-
return sorted(classes, key=lambda c: c[
|
|
86
|
+
return sorted(classes, key=lambda c: c["name"])
|
|
82
87
|
|
|
83
88
|
|
|
84
89
|
def get_module_docstring(module_path: Path) -> tuple[str | None, str | None]:
|
|
@@ -91,7 +96,7 @@ def get_module_docstring(module_path: Path) -> tuple[str | None, str | None]:
|
|
|
91
96
|
tree = ast.parse(f.read(), filename=str(module_path))
|
|
92
97
|
docstring = ast.get_docstring(tree)
|
|
93
98
|
if docstring:
|
|
94
|
-
first_line = docstring.split(
|
|
99
|
+
first_line = docstring.split("\n")[0].strip()
|
|
95
100
|
return first_line, docstring
|
|
96
101
|
except Exception as e:
|
|
97
102
|
logger.warning(f"Could not parse {module_path}: {e}")
|
|
@@ -103,7 +108,7 @@ def scan_bounded_context(slug: str, project_root: Path) -> dict | None:
|
|
|
103
108
|
"""Introspect src/{slug}/ for ADR 001-compliant code structure."""
|
|
104
109
|
snake_slug = kebab_to_snake(slug)
|
|
105
110
|
config = get_config()
|
|
106
|
-
src_dir = config.get_path(
|
|
111
|
+
src_dir = config.get_path("bounded_contexts")
|
|
107
112
|
context_dir = src_dir / snake_slug
|
|
108
113
|
|
|
109
114
|
if not context_dir.exists() and snake_slug != slug:
|
|
@@ -117,14 +122,16 @@ def scan_bounded_context(slug: str, project_root: Path) -> dict | None:
|
|
|
117
122
|
objective, full_docstring = get_module_docstring(init_file)
|
|
118
123
|
|
|
119
124
|
return {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
125
|
+
"entities": scan_python_classes(context_dir / "domain" / "models"),
|
|
126
|
+
"use_cases": scan_python_classes(context_dir / "use_cases"),
|
|
127
|
+
"repository_protocols": scan_python_classes(
|
|
128
|
+
context_dir / "domain" / "repositories"
|
|
129
|
+
),
|
|
130
|
+
"service_protocols": scan_python_classes(context_dir / "domain" / "services"),
|
|
131
|
+
"has_infrastructure": (context_dir / "infrastructure").exists(),
|
|
132
|
+
"code_dir": context_dir.name,
|
|
133
|
+
"objective": objective,
|
|
134
|
+
"docstring": full_docstring,
|
|
128
135
|
}
|
|
129
136
|
|
|
130
137
|
|
|
@@ -134,7 +141,7 @@ def scan_code_structure(app):
|
|
|
134
141
|
_code_registry = {}
|
|
135
142
|
|
|
136
143
|
config = get_config()
|
|
137
|
-
src_dir = config.get_path(
|
|
144
|
+
src_dir = config.get_path("bounded_contexts")
|
|
138
145
|
|
|
139
146
|
if not src_dir.exists():
|
|
140
147
|
logger.info("src/ directory not found - no code to introspect yet")
|
|
@@ -150,19 +157,22 @@ def scan_code_structure(app):
|
|
|
150
157
|
code_info = scan_bounded_context(slug, config.project_root)
|
|
151
158
|
if code_info:
|
|
152
159
|
_code_registry[slug] = code_info
|
|
153
|
-
logger.info(
|
|
154
|
-
|
|
155
|
-
|
|
160
|
+
logger.info(
|
|
161
|
+
f"Introspected bounded context '{slug}': "
|
|
162
|
+
f"{len(code_info['entities'])} entities, "
|
|
163
|
+
f"{len(code_info['use_cases'])} use cases"
|
|
164
|
+
)
|
|
156
165
|
|
|
157
166
|
|
|
158
167
|
def get_apps_for_accelerator(accelerator_slug: str) -> list[str]:
|
|
159
168
|
"""Get apps that expose this accelerator (from app manifests)."""
|
|
160
169
|
from . import apps
|
|
170
|
+
|
|
161
171
|
_app_registry = apps.get_app_registry()
|
|
162
172
|
|
|
163
173
|
result = []
|
|
164
174
|
for app_slug, app_data in _app_registry.items():
|
|
165
|
-
if accelerator_slug in app_data.get(
|
|
175
|
+
if accelerator_slug in app_data.get("accelerators", []):
|
|
166
176
|
result.append(app_slug)
|
|
167
177
|
return sorted(result)
|
|
168
178
|
|
|
@@ -170,13 +180,14 @@ def get_apps_for_accelerator(accelerator_slug: str) -> list[str]:
|
|
|
170
180
|
def get_stories_for_accelerator(accelerator_slug: str) -> list[dict]:
|
|
171
181
|
"""Get stories for apps that use this accelerator."""
|
|
172
182
|
from . import stories
|
|
183
|
+
|
|
173
184
|
_story_registry = stories.get_story_registry()
|
|
174
185
|
|
|
175
186
|
app_slugs = get_apps_for_accelerator(accelerator_slug)
|
|
176
187
|
result = []
|
|
177
188
|
|
|
178
189
|
for story in _story_registry:
|
|
179
|
-
if story[
|
|
190
|
+
if story["app"] in app_slugs:
|
|
180
191
|
result.append(story)
|
|
181
192
|
|
|
182
193
|
return result
|
|
@@ -185,16 +196,17 @@ def get_stories_for_accelerator(accelerator_slug: str) -> list[dict]:
|
|
|
185
196
|
def get_journeys_for_accelerator(accelerator_slug: str, env) -> list[str]:
|
|
186
197
|
"""Get journeys that include stories from this accelerator's apps."""
|
|
187
198
|
from . import journeys
|
|
199
|
+
|
|
188
200
|
journey_registry = journeys.get_journey_registry(env)
|
|
189
201
|
|
|
190
202
|
story_list = get_stories_for_accelerator(accelerator_slug)
|
|
191
|
-
story_titles = {normalize_name(s[
|
|
203
|
+
story_titles = {normalize_name(s["feature"]) for s in story_list}
|
|
192
204
|
|
|
193
205
|
result = []
|
|
194
206
|
for slug, journey in journey_registry.items():
|
|
195
|
-
for step in journey.get(
|
|
196
|
-
if step.get(
|
|
197
|
-
if normalize_name(step[
|
|
207
|
+
for step in journey.get("steps", []):
|
|
208
|
+
if step.get("type") == "story":
|
|
209
|
+
if normalize_name(step["ref"]) in story_titles:
|
|
198
210
|
result.append(slug)
|
|
199
211
|
break
|
|
200
212
|
|
|
@@ -220,13 +232,13 @@ class DefineAcceleratorDirective(SphinxDirective):
|
|
|
220
232
|
required_arguments = 1
|
|
221
233
|
has_content = True
|
|
222
234
|
option_spec = {
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
235
|
+
"status": directives.unchanged,
|
|
236
|
+
"milestone": directives.unchanged,
|
|
237
|
+
"acceptance": directives.unchanged,
|
|
238
|
+
"sources_from": directives.unchanged,
|
|
239
|
+
"feeds_into": directives.unchanged,
|
|
240
|
+
"publishes_to": directives.unchanged,
|
|
241
|
+
"depends_on": directives.unchanged,
|
|
230
242
|
}
|
|
231
243
|
|
|
232
244
|
def run(self):
|
|
@@ -234,31 +246,31 @@ class DefineAcceleratorDirective(SphinxDirective):
|
|
|
234
246
|
|
|
235
247
|
get_documented_accelerators(self.env).add(slug)
|
|
236
248
|
|
|
237
|
-
status = self.options.get(
|
|
238
|
-
milestone = self.options.get(
|
|
239
|
-
acceptance = self.options.get(
|
|
240
|
-
sources_from = parse_integration_options(self.options.get(
|
|
241
|
-
feeds_into = parse_list_option(self.options.get(
|
|
242
|
-
publishes_to = parse_integration_options(self.options.get(
|
|
243
|
-
depends_on = parse_list_option(self.options.get(
|
|
249
|
+
status = self.options.get("status", "").strip()
|
|
250
|
+
milestone = self.options.get("milestone", "").strip()
|
|
251
|
+
acceptance = self.options.get("acceptance", "").strip()
|
|
252
|
+
sources_from = parse_integration_options(self.options.get("sources_from", ""))
|
|
253
|
+
feeds_into = parse_list_option(self.options.get("feeds_into", ""))
|
|
254
|
+
publishes_to = parse_integration_options(self.options.get("publishes_to", ""))
|
|
255
|
+
depends_on = parse_list_option(self.options.get("depends_on", ""))
|
|
244
256
|
|
|
245
|
-
objective =
|
|
257
|
+
objective = "\n".join(self.content).strip()
|
|
246
258
|
|
|
247
259
|
get_accelerator_registry(self.env)[slug] = {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
260
|
+
"slug": slug,
|
|
261
|
+
"status": status,
|
|
262
|
+
"milestone": milestone,
|
|
263
|
+
"acceptance": acceptance,
|
|
264
|
+
"objective": objective,
|
|
265
|
+
"sources_from": sources_from,
|
|
266
|
+
"feeds_into": feeds_into,
|
|
267
|
+
"publishes_to": publishes_to,
|
|
268
|
+
"depends_on": depends_on,
|
|
269
|
+
"docname": self.env.docname,
|
|
258
270
|
}
|
|
259
271
|
|
|
260
272
|
node = DefineAcceleratorPlaceholder()
|
|
261
|
-
node[
|
|
273
|
+
node["accelerator_slug"] = slug
|
|
262
274
|
return [node]
|
|
263
275
|
|
|
264
276
|
|
|
@@ -285,7 +297,7 @@ class AcceleratorStatusDirective(SphinxDirective):
|
|
|
285
297
|
|
|
286
298
|
def run(self):
|
|
287
299
|
node = AcceleratorStatusPlaceholder()
|
|
288
|
-
node[
|
|
300
|
+
node["accelerator_slug"] = self.arguments[0]
|
|
289
301
|
return [node]
|
|
290
302
|
|
|
291
303
|
|
|
@@ -300,7 +312,7 @@ class AcceleratorsForAppDirective(SphinxDirective):
|
|
|
300
312
|
|
|
301
313
|
def run(self):
|
|
302
314
|
node = AcceleratorsForAppPlaceholder()
|
|
303
|
-
node[
|
|
315
|
+
node["app_slug"] = self.arguments[0]
|
|
304
316
|
return [node]
|
|
305
317
|
|
|
306
318
|
|
|
@@ -312,12 +324,12 @@ class DependentAcceleratorsDirective(SphinxDirective):
|
|
|
312
324
|
"""List accelerators that depend on or publish to an integration."""
|
|
313
325
|
|
|
314
326
|
option_spec = {
|
|
315
|
-
|
|
327
|
+
"relationship": directives.unchanged_required,
|
|
316
328
|
}
|
|
317
329
|
|
|
318
330
|
def run(self):
|
|
319
|
-
relationship = self.options.get(
|
|
320
|
-
if relationship not in (
|
|
331
|
+
relationship = self.options.get("relationship", "").strip()
|
|
332
|
+
if relationship not in ("sources_from", "publishes_to"):
|
|
321
333
|
error = self.state_machine.reporter.error(
|
|
322
334
|
f"Invalid relationship '{relationship}'. "
|
|
323
335
|
f"Must be 'sources_from' or 'publishes_to'.",
|
|
@@ -326,11 +338,11 @@ class DependentAcceleratorsDirective(SphinxDirective):
|
|
|
326
338
|
return [error]
|
|
327
339
|
|
|
328
340
|
docname = self.env.docname
|
|
329
|
-
integration_slug = docname.split(
|
|
341
|
+
integration_slug = docname.split("/")[-1]
|
|
330
342
|
|
|
331
343
|
node = DependentAcceleratorsPlaceholder()
|
|
332
|
-
node[
|
|
333
|
-
node[
|
|
344
|
+
node["integration_slug"] = integration_slug
|
|
345
|
+
node["relationship"] = relationship
|
|
334
346
|
return [node]
|
|
335
347
|
|
|
336
348
|
|
|
@@ -345,7 +357,7 @@ class AcceleratorDependencyDiagramDirective(SphinxDirective):
|
|
|
345
357
|
|
|
346
358
|
def run(self):
|
|
347
359
|
node = AcceleratorDependencyDiagramPlaceholder()
|
|
348
|
-
node[
|
|
360
|
+
node["accelerator_slug"] = self.arguments[0]
|
|
349
361
|
return [node]
|
|
350
362
|
|
|
351
363
|
|
|
@@ -360,7 +372,7 @@ class SrcAcceleratorBacklinksDirective(SphinxDirective):
|
|
|
360
372
|
|
|
361
373
|
def run(self):
|
|
362
374
|
node = SrcAcceleratorBacklinksPlaceholder()
|
|
363
|
-
node[
|
|
375
|
+
node["accelerator_slug"] = self.arguments[0]
|
|
364
376
|
return [node]
|
|
365
377
|
|
|
366
378
|
|
|
@@ -375,7 +387,7 @@ class SrcAppBacklinksDirective(SphinxDirective):
|
|
|
375
387
|
|
|
376
388
|
def run(self):
|
|
377
389
|
node = SrcAppBacklinksPlaceholder()
|
|
378
|
-
node[
|
|
390
|
+
node["app_slug"] = self.arguments[0]
|
|
379
391
|
return [node]
|
|
380
392
|
|
|
381
393
|
|
|
@@ -395,22 +407,22 @@ def build_accelerator_status(slug: str, env) -> list:
|
|
|
395
407
|
accel = accelerator_registry[slug]
|
|
396
408
|
result_nodes = []
|
|
397
409
|
|
|
398
|
-
if accel[
|
|
410
|
+
if accel["status"] or accel["milestone"]:
|
|
399
411
|
status_para = nodes.paragraph()
|
|
400
|
-
if accel[
|
|
412
|
+
if accel["status"]:
|
|
401
413
|
status_para += nodes.strong(text="Status: ")
|
|
402
|
-
status_para += nodes.Text(accel[
|
|
403
|
-
if accel[
|
|
414
|
+
status_para += nodes.Text(accel["status"].title())
|
|
415
|
+
if accel["status"] and accel["milestone"]:
|
|
404
416
|
status_para += nodes.Text(" | ")
|
|
405
|
-
if accel[
|
|
417
|
+
if accel["milestone"]:
|
|
406
418
|
status_para += nodes.strong(text="Milestone: ")
|
|
407
|
-
status_para += nodes.Text(accel[
|
|
419
|
+
status_para += nodes.Text(accel["milestone"])
|
|
408
420
|
result_nodes.append(status_para)
|
|
409
421
|
|
|
410
|
-
if accel[
|
|
422
|
+
if accel["acceptance"]:
|
|
411
423
|
accept_para = nodes.paragraph()
|
|
412
424
|
accept_para += nodes.strong(text="Acceptance: ")
|
|
413
|
-
accept_para += nodes.Text(accel[
|
|
425
|
+
accept_para += nodes.Text(accel["acceptance"])
|
|
414
426
|
result_nodes.append(accept_para)
|
|
415
427
|
|
|
416
428
|
return result_nodes
|
|
@@ -437,10 +449,10 @@ def build_accelerator_content(slug: str, docname: str, env) -> list:
|
|
|
437
449
|
code_info = _code_registry.get(slug) or _code_registry.get(snake_slug)
|
|
438
450
|
|
|
439
451
|
objective = None
|
|
440
|
-
if code_info and code_info.get(
|
|
441
|
-
objective = code_info[
|
|
442
|
-
elif accel[
|
|
443
|
-
objective = accel[
|
|
452
|
+
if code_info and code_info.get("objective"):
|
|
453
|
+
objective = code_info["objective"]
|
|
454
|
+
elif accel["objective"]:
|
|
455
|
+
objective = accel["objective"]
|
|
444
456
|
|
|
445
457
|
if objective:
|
|
446
458
|
obj_para = nodes.paragraph()
|
|
@@ -450,11 +462,22 @@ def build_accelerator_content(slug: str, docname: str, env) -> list:
|
|
|
450
462
|
seealso_items = []
|
|
451
463
|
|
|
452
464
|
if code_info:
|
|
453
|
-
code_dir = code_info.get(
|
|
465
|
+
code_dir = code_info.get("code_dir", snake_slug)
|
|
454
466
|
autodoc_path = f"{prefix}source/_autosummary/rba.{code_dir}.html"
|
|
455
|
-
seealso_items.append((
|
|
467
|
+
seealso_items.append(("Source", [(autodoc_path, f"rba.{code_dir}", True)]))
|
|
456
468
|
else:
|
|
457
|
-
seealso_items.append(
|
|
469
|
+
seealso_items.append(
|
|
470
|
+
(
|
|
471
|
+
"Source",
|
|
472
|
+
[
|
|
473
|
+
(
|
|
474
|
+
None,
|
|
475
|
+
f"No implementation yet — expecting code at src/{snake_slug}/",
|
|
476
|
+
False,
|
|
477
|
+
)
|
|
478
|
+
],
|
|
479
|
+
)
|
|
480
|
+
)
|
|
458
481
|
|
|
459
482
|
apps = get_apps_for_accelerator(slug)
|
|
460
483
|
if apps:
|
|
@@ -462,51 +485,71 @@ def build_accelerator_content(slug: str, docname: str, env) -> list:
|
|
|
462
485
|
for app_slug in apps:
|
|
463
486
|
app_path = f"{prefix}{config.get_doc_path('applications')}/{app_slug}.html"
|
|
464
487
|
app_links.append((app_path, app_slug.replace("-", " ").title(), False))
|
|
465
|
-
seealso_items.append((
|
|
488
|
+
seealso_items.append(("Exposed By", app_links))
|
|
466
489
|
|
|
467
490
|
journeys = get_journeys_for_accelerator(slug, env)
|
|
468
491
|
if journeys:
|
|
469
492
|
journey_links = []
|
|
470
493
|
for journey_slug in journeys:
|
|
471
|
-
journey_path =
|
|
472
|
-
|
|
473
|
-
|
|
494
|
+
journey_path = (
|
|
495
|
+
f"{prefix}{config.get_doc_path('journeys')}/{journey_slug}.html"
|
|
496
|
+
)
|
|
497
|
+
journey_links.append(
|
|
498
|
+
(journey_path, journey_slug.replace("-", " ").title(), False)
|
|
499
|
+
)
|
|
500
|
+
seealso_items.append(("Journeys", journey_links))
|
|
474
501
|
|
|
475
|
-
if accel[
|
|
502
|
+
if accel["depends_on"]:
|
|
476
503
|
accel_links = []
|
|
477
|
-
for dep_slug in accel[
|
|
504
|
+
for dep_slug in accel["depends_on"]:
|
|
478
505
|
if dep_slug in accelerator_registry:
|
|
479
|
-
accel_path =
|
|
480
|
-
|
|
506
|
+
accel_path = (
|
|
507
|
+
f"{prefix}{config.get_doc_path('accelerators')}/{dep_slug}.html"
|
|
508
|
+
)
|
|
509
|
+
accel_links.append(
|
|
510
|
+
(accel_path, dep_slug.replace("-", " ").title(), False)
|
|
511
|
+
)
|
|
481
512
|
else:
|
|
482
|
-
accel_links.append(
|
|
483
|
-
|
|
513
|
+
accel_links.append(
|
|
514
|
+
(None, f"{dep_slug.replace('-', ' ').title()} [not found]", False)
|
|
515
|
+
)
|
|
516
|
+
seealso_items.append(("Depends On", accel_links))
|
|
484
517
|
|
|
485
|
-
if accel[
|
|
518
|
+
if accel["feeds_into"]:
|
|
486
519
|
accel_links = []
|
|
487
|
-
for feed_slug in accel[
|
|
520
|
+
for feed_slug in accel["feeds_into"]:
|
|
488
521
|
if feed_slug in accelerator_registry:
|
|
489
|
-
accel_path =
|
|
490
|
-
|
|
522
|
+
accel_path = (
|
|
523
|
+
f"{prefix}{config.get_doc_path('accelerators')}/{feed_slug}.html"
|
|
524
|
+
)
|
|
525
|
+
accel_links.append(
|
|
526
|
+
(accel_path, feed_slug.replace("-", " ").title(), False)
|
|
527
|
+
)
|
|
491
528
|
else:
|
|
492
|
-
accel_links.append(
|
|
493
|
-
|
|
529
|
+
accel_links.append(
|
|
530
|
+
(None, f"{feed_slug.replace('-', ' ').title()} [not found]", False)
|
|
531
|
+
)
|
|
532
|
+
seealso_items.append(("Feeds Into", accel_links))
|
|
494
533
|
|
|
495
|
-
if accel[
|
|
534
|
+
if accel["sources_from"]:
|
|
496
535
|
int_links = []
|
|
497
|
-
for source in accel[
|
|
498
|
-
int_path =
|
|
499
|
-
|
|
536
|
+
for source in accel["sources_from"]:
|
|
537
|
+
int_path = (
|
|
538
|
+
f"{prefix}{config.get_doc_path('integrations')}/{source['slug']}.html"
|
|
539
|
+
)
|
|
540
|
+
label = source["slug"].replace("-", " ").title()
|
|
500
541
|
int_links.append((int_path, label, False))
|
|
501
|
-
seealso_items.append((
|
|
542
|
+
seealso_items.append(("Sources From", int_links))
|
|
502
543
|
|
|
503
|
-
if accel[
|
|
544
|
+
if accel["publishes_to"]:
|
|
504
545
|
int_links = []
|
|
505
|
-
for target in accel[
|
|
506
|
-
int_path =
|
|
507
|
-
|
|
546
|
+
for target in accel["publishes_to"]:
|
|
547
|
+
int_path = (
|
|
548
|
+
f"{prefix}{config.get_doc_path('integrations')}/{target['slug']}.html"
|
|
549
|
+
)
|
|
550
|
+
label = target["slug"].replace("-", " ").title()
|
|
508
551
|
int_links.append((int_path, label, False))
|
|
509
|
-
seealso_items.append((
|
|
552
|
+
seealso_items.append(("Publishes To", int_links))
|
|
510
553
|
|
|
511
554
|
if seealso_items:
|
|
512
555
|
seealso_node = seealso()
|
|
@@ -548,21 +591,21 @@ def build_accelerator_index(docname: str, env) -> list:
|
|
|
548
591
|
para += nodes.emphasis(text="No accelerators defined")
|
|
549
592
|
return [para]
|
|
550
593
|
|
|
551
|
-
by_status = {
|
|
594
|
+
by_status = {"alpha": [], "future": [], "production": [], "other": []}
|
|
552
595
|
for slug, accel in accelerator_registry.items():
|
|
553
|
-
status = accel.get(
|
|
596
|
+
status = accel.get("status", "").lower()
|
|
554
597
|
if status in by_status:
|
|
555
598
|
by_status[status].append((slug, accel))
|
|
556
599
|
else:
|
|
557
|
-
by_status[
|
|
600
|
+
by_status["other"].append((slug, accel))
|
|
558
601
|
|
|
559
602
|
result_nodes = []
|
|
560
603
|
|
|
561
604
|
status_sections = [
|
|
562
|
-
(
|
|
563
|
-
(
|
|
564
|
-
(
|
|
565
|
-
(
|
|
605
|
+
("alpha", "Alpha Phase"),
|
|
606
|
+
("production", "Production"),
|
|
607
|
+
("future", "Future"),
|
|
608
|
+
("other", "Other"),
|
|
566
609
|
]
|
|
567
610
|
|
|
568
611
|
for status_key, status_label in status_sections:
|
|
@@ -585,7 +628,7 @@ def build_accelerator_index(docname: str, env) -> list:
|
|
|
585
628
|
ref += nodes.Text(slug.replace("-", " ").title())
|
|
586
629
|
para += ref
|
|
587
630
|
|
|
588
|
-
if accel.get(
|
|
631
|
+
if accel.get("milestone"):
|
|
589
632
|
para += nodes.Text(f" — {accel['milestone']}")
|
|
590
633
|
|
|
591
634
|
if slug in _code_registry:
|
|
@@ -593,9 +636,9 @@ def build_accelerator_index(docname: str, env) -> list:
|
|
|
593
636
|
|
|
594
637
|
item += para
|
|
595
638
|
|
|
596
|
-
if accel.get(
|
|
639
|
+
if accel.get("objective"):
|
|
597
640
|
obj_para = nodes.paragraph()
|
|
598
|
-
obj_text = accel[
|
|
641
|
+
obj_text = accel["objective"]
|
|
599
642
|
if len(obj_text) > 100:
|
|
600
643
|
obj_text = obj_text[:100] + "..."
|
|
601
644
|
obj_para += nodes.Text(obj_text)
|
|
@@ -625,7 +668,7 @@ def build_accelerators_for_app(app_slug: str, docname: str, env) -> list:
|
|
|
625
668
|
para += nodes.emphasis(text=f"App '{app_slug}' not found")
|
|
626
669
|
return [para]
|
|
627
670
|
|
|
628
|
-
accel_slugs = app_data.get(
|
|
671
|
+
accel_slugs = app_data.get("accelerators", [])
|
|
629
672
|
if not accel_slugs:
|
|
630
673
|
para = nodes.paragraph()
|
|
631
674
|
para += nodes.emphasis(text="No accelerators")
|
|
@@ -643,7 +686,7 @@ def build_accelerators_for_app(app_slug: str, docname: str, env) -> list:
|
|
|
643
686
|
para += ref
|
|
644
687
|
|
|
645
688
|
if slug in accelerator_registry:
|
|
646
|
-
objective = accelerator_registry[slug].get(
|
|
689
|
+
objective = accelerator_registry[slug].get("objective", "")
|
|
647
690
|
if objective:
|
|
648
691
|
para += nodes.Text(f" — {objective[:60]}...")
|
|
649
692
|
|
|
@@ -653,7 +696,9 @@ def build_accelerators_for_app(app_slug: str, docname: str, env) -> list:
|
|
|
653
696
|
return [bullet_list]
|
|
654
697
|
|
|
655
698
|
|
|
656
|
-
def build_dependent_accelerators(
|
|
699
|
+
def build_dependent_accelerators(
|
|
700
|
+
integration_slug: str, relationship: str, docname: str, env
|
|
701
|
+
) -> list:
|
|
657
702
|
"""Build table of accelerators that depend on or publish to an integration."""
|
|
658
703
|
config = get_config()
|
|
659
704
|
accelerator_registry = get_accelerator_registry(env)
|
|
@@ -664,11 +709,13 @@ def build_dependent_accelerators(integration_slug: str, relationship: str, docna
|
|
|
664
709
|
for accel_slug, accel in accelerator_registry.items():
|
|
665
710
|
rel_list = accel.get(relationship, [])
|
|
666
711
|
for rel in rel_list:
|
|
667
|
-
if rel[
|
|
668
|
-
matches.append(
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
712
|
+
if rel["slug"] == integration_slug:
|
|
713
|
+
matches.append(
|
|
714
|
+
{
|
|
715
|
+
"slug": accel_slug,
|
|
716
|
+
"description": rel.get("description"),
|
|
717
|
+
}
|
|
718
|
+
)
|
|
672
719
|
break
|
|
673
720
|
|
|
674
721
|
if not matches:
|
|
@@ -693,7 +740,7 @@ def build_dependent_accelerators(integration_slug: str, relationship: str, docna
|
|
|
693
740
|
header_row += accel_header
|
|
694
741
|
|
|
695
742
|
data_header = nodes.entry()
|
|
696
|
-
if relationship ==
|
|
743
|
+
if relationship == "sources_from":
|
|
697
744
|
data_header += nodes.paragraph(text="What it sources")
|
|
698
745
|
else:
|
|
699
746
|
data_header += nodes.paragraph(text="What it publishes")
|
|
@@ -702,23 +749,25 @@ def build_dependent_accelerators(integration_slug: str, relationship: str, docna
|
|
|
702
749
|
tbody = nodes.tbody()
|
|
703
750
|
tgroup += tbody
|
|
704
751
|
|
|
705
|
-
for match in sorted(matches, key=lambda m: m[
|
|
752
|
+
for match in sorted(matches, key=lambda m: m["slug"]):
|
|
706
753
|
row = nodes.row()
|
|
707
754
|
tbody += row
|
|
708
755
|
|
|
709
756
|
accel_cell = nodes.entry()
|
|
710
757
|
accel_para = nodes.paragraph()
|
|
711
|
-
accel_path =
|
|
758
|
+
accel_path = (
|
|
759
|
+
f"{prefix}{config.get_doc_path('accelerators')}/{match['slug']}.html"
|
|
760
|
+
)
|
|
712
761
|
ref = nodes.reference("", "", refuri=accel_path)
|
|
713
|
-
ref += nodes.strong(text=match[
|
|
762
|
+
ref += nodes.strong(text=match["slug"].replace("-", " ").title())
|
|
714
763
|
accel_para += ref
|
|
715
764
|
accel_cell += accel_para
|
|
716
765
|
row += accel_cell
|
|
717
766
|
|
|
718
767
|
desc_cell = nodes.entry()
|
|
719
768
|
desc_para = nodes.paragraph()
|
|
720
|
-
if match[
|
|
721
|
-
desc_para += nodes.Text(match[
|
|
769
|
+
if match["description"]:
|
|
770
|
+
desc_para += nodes.Text(match["description"])
|
|
722
771
|
else:
|
|
723
772
|
desc_para += nodes.emphasis(text="(not specified)")
|
|
724
773
|
desc_cell += desc_para
|
|
@@ -740,8 +789,8 @@ def build_accelerator_dependency_diagram(slug: str, docname: str, env) -> list:
|
|
|
740
789
|
|
|
741
790
|
accel = accelerator_registry[slug]
|
|
742
791
|
apps = get_apps_for_accelerator(slug)
|
|
743
|
-
sources_from = accel.get(
|
|
744
|
-
publishes_to = accel.get(
|
|
792
|
+
sources_from = accel.get("sources_from", [])
|
|
793
|
+
publishes_to = accel.get("publishes_to", [])
|
|
745
794
|
|
|
746
795
|
lines = [
|
|
747
796
|
"@startuml",
|
|
@@ -779,17 +828,19 @@ def build_accelerator_dependency_diagram(slug: str, docname: str, env) -> list:
|
|
|
779
828
|
lines.append("' Integration dependencies")
|
|
780
829
|
|
|
781
830
|
for source in sources_from:
|
|
782
|
-
source_slug = source[
|
|
831
|
+
source_slug = source["slug"]
|
|
783
832
|
source_id = safe_id(source_slug)
|
|
784
833
|
source_name = source_slug.replace("-", " ").title()
|
|
785
834
|
lines.append(f'component "{source_name}" as {source_id} <<integration>>')
|
|
786
835
|
|
|
787
836
|
for target in publishes_to:
|
|
788
|
-
target_slug = target[
|
|
837
|
+
target_slug = target["slug"]
|
|
789
838
|
target_id = safe_id(target_slug)
|
|
790
|
-
if not any(s[
|
|
839
|
+
if not any(s["slug"] == target_slug for s in sources_from):
|
|
791
840
|
target_name = target_slug.replace("-", " ").title()
|
|
792
|
-
lines.append(
|
|
841
|
+
lines.append(
|
|
842
|
+
f'component "{target_name}" as {target_id} <<integration>>'
|
|
843
|
+
)
|
|
793
844
|
|
|
794
845
|
lines.append("")
|
|
795
846
|
|
|
@@ -800,20 +851,20 @@ def build_accelerator_dependency_diagram(slug: str, docname: str, env) -> list:
|
|
|
800
851
|
lines.append(f"{app_id} --> {accel_id} : exposes")
|
|
801
852
|
|
|
802
853
|
for source in sources_from:
|
|
803
|
-
source_id = safe_id(source[
|
|
854
|
+
source_id = safe_id(source["slug"])
|
|
804
855
|
label = "sources from"
|
|
805
|
-
if source.get(
|
|
806
|
-
desc = source[
|
|
856
|
+
if source.get("description"):
|
|
857
|
+
desc = source["description"]
|
|
807
858
|
if len(desc) > 30:
|
|
808
859
|
desc = desc[:27] + "..."
|
|
809
860
|
label = desc
|
|
810
861
|
lines.append(f'{accel_id} --> {source_id} : "{label}"')
|
|
811
862
|
|
|
812
863
|
for target in publishes_to:
|
|
813
|
-
target_id = safe_id(target[
|
|
864
|
+
target_id = safe_id(target["slug"])
|
|
814
865
|
label = "publishes to"
|
|
815
|
-
if target.get(
|
|
816
|
-
desc = target[
|
|
866
|
+
if target.get("description"):
|
|
867
|
+
desc = target["description"]
|
|
817
868
|
if len(desc) > 30:
|
|
818
869
|
desc = desc[:27] + "..."
|
|
819
870
|
label = desc
|
|
@@ -825,9 +876,9 @@ def build_accelerator_dependency_diagram(slug: str, docname: str, env) -> list:
|
|
|
825
876
|
puml_source = "\n".join(lines)
|
|
826
877
|
|
|
827
878
|
node = plantuml(puml_source)
|
|
828
|
-
node[
|
|
829
|
-
node[
|
|
830
|
-
node[
|
|
879
|
+
node["uml"] = puml_source
|
|
880
|
+
node["incdir"] = os.path.dirname(docname)
|
|
881
|
+
node["filename"] = os.path.basename(docname) + ".rst"
|
|
831
882
|
|
|
832
883
|
return [node]
|
|
833
884
|
|
|
@@ -835,6 +886,7 @@ def build_accelerator_dependency_diagram(slug: str, docname: str, env) -> list:
|
|
|
835
886
|
def build_accelerator_backlinks(slug: str, docname: str, env) -> nodes.Element:
|
|
836
887
|
"""Build seealso node with backlinks for an accelerator."""
|
|
837
888
|
from sphinx.addnodes import seealso
|
|
889
|
+
|
|
838
890
|
from . import apps
|
|
839
891
|
|
|
840
892
|
config = get_config()
|
|
@@ -849,26 +901,40 @@ def build_accelerator_backlinks(slug: str, docname: str, env) -> nodes.Element:
|
|
|
849
901
|
|
|
850
902
|
accel_path = f"{prefix}{config.get_doc_path('accelerators')}/{slug}.html"
|
|
851
903
|
accel_data = accelerator_registry.get(slug, {})
|
|
852
|
-
accel_desc = accel_data.get(
|
|
904
|
+
accel_desc = accel_data.get("objective", "").strip()
|
|
853
905
|
if not accel_desc:
|
|
854
906
|
accel_desc = f"Business accelerator for {slug.replace('-', ' ')} capabilities"
|
|
855
907
|
if len(accel_desc) > 120:
|
|
856
908
|
accel_desc = accel_desc[:117] + "..."
|
|
857
|
-
items.append(
|
|
909
|
+
items.append(
|
|
910
|
+
(accel_path, f"{slug.replace('-', ' ').title()} Accelerator", accel_desc)
|
|
911
|
+
)
|
|
858
912
|
|
|
859
913
|
app_list = get_apps_for_accelerator(slug)
|
|
860
914
|
for app_slug in app_list:
|
|
861
915
|
app_path = f"{prefix}{config.get_doc_path('applications')}/{app_slug}.html"
|
|
862
916
|
app_data = _app_registry.get(app_slug, {})
|
|
863
|
-
app_desc = app_data.get(
|
|
917
|
+
app_desc = app_data.get("description", "Application documentation")
|
|
864
918
|
if len(app_desc) > 120:
|
|
865
919
|
app_desc = app_desc[:117] + "..."
|
|
866
|
-
items.append(
|
|
920
|
+
items.append(
|
|
921
|
+
(
|
|
922
|
+
app_path,
|
|
923
|
+
app_data.get("name", app_slug.replace("-", " ").title()),
|
|
924
|
+
app_desc,
|
|
925
|
+
)
|
|
926
|
+
)
|
|
867
927
|
|
|
868
928
|
if app_list:
|
|
869
929
|
for app_slug in app_list[:2]:
|
|
870
930
|
story_path = f"{prefix}{config.get_doc_path('stories')}/{app_slug}.html"
|
|
871
|
-
items.append(
|
|
931
|
+
items.append(
|
|
932
|
+
(
|
|
933
|
+
story_path,
|
|
934
|
+
f"{app_slug.replace('-', ' ').title()} Stories",
|
|
935
|
+
"User stories",
|
|
936
|
+
)
|
|
937
|
+
)
|
|
872
938
|
|
|
873
939
|
def_list = nodes.definition_list()
|
|
874
940
|
for path, title, description in items:
|
|
@@ -895,7 +961,8 @@ def build_accelerator_backlinks(slug: str, docname: str, env) -> nodes.Element:
|
|
|
895
961
|
def build_app_backlinks(app_slug: str, docname: str, env) -> nodes.Element:
|
|
896
962
|
"""Build seealso node with backlinks for an app."""
|
|
897
963
|
from sphinx.addnodes import seealso
|
|
898
|
-
|
|
964
|
+
|
|
965
|
+
from . import apps, journeys, stories
|
|
899
966
|
|
|
900
967
|
config = get_config()
|
|
901
968
|
accelerator_registry = get_accelerator_registry(env)
|
|
@@ -912,38 +979,62 @@ def build_app_backlinks(app_slug: str, docname: str, env) -> nodes.Element:
|
|
|
912
979
|
|
|
913
980
|
if app_data:
|
|
914
981
|
app_path = f"{prefix}{config.get_doc_path('applications')}/{app_slug}.html"
|
|
915
|
-
app_desc = app_data.get(
|
|
982
|
+
app_desc = app_data.get("description", "Application documentation")
|
|
916
983
|
if len(app_desc) > 120:
|
|
917
984
|
app_desc = app_desc[:117] + "..."
|
|
918
|
-
items.append(
|
|
985
|
+
items.append(
|
|
986
|
+
(
|
|
987
|
+
app_path,
|
|
988
|
+
app_data.get("name", app_slug.replace("-", " ").title()),
|
|
989
|
+
app_desc,
|
|
990
|
+
)
|
|
991
|
+
)
|
|
919
992
|
|
|
920
|
-
accelerators = app_data.get(
|
|
993
|
+
accelerators = app_data.get("accelerators", [])
|
|
921
994
|
for accel_slug in accelerators[:4]:
|
|
922
|
-
accel_path =
|
|
995
|
+
accel_path = (
|
|
996
|
+
f"{prefix}{config.get_doc_path('accelerators')}/{accel_slug}.html"
|
|
997
|
+
)
|
|
923
998
|
accel_data = accelerator_registry.get(accel_slug, {})
|
|
924
|
-
accel_desc = accel_data.get(
|
|
999
|
+
accel_desc = accel_data.get("objective", "").strip()
|
|
925
1000
|
if not accel_desc:
|
|
926
1001
|
accel_desc = f"Business accelerator for {accel_slug.replace('-', ' ')} capabilities"
|
|
927
1002
|
if len(accel_desc) > 120:
|
|
928
1003
|
accel_desc = accel_desc[:117] + "..."
|
|
929
|
-
items.append(
|
|
1004
|
+
items.append(
|
|
1005
|
+
(
|
|
1006
|
+
accel_path,
|
|
1007
|
+
f"{accel_slug.replace('-', ' ').title()} Accelerator",
|
|
1008
|
+
accel_desc,
|
|
1009
|
+
)
|
|
1010
|
+
)
|
|
930
1011
|
|
|
931
1012
|
app_normalized = normalize_name(app_slug)
|
|
932
1013
|
if app_normalized in {normalize_name(a) for a in _apps_with_stories}:
|
|
933
1014
|
story_path = f"{prefix}{config.get_doc_path('stories')}/{app_slug}.html"
|
|
934
|
-
items.append(
|
|
1015
|
+
items.append(
|
|
1016
|
+
(
|
|
1017
|
+
story_path,
|
|
1018
|
+
f"{app_slug.replace('-', ' ').title()} Stories",
|
|
1019
|
+
"User stories",
|
|
1020
|
+
)
|
|
1021
|
+
)
|
|
935
1022
|
|
|
936
1023
|
def get_journeys_for_app_slug(slug):
|
|
937
1024
|
journey_registry = journeys.get_journey_registry(env)
|
|
938
1025
|
_story_registry = stories.get_story_registry()
|
|
939
|
-
story_list = [
|
|
940
|
-
|
|
1026
|
+
story_list = [
|
|
1027
|
+
s
|
|
1028
|
+
for s in _story_registry
|
|
1029
|
+
if normalize_name(s["app"]) == normalize_name(slug)
|
|
1030
|
+
]
|
|
1031
|
+
story_titles = {normalize_name(s["feature"]) for s in story_list}
|
|
941
1032
|
|
|
942
1033
|
result = []
|
|
943
1034
|
for j_slug, journey in journey_registry.items():
|
|
944
|
-
for step in journey.get(
|
|
945
|
-
if step.get(
|
|
946
|
-
if normalize_name(step[
|
|
1035
|
+
for step in journey.get("steps", []):
|
|
1036
|
+
if step.get("type") == "story":
|
|
1037
|
+
if normalize_name(step["ref"]) in story_titles:
|
|
947
1038
|
result.append(j_slug)
|
|
948
1039
|
break
|
|
949
1040
|
return sorted(set(result))
|
|
@@ -951,7 +1042,9 @@ def build_app_backlinks(app_slug: str, docname: str, env) -> nodes.Element:
|
|
|
951
1042
|
journey_list = get_journeys_for_app_slug(app_slug)
|
|
952
1043
|
for journey_slug in journey_list[:3]:
|
|
953
1044
|
journey_path = f"{prefix}{config.get_doc_path('journeys')}/{journey_slug}.html"
|
|
954
|
-
items.append(
|
|
1045
|
+
items.append(
|
|
1046
|
+
(journey_path, f"{journey_slug.replace('-', ' ').title()}", "User journey")
|
|
1047
|
+
)
|
|
955
1048
|
|
|
956
1049
|
def_list = nodes.definition_list()
|
|
957
1050
|
for path, title, description in items:
|
|
@@ -984,7 +1077,7 @@ def validate_accelerators(app, env):
|
|
|
984
1077
|
|
|
985
1078
|
referenced_accelerators = set()
|
|
986
1079
|
for app_data in _app_registry.values():
|
|
987
|
-
for accel in app_data.get(
|
|
1080
|
+
for accel in app_data.get("accelerators", []):
|
|
988
1081
|
referenced_accelerators.add(accel)
|
|
989
1082
|
|
|
990
1083
|
for accel in referenced_accelerators:
|
|
@@ -1008,12 +1101,12 @@ def process_accelerator_placeholders(app, doctree, docname):
|
|
|
1008
1101
|
env = app.env
|
|
1009
1102
|
|
|
1010
1103
|
for node in doctree.traverse(DefineAcceleratorPlaceholder):
|
|
1011
|
-
slug = node[
|
|
1104
|
+
slug = node["accelerator_slug"]
|
|
1012
1105
|
content = build_accelerator_content(slug, docname, env)
|
|
1013
1106
|
node.replace_self(content)
|
|
1014
1107
|
|
|
1015
1108
|
for node in doctree.traverse(AcceleratorStatusPlaceholder):
|
|
1016
|
-
slug = node[
|
|
1109
|
+
slug = node["accelerator_slug"]
|
|
1017
1110
|
content = build_accelerator_status(slug, env)
|
|
1018
1111
|
node.replace_self(content)
|
|
1019
1112
|
|
|
@@ -1022,28 +1115,30 @@ def process_accelerator_placeholders(app, doctree, docname):
|
|
|
1022
1115
|
node.replace_self(content)
|
|
1023
1116
|
|
|
1024
1117
|
for node in doctree.traverse(AcceleratorsForAppPlaceholder):
|
|
1025
|
-
app_slug = node[
|
|
1118
|
+
app_slug = node["app_slug"]
|
|
1026
1119
|
content = build_accelerators_for_app(app_slug, docname, env)
|
|
1027
1120
|
node.replace_self(content)
|
|
1028
1121
|
|
|
1029
1122
|
for node in doctree.traverse(DependentAcceleratorsPlaceholder):
|
|
1030
|
-
integration_slug = node[
|
|
1031
|
-
relationship = node[
|
|
1032
|
-
content = build_dependent_accelerators(
|
|
1123
|
+
integration_slug = node["integration_slug"]
|
|
1124
|
+
relationship = node["relationship"]
|
|
1125
|
+
content = build_dependent_accelerators(
|
|
1126
|
+
integration_slug, relationship, docname, env
|
|
1127
|
+
)
|
|
1033
1128
|
node.replace_self(content)
|
|
1034
1129
|
|
|
1035
1130
|
for node in doctree.traverse(AcceleratorDependencyDiagramPlaceholder):
|
|
1036
|
-
slug = node[
|
|
1131
|
+
slug = node["accelerator_slug"]
|
|
1037
1132
|
content = build_accelerator_dependency_diagram(slug, docname, env)
|
|
1038
1133
|
node.replace_self(content)
|
|
1039
1134
|
|
|
1040
1135
|
for node in doctree.traverse(SrcAcceleratorBacklinksPlaceholder):
|
|
1041
|
-
slug = node[
|
|
1136
|
+
slug = node["accelerator_slug"]
|
|
1042
1137
|
content = build_accelerator_backlinks(slug, docname, env)
|
|
1043
1138
|
node.replace_self([content])
|
|
1044
1139
|
|
|
1045
1140
|
for node in doctree.traverse(SrcAppBacklinksPlaceholder):
|
|
1046
|
-
app_slug = node[
|
|
1141
|
+
app_slug = node["app_slug"]
|
|
1047
1142
|
content = build_app_backlinks(app_slug, docname, env)
|
|
1048
1143
|
node.replace_self([content])
|
|
1049
1144
|
|
|
@@ -1058,7 +1153,9 @@ def setup(app):
|
|
|
1058
1153
|
app.add_directive("accelerator-status", AcceleratorStatusDirective)
|
|
1059
1154
|
app.add_directive("accelerators-for-app", AcceleratorsForAppDirective)
|
|
1060
1155
|
app.add_directive("dependent-accelerators", DependentAcceleratorsDirective)
|
|
1061
|
-
app.add_directive(
|
|
1156
|
+
app.add_directive(
|
|
1157
|
+
"accelerator-dependency-diagram", AcceleratorDependencyDiagramDirective
|
|
1158
|
+
)
|
|
1062
1159
|
app.add_directive("src-accelerator-backlinks", SrcAcceleratorBacklinksDirective)
|
|
1063
1160
|
app.add_directive("src-app-backlinks", SrcAppBacklinksDirective)
|
|
1064
1161
|
|