Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Allow configuring description of extra option #1338

Merged
merged 5 commits into from
Oct 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions docs/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,12 @@ For example:
{directive="spec", title="Specification", prefix="S_", color="#FEDCD2", style="node"},
]

To specify a different `table path <https://toml.io/en/v1.0.0#table>`__ to read from in the toml file, use the ``needs_from_toml_table`` option.
To specify a different `root table path <https://toml.io/en/v1.0.0#table>`__ to read from in the toml file, use the ``needs_from_toml_table`` option.
For example to read from a ``[tool.needs]`` table:

.. code-block:: python

needs_from_toml_table = ["tool", "needs"]
needs_from_toml_table = ["tool"]

.. caution:: Any configuration specifying relative paths in the toml file will be resolved relative to the directory containing the :file:`conf.py` file.

Expand Down Expand Up @@ -256,6 +256,24 @@ And use it like:
.. needlist::
:filter: "filter_me" in another_option

.. versionadded:: 4.1.0

Values in the list can also be dictionaries, with keys:

* ``name``: The name of the option (required).
* ``description``: A description of the option (optional).
This will be output in the schema of the :ref:`needs.json <needs_builder_format>`,
and can be used by other tools.

For example:

.. code-block:: python

needs_extra_options = [
"my_extra_option",
{"name": "my_other_option", "description": "This is a description of the option"}
]

.. _needs_global_options:

needs_global_options
Expand Down
14 changes: 11 additions & 3 deletions sphinx_needs/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,14 @@ class NeedType(TypedDict):
"""The default node style to use in diagrams (default: "node")."""


class NeedExtraOption(TypedDict):
"""Defines an extra option for needs"""

name: str
description: NotRequired[str]
"""A description of the option."""


@dataclass
class NeedsSphinxConfig:
"""A wrapper around the Sphinx configuration,
Expand Down Expand Up @@ -313,9 +321,9 @@ def get_default(cls, name: str) -> Any:
"""Path to a TOML file to load configuration from."""

from_toml_table: list[str] = field(
default_factory=lambda: ["needs"], metadata={"rebuild": "env", "types": (list,)}
default_factory=list, metadata={"rebuild": "env", "types": (list,)}
)
"""Path to the table in the toml file to load configuration from."""
"""Path to the root table in the toml file to load configuration from."""

types: list[NeedType] = field(
default_factory=lambda: [
Expand Down Expand Up @@ -407,7 +415,7 @@ def get_default(cls, name: str) -> Any:
default=30, metadata={"rebuild": "html", "types": (int,)}
)
"""Maximum length of the title in the need role output."""
_extra_options: list[str] = field(
_extra_options: list[str | NeedExtraOption] = field(
default_factory=list, metadata={"rebuild": "html", "types": (list,)}
)
"""List of extra options for needs, that get added as directive options and need fields."""
Expand Down
37 changes: 31 additions & 6 deletions sphinx_needs/needs.py
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@
try:
with toml_file.open("rb") as f:
toml_data = tomllib.load(f)
for key in toml_path:
for key in (*toml_path, "needs"):
toml_data = toml_data[key]
assert isinstance(toml_data, dict), "Data must be a dict"
except Exception as e:
Expand All @@ -411,15 +411,40 @@
needs_config = NeedsSphinxConfig(app.config)

if isinstance(needs_config._extra_options, dict):
LOGGER.info(
log_warning(

Check warning on line 414 in sphinx_needs/needs.py

View check run for this annotation

Codecov / codecov/patch

sphinx_needs/needs.py#L414

Added line #L414 was not covered by tests
LOGGER,
'Config option "needs_extra_options" supports list and dict. However new default type since '
"Sphinx-Needs 0.7.2 is list. Please see docs for details."
"Sphinx-Needs 0.7.2 is list. Please see docs for details.",
"config",
None,
)

for option in needs_config._extra_options:
_NEEDS_CONFIG.add_extra_option(
option, "Added by needs_extra_options config", override=True
)
description = "Added by needs_extra_options config"
if isinstance(option, str):
name = option
elif isinstance(option, dict):
try:
name = option["name"]
except KeyError:
log_warning(
LOGGER,
f"extra_option is a dict, but does not contain a 'name' key: {option}",
"config",
None,
)
continue
description = option.get("description", description)
else:
log_warning(
LOGGER,
f"extra_option is not a string or dict: {option}",
"config",
None,
)
continue

_NEEDS_CONFIG.add_extra_option(name, description, override=True)

# ensure options for ``needgantt`` functionality are added to the extra options
for option in (needs_config.duration_option, needs_config.completion_option):
Expand Down
Loading
Loading