Skip to content

Commit d99bb11

Browse files
committed
feat: Add a config for openedx-events annotations
1 parent 786da8c commit d99bb11

File tree

3 files changed

+156
-0
lines changed

3 files changed

+156
-0
lines changed

code_annotations/contrib/config/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,7 @@
1313
"code_annotations",
1414
os.path.join("contrib", "config", "setting_annotations.yaml"),
1515
)
16+
OPENEDX_EVENTS_ANNOTATIONS_CONFIG_PATH = pkg_resources.resource_filename(
17+
"code_annotations",
18+
os.path.join("contrib", "config", "openedx_events_annotations.yaml"),
19+
)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# This code-annotations configuration file supports openedx-events
2+
3+
source_path: ./
4+
report_path: reports
5+
safelist_path: .annotation_safe_list.yml
6+
coverage_target: 100.0
7+
annotations:
8+
feature_toggle:
9+
# See annotation format documentation: https://edx-toggles.readthedocs.io/en/latest/how_to/documenting_new_feature_toggles.html
10+
- ".. event_type:":
11+
- ".. event_name:":
12+
- ".. event_description:":
13+
- ".. event_data:":
14+
- ".. event_key_field:":
15+
extensions:
16+
python:
17+
- py
18+
rst_template: doc.rst.j2
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
"""
2+
Sphinx extension for viewing openedx events annotations.
3+
"""
4+
import os
5+
6+
from docutils import nodes
7+
from sphinx.util.docutils import SphinxDirective
8+
9+
from code_annotations.contrib.config import OPENEDX_EVENTS_ANNOTATIONS_CONFIG_PATH
10+
11+
from .base import find_annotations, quote_value
12+
13+
14+
def find_events(source_path):
15+
"""
16+
Find the feature toggles as defined in the configuration file.
17+
18+
Return:
19+
toggles (dict): feature toggles indexed by name.
20+
"""
21+
return find_annotations(
22+
source_path, OPENEDX_EVENTS_ANNOTATIONS_CONFIG_PATH, ".. event_type:"
23+
)
24+
25+
26+
class OpenedxEvents(SphinxDirective):
27+
"""
28+
Sphinx directive to list the events in a single documentation page.
29+
30+
Use this directive as follows::
31+
32+
.. openedxevents::
33+
34+
This directive supports the following configuration parameters:
35+
36+
- ``openedxevents_source_path``: absolute path to the repository file tree. E.g:
37+
38+
openedxevents_source_path = os.path.join(os.path.dirname(__file__), "..", "..")
39+
40+
- ``openedxevents_repo_url``: Github repository where the code is hosted. E.g:
41+
42+
openedxevents_repo_url = "https://github.com/openedx/myrepo"
43+
44+
- ``openedxevents_repo_version``: current version of the git repository. E.g:
45+
46+
import git
47+
try:
48+
repo = git.Repo(search_parent_directories=True)
49+
openedxevents_repo_version = repo.head.object.hexsha
50+
except git.InvalidGitRepositoryError:
51+
openedxevents_repo_version = "main"
52+
"""
53+
54+
required_arguments = 0
55+
optional_arguments = 0
56+
option_spec = {}
57+
58+
def run(self):
59+
"""
60+
Public interface of the Directive class.
61+
62+
Return:
63+
nodes (list): nodes to be appended to the resulting document.
64+
"""
65+
return list(self.iter_nodes())
66+
67+
def iter_nodes(self):
68+
"""
69+
Iterate on the docutils nodes generated by this directive.
70+
"""
71+
events = find_events(self.env.config.openedxevents_source_path)
72+
73+
current_domain = ""
74+
domain_header = None
75+
76+
for event_type in sorted(events):
77+
domain = event_type.split(".")[2]
78+
if domain != current_domain:
79+
if domain_header:
80+
yield domain_header
81+
82+
current_domain = domain
83+
domain_header = nodes.section("", ids=[f"openedxevent-domain-{domain}"])
84+
domain_header += nodes.title(text=f"Architectural domain: {domain}")
85+
86+
event = events[event_type]
87+
event_name = event[".. event_name:"]
88+
event_name_literal = nodes.literal(text=quote_value(event_name))
89+
event_data = event[".. event_data:"]
90+
event_key_field = event.get(".. event_key_field:", None)
91+
event_key_literal = nodes.literal(text=quote_value(event_key_field))
92+
event_description = event[".. event_description:"]
93+
94+
event_section = nodes.section("", ids=[f"openedxevent-{event_type}"])
95+
event_section += nodes.title(text=event_type, ids=[f"title-{event_type}"])
96+
event_section += nodes.paragraph("", "Signal name:", event_name_literal)
97+
if event_key_field:
98+
event_section += nodes.paragraph(
99+
"",
100+
"Event key field:",
101+
event_key_literal
102+
)
103+
event_section += nodes.paragraph(text=f"Description:"
104+
f" {event_description}")
105+
event_section += nodes.paragraph(text=f"Event data: {event_data}")
106+
event_section += nodes.paragraph(
107+
text=f"Defined at: {event['filename']} (line"
108+
f" {event['line_number']})"
109+
)
110+
111+
domain_header += event_section
112+
113+
if domain_header:
114+
yield domain_header
115+
116+
117+
def setup(app):
118+
"""
119+
Declare the Sphinx extension.
120+
"""
121+
app.add_config_value(
122+
"openedxevents_source_path",
123+
os.path.abspath(".."),
124+
"env",
125+
)
126+
app.add_config_value("openedxevents_repo_url", "", "env")
127+
app.add_config_value("openedxevents_repo_version", "main", "env")
128+
app.add_directive("openedxevents", OpenedxEvents)
129+
130+
return {
131+
"version": "0.1",
132+
"parallel_read_safe": True,
133+
"parallel_write_safe": True,
134+
}

0 commit comments

Comments
 (0)