SEED: Create Sphinx directive for metadata
Change-Id: I0f9fa9e7b611161b7a2b30818dc0244194f37672
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/161517
Commit-Queue: Chad Norvell <chadnorvell@google.com>
Reviewed-by: Alexei Frolov <frolv@google.com>
Presubmit-Verified: CQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com>
diff --git a/docs/conf.py b/docs/conf.py
index ea55906..47e8425 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -43,6 +43,7 @@
'pw_docgen.sphinx.google_analytics', # Enables optional Google Analytics
'pw_docgen.sphinx.kconfig',
'pw_docgen.sphinx.module_metadata',
+ 'pw_docgen.sphinx.seed_metadata',
'sphinx.ext.autodoc', # Automatic documentation for Python code
'sphinx.ext.napoleon', # Parses Google-style docstrings
'sphinxarg.ext', # Automatic documentation of Python argparse
diff --git a/pw_docgen/py/BUILD.gn b/pw_docgen/py/BUILD.gn
index c298850..0f4b511 100644
--- a/pw_docgen/py/BUILD.gn
+++ b/pw_docgen/py/BUILD.gn
@@ -28,6 +28,7 @@
"pw_docgen/sphinx/google_analytics.py",
"pw_docgen/sphinx/kconfig.py",
"pw_docgen/sphinx/module_metadata.py",
+ "pw_docgen/sphinx/seed_metadata.py",
]
pylintrc = "$dir_pigweed/.pylintrc"
mypy_ini = "$dir_pigweed/.mypy.ini"
diff --git a/pw_docgen/py/pw_docgen/sphinx/seed_metadata.py b/pw_docgen/py/pw_docgen/sphinx/seed_metadata.py
new file mode 100644
index 0000000..9134081
--- /dev/null
+++ b/pw_docgen/py/pw_docgen/sphinx/seed_metadata.py
@@ -0,0 +1,133 @@
+# Copyright 2023 The Pigweed Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not
+# use this file except in compliance with the License. You may obtain a copy of
+# the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations under
+# the License.
+"""Sphinx directives for Pigweed SEEDs"""
+
+from typing import List
+
+import docutils
+from docutils import nodes
+import docutils.statemachine
+
+# pylint: disable=consider-using-from-import
+import docutils.parsers.rst.directives as directives # type: ignore
+
+# pylint: enable=consider-using-from-import
+from sphinx.application import Sphinx as SphinxApplication
+from sphinx.util.docutils import SphinxDirective
+
+from sphinx_design.cards import CardDirective
+
+
+def status_choice(arg) -> str:
+ return directives.choice(
+ arg, ('open_for_comments', 'last_call', 'accepted', 'rejected')
+ )
+
+
+def parse_status(arg) -> str:
+ """Support variations on the status choices.
+
+ For example, you can use capital letters and spaces.
+ """
+
+ return status_choice('_'.join([token.lower() for token in arg.split(' ')]))
+
+
+def status_badge(seed_status: str, badge_status) -> str:
+ """Given a SEED status, return the status badge for rendering."""
+
+ return (
+ ':bdg-primary:'
+ if seed_status == badge_status
+ else ':bdg-secondary-line:'
+ )
+
+
+def cl_link(cl_num):
+ return (
+ f'`pwrev/{cl_num} '
+ '<https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/'
+ f'{cl_num}>`_'
+ )
+
+
+class PigweedSeedDirective(SphinxDirective):
+ """Directive registering & rendering SEED metadata."""
+
+ required_arguments = 0
+ final_argument_whitespace = True
+ has_content = True
+ option_spec = {
+ 'number': directives.positive_int,
+ 'name': directives.unchanged_required,
+ 'status': parse_status,
+ 'proposal_date': directives.unchanged_required,
+ 'cl': directives.positive_int_list,
+ }
+
+ def _try_get_option(self, option: str):
+ """Try to get an option by name and raise on failure."""
+
+ try:
+ return self.options[option]
+ except KeyError:
+ raise self.error(f' :{option}: option is required')
+
+ def run(self) -> List[nodes.Node]:
+ seed_number = '{:04d}'.format(self._try_get_option('number'))
+ seed_name = self._try_get_option('name')
+ status = self._try_get_option('status')
+ proposal_date = self._try_get_option('proposal_date')
+ cl_nums = self._try_get_option('cl')
+
+ title = (
+ f':fas:`seedling` SEED-{seed_number}: :ref:'
+ f'`{seed_name}<seed-{seed_number}>`\n'
+ )
+
+ self.content = docutils.statemachine.StringList(
+ [
+ ':octicon:`comment-discussion` Status:',
+ f'{status_badge(status, "open_for_comments")}'
+ '`Open for Comments`',
+ ':octicon:`chevron-right`',
+ f'{status_badge(status, "last_call")}`Last Call`',
+ ':octicon:`chevron-right`',
+ f'{status_badge(status, "accepted")}`Accepted`',
+ ':octicon:`kebab-horizontal`',
+ f'{status_badge(status, "rejected")}`Rejected`',
+ '\n',
+ f':octicon:`calendar` Proposal Date: {proposal_date}',
+ '\n',
+ ':octicon:`code-review` CL: ',
+ ', '.join([cl_link(cl_num) for cl_num in cl_nums]),
+ ]
+ )
+
+ card = CardDirective.create_card(
+ inst=self,
+ arguments=[title],
+ options={},
+ )
+
+ return [card]
+
+
+def setup(app: SphinxApplication):
+ app.add_directive('seed', PigweedSeedDirective)
+
+ return {
+ 'parallel_read_safe': True,
+ 'parallel_write_safe': True,
+ }
diff --git a/seed/0001-the-seed-process.rst b/seed/0001-the-seed-process.rst
index 3b7958b..58182a8 100644
--- a/seed/0001-the-seed-process.rst
+++ b/seed/0001-the-seed-process.rst
@@ -3,22 +3,12 @@
======================
0001: The SEED Process
======================
-
-.. card::
- :fas:`seedling` SEED-0001: :ref:`The SEED Process<seed-0001>`
-
- :octicon:`comment-discussion` Status:
- :bdg-secondary-line:`Open for Comments`
- :octicon:`chevron-right`
- :bdg-secondary-line:`Last Call`
- :octicon:`chevron-right`
- :bdg-primary:`Accepted`
- :octicon:`kebab-horizontal`
- :bdg-secondary-line:`Rejected`
-
- :octicon:`calendar` Proposal Date: 2022-10-31
-
- :octicon:`code-review` CL: `pwrev/116577 <https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/116577>`_
+.. seed::
+ :number: 1
+ :name: The SEED Process
+ :status: Accepted
+ :proposal_date: 2022-10-31
+ :cl: 116577
-------
Summary
diff --git a/seed/0002-template.rst b/seed/0002-template.rst
index 5b34f9f..844c6e1 100644
--- a/seed/0002-template.rst
+++ b/seed/0002-template.rst
@@ -3,22 +3,12 @@
===================
0002: SEED Template
===================
-
-.. card::
- :fas:`seedling` SEED-0002: :ref:`SEED Template<seed-0002>`
-
- :octicon:`comment-discussion` Status:
- :bdg-primary:`Open for Comments`
- :octicon:`chevron-right`
- :bdg-secondary-line:`Last Call`
- :octicon:`chevron-right`
- :bdg-secondary-line:`Accepted`
- :octicon:`kebab-horizontal`
- :bdg-secondary-line:`Rejected`
-
- :octicon:`calendar` Proposal Date: 2022-11-30
-
- :octicon:`code-review` CL: `pwrev/123090 <https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/123090>`_
+.. seed::
+ :number: 2
+ :name: SEED Template
+ :status: Open for Comments
+ :proposal_date: 2022-11-30
+ :cl: 123090
-------
Summary
diff --git a/seed/0101-pigweed.json.rst b/seed/0101-pigweed.json.rst
index b1f5eda..271f0b1 100644
--- a/seed/0101-pigweed.json.rst
+++ b/seed/0101-pigweed.json.rst
@@ -3,22 +3,12 @@
==================
0101: pigweed.json
==================
-
-.. card::
- :fas:`seedling` SEED-0101: :ref:`pigweed.json<seed-0101>`
-
- :octicon:`comment-discussion` Status:
- :bdg-secondary-line:`Open for Comments`
- :octicon:`chevron-right`
- :bdg-secondary-line:`Last Call`
- :octicon:`chevron-right`
- :bdg-primary:`Accepted`
- :octicon:`kebab-horizontal`
- :bdg-secondary-line:`Rejected`
-
- :octicon:`calendar` Proposal Date: 2023-02-06
-
- :octicon:`code-review` CL: `pwrev/128010 <https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/128010>`_
+.. seed::
+ :number: 0101
+ :name: pigweed.json
+ :status: Accepted
+ :proposal_date: 2023-02-06
+ :cl: 128010
-------
Summary
diff --git a/seed/0102-module-docs.rst b/seed/0102-module-docs.rst
index 9cdff64..3e81791 100644
--- a/seed/0102-module-docs.rst
+++ b/seed/0102-module-docs.rst
@@ -3,22 +3,12 @@
=====================================
0102: Consistent Module Documentation
=====================================
-
-.. card::
- :fas:`seedling` SEED-0102: :ref:`Consistent Module Documentation<seed-0102>`
-
- :octicon:`comment-discussion` Status:
- :bdg-secondary-line:`Open for Comments`
- :octicon:`chevron-right`
- :bdg-secondary-line:`Last Call`
- :octicon:`chevron-right`
- :bdg-primary:`Accepted`
- :octicon:`kebab-horizontal`
- :bdg-secondary-line:`Rejected`
-
- :octicon:`calendar` Proposal Date: 2023-02-10
-
- :octicon:`code-review` CL: `pwrev/128811 <https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/128811>`_, `pwrev/130410 <https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/130410>`_
+.. seed::
+ :number: 102
+ :name: Consistent Module Documentation
+ :status: Accepted
+ :proposal_date: 2023-02-10
+ :cl: 128811, 130410
-------
Summary