From d99bb1123bd89d240575990d29532ad360d060b3 Mon Sep 17 00:00:00 2001 From: Brian Mesick Date: Fri, 16 Feb 2024 13:02:22 -0500 Subject: [PATCH 1/5] feat: Add a config for openedx-events annotations --- code_annotations/contrib/config/__init__.py | 4 + .../config/openedx_events_annotations.yaml | 18 +++ .../sphinx/extensions/openedx_events.py | 134 ++++++++++++++++++ 3 files changed, 156 insertions(+) create mode 100644 code_annotations/contrib/config/openedx_events_annotations.yaml create mode 100644 code_annotations/contrib/sphinx/extensions/openedx_events.py diff --git a/code_annotations/contrib/config/__init__.py b/code_annotations/contrib/config/__init__.py index 1a8c0e9..3e83f7a 100644 --- a/code_annotations/contrib/config/__init__.py +++ b/code_annotations/contrib/config/__init__.py @@ -13,3 +13,7 @@ "code_annotations", os.path.join("contrib", "config", "setting_annotations.yaml"), ) +OPENEDX_EVENTS_ANNOTATIONS_CONFIG_PATH = pkg_resources.resource_filename( + "code_annotations", + os.path.join("contrib", "config", "openedx_events_annotations.yaml"), +) diff --git a/code_annotations/contrib/config/openedx_events_annotations.yaml b/code_annotations/contrib/config/openedx_events_annotations.yaml new file mode 100644 index 0000000..2c25ce0 --- /dev/null +++ b/code_annotations/contrib/config/openedx_events_annotations.yaml @@ -0,0 +1,18 @@ +# This code-annotations configuration file supports openedx-events + +source_path: ./ +report_path: reports +safelist_path: .annotation_safe_list.yml +coverage_target: 100.0 +annotations: + feature_toggle: + # See annotation format documentation: https://edx-toggles.readthedocs.io/en/latest/how_to/documenting_new_feature_toggles.html + - ".. event_type:": + - ".. event_name:": + - ".. event_description:": + - ".. event_data:": + - ".. event_key_field:": +extensions: + python: + - py +rst_template: doc.rst.j2 diff --git a/code_annotations/contrib/sphinx/extensions/openedx_events.py b/code_annotations/contrib/sphinx/extensions/openedx_events.py new file mode 100644 index 0000000..9a9f05d --- /dev/null +++ b/code_annotations/contrib/sphinx/extensions/openedx_events.py @@ -0,0 +1,134 @@ +""" +Sphinx extension for viewing openedx events annotations. +""" +import os + +from docutils import nodes +from sphinx.util.docutils import SphinxDirective + +from code_annotations.contrib.config import OPENEDX_EVENTS_ANNOTATIONS_CONFIG_PATH + +from .base import find_annotations, quote_value + + +def find_events(source_path): + """ + Find the feature toggles as defined in the configuration file. + + Return: + toggles (dict): feature toggles indexed by name. + """ + return find_annotations( + source_path, OPENEDX_EVENTS_ANNOTATIONS_CONFIG_PATH, ".. event_type:" + ) + + +class OpenedxEvents(SphinxDirective): + """ + Sphinx directive to list the events in a single documentation page. + + Use this directive as follows:: + + .. openedxevents:: + + This directive supports the following configuration parameters: + + - ``openedxevents_source_path``: absolute path to the repository file tree. E.g: + + openedxevents_source_path = os.path.join(os.path.dirname(__file__), "..", "..") + + - ``openedxevents_repo_url``: Github repository where the code is hosted. E.g: + + openedxevents_repo_url = "https://github.com/openedx/myrepo" + + - ``openedxevents_repo_version``: current version of the git repository. E.g: + + import git + try: + repo = git.Repo(search_parent_directories=True) + openedxevents_repo_version = repo.head.object.hexsha + except git.InvalidGitRepositoryError: + openedxevents_repo_version = "main" + """ + + required_arguments = 0 + optional_arguments = 0 + option_spec = {} + + def run(self): + """ + Public interface of the Directive class. + + Return: + nodes (list): nodes to be appended to the resulting document. + """ + return list(self.iter_nodes()) + + def iter_nodes(self): + """ + Iterate on the docutils nodes generated by this directive. + """ + events = find_events(self.env.config.openedxevents_source_path) + + current_domain = "" + domain_header = None + + for event_type in sorted(events): + domain = event_type.split(".")[2] + if domain != current_domain: + if domain_header: + yield domain_header + + current_domain = domain + domain_header = nodes.section("", ids=[f"openedxevent-domain-{domain}"]) + domain_header += nodes.title(text=f"Architectural domain: {domain}") + + event = events[event_type] + event_name = event[".. event_name:"] + event_name_literal = nodes.literal(text=quote_value(event_name)) + event_data = event[".. event_data:"] + event_key_field = event.get(".. event_key_field:", None) + event_key_literal = nodes.literal(text=quote_value(event_key_field)) + event_description = event[".. event_description:"] + + event_section = nodes.section("", ids=[f"openedxevent-{event_type}"]) + event_section += nodes.title(text=event_type, ids=[f"title-{event_type}"]) + event_section += nodes.paragraph("", "Signal name:", event_name_literal) + if event_key_field: + event_section += nodes.paragraph( + "", + "Event key field:", + event_key_literal + ) + event_section += nodes.paragraph(text=f"Description:" + f" {event_description}") + event_section += nodes.paragraph(text=f"Event data: {event_data}") + event_section += nodes.paragraph( + text=f"Defined at: {event['filename']} (line" + f" {event['line_number']})" + ) + + domain_header += event_section + + if domain_header: + yield domain_header + + +def setup(app): + """ + Declare the Sphinx extension. + """ + app.add_config_value( + "openedxevents_source_path", + os.path.abspath(".."), + "env", + ) + app.add_config_value("openedxevents_repo_url", "", "env") + app.add_config_value("openedxevents_repo_version", "main", "env") + app.add_directive("openedxevents", OpenedxEvents) + + return { + "version": "0.1", + "parallel_read_safe": True, + "parallel_write_safe": True, + } From 541f1f7f432cfd146ab2ebb484ece8140c165fe9 Mon Sep 17 00:00:00 2001 From: Brian Mesick Date: Tue, 20 Feb 2024 11:18:09 -0500 Subject: [PATCH 2/5] feat: Add a config for openedx-events annotations --- .../sphinx/extensions/openedx_events.py | 34 ++++++++++++------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/code_annotations/contrib/sphinx/extensions/openedx_events.py b/code_annotations/contrib/sphinx/extensions/openedx_events.py index 9a9f05d..35c8b71 100644 --- a/code_annotations/contrib/sphinx/extensions/openedx_events.py +++ b/code_annotations/contrib/sphinx/extensions/openedx_events.py @@ -8,7 +8,7 @@ from code_annotations.contrib.config import OPENEDX_EVENTS_ANNOTATIONS_CONFIG_PATH -from .base import find_annotations, quote_value +from .base import find_annotations def find_events(source_path): @@ -72,43 +72,53 @@ def iter_nodes(self): current_domain = "" domain_header = None + current_subject = "" + subject_header = None for event_type in sorted(events): domain = event_type.split(".")[2] + subject = event_type.split(".")[3] if domain != current_domain: if domain_header: yield domain_header current_domain = domain domain_header = nodes.section("", ids=[f"openedxevent-domain-{domain}"]) - domain_header += nodes.title(text=f"Architectural domain: {domain}") + domain_header += nodes.title(text=f"Architectural subdomain: {domain}") + if subject != current_subject: + current_subject = subject + subject_header = nodes.section("", ids=[f"openedxevent-subject" + f"-{subject}"]) + subject_header += nodes.title(text=f"Subject: {subject}") + domain_header += subject_header event = events[event_type] event_name = event[".. event_name:"] - event_name_literal = nodes.literal(text=quote_value(event_name)) + event_name_literal = nodes.literal(text=event_name) event_data = event[".. event_data:"] - event_key_field = event.get(".. event_key_field:", None) - event_key_literal = nodes.literal(text=quote_value(event_key_field)) + event_data_literal = nodes.literal(text=event_data) + event_key_field = event.get(".. event_key_field:", "") + event_key_literal = nodes.literal(text=event_key_field) event_description = event[".. event_description:"] event_section = nodes.section("", ids=[f"openedxevent-{event_type}"]) event_section += nodes.title(text=event_type, ids=[f"title-{event_type}"]) - event_section += nodes.paragraph("", "Signal name:", event_name_literal) + event_section += nodes.paragraph(text=f"Description:" + f"{event_description}") + event_section += nodes.paragraph(" ", "Signal name:", event_name_literal) if event_key_field: event_section += nodes.paragraph( - "", - "Event key field:", + " ", + "Event key field: ", event_key_literal ) - event_section += nodes.paragraph(text=f"Description:" - f" {event_description}") - event_section += nodes.paragraph(text=f"Event data: {event_data}") + event_section += nodes.paragraph(" ", "Event data:", event_data_literal) event_section += nodes.paragraph( text=f"Defined at: {event['filename']} (line" f" {event['line_number']})" ) - domain_header += event_section + subject_header += event_section if domain_header: yield domain_header From f4fbc7191ec1bc9caea666b25cc6ca69034f53d9 Mon Sep 17 00:00:00 2001 From: Brian Mesick Date: Tue, 20 Feb 2024 15:42:11 -0500 Subject: [PATCH 3/5] fix: Formatting of event annotation output --- .../contrib/sphinx/extensions/openedx_events.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code_annotations/contrib/sphinx/extensions/openedx_events.py b/code_annotations/contrib/sphinx/extensions/openedx_events.py index 35c8b71..7fac84f 100644 --- a/code_annotations/contrib/sphinx/extensions/openedx_events.py +++ b/code_annotations/contrib/sphinx/extensions/openedx_events.py @@ -103,16 +103,16 @@ def iter_nodes(self): event_section = nodes.section("", ids=[f"openedxevent-{event_type}"]) event_section += nodes.title(text=event_type, ids=[f"title-{event_type}"]) - event_section += nodes.paragraph(text=f"Description:" + event_section += nodes.paragraph(text=f"Description: " f"{event_description}") - event_section += nodes.paragraph(" ", "Signal name:", event_name_literal) + event_section += nodes.paragraph("", "Signal name: ", event_name_literal) if event_key_field: event_section += nodes.paragraph( - " ", + "", "Event key field: ", event_key_literal ) - event_section += nodes.paragraph(" ", "Event data:", event_data_literal) + event_section += nodes.paragraph("", "Event data: ", event_data_literal) event_section += nodes.paragraph( text=f"Defined at: {event['filename']} (line" f" {event['line_number']})" From 06124eac584b3480bd33e7092e23d3b2357b65f5 Mon Sep 17 00:00:00 2001 From: Brian Mesick Date: Tue, 20 Feb 2024 15:42:26 -0500 Subject: [PATCH 4/5] chore: Bump version to 1.7.0 --- code_annotations/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code_annotations/__init__.py b/code_annotations/__init__.py index 5089f01..40aa8f8 100644 --- a/code_annotations/__init__.py +++ b/code_annotations/__init__.py @@ -2,4 +2,4 @@ Extensible tools for parsing annotations in codebases. """ -__version__ = '1.6.0' +__version__ = '1.7.0' From da3fe3bf0f0bb9fe4b562c6f628612265d8ffa95 Mon Sep 17 00:00:00 2001 From: Brian Mesick Date: Mon, 26 Feb 2024 10:29:35 -0500 Subject: [PATCH 5/5] docs: Fix copied comment to match reality --- code_annotations/contrib/sphinx/extensions/openedx_events.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code_annotations/contrib/sphinx/extensions/openedx_events.py b/code_annotations/contrib/sphinx/extensions/openedx_events.py index 7fac84f..b8f839c 100644 --- a/code_annotations/contrib/sphinx/extensions/openedx_events.py +++ b/code_annotations/contrib/sphinx/extensions/openedx_events.py @@ -13,10 +13,10 @@ def find_events(source_path): """ - Find the feature toggles as defined in the configuration file. + Find the events as defined in the configuration file. Return: - toggles (dict): feature toggles indexed by name. + events (dict): found events indexed by event type. """ return find_annotations( source_path, OPENEDX_EVENTS_ANNOTATIONS_CONFIG_PATH, ".. event_type:"