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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

馃敡 Centralise access to sphinx-needs config #998

Merged
merged 1 commit into from Aug 28, 2023
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 3 additions & 3 deletions sphinx_needs/api/configuration.py
Expand Up @@ -10,7 +10,7 @@
from sphinx.util.logging import SphinxLoggerAdapter

from sphinx_needs.api.exceptions import NeedsApiConfigException, NeedsApiConfigWarning
from sphinx_needs.config import NEEDS_CONFIG
from sphinx_needs.config import NEEDS_CONFIG, NeedsSphinxConfig
from sphinx_needs.functions import register_func
from sphinx_needs.functions.functions import DynamicFunction

Expand All @@ -28,7 +28,7 @@ def get_need_types(app: Sphinx) -> List[str]:
:param app: Sphinx application object
:return: list of strings
"""
needs_types = app.config.needs_types
needs_types = NeedsSphinxConfig(app.config).types
return [x["directive"] for x in needs_types]


Expand Down Expand Up @@ -58,7 +58,7 @@ def add_need_type(
"""
import sphinx_needs.directives.need

needs_types = app.config.needs_types
needs_types = NeedsSphinxConfig(app.config).types
type_names = [x["directive"] for x in needs_types]

if directive in type_names:
Expand Down
48 changes: 24 additions & 24 deletions sphinx_needs/api/need.py
Expand Up @@ -21,6 +21,7 @@
NeedsTagNotAllowed,
NeedsTemplateException,
)
from sphinx_needs.config import NeedsSphinxConfig
from sphinx_needs.directives.needuml import Needuml, NeedumlException
from sphinx_needs.filter_common import filter_single_need
from sphinx_needs.logging import get_logger
Expand Down Expand Up @@ -136,7 +137,8 @@ def run():
# Get environment
#############################################################################################
env = app.env
types = app.config.needs_types
needs_config = NeedsSphinxConfig(app.config)
types = needs_config.types
type_name = ""
type_prefix = ""
type_color = ""
Expand Down Expand Up @@ -176,7 +178,7 @@ def run():
# TODO: Check, if id was already given. If True, recalculate id
# id = self.options.get("id", ''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for
# _ in range(5)))
if id is None and app.config.needs_id_required:
if id is None and needs_config.id_required:
raise NeedsNoIdException(
"An id is missing for this need and must be set, because 'needs_id_required' "
"is set to True in conf.py. Need '{}' in {} ({})".format(title, docname, lineno)
Expand All @@ -187,12 +189,8 @@ def run():
else:
need_id = id

if app.config.needs_id_regex and not re.match(app.config.needs_id_regex, need_id):
raise NeedsInvalidException(
"Given ID '{id}' does not match configured regex '{regex}'".format(
id=need_id, regex=app.config.needs_id_regex
)
)
if needs_config.id_regex and not re.match(needs_config.id_regex, need_id):
raise NeedsInvalidException(f"Given ID '{need_id}' does not match configured regex '{needs_config.id_regex}'")

# Calculate target id, to be able to set a link back
if is_external:
Expand All @@ -203,7 +201,7 @@ def run():

# Handle status
# Check if status is in needs_statuses. If not raise an error.
if app.config.needs_statuses and status not in [stat["name"] for stat in app.config.needs_statuses]:
if needs_config.statuses and status not in [stat["name"] for stat in needs_config.statuses]:
raise NeedsStatusNotAllowed(
f"Status {status} of need id {need_id} is not allowed " "by config value 'needs_statuses'."
)
Expand All @@ -226,9 +224,9 @@ def run():

tags = new_tags
# Check if tag is in needs_tags. If not raise an error.
if app.config.needs_tags:
if needs_config.tags:
for tag in tags:
needs_tags = [tag["name"] for tag in app.config.needs_tags]
needs_tags = [tag["name"] for tag in needs_config.tags]
if tag not in needs_tags:
raise NeedsTagNotAllowed(
f"Tag {tag} of need id {need_id} is not allowed " "by config value 'needs_tags'."
Expand Down Expand Up @@ -258,9 +256,9 @@ def run():

constraints = new_constraints
# Check if constraint is in needs_constraints. If not raise an error.
if env.app.config.needs_constraints:
if needs_config.constraints:
for constraint in constraints:
if constraint not in env.app.config.needs_constraints.keys():
if constraint not in needs_config.constraints.keys():
raise NeedsConstraintNotAllowed(
f"Constraint {constraint} of need id {need_id} is not allowed "
"by config value 'needs_constraints'."
Expand Down Expand Up @@ -294,7 +292,7 @@ def run():
)

# Trim title if it is too long
max_length = app.config.needs_max_title_length
max_length = needs_config.max_title_length
if max_length == -1 or len(title) <= max_length:
trimmed_title = title
elif max_length <= 3:
Expand Down Expand Up @@ -353,10 +351,10 @@ def run():
needs_extra_option_names = NEEDS_CONFIG.get("extra_options").keys()
_merge_extra_options(needs_info, kwargs, needs_extra_option_names)

needs_global_options = app.config.needs_global_options
needs_global_options = needs_config.global_options
_merge_global_options(app, needs_info, needs_global_options)

link_names = [x["option"] for x in app.config.needs_extra_links]
link_names = [x["option"] for x in needs_config.extra_links]
for keyword in kwargs:
if keyword not in needs_extra_option_names and keyword not in link_names:
raise NeedsInvalidOption(
Expand All @@ -368,7 +366,7 @@ def run():
# Merge links
copy_links = []

for link_type in app.config.needs_extra_links:
for link_type in needs_config.extra_links:
# Check, if specific link-type got some arguments during method call
if link_type["option"] not in kwargs and link_type["option"] not in needs_global_options:
# if not we set no links, but entry in needS_info must be there
Expand Down Expand Up @@ -398,8 +396,8 @@ def run():
# Jinja support for need content
if jinja_content:
need_content_context = {**needs_info}
need_content_context.update(**env.app.config.needs_filter_data)
need_content_context.update(**env.app.config.needs_render_context)
need_content_context.update(**needs_config.filter_data)
need_content_context.update(**needs_config.render_context)
new_content = jinja_parse(need_content_context, needs_info["content"])
# Overwrite current content
content = new_content
Expand Down Expand Up @@ -572,7 +570,8 @@ def add_external_need(


def _prepare_template(app: Sphinx, needs_info, template_key: str) -> str:
template_folder = app.config.needs_template_folder
needs_config = NeedsSphinxConfig(app.config)
template_folder = needs_config.template_folder
if not os.path.isabs(template_folder):
template_folder = os.path.join(app.srcdir, template_folder)

Expand All @@ -587,7 +586,7 @@ def _prepare_template(app: Sphinx, needs_info, template_key: str) -> str:
with open(template_path) as template_file:
template_content = "".join(template_file.readlines())
template_obj = Template(template_content)
new_content = template_obj.render(**needs_info, **app.config.needs_render_context)
new_content = template_obj.render(**needs_info, **needs_config.render_context)

return new_content

Expand Down Expand Up @@ -653,9 +652,10 @@ def make_hashed_id(app: Sphinx, need_type: str, full_title: str, content: str, i
:param id_length: maximum length of the generated ID
:return: ID as string
"""
types = app.config.needs_types
needs_config = NeedsSphinxConfig(app.config)
types = needs_config.types
if id_length is None:
id_length = app.config.needs_id_length
id_length = needs_config.id_length
type_prefix = None
for ntype in types:
if ntype["directive"] == need_type:
Expand All @@ -669,7 +669,7 @@ def make_hashed_id(app: Sphinx, need_type: str, full_title: str, content: str, i

# check if needs_id_from_title is configured
cal_hashed_id = hashed_id
if app.config.needs_id_from_title:
if needs_config.id_from_title:
id_from_title = full_title.upper().replace(" ", "_") + "_"
cal_hashed_id = id_from_title + hashed_id

Expand Down
22 changes: 12 additions & 10 deletions sphinx_needs/builder.py
Expand Up @@ -6,6 +6,7 @@
from sphinx.application import Sphinx
from sphinx.builders import Builder

from sphinx_needs.config import NeedsSphinxConfig
from sphinx_needs.logging import get_logger
from sphinx_needs.needsfile import NeedsList
from sphinx_needs.utils import unwrap
Expand All @@ -26,12 +27,12 @@ def finish(self) -> None:
env = unwrap(self.env)
needs = env.needs_all_needs.values() # We need a list of needs for later filter checks
filters = env.needs_all_filters
config = env.config
version = getattr(config, "version", "unset")
needs_list = NeedsList(config, self.outdir, self.srcdir)
version = getattr(env.config, "version", "unset")
needs_list = NeedsList(env.config, self.outdir, self.srcdir)
needs_config = NeedsSphinxConfig(env.config)

if config.needs_file:
needs_file = config.needs_file
if needs_config.file:
needs_file = needs_config.file
needs_list.load_json(needs_file)
else:
# check if needs.json file exists in conf.py directory
Expand All @@ -46,7 +47,7 @@ def finish(self) -> None:
#
from sphinx_needs.filter_common import filter_needs

filter_string = self.app.config.needs_builder_filter
filter_string = needs_config.builder_filter
filtered_needs = filter_needs(self.app, needs, filter_string)

for need in filtered_needs:
Expand Down Expand Up @@ -82,7 +83,7 @@ def get_target_uri(self, _docname: str, _typ: Optional[str] = None) -> str:
def build_needs_json(app: Sphinx, _exception: Exception) -> None:
env = unwrap(app.env)

if not env.config.needs_build_json:
if not NeedsSphinxConfig(env.config).build_json:
return

# Do not create an additional needs.json, if builder is already "needs".
Expand Down Expand Up @@ -139,8 +140,9 @@ def get_target_uri(self, _docname: str, _typ: Optional[str] = None) -> str:

def build_needumls_pumls(app: Sphinx, _exception: Exception) -> None:
env = unwrap(app.env)
config = NeedsSphinxConfig(env.config)

if not env.config.needs_build_needumls:
if not config.build_needumls:
return

# Do not create additional files for saved plantuml content, if builder is already "needumls".
Expand All @@ -150,10 +152,10 @@ def build_needumls_pumls(app: Sphinx, _exception: Exception) -> None:
# if other builder like html used together with config: needs_build_needumls
if version_info[0] >= 5:
needs_builder = NeedumlsBuilder(app, env)
needs_builder.outdir = os.path.join(needs_builder.outdir, env.config.needs_build_needumls)
needs_builder.outdir = os.path.join(needs_builder.outdir, config.build_needumls)
else:
needs_builder = NeedumlsBuilder(app)
needs_builder.outdir = os.path.join(needs_builder.outdir, env.config.needs_build_needumls)
needs_builder.outdir = os.path.join(needs_builder.outdir, config.build_needumls)
needs_builder.set_environment(env)

needs_builder.finish()