Skip to content

Commit

Permalink
🔧 Replace Directive with SphinxDirective (#986)
Browse files Browse the repository at this point in the history
`SphinxDirective` provides a number of additional helper methods over the docutils class, including access to the Sphinx environment.
This commit ensures it is used for all directives.
  • Loading branch information
chrisjsewell committed Aug 25, 2023
1 parent bf8528b commit 4479bee
Show file tree
Hide file tree
Showing 18 changed files with 47 additions and 56 deletions.
6 changes: 3 additions & 3 deletions sphinx_needs/api/need.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,16 +82,16 @@ def add_need(
.. code-block:: python
from docutils.parsers.rst import Directive
from sphinx.util.docutils import SphinxDirective
from sphinx_needs.api import add_need
class MyDirective(Directive)
class MyDirective(SphinxDirective)
# configs and init routine
def run():
main_section = []
docname = self.state.document.settings.env.docname
docname = self.env.docname
# All needed sphinx-internal information we can take from our current directive class.
# e..g app, state, lineno
Expand Down
28 changes: 12 additions & 16 deletions sphinx_needs/diagrams_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
from urllib.parse import urlparse

from docutils import nodes
from docutils.parsers.rst import Directive, directives
from docutils.parsers.rst import directives
from sphinx.application import Sphinx
from sphinx.environment import BuildEnvironment
from sphinx.util.docutils import SphinxDirective

from sphinx_needs.errors import NoUri
from sphinx_needs.logging import get_logger
Expand All @@ -22,7 +22,7 @@
logger = get_logger(__name__)


class DiagramBase(Directive):
class DiagramBase(SphinxDirective):
has_content = True

base_option_spec = {
Expand All @@ -38,28 +38,24 @@ class DiagramBase(Directive):
}

def prepare_env(self, env_var: str) -> str:
env = self.state.document.settings.env
env_var = "need_all_" + env_var
if not hasattr(env, env_var):
setattr(env, env_var, {})
if not hasattr(self.env, env_var):
setattr(self.env, env_var, {})

# be sure, global var is available. If not, create it
if not hasattr(env, "needs_all_needs"):
env.needs_all_needs = {}
if not hasattr(self.env, "needs_all_needs"):
self.env.needs_all_needs = {}

return env_var

def create_target(self, target_name: str) -> Tuple[int, str, nodes.target]:
env: BuildEnvironment = self.state.document.settings.env
id = env.new_serialno(target_name)
targetid = f"{target_name}-{env.docname}-{id}"
id = self.env.new_serialno(target_name)
targetid = f"{target_name}-{self.env.docname}-{id}"
targetnode = nodes.target("", "", ids=[targetid])

return id, targetid, targetnode

def collect_diagram_attributes(self) -> Dict[str, Any]:
env = self.state.document.settings.env

link_types = self.options.get("link_types", "links")
if len(link_types) > 0:
link_types = [link_type.strip() for link_type in re.split(";|,", link_types)]
Expand All @@ -70,16 +66,16 @@ def collect_diagram_attributes(self) -> Dict[str, Any]:
"Scruffy link_type definition found in needsequence. "
"Defined link_type contains spaces only. [needs]",
type="needs",
location=(env.docname, self.lineno),
location=(self.env.docname, self.lineno),
)

config_names = self.options.get("config")
configs = []
if config_names:
for config_name in config_names.split(","):
config_name = config_name.strip()
if config_name and config_name in env.config.needs_flow_configs:
configs.append(env.config.needs_flow_configs[config_name])
if config_name and config_name in self.config.needs_flow_configs:
configs.append(self.config.needs_flow_configs[config_name])

scale = self.options.get("scale", "100").replace("%", "")
if not scale.isdigit():
Expand Down
7 changes: 4 additions & 3 deletions sphinx_needs/directives/list2need.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
from typing import Any, List, Sequence

from docutils import nodes
from docutils.parsers.rst import Directive, directives
from docutils.parsers.rst import directives
from jinja2 import Template
from sphinx.errors import SphinxError, SphinxWarning
from sphinx.util.docutils import SphinxDirective

NEED_TEMPLATE = """.. {{type}}:: {{title}}
{% if need_id is not none %}:id: {{need_id}}{%endif%}
Expand All @@ -28,7 +29,7 @@ class List2Need(nodes.General, nodes.Element): # type: ignore
pass


class List2NeedDirective(Directive):
class List2NeedDirective(SphinxDirective):
"""
Directive to filter needs and present them inside a list, table or diagram.
Expand All @@ -54,7 +55,7 @@ def presentation(argument: str) -> Any:
}

def run(self) -> Sequence[nodes.Node]:
env = self.state.document.settings.env
env = self.env

presentation = self.options.get("presentation")
if not presentation:
Expand Down
2 changes: 1 addition & 1 deletion sphinx_needs/directives/needbar.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class NeedbarDirective(FilterBase):
# 2. Stores infos for needbar
def run(self) -> Sequence[nodes.Node]:
# 1. define constants
env = self.state.document.settings.env
env = self.env
if not hasattr(env, "need_all_needbar"):
env.need_all_needbar = {}

Expand Down
2 changes: 1 addition & 1 deletion sphinx_needs/directives/needextend.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class NeedextendDirective(SphinxDirective):
}

def run(self) -> Sequence[nodes.Node]:
env = self.state.document.settings.env
env = self.env
if not hasattr(env, "need_all_needextend"):
env.need_all_needextend = {}

Expand Down
2 changes: 1 addition & 1 deletion sphinx_needs/directives/needextract.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class NeedextractDirective(FilterBase):
option_spec.update(FilterBase.base_option_spec)

def run(self) -> Sequence[nodes.Node]:
env = self.state.document.settings.env
env = self.env
if not hasattr(env, "need_all_needextracts"):
env.need_all_needextracts = {}

Expand Down
2 changes: 1 addition & 1 deletion sphinx_needs/directives/needfilter.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def layout(argument: str) -> str:
option_spec.update(FilterBase.base_option_spec)

def run(self) -> Sequence[nodes.Node]:
env = self.state.document.settings.env
env = self.env
if not hasattr(env, "need_all_needfilters"):
env.need_all_needfilters = {}

Expand Down
2 changes: 1 addition & 1 deletion sphinx_needs/directives/needflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class NeedflowDirective(FilterBase):

@measure_time("needflow")
def run(self) -> Sequence[nodes.Node]:
env = self.state.document.settings.env
env = self.env
if not hasattr(env, "need_all_needflows"):
env.need_all_needflows = {}

Expand Down
2 changes: 1 addition & 1 deletion sphinx_needs/directives/needgantt.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class NeedganttDirective(FilterBase, DiagramBase):
option_spec.update(DiagramBase.base_option_spec)

def run(self) -> Sequence[nodes.Node]:
env = self.state.document.settings.env
env = self.env
# Creates env.need_all_needgantts safely and other vars
self.prepare_env("needgantts")

Expand Down
12 changes: 4 additions & 8 deletions sphinx_needs/directives/needimport.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import json
import os
import re
from typing import Sequence, cast
from typing import Sequence
from urllib.parse import urlparse

import requests
from docutils import nodes
from docutils.parsers.rst import Directive, directives
from docutils.parsers.rst import directives
from requests_file import FileAdapter
from sphinx.environment import BuildEnvironment
from sphinx.util.docutils import SphinxDirective

from sphinx_needs.api import add_need
from sphinx_needs.config import NEEDS_CONFIG
Expand All @@ -22,7 +22,7 @@ class Needimport(nodes.General, nodes.Element): # type: ignore
pass


class NeedimportDirective(Directive):
class NeedimportDirective(SphinxDirective):
has_content = False

required_arguments = 1
Expand Down Expand Up @@ -229,10 +229,6 @@ def run(self) -> Sequence[nodes.Node]:

return need_nodes

@property
def env(self) -> BuildEnvironment:
return cast(BuildEnvironment, self.state.document.settings.env)

@property
def docname(self) -> str:
return self.env.docname
Expand Down
2 changes: 1 addition & 1 deletion sphinx_needs/directives/needlist.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class NeedlistDirective(FilterBase):
option_spec.update(FilterBase.base_option_spec) # type: ignore[arg-type]

def run(self) -> Sequence[nodes.Node]:
env = self.state.document.settings.env
env = self.env
if not hasattr(env, "need_all_needlists"):
env.need_all_needlists = {}

Expand Down
2 changes: 1 addition & 1 deletion sphinx_needs/directives/needpie.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class NeedpieDirective(FilterBase):
# Update the options_spec only with value filter-func defined in the FilterBase class

def run(self) -> Sequence[nodes.Node]:
env = self.state.document.settings.env
env = self.env
if not hasattr(env, "need_all_needpie"):
env.need_all_needpie = {}

Expand Down
7 changes: 4 additions & 3 deletions sphinx_needs/directives/needreport.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
from typing import Sequence

from docutils import nodes
from docutils.parsers.rst import Directive, directives
from docutils.parsers.rst import directives
from jinja2 import Template
from sphinx.errors import SphinxError
from sphinx.util.docutils import SphinxDirective

from sphinx_needs.directives.utils import analyse_needs_metrics
from sphinx_needs.utils import add_doc
Expand All @@ -14,7 +15,7 @@ class NeedsReportException(SphinxError):
pass


class NeedReportDirective(Directive):
class NeedReportDirective(SphinxDirective):
final_argument_whitespace = True
option_spec = {
"types": directives.unchanged,
Expand All @@ -24,7 +25,7 @@ class NeedReportDirective(Directive):
}

def run(self) -> Sequence[nodes.raw]:
env = self.state.document.settings.env
env = self.env

if len(self.options.keys()) == 0: # Check if options is empty
error_file, error_line = self.state_machine.input_lines.items[0]
Expand Down
2 changes: 1 addition & 1 deletion sphinx_needs/directives/needsequence.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class NeedsequenceDirective(FilterBase, DiagramBase, Exception):
option_spec.update(DiagramBase.base_option_spec)

def run(self) -> Sequence[nodes.Node]:
env = self.state.document.settings.env
env = self.env
# Creates env.need_all_needsequences safely and other vars
self.prepare_env("needsequences")

Expand Down
11 changes: 3 additions & 8 deletions sphinx_needs/directives/needservice.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import typing
from typing import Any, Dict, List, Sequence

from docutils import nodes
from docutils.parsers.rst import Directive, directives
from docutils.parsers.rst import directives
from docutils.parsers.rst.states import RSTState, RSTStateMachine
from docutils.statemachine import StringList
from sphinx.environment import BuildEnvironment
from sphinx.util.docutils import SphinxDirective
from sphinx_data_viewer.api import get_data_viewer_node

from sphinx_needs.api import add_need
Expand All @@ -19,7 +18,7 @@ class Needservice(nodes.General, nodes.Element): # type: ignore
pass


class NeedserviceDirective(Directive):
class NeedserviceDirective(SphinxDirective):
has_content = True

required_arguments = 1
Expand Down Expand Up @@ -49,10 +48,6 @@ def __init__(
super().__init__(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine)
self.log = get_logger(__name__)

@property
def env(self) -> BuildEnvironment:
return typing.cast(BuildEnvironment, self.state.document.settings.env)

def run(self) -> Sequence[nodes.Node]:
docname = self.env.docname
app = self.env.app
Expand Down
2 changes: 1 addition & 1 deletion sphinx_needs/directives/needtable.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class NeedtableDirective(FilterBase):

@profile("NEEDTABLE_RUN")
def run(self) -> Sequence[nodes.Node]:
env = self.state.document.settings.env
env = self.env
if not hasattr(env, "need_all_needtables"):
env.need_all_needtables = {}

Expand Down
7 changes: 4 additions & 3 deletions sphinx_needs/directives/needuml.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
from typing import Sequence

from docutils import nodes
from docutils.parsers.rst import Directive, directives
from docutils.parsers.rst import directives
from jinja2 import BaseLoader, Environment, Template
from sphinx.util.docutils import SphinxDirective

from sphinx_needs.debug import measure_time
from sphinx_needs.diagrams_common import calculate_link
Expand All @@ -17,7 +18,7 @@ class Needuml(nodes.General, nodes.Element):
pass


class NeedumlDirective(Directive):
class NeedumlDirective(SphinxDirective):
"""
Directive to get flow charts.
"""
Expand All @@ -36,7 +37,7 @@ class NeedumlDirective(Directive):
}

def run(self) -> Sequence[nodes.Node]:
env = self.state.document.settings.env
env = self.env
if not hasattr(env, "needs_all_needumls"):
env.needs_all_needumls = {}

Expand Down
5 changes: 3 additions & 2 deletions sphinx_needs/filter_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,17 @@
import re
from typing import Any, Dict, List

from docutils.parsers.rst import Directive, directives
from docutils.parsers.rst import directives
from sphinx.application import Sphinx
from sphinx.util.docutils import SphinxDirective

from sphinx_needs.api.exceptions import NeedsInvalidFilter
from sphinx_needs.debug import measure_time
from sphinx_needs.utils import check_and_get_external_filter_func
from sphinx_needs.utils import logger as log


class FilterBase(Directive):
class FilterBase(SphinxDirective):
has_content = True

base_option_spec = {
Expand Down

0 comments on commit 4479bee

Please sign in to comment.