From bdc4d775185ad64dfcc7db02e6d0dccc88bdd13f Mon Sep 17 00:00:00 2001 From: Namnn07 Date: Tue, 18 Jul 2023 13:34:51 +0700 Subject: [PATCH 01/48] add builder needs look up for permalink --- docs/conf.py | 2 + sphinx_needs/builder.py | 67 +++++++++++++++++++++++++++ sphinx_needs/needs.py | 9 +++- sphinx_needs/templates/permalink.html | 23 ++++----- 4 files changed, 86 insertions(+), 15 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 029906270..856d89e93 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -380,6 +380,8 @@ def custom_defined_func(): # build needs.json to make permalinks work needs_build_json = True +needs_lut_build = True + # Get and maybe set GitHub credentials for services. # This is needed as the rate limit for not authenticated users is too low for the amount of requests we # need to perform for this documentation diff --git a/sphinx_needs/builder.py b/sphinx_needs/builder.py index 3af315e5f..51ef316a1 100644 --- a/sphinx_needs/builder.py +++ b/sphinx_needs/builder.py @@ -9,6 +9,7 @@ from sphinx_needs.logging import get_logger from sphinx_needs.needsfile import NeedsList from sphinx_needs.utils import unwrap +import json log = get_logger(__name__) @@ -158,3 +159,69 @@ def build_needumls_pumls(app: Sphinx, _exception: Exception) -> None: needs_builder.set_environment(env) needs_builder.finish() + + +class NeedsLookUpTableBuilder(Builder): + name = "needs_lut" + format = "json" + file_suffix = ".txt" + links_suffix = None + + def write_doc(self, docname: str, doctree: nodes.document) -> None: + pass + + def finish(self) -> None: + env = unwrap(self.env) + needs = env.needs_all_needs.values() + config = env.config + + needs_dict = {} + for need in needs: + if need["is_external"]: + needs_dict[need["id"]] = need["external_url"] + else: + needs_dict[need["id"]] = need["docname"] + + try: + fname = os.path.join(self.outdir, config.needs_lut_file) + with open(fname, "w", encoding="utf-8") as f: + json.dump(needs_dict, f, indent=4) + except Exception as e: + log.error(f"Error during writing json file: {e}") + else: + log.info("Needs doc lookup table json successfully created") + + def get_outdated_docs(self) -> Iterable[str]: + return [] + + def prepare_writing(self, _docnames: Set[str]) -> None: + pass + + def write_doc_serialized(self, _docname: str, _doctree: nodes.document) -> None: + pass + + def cleanup(self) -> None: + pass + + def get_target_uri(self, _docname: str, _typ: Optional[str] = None) -> str: + return "" + + +def build_needs_look_up_json(app: Sphinx, _exception: Exception) -> None: + + env = unwrap(app.env) + + if not env.config.needs_lut_build: + return + + # Do not create an additional look up table json, if builder is already in use. + if isinstance(app.builder, NeedsLookUpTableBuilder): + return + + try: + needs_lut_builder = NeedsLookUpTableBuilder(app, env) + except TypeError: + needs_lut_builder = NeedsLookUpTableBuilder(app) + needs_lut_builder.set_environment(env) + + needs_lut_builder.finish() \ No newline at end of file diff --git a/sphinx_needs/needs.py b/sphinx_needs/needs.py index a7ffa096b..9e11cb139 100644 --- a/sphinx_needs/needs.py +++ b/sphinx_needs/needs.py @@ -13,8 +13,10 @@ from sphinx_needs.builder import ( NeedsBuilder, NeedumlsBuilder, + NeedsLookUpTableBuilder, build_needs_json, build_needumls_pumls, + build_needs_look_up_json ) from sphinx_needs.config import NEEDS_CONFIG from sphinx_needs.defaults import ( @@ -141,6 +143,7 @@ def setup(app: Sphinx) -> Dict[str, Any]: app.add_builder(NeedsBuilder) app.add_builder(NeedumlsBuilder) + app.add_builder(NeedsLookUpTableBuilder) app.add_config_value( "needs_types", [ @@ -279,6 +282,9 @@ def setup(app: Sphinx) -> Dict[str, Any]: # app.add_config_value("needs_debug_measurement", False, "html", types=[dict]) + app.add_config_value("needs_lut_build", False, "html", types=[bool]) + app.add_config_value("needs_lut_file", "needs_lut.json", "html") + app.add_config_value("needs_permalink_url", None, "html") # Define nodes app.add_node(Need, html=(html_visit, html_depart), latex=(latex_visit, latex_depart)) app.add_node( @@ -370,10 +376,11 @@ def setup(app: Sphinx) -> Dict[str, Any]: app.connect("build-finished", process_warnings) app.connect("build-finished", build_needs_json) app.connect("build-finished", build_needumls_pumls) + app.connect("build-finished", build_needs_look_up_json) app.connect("build-finished", debug.process_timing) app.connect("env-updated", install_lib_static_files) app.connect("env-updated", install_permalink_file) - + # This should be called last, so that need-styles can override styles from used libraries app.connect("env-updated", install_styles_static_files) diff --git a/sphinx_needs/templates/permalink.html b/sphinx_needs/templates/permalink.html index f072fae8b..727f2c97f 100644 --- a/sphinx_needs/templates/permalink.html +++ b/sphinx_needs/templates/permalink.html @@ -21,30 +21,25 @@ } function main() { - loadJSON('{{ needs_file }}', function (response) { + loadJSON('needs_lut.json', function (response) { const needs = JSON.parse(response); - const current_version = needs['current_version']; - const versions = needs['versions']; - const version = versions[current_version]; - const needs_obj = version['needs']; - const id = getParameterByName('id'); var pathname = new URL(window.location.href).pathname; - pathname = pathname.substring(0, pathname.lastIndexOf('{{ permalink_file }}')); - - const keys = Object.keys(needs_obj); - + pathname = pathname.substring(0, pathname.lastIndexOf('permalink.html')); + const keys = Object.keys(needs); var docname = 'index'; - keys.forEach((key, index) => { if (key === id) { - const need = needs_obj[key]; - docname = need['docname']; + docname = needs[key]; return; } }); - window.location.replace(pathname + docname + '.html#' + id); + if (docname.includes("#" + id)) { + window.location.replace(pathname + docname); + } else { + window.location.replace(pathname + docname + '.html#' + id); + } }); } From 37deab73f8535827965cc2d48ace5e8cd6260e18 Mon Sep 17 00:00:00 2001 From: Namnn07 Date: Tue, 18 Jul 2023 16:23:13 +0700 Subject: [PATCH 02/48] keep variable for need_file --- sphinx_needs/templates/permalink.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sphinx_needs/templates/permalink.html b/sphinx_needs/templates/permalink.html index 727f2c97f..9f256378f 100644 --- a/sphinx_needs/templates/permalink.html +++ b/sphinx_needs/templates/permalink.html @@ -21,7 +21,7 @@ } function main() { - loadJSON('needs_lut.json', function (response) { + loadJSON('{{ needs_file }}', function (response) { const needs = JSON.parse(response); const id = getParameterByName('id'); var pathname = new URL(window.location.href).pathname; From 4095a0d00e4d56d45418e13a9decd392b262443e Mon Sep 17 00:00:00 2001 From: Namnn07 Date: Tue, 18 Jul 2023 16:34:45 +0700 Subject: [PATCH 03/48] keep variable for need_file --- sphinx_needs/templates/permalink.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sphinx_needs/templates/permalink.html b/sphinx_needs/templates/permalink.html index 9f256378f..e8ea9b990 100644 --- a/sphinx_needs/templates/permalink.html +++ b/sphinx_needs/templates/permalink.html @@ -21,7 +21,7 @@ } function main() { - loadJSON('{{ needs_file }}', function (response) { + loadJSON('{{ needs_lut_file }}', function (response) { const needs = JSON.parse(response); const id = getParameterByName('id'); var pathname = new URL(window.location.href).pathname; From b144bc37718ebe9505cb043ca75305bac71ad6a8 Mon Sep 17 00:00:00 2001 From: Namnn07 Date: Thu, 20 Jul 2023 17:12:37 +0700 Subject: [PATCH 04/48] change some env variable --- sphinx_needs/builder.py | 2 +- sphinx_needs/needs.py | 4 ++-- sphinx_needs/templates/permalink.html | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sphinx_needs/builder.py b/sphinx_needs/builder.py index 51ef316a1..1806413eb 100644 --- a/sphinx_needs/builder.py +++ b/sphinx_needs/builder.py @@ -183,7 +183,7 @@ def finish(self) -> None: needs_dict[need["id"]] = need["docname"] try: - fname = os.path.join(self.outdir, config.needs_lut_file) + fname = os.path.join(self.outdir, config.needs_permalink_data) with open(fname, "w", encoding="utf-8") as f: json.dump(needs_dict, f, indent=4) except Exception as e: diff --git a/sphinx_needs/needs.py b/sphinx_needs/needs.py index 9e11cb139..030d44091 100644 --- a/sphinx_needs/needs.py +++ b/sphinx_needs/needs.py @@ -263,7 +263,7 @@ def setup(app: Sphinx) -> Dict[str, Any]: # path to permalink.html; absolute path from web-root app.add_config_value("needs_permalink_file", "permalink.html", "html") # path to needs.json relative to permalink.html - app.add_config_value("needs_permalink_data", "needs.json", "html") + app.add_config_value("needs_permalink_data", "needs_lut.json", "html") # path to needs_report_template file which is based on the conf.py directory. app.add_config_value("needs_report_template", "", "html", types=[str]) @@ -283,7 +283,7 @@ def setup(app: Sphinx) -> Dict[str, Any]: app.add_config_value("needs_debug_measurement", False, "html", types=[dict]) app.add_config_value("needs_lut_build", False, "html", types=[bool]) - app.add_config_value("needs_lut_file", "needs_lut.json", "html") + app.add_config_value("needs_permalink_url", None, "html") # Define nodes app.add_node(Need, html=(html_visit, html_depart), latex=(latex_visit, latex_depart)) diff --git a/sphinx_needs/templates/permalink.html b/sphinx_needs/templates/permalink.html index e8ea9b990..9f256378f 100644 --- a/sphinx_needs/templates/permalink.html +++ b/sphinx_needs/templates/permalink.html @@ -21,7 +21,7 @@ } function main() { - loadJSON('{{ needs_lut_file }}', function (response) { + loadJSON('{{ needs_file }}', function (response) { const needs = JSON.parse(response); const id = getParameterByName('id'); var pathname = new URL(window.location.href).pathname; From 0af51758c62135252650087aae397bc00840f1a2 Mon Sep 17 00:00:00 2001 From: Namnn07 Date: Fri, 21 Jul 2023 11:40:23 +0700 Subject: [PATCH 05/48] add config mode permalink --- docs/conf.py | 2 +- sphinx_needs/environment.py | 1 + sphinx_needs/needs.py | 2 + sphinx_needs/templates/permalink.html | 63 ++++++++++++++++++++------- 4 files changed, 51 insertions(+), 17 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 856d89e93..47956976b 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -586,7 +586,7 @@ def custom_defined_func(): # Check, if docs get built on ci. # If this is the case, external services like Open-Needs are not available and # docs will show images instead of getting real data. -on_ci = os.environ.get("ON_CI", "False").upper() == "TRUE" +on_ci = os.environ.get("ON_CI", "True").upper() == "TRUE" fast_build = os.environ.get("FAST_BUILD", "False").upper() == "TRUE" html_context = {"on_ci": on_ci, "fast_build": fast_build} diff --git a/sphinx_needs/environment.py b/sphinx_needs/environment.py index 5570ade54..59063e85e 100644 --- a/sphinx_needs/environment.py +++ b/sphinx_needs/environment.py @@ -209,6 +209,7 @@ def install_permalink_file(app: Sphinx, env: BuildEnvironment) -> None: template.render( permalink_file=env.config.needs_permalink_file, needs_file=env.config.needs_permalink_data, + needs_lut_mode=env.config.needs_lut_mode, **app.config.needs_render_context, ) ) diff --git a/sphinx_needs/needs.py b/sphinx_needs/needs.py index 030d44091..3ea2b9c0a 100644 --- a/sphinx_needs/needs.py +++ b/sphinx_needs/needs.py @@ -264,6 +264,8 @@ def setup(app: Sphinx) -> Dict[str, Any]: app.add_config_value("needs_permalink_file", "permalink.html", "html") # path to needs.json relative to permalink.html app.add_config_value("needs_permalink_data", "needs_lut.json", "html") + # add config mode permalink + app.add_config_value("needs_lut_mode", False, "html", types=[bool]) # path to needs_report_template file which is based on the conf.py directory. app.add_config_value("needs_report_template", "", "html", types=[str]) diff --git a/sphinx_needs/templates/permalink.html b/sphinx_needs/templates/permalink.html index 9f256378f..f433bad65 100644 --- a/sphinx_needs/templates/permalink.html +++ b/sphinx_needs/templates/permalink.html @@ -21,28 +21,59 @@ } function main() { + var needs_lut_mode = '{{ needs_lut_mode }}'; + t + console.log(`needs_lut_mode:${needs_lut_mode}`); loadJSON('{{ needs_file }}', function (response) { - const needs = JSON.parse(response); - const id = getParameterByName('id'); - var pathname = new URL(window.location.href).pathname; - pathname = pathname.substring(0, pathname.lastIndexOf('permalink.html')); - const keys = Object.keys(needs); - var docname = 'index'; - keys.forEach((key, index) => { - if (key === id) { - docname = needs[key]; - return; + if (needs_lut_mode == True) { + const needs = JSON.parse(response); + const id = getParameterByName('id'); + var pathname = new URL(window.location.href).pathname; + pathname = pathname.substring(0, pathname.lastIndexOf('permalink.html')); + const keys = Object.keys(needs); + var docname = 'index'; + keys.forEach((key, index) => { + if (key === id) { + docname = needs[key]; + return; + } + }); + + if (docname.includes("#" + id)) { + window.location.replace(pathname + docname); + } else { + window.location.replace(pathname + docname + '.html#' + id); } - }); + } + else { + const needs = JSON.parse(response); + const current_version = needs['current_version']; + const versions = needs['versions']; + const version = versions[current_version]; + const needs_obj = version['needs']; + + const id = getParameterByName('id'); + var pathname = new URL(window.location.href).pathname; + pathname = pathname.substring(0, pathname.lastIndexOf('{{ permalink_file }}')); + + const keys = Object.keys(needs_obj); + + var docname = 'index'; + + keys.forEach((key, index) => { + if (key === id) { + const need = needs_obj[key]; + docname = need['docname']; + return; + } + }); - if (docname.includes("#" + id)) { - window.location.replace(pathname + docname); - } else { window.location.replace(pathname + docname + '.html#' + id); } }); - } + + } function getParameterByName(name, url = window.location.href) { name = name.replace(/[\[\]]/g, '\\$&'); var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'), @@ -60,4 +91,4 @@ - + \ No newline at end of file From c9a10fd48178e5b67984572c9b840bdb248691e0 Mon Sep 17 00:00:00 2001 From: Namnn07 Date: Fri, 21 Jul 2023 11:40:55 +0700 Subject: [PATCH 06/48] add config mode permalink --- docs/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index 47956976b..856d89e93 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -586,7 +586,7 @@ def custom_defined_func(): # Check, if docs get built on ci. # If this is the case, external services like Open-Needs are not available and # docs will show images instead of getting real data. -on_ci = os.environ.get("ON_CI", "True").upper() == "TRUE" +on_ci = os.environ.get("ON_CI", "False").upper() == "TRUE" fast_build = os.environ.get("FAST_BUILD", "False").upper() == "TRUE" html_context = {"on_ci": on_ci, "fast_build": fast_build} From db592c0c835acc9d6c566f214a3d2cf8621046c0 Mon Sep 17 00:00:00 2001 From: Namnn07 Date: Fri, 21 Jul 2023 11:41:07 +0700 Subject: [PATCH 07/48] add config mode permalink --- sphinx_needs/templates/permalink.html | 1 - 1 file changed, 1 deletion(-) diff --git a/sphinx_needs/templates/permalink.html b/sphinx_needs/templates/permalink.html index f433bad65..cc79611ec 100644 --- a/sphinx_needs/templates/permalink.html +++ b/sphinx_needs/templates/permalink.html @@ -22,7 +22,6 @@ function main() { var needs_lut_mode = '{{ needs_lut_mode }}'; - t console.log(`needs_lut_mode:${needs_lut_mode}`); loadJSON('{{ needs_file }}', function (response) { if (needs_lut_mode == True) { From 99dc2ddfea9b75a3a610b60c43edea1fbe4dac1a Mon Sep 17 00:00:00 2001 From: Namnn07 Date: Fri, 21 Jul 2023 11:41:19 +0700 Subject: [PATCH 08/48] add config mode permalink --- sphinx_needs/templates/permalink.html | 1 - 1 file changed, 1 deletion(-) diff --git a/sphinx_needs/templates/permalink.html b/sphinx_needs/templates/permalink.html index cc79611ec..34498bca9 100644 --- a/sphinx_needs/templates/permalink.html +++ b/sphinx_needs/templates/permalink.html @@ -22,7 +22,6 @@ function main() { var needs_lut_mode = '{{ needs_lut_mode }}'; - console.log(`needs_lut_mode:${needs_lut_mode}`); loadJSON('{{ needs_file }}', function (response) { if (needs_lut_mode == True) { const needs = JSON.parse(response); From 945270843b5067be4ec23179290d3b4a1b570355 Mon Sep 17 00:00:00 2001 From: Namnn07 Date: Thu, 10 Aug 2023 14:47:55 +0700 Subject: [PATCH 09/48] fix ci test --- sphinx_needs/builder.py | 6 ++---- sphinx_needs/needs.py | 10 +++++----- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/sphinx_needs/builder.py b/sphinx_needs/builder.py index 1806413eb..5add07a78 100644 --- a/sphinx_needs/builder.py +++ b/sphinx_needs/builder.py @@ -1,3 +1,4 @@ +import json import os from typing import Iterable, Optional, Set @@ -9,7 +10,6 @@ from sphinx_needs.logging import get_logger from sphinx_needs.needsfile import NeedsList from sphinx_needs.utils import unwrap -import json log = get_logger(__name__) @@ -81,7 +81,6 @@ 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: @@ -208,7 +207,6 @@ def get_target_uri(self, _docname: str, _typ: Optional[str] = None) -> str: def build_needs_look_up_json(app: Sphinx, _exception: Exception) -> None: - env = unwrap(app.env) if not env.config.needs_lut_build: @@ -224,4 +222,4 @@ def build_needs_look_up_json(app: Sphinx, _exception: Exception) -> None: needs_lut_builder = NeedsLookUpTableBuilder(app) needs_lut_builder.set_environment(env) - needs_lut_builder.finish() \ No newline at end of file + needs_lut_builder.finish() diff --git a/sphinx_needs/needs.py b/sphinx_needs/needs.py index 3ea2b9c0a..f3a353847 100644 --- a/sphinx_needs/needs.py +++ b/sphinx_needs/needs.py @@ -12,11 +12,11 @@ from sphinx_needs.api.configuration import add_extra_option from sphinx_needs.builder import ( NeedsBuilder, - NeedumlsBuilder, NeedsLookUpTableBuilder, + NeedumlsBuilder, build_needs_json, + build_needs_look_up_json, build_needumls_pumls, - build_needs_look_up_json ) from sphinx_needs.config import NEEDS_CONFIG from sphinx_needs.defaults import ( @@ -264,8 +264,8 @@ def setup(app: Sphinx) -> Dict[str, Any]: app.add_config_value("needs_permalink_file", "permalink.html", "html") # path to needs.json relative to permalink.html app.add_config_value("needs_permalink_data", "needs_lut.json", "html") - # add config mode permalink - app.add_config_value("needs_lut_mode", False, "html", types=[bool]) + # add config mode permalink + app.add_config_value("needs_lut_mode", False, "html", types=[bool]) # path to needs_report_template file which is based on the conf.py directory. app.add_config_value("needs_report_template", "", "html", types=[str]) @@ -382,7 +382,7 @@ def setup(app: Sphinx) -> Dict[str, Any]: app.connect("build-finished", debug.process_timing) app.connect("env-updated", install_lib_static_files) app.connect("env-updated", install_permalink_file) - + # This should be called last, so that need-styles can override styles from used libraries app.connect("env-updated", install_styles_static_files) From 9d6badf554ca492ec007e040a12b974b8b94c125 Mon Sep 17 00:00:00 2001 From: Namnn07 Date: Fri, 11 Aug 2023 11:19:59 +0700 Subject: [PATCH 10/48] update confiration for needs_lut --- docs/conf.py | 3 ++- docs/configuration.rst | 22 +++++++++++++++++++++- sphinx_needs/builder.py | 6 ++---- sphinx_needs/environment.py | 1 - sphinx_needs/needs.py | 8 +++----- sphinx_needs/templates/permalink.html | 6 +++--- tests/test_needs_look_up.py | 19 +++++++++++++++++++ 7 files changed, 50 insertions(+), 15 deletions(-) create mode 100644 tests/test_needs_look_up.py diff --git a/docs/conf.py b/docs/conf.py index 856d89e93..b20cbf572 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -380,7 +380,8 @@ def custom_defined_func(): # build needs.json to make permalinks work needs_build_json = True -needs_lut_build = True +# build needs_lut.json to make permalinks work +needs_lut_build_json = True # Get and maybe set GitHub credentials for services. # This is needed as the rate limit for not authenticated users is too low for the amount of requests we diff --git a/docs/configuration.rst b/docs/configuration.rst index af4180c14..524f31356 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -1870,7 +1870,7 @@ needs_permalink_file The option specifies the name of the permalink html file, which will be copied to the html build directory during build. -The permalink web site will load a ``needs.json`` file as specified +The permalink web site will load a ``needs.json`` or ``needs_lut.json`` file as specified by :ref:`needs_permalink_data` and re-direct the web browser to the html document of the need, which is specified by appending the need ID as a query parameter, e.g., ``http://localhost:8000/permalink.html?id=REQ_4711``. @@ -1902,6 +1902,7 @@ an absolute path (on the web server) or an URL. Default value: ``needs.json`` +You can choice option ``needs_lut.json`` as detail :ref:`needs_lut_build_json` .. _needs_constraints: @@ -2338,3 +2339,22 @@ If true, need options like status, tags or links are collapsed and shown only af Default value: True Can be overwritten for each single need by setting :ref:`need_collapse`. + +.. __needs_lut_build_json: + +needs_lut_build_json +~~~~~~~~~~~~~~~~~~~~~~~ +Builds a ``needs_lut.json`` file during other builds, like ``html``. Different from ``needs.json``, ``needs_lut.json`` only include list of key ``id`` and value in list [``docname``, ``external_url``]. +A helpful load data fastly when you need improve performance. +Default: False + +Example: + +.. code-block:: python + + needs_lut_build_json = False + +.. hint:: + + The created ``needs_lut.json`` file gets stored in the ``outdir`` of the current builder. + So if ``html`` is used as builder, the final location is e.g. ``_build/html/needs_lut.json``. \ No newline at end of file diff --git a/sphinx_needs/builder.py b/sphinx_needs/builder.py index 5add07a78..2950115da 100644 --- a/sphinx_needs/builder.py +++ b/sphinx_needs/builder.py @@ -172,8 +172,6 @@ def write_doc(self, docname: str, doctree: nodes.document) -> None: def finish(self) -> None: env = unwrap(self.env) needs = env.needs_all_needs.values() - config = env.config - needs_dict = {} for need in needs: if need["is_external"]: @@ -182,7 +180,7 @@ def finish(self) -> None: needs_dict[need["id"]] = need["docname"] try: - fname = os.path.join(self.outdir, config.needs_permalink_data) + fname = os.path.join(self.outdir, "needs_lut.json") with open(fname, "w", encoding="utf-8") as f: json.dump(needs_dict, f, indent=4) except Exception as e: @@ -209,7 +207,7 @@ def get_target_uri(self, _docname: str, _typ: Optional[str] = None) -> str: def build_needs_look_up_json(app: Sphinx, _exception: Exception) -> None: env = unwrap(app.env) - if not env.config.needs_lut_build: + if not env.config.needs_lut_build_json: return # Do not create an additional look up table json, if builder is already in use. diff --git a/sphinx_needs/environment.py b/sphinx_needs/environment.py index 59063e85e..5570ade54 100644 --- a/sphinx_needs/environment.py +++ b/sphinx_needs/environment.py @@ -209,7 +209,6 @@ def install_permalink_file(app: Sphinx, env: BuildEnvironment) -> None: template.render( permalink_file=env.config.needs_permalink_file, needs_file=env.config.needs_permalink_data, - needs_lut_mode=env.config.needs_lut_mode, **app.config.needs_render_context, ) ) diff --git a/sphinx_needs/needs.py b/sphinx_needs/needs.py index f3a353847..072eb032f 100644 --- a/sphinx_needs/needs.py +++ b/sphinx_needs/needs.py @@ -259,13 +259,13 @@ def setup(app: Sphinx) -> Dict[str, Any]: app.add_config_value("needs_build_needumls", "", "html", types=[str]) + app.add_config_value("needs_lut_build_json", False, "html", types=[bool]) + # Permalink related config values. # path to permalink.html; absolute path from web-root app.add_config_value("needs_permalink_file", "permalink.html", "html") # path to needs.json relative to permalink.html - app.add_config_value("needs_permalink_data", "needs_lut.json", "html") - # add config mode permalink - app.add_config_value("needs_lut_mode", False, "html", types=[bool]) + app.add_config_value("needs_permalink_data", "needs.json", "html") # path to needs_report_template file which is based on the conf.py directory. app.add_config_value("needs_report_template", "", "html", types=[str]) @@ -284,8 +284,6 @@ def setup(app: Sphinx) -> Dict[str, Any]: # app.add_config_value("needs_debug_measurement", False, "html", types=[dict]) - app.add_config_value("needs_lut_build", False, "html", types=[bool]) - app.add_config_value("needs_permalink_url", None, "html") # Define nodes app.add_node(Need, html=(html_visit, html_depart), latex=(latex_visit, latex_depart)) diff --git a/sphinx_needs/templates/permalink.html b/sphinx_needs/templates/permalink.html index 34498bca9..ebe6c3c7a 100644 --- a/sphinx_needs/templates/permalink.html +++ b/sphinx_needs/templates/permalink.html @@ -21,9 +21,9 @@ } function main() { - var needs_lut_mode = '{{ needs_lut_mode }}'; - loadJSON('{{ needs_file }}', function (response) { - if (needs_lut_mode == True) { + var needs_file = '{{ needs_file }}'; + loadJSON(needs_file, function (response) { + if (needs_file == "needs_lut.json") { const needs = JSON.parse(response); const id = getParameterByName('id'); var pathname = new URL(window.location.href).pathname; diff --git a/tests/test_needs_look_up.py b/tests/test_needs_look_up.py new file mode 100644 index 000000000..bb618ea4e --- /dev/null +++ b/tests/test_needs_look_up.py @@ -0,0 +1,19 @@ +import json +from pathlib import Path + +import pytest + + +@pytest.mark.parametrize( + "test_app", [{"buildername": "needs_lut", "srcdir": "doc_test/doc_needs_builder"}], indirect=True +) +def test_doc_needs_id_builder(test_app): + app = test_app + app.build() + + needs_json = Path(app.outdir, "needs_lut.json") + with open(needs_json) as needs_file: + needs_file_content = needs_file.read() + + needs_list = json.loads(needs_file_content) + assert needs_list["TC_NEG_001"] From adfc8858186b31baf436d30e1e92d3b5a4e72a7d Mon Sep 17 00:00:00 2001 From: Namnn07 Date: Fri, 11 Aug 2023 16:28:51 +0700 Subject: [PATCH 11/48] update confiration for needs_lut --- docs/builders.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/builders.rst b/docs/builders.rst index 52e37fc43..fa59cb0b7 100644 --- a/docs/builders.rst +++ b/docs/builders.rst @@ -162,4 +162,4 @@ or .. hint:: - As an alternative, you can set the config option :ref:`needs_build_needumls` to export the needumls files during each build. + As an alternative, you can set the config option :ref:`needs_build_needumls` to export the needumls files during each build. \ No newline at end of file From 02e65bebd131f00be6fd9780d8826313e0b8eac6 Mon Sep 17 00:00:00 2001 From: Namnn07 Date: Tue, 15 Aug 2023 13:26:24 +0700 Subject: [PATCH 12/48] add test-case and fix some setting for need per id builder --- docs/builders.rst | 52 ++++++++++++++++++++++++++- docs/conf.py | 2 +- docs/configuration.rst | 8 ++--- sphinx_needs/builder.py | 2 +- sphinx_needs/needs.py | 1 - sphinx_needs/templates/permalink.html | 46 ++++++++++++------------ 6 files changed, 80 insertions(+), 31 deletions(-) diff --git a/docs/builders.rst b/docs/builders.rst index fa59cb0b7..2a9dd13c8 100644 --- a/docs/builders.rst +++ b/docs/builders.rst @@ -162,4 +162,54 @@ or .. hint:: - As an alternative, you can set the config option :ref:`needs_build_needumls` to export the needumls files during each build. \ No newline at end of file + As an alternative, you can set the config option :ref:`needs_build_needumls` to export the needumls files during each build. + +.. _needs_lut_builder: + +needs_lut +-------- +.. versionadded:: 1.3.0 + +The **needs_lut** builder exports all found needs to a single json file, which only include list of key ``id`` and value of ``docname`` or ``external_url``. + +The build creates file called **needs_lut.json** inside the given build-folder. +Usage ++++++ + +.. code-block:: bash + + sphinx-build -b needs_lut source_dir build_dir + +Format +++++++ + +.. code-block:: python + + { + "extend_test_001": "directives/needextend", + "extend_test_002": "directives/needextend", + + "req_arch_001": "directives/needarch", + "req_arch_004": "directives/needarch", + + "spec_arch_001": "directives/needarch", + "test_arch_001": "directives/needarch", + "COMP_T_001": "directives/needarch", + "COMP_T_002": "directives/needarch", + + "EX_REQ_1": "examples/index", + "EX_REQ_2": "examples/index", + + "R_F4722": "examples/index", + "OWN_ID_123": "examples/index", + "IMPL_01": "examples/index", + "T_C3893": "examples/index", + "R_2A9D0": "filter", + "R_22EB2": "filter", + "S_D70B0": "filter", + "S_01A67": "filter", + "T_5CCAA": "filter", + "R_17EB4": "filter", + "req_flow_001": "directives/needflow", + "spec_flow_001": "directives/needflow", + } \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py index b20cbf572..41f3b1815 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -381,7 +381,7 @@ def custom_defined_func(): needs_build_json = True # build needs_lut.json to make permalinks work -needs_lut_build_json = True +needs_lut_build_json = False # Get and maybe set GitHub credentials for services. # This is needed as the rate limit for not authenticated users is too low for the amount of requests we diff --git a/docs/configuration.rst b/docs/configuration.rst index 524f31356..1c32dd14b 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -1902,7 +1902,7 @@ an absolute path (on the web server) or an URL. Default value: ``needs.json`` -You can choice option ``needs_lut.json`` as detail :ref:`needs_lut_build_json` +You can choose needs_lut_build_json ``needs_lut.json`` after setting :ref:`needs_lut_build_json` .. _needs_constraints: @@ -2343,9 +2343,9 @@ Can be overwritten for each single need by setting :ref:`need_collapse`. .. __needs_lut_build_json: needs_lut_build_json -~~~~~~~~~~~~~~~~~~~~~~~ -Builds a ``needs_lut.json`` file during other builds, like ``html``. Different from ``needs.json``, ``needs_lut.json`` only include list of key ``id`` and value in list [``docname``, ``external_url``]. -A helpful load data fastly when you need improve performance. +~~~~~~~~~~~~~~~~~~~~ +Builds a ``needs_lut.json`` file during other builds (like ``html``), which is different from ``needs.json``, only include list of key ``id`` and value of ``docname`` or ``external_url``. +This is helpful for loading data fastly when you need improve performance. Default: False Example: diff --git a/sphinx_needs/builder.py b/sphinx_needs/builder.py index 2950115da..08285ff2f 100644 --- a/sphinx_needs/builder.py +++ b/sphinx_needs/builder.py @@ -186,7 +186,7 @@ def finish(self) -> None: except Exception as e: log.error(f"Error during writing json file: {e}") else: - log.info("Needs doc lookup table json successfully created") + log.info("Needs lookup table json successfully created") def get_outdated_docs(self) -> Iterable[str]: return [] diff --git a/sphinx_needs/needs.py b/sphinx_needs/needs.py index 072eb032f..6def6afc3 100644 --- a/sphinx_needs/needs.py +++ b/sphinx_needs/needs.py @@ -284,7 +284,6 @@ def setup(app: Sphinx) -> Dict[str, Any]: # app.add_config_value("needs_debug_measurement", False, "html", types=[dict]) - app.add_config_value("needs_permalink_url", None, "html") # Define nodes app.add_node(Need, html=(html_visit, html_depart), latex=(latex_visit, latex_depart)) app.add_node( diff --git a/sphinx_needs/templates/permalink.html b/sphinx_needs/templates/permalink.html index ebe6c3c7a..13aa57a3a 100644 --- a/sphinx_needs/templates/permalink.html +++ b/sphinx_needs/templates/permalink.html @@ -21,29 +21,9 @@ } function main() { - var needs_file = '{{ needs_file }}'; - loadJSON(needs_file, function (response) { - if (needs_file == "needs_lut.json") { - const needs = JSON.parse(response); - const id = getParameterByName('id'); - var pathname = new URL(window.location.href).pathname; - pathname = pathname.substring(0, pathname.lastIndexOf('permalink.html')); - const keys = Object.keys(needs); - var docname = 'index'; - keys.forEach((key, index) => { - if (key === id) { - docname = needs[key]; - return; - } - }); - - if (docname.includes("#" + id)) { - window.location.replace(pathname + docname); - } else { - window.location.replace(pathname + docname + '.html#' + id); - } - } - else { + loadJSON('{{ needs_file }}', function (response) { + const needs = JSON.parse(response); + if(needs.hasOwnProperty("current_version")) { const needs = JSON.parse(response); const current_version = needs['current_version']; const versions = needs['versions']; @@ -68,6 +48,26 @@ window.location.replace(pathname + docname + '.html#' + id); } + else { + const needs = JSON.parse(response); + const id = getParameterByName('id'); + var pathname = new URL(window.location.href).pathname; + pathname = pathname.substring(0, pathname.lastIndexOf('permalink.html')); + const keys = Object.keys(needs); + var docname = 'index'; + keys.forEach((key, index) => { + if (key === id) { + docname = needs[key]; + return; + } + }); + + if (docname.includes("#" + id)) { + window.location.replace(pathname + docname); + } else { + window.location.replace(pathname + docname + '.html#' + id); + } + } }); From 5199edc99e9751984f51ab6b0689b7db254b35f8 Mon Sep 17 00:00:00 2001 From: Namnn07 Date: Mon, 21 Aug 2023 16:10:28 +0700 Subject: [PATCH 13/48] update version --- docs/changelog.rst | 4 ++++ docs/configuration.rst | 3 +++ 2 files changed, 7 insertions(+) diff --git a/docs/changelog.rst b/docs/changelog.rst index 83d0f5e8d..45d8be822 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -7,6 +7,10 @@ License ------- .. include:: ../LICENSE +1.4.0 +----- +Released: under development +* Improvement: Added Builder :ref:`needs_lut_builder` and config option :ref:`needs_lut_build_json` in `conf.py`. 1.3.0 ----- diff --git a/docs/configuration.rst b/docs/configuration.rst index 1c32dd14b..0f06eb750 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -2344,6 +2344,9 @@ Can be overwritten for each single need by setting :ref:`need_collapse`. needs_lut_build_json ~~~~~~~~~~~~~~~~~~~~ + +.. versionadded:: 1.4.0 + Builds a ``needs_lut.json`` file during other builds (like ``html``), which is different from ``needs.json``, only include list of key ``id`` and value of ``docname`` or ``external_url``. This is helpful for loading data fastly when you need improve performance. Default: False From d4e4f043f391316be6671c0450264f5ecb9a7dd6 Mon Sep 17 00:00:00 2001 From: haiyangToAI Date: Fri, 17 Feb 2023 15:18:39 +0100 Subject: [PATCH 14/48] Removed esbonio for IDE support --- docs/_images/lsp_auto_ids.gif | Bin 11463 -> 0 bytes ...nippets_inside_eval_rst_block_markdown.gif | Bin 85609 -> 0 bytes .../lsp_directive_snippets_markdown.gif | Bin 75079 -> 0 bytes docs/_images/lsp_goto.gif | Bin 58585 -> 0 bytes docs/_images/lsp_id_selection.gif | Bin 17231 -> 0 bytes ...lsp_need_role_need_suggestion_markdown.gif | Bin 81374 -> 0 bytes docs/_images/lsp_preview.gif | Bin 25684 -> 0 bytes docs/_images/lsp_snippets.gif | Bin 21741 -> 0 bytes docs/changelog.rst | 11 +- docs/configuration.rst | 85 --- docs/contributing.rst | 96 --- docs/ide/index.rst | 171 +---- docs/requirements.txt | 3 +- noxfile.py | 2 - poetry.lock | 305 ++------- pyproject.toml | 4 - sphinx_needs/__init__.py | 1 - sphinx_needs/lsp/__init__.py | 4 - sphinx_needs/lsp/esbonio.py | 647 ------------------ sphinx_needs/lsp/exceptions.py | 2 - sphinx_needs/lsp/needs_store.py | 110 --- sphinx_needs/needs.py | 2 - tests/test_lsp/doc_example_lsp/Makefile | 20 - tests/test_lsp/doc_example_lsp/conf.py | 62 -- tests/test_lsp/doc_example_lsp/index.rst | 31 - tests/test_lsp/doc_example_lsp/make.bat | 35 - .../Makefile | 20 - .../doc_lsp_custom_directive_snippets/conf.py | 95 --- .../index.rst | 31 - .../make.bat | 35 - .../Makefile | 20 - .../conf.py | 65 -- .../index.rst | 31 - .../make.bat | 35 - .../Makefile | 20 - .../conf.py | 65 -- .../index.rst | 31 - .../make.bat | 35 - tests/test_lsp/doc_lsp_support_MyST/Makefile | 20 - tests/test_lsp/doc_lsp_support_MyST/conf.py | 64 -- tests/test_lsp/doc_lsp_support_MyST/index.rst | 29 - tests/test_lsp/doc_lsp_support_MyST/make.bat | 35 - .../md_subfolder/MySecond.md | 15 - tests/test_lsp/doc_lsp_support_MyST/myfile.md | 48 -- tests/test_lsp/test_lsp.py | 332 --------- .../test_lsp_custom_directive_snippets.py | 88 --- ..._lsp_custom_need_id_generate_from_title.py | 60 -- ...test_lsp_custom_need_id_generate_random.py | 62 -- tests/test_lsp/test_lsp_support_MyST.py | 308 --------- 49 files changed, 82 insertions(+), 3053 deletions(-) delete mode 100644 docs/_images/lsp_auto_ids.gif delete mode 100644 docs/_images/lsp_directive_snippets_inside_eval_rst_block_markdown.gif delete mode 100644 docs/_images/lsp_directive_snippets_markdown.gif delete mode 100644 docs/_images/lsp_goto.gif delete mode 100644 docs/_images/lsp_id_selection.gif delete mode 100644 docs/_images/lsp_need_role_need_suggestion_markdown.gif delete mode 100644 docs/_images/lsp_preview.gif delete mode 100644 docs/_images/lsp_snippets.gif delete mode 100644 sphinx_needs/lsp/__init__.py delete mode 100644 sphinx_needs/lsp/esbonio.py delete mode 100644 sphinx_needs/lsp/exceptions.py delete mode 100644 sphinx_needs/lsp/needs_store.py delete mode 100644 tests/test_lsp/doc_example_lsp/Makefile delete mode 100644 tests/test_lsp/doc_example_lsp/conf.py delete mode 100644 tests/test_lsp/doc_example_lsp/index.rst delete mode 100644 tests/test_lsp/doc_example_lsp/make.bat delete mode 100644 tests/test_lsp/doc_lsp_custom_directive_snippets/Makefile delete mode 100644 tests/test_lsp/doc_lsp_custom_directive_snippets/conf.py delete mode 100644 tests/test_lsp/doc_lsp_custom_directive_snippets/index.rst delete mode 100644 tests/test_lsp/doc_lsp_custom_directive_snippets/make.bat delete mode 100644 tests/test_lsp/doc_lsp_custom_need_id_generate_from_title/Makefile delete mode 100644 tests/test_lsp/doc_lsp_custom_need_id_generate_from_title/conf.py delete mode 100644 tests/test_lsp/doc_lsp_custom_need_id_generate_from_title/index.rst delete mode 100644 tests/test_lsp/doc_lsp_custom_need_id_generate_from_title/make.bat delete mode 100644 tests/test_lsp/doc_lsp_custom_need_id_generate_random/Makefile delete mode 100644 tests/test_lsp/doc_lsp_custom_need_id_generate_random/conf.py delete mode 100644 tests/test_lsp/doc_lsp_custom_need_id_generate_random/index.rst delete mode 100644 tests/test_lsp/doc_lsp_custom_need_id_generate_random/make.bat delete mode 100644 tests/test_lsp/doc_lsp_support_MyST/Makefile delete mode 100644 tests/test_lsp/doc_lsp_support_MyST/conf.py delete mode 100644 tests/test_lsp/doc_lsp_support_MyST/index.rst delete mode 100644 tests/test_lsp/doc_lsp_support_MyST/make.bat delete mode 100644 tests/test_lsp/doc_lsp_support_MyST/md_subfolder/MySecond.md delete mode 100644 tests/test_lsp/doc_lsp_support_MyST/myfile.md delete mode 100644 tests/test_lsp/test_lsp.py delete mode 100644 tests/test_lsp/test_lsp_custom_directive_snippets.py delete mode 100644 tests/test_lsp/test_lsp_custom_need_id_generate_from_title.py delete mode 100644 tests/test_lsp/test_lsp_custom_need_id_generate_random.py delete mode 100644 tests/test_lsp/test_lsp_support_MyST.py diff --git a/docs/_images/lsp_auto_ids.gif b/docs/_images/lsp_auto_ids.gif deleted file mode 100644 index f6c73f4bab3f075b7d37e500e9511d3a2adb1065..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11463 zcmeI2XH-+)y6#s<2%(1}T@1ZQ?*yWucLYJI1p#RS(nOjXI#NTCUP4g?>+nMG4?qh?iu@hx#yRWu|8yEthweKb3V`WzDv(QS4H*aKBx~k z1Z06zfLhO&&cKh}wS@6*3p})w#q=I4_A_hh68q&4_TpdMmZ7}AIfvjE^TD*Z;&KYd>Z81QlHqB$*rc)n(Ox zV{EDJ7=c2eE|^`vU>k73CGO(Ii|DJt8osHTiW-_^uH4YN9;$8Qq(dekT~|p**WOi6 zPtV}SZG(r;3~zcFM${USx%JQ(X=v>1Yf8rK@+J3sm%?()ZU>vAE}4_@h_v*1cm-{7 z<%*S6{9?Ck99@5bAQCSJXI^;%@!^@msohno(Oj~#=O zoedptB^0`n3B|f5mAc>d^mvfw@gUtJ^@%4LFE7uGN-xvf-ekfbduLYrkcrIni_Z2d zXz(YK{UX4^H=wxXuBHFIxV)gCpkRDwNPb;NMOP@9u=`<&g<(~1?~{4(;6cp*h71;m z!8L}z9E-U6FtTYficCBH6_{54=No3xxBs(Rf z6jr4Stf!JmOHXr2NgLiuAKS?o|MvLtUy%L4|B?Da%N6)b93|N zf8~2-7m%rFC@d*2Z0s#AE-vvYEP3{_tnA5eo;N-v(>_@4Us_&XUQtm|`Ff<1Fj7_D zR@FIL{k*EWwfp(Kisxir)Vv6K_To1+FS^HTYisL6Uevd|u75k((9qCCrhmHmL4EV9 zu4Y1S%Y&D#t*x&x&96G&c64-fMz(j6>F(|tU+C`c>4|>*c3`-dOkaQh;LsqMp^@R? z;nC62aWa!r;~!S0rlzKeYinEIcJ>eV4vv2Q`o(ujYpP>up`~G_BPS&T1_1!TcMPGV zAzvlPU*PvPiT&SA^1qwp|L08tI|VplJo+`b&PW)G_|?9e;_g_ufMLFVZONMi4tbA- zzS`2>6oghhk3n5of4Zne<<R_i_jKx-=h57#!B_m z#ZCGKcw=J(vL%IrR#UZ0MQZsW3Zsj!g5N_zCdwHLrG+gfE3eJVQnUwpaLHH-T-g%S zvwr0A?wMJNaztU`>w2}&!Q?$7FK z!UY2k`%akMv}{lT@w_rMps&U)LE{*@g|ylEoba|ebr0*&jaxT%R%IuL(Wa_(`Ddsb zd^WtEF@g8+dG`$2K1OcLX`kjSX_qa6{8QWBklB1MC6Ng{PRW+MX9GUg0?^fNd{c~NyA zLz{Yy<}S_y+#7-vNu{ofR=V$2B#%-%f;NGI+Gzn@b(9uK-vJYVvm7?;M(`hoxnhx9 zh)y*3fx{YK9DiCLI#o}�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 diff --git a/docs/_images/lsp_directive_snippets_inside_eval_rst_block_markdown.gif b/docs/_images/lsp_directive_snippets_inside_eval_rst_block_markdown.gif deleted file mode 100644 index a95ea7c3a5b002010e67f238fb56dee8a93068c4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 85609 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�|0N(1~x;u|~Jf5pEgg3tJu z#g>+M0k8Z{;J*V%G7uYvf;nUgF)tZnfWerqLkxgX*J)rywaVb8x!u*^sZuf9Mqtvy z4kQt-v8PI5e~2bLqjYNRSZm#$Ch|eMnzb&bJ_n%Nkc1r)FVAj&!XCLg&n$PI`JTXk`k|M(P;aE2dQ3T90> zEPZ=xF7}Fa8|R`?r^duaTtMIX7bH;U(e3P8fyf*j+_+1Z?@Pk|wggXi*D;tp?r#;$ zUp)~EkjeOGw*!Si{*F-D|6>Rh0D!U=nK;2Gx3DX^p?IX6_w15|mV8hgR(5&#r1?q$`MJcXdS$xi#$f zLvmm5mz?QHCg1BIJtFH(*zqbw3U|Z@X*eM!HHcxzr=pmS`^_$L&B^F=T(-b ziHFoTU}B2}i=pro>hXR-rg8cA9;Y*23*3kbri?lt#_P8#KGa#7jh4T-MN-O(;dqEA zqEE20AY+|RMk{l(2|5DWjR7;qu7v zvrJC8##V_A<~_|!8oQKMBt*o`c`~}fqu-zOh)k=KOVEHIEZ8bBNNuSEau*kdRD{;q5W$7SbEJQ z;Y=9$(@mPZPVd8f2*3(cLiJmlpVHqZwSuyYL5!i+_-3Ou8iNn03zNQCPh`dtf={W) z6Bt}n2qi!ytrZMfVn=f?EFC|AtUo`!$?%>WG2kO(UtDjBD~E6x)dfI^eFv=%Q1@M( zv#yGEY2EV%m2+~K%QvqbIi@gr`>{8Fqt=POMfK6)FDn4&FtZ9}F4$YTzbb2;s}Vnw+Gt+*H9clDzL}U3Vfd{jEZ=#=nB;*@5q7d3_#Xk0z;rY{?JDh zKqHHc^_yYN8*2$T3U9p)i$9gkP*MH-L8G)KhEmyYJ&DZpOnu#TAqF zKEYAL>=X`%Ab_m00hh6`9_~Tp4F!cLSoD*VeB_E90l;yCc+Rd^5diNJlg=S?C78Jh zQn+kC76@Kc7DTYs(sS!yf&xxu>i$tajyG&h2@bs`9mZKRJSl)mKXz%*{^%1?^llAz)e3=Huiz$3ZK_SyZnrMPr`-|rvW4@#>?Vb`9@jaFUa*p>f zn^5`~S#l<6@JfLGjG%xU?Fb-^a_q1&;S@1K-UC!u<^OWkL zzWI89?+fV(tC%yc)A%?T`x>aziV^~UMFBf=Phf!rb--h)`qqtz9j4$t?WUEjc58`e1_r1h0ZLomR>g{RA{ zLspWRARW1u#XH6P#)JcZU|7 zc0Lpffp)GCK*01S%!~A3vNVLJZ#rV8rWqYq7AkHw!xW_Y_s7@&Iy?A3_=6}q9Xa>s zQBR@26ODu96j_fxqd$qp*M7mUXPN&uqEW2gd7mTDkCXq$QBVB!J^nwBdhVD0?n9A> zvrQJ3=vEg`?JEB`>RIaCN)pht#f?`wT|Rw=>m;^5Ak^)+foV<2`~B2{_q}hWr(SY2 zyEs4#&tW}z7#pKCudPpYCLExr7Tm0u>hU`$nNoD@UUggaf^Mr>UDfhP!J)GjN0L*E zvv0Mzy9BB^Hr%Kc-wWi4f2MErVetzF~E8iyR=%$MaDCA(_K4PJY;JKGDeO!g=>`Uaogu-_qD3G@rKV7{y&& zlNdU{+T`d;Z@MB||&%ARE^?#j}Ye-Moys~C&n z?`Qr&G?E^D`h#c`zRWD3yRc6*uKgw&C0AuVsRMMP@xw={{ReBzaMN{}^HIkaq_b>Z zZrIL|UUrOikQ!i@iZ?p=515@2bC+N9IgaKS>8>rc6Dd)hCtdSxz;;S+_ALkQ+O?u? ztjef~|9sS?Df7}nwqKv;vS0b(YbV96D;mOlpw;99tYXtKyYYx=EnUurw)AU{G}pam zWfWQ(8A=XU2Y<4tl_hFMDlDbn>l40#z5MNcKxOilttkf$s-uFqB{Cp*2H6_-+RpQG z#=wo@k!!W@y4YpKHXtnCii1`nQ4g;#e)_&hmaF<^H;n6xt+!}9uaXYCv$|9JE|tYw z3?Kilx<*@k_SwM|QT897Da507cDWoUgEfQj@-`Yz`Jo%Dv&W9!T&QM#Z>$xXb^eSP z8uIzqH+__l?S|e-s>K(*%#qvHue4dc*Jg&jU({qY955Ey5m!X)?0$PvzT+%BWz{ev zd$2(E(z8uljmd8^%fY?uqa1HPty3$_LVJTSedI>K?S2!R0fB~ws%=|Aov=OiB&+#jBmQXf0oSdrPTjlA^wQte6!IOT%U6*=qQ`a`w{*Q!`;vGoJx5IS zkcPJ-+r5PO90|kk1e5KsxE`n0Y0n)k?$0%>GZ#=lAwp@#Y2NI))Qzb z{~d;RijWp&d!#F-1dTZS`~@_`PlW&dnMn5AY&6x=yLz}Lbi4du;`3k|VcunGxP&AQ z?W@JWw=~@$l4oq~fAX4y;CzQfG5|BHB1rf}8Y)HUMjesRK`&$4w1uXl+*ormKF2JA zm3yq?CpexUePIgK39w5`4CGa#54bVwFt`nYKc5gHP&*T~9(5jjjX>auuo^0Qyqaaq zW;m>?F`O-$UC7|>uH!6;4mj+`Ayy97EcgM)H|Q~6xatwI&H6WP{u4XB@_wNAq zLJ7#U4)>ZyuBb~oQWLd%Hn=+cGs&Ep&~^Ws%$Nk3%a=_*XnxFP7+Zo^e?Z4Ga~g0B zV3;5czLOSyp}6WngKs#1b&(0un1PNuJ-%Wq-uAT#RnT#0{WR+Uw?1};tIMm`bmk-} z_loiu1QT8cPiKK5R>=@_kvykKG8k#%W1tbIiSX-lLBQ?;2M5dH5@qKEHu|XHnp#7_ zlS)sRj5{oPr;(!_*9FoDEn<_x&}HqDp2vtmmV zeeL4=ym%AlS=RUCjp5U;r+oT7A1+TwHL@P=y!)QZh5wy%+sB^r2Qp=@SHi{zKj3n+ z%|CgmpOJb!Q2jjr*(dLahwnbHsunfNtY5wK-SMM^s#Qq_*Y)~(@wJYg`o$yeej`6W zNJZ5oQTsm=6YHmdE0Iml*r_2kt5YybHJ#+buyD=Y8FYMYo4CaWN!wv&`C@Im>cB>v zC3f!Po7zr8i>oAJ!=wmJ?nTeZyH|blZ!e&xLZzKQ_@td}Som;Pz5n^(K*qPp8MRm6 zPw_RuYo8JMliYShipt}fG#aoO1uz}eAs@C`m{+M=0N;*1>$$*O1gE|HI?nVX_KgNtDXsw8& zwtCLoT`Da&))u9JjL@DHxG<>8DGr2}ULmT1!H=1UiOlj^s$L)p7 z>1`EuBI-Nuvhdtt{T7sb3YyIo)bhrE8es8#z!*V>UZY+NIK`Sp4r;q}o8<=cxX<0- zMdnFoM!KheG2jnT<6qB*3L-*I%cBR-C}#?xInOsJ0l8Gh`feIg-03H~>G$(((Dg-R zZ|05D0IW`)broQ>uetka(Z?SjI!C?%c43~S*eXYQYSdhF!1&tNdeI&B&h3Ppb@Osj z3wN*!zo_QtHWuz$5Z)+;@LCE#kBDd%i`c#x@i{zVH!EVZBcgC7A}G=)q~J0kk}qt@ zJ0gHDs=zy%=EfJB>K$*#m+0nw45#&Aq6#n( zMYW{bi=>np(kLuCNjSQ4j8whkQI%@=qRXpZ&8V@~YnUyjB{I5g$GtTmrX?k&XUwy2 zET(olW>C#@SS_~1Hug<`$5?7CxjJ?-)&0XxY!Y|eY~+P`yErcYxFtKMmD;%K*KzA= zc2rEftxEiso%MD={77>Ak4UrKvG|Uyc;JO8gL*=>O#;l=6p@xtT9tq-G-3UoP{5hU zu5Q9Lo3 zJ_tyY34HP3?eK%U_A&(C)IP=3&_e0(o2gw%sU&ylnDNxMFR2N1iB~zo*HuJN8jlJl_L-C=9CHCxPypIkjJgVYlufF+6DDhF< zIJ#l{5%b0)N*cOFJsobH-eHgKN=pZqr}y!SckHA?=hFL(GrHX~I-)XK3o|I)8I8Q? zzj1N@dT+r7=mSWAm9ACr0BDSp2~R&X1->|pD7Ly_q!xr0elzlAdMd@8P02}W1Et#- z!}e`_8KIa>2@*1Wb7DvClyT4t3*CTJg~@Ox@wBzxrH}L7J~LOt&Ubvt0be9z3Fkg; ziVicGK4MC*DwPz0n+vEBa4NXJsKNhqz%l=(wBQ4tYb|}j_k)$-93skKm&}$BG>eF` zk(D$4zi^%Z^auX+H~tzD=Wn7jfvoHXXJ*opkjd0_`}>Z}zkcZnfCRt+F8aS<543+> z<+I0Wstjeqd5 z879yFxotG9E*`Jk*QfMWKYLfR&&U4NHrA9*y(EB{1zGI|y1V>M|qZm#TV1jnjx0qy?oQNB2YEMGHSYw1kxXuM+5;#0kaS^;BwV6aA z(hfP~U|^SEC^9Q`R{QVw#QvPe0e18`U!boutOOPG@8=xrMx7>-IDTt_4zxu>bOL{C zg2F@$9@FQ1p)Hy|t@KtM*YWVL?R+AWz~5T+|DSW-e%jl6UF3A-!{M}katGaU&+}EO z=A+>0z^@Bq>AqLqT%M?27CL_VHbef`^~H=m$mXUDfQTQ1aAK?4f@zm>_;>aK2`0Bp>9( zs;GgEAu}D8lIB`c&L5RIvxk2!Y2-OT_#68EH3F;s5$x=%!(ecB{VuCa-Eg>oMrf*4 zmO&`DoNeDf>Av)ImjZNVp=<(Ys;~i>?Iv+(SEl0c)8_}6wN6%}hc?gu)8hT(Mtb*O zx{>70Z5i#0%eZy+PDEAY_C8=Ys0iI(y!Vx^to*s%`@eT1y(07K5xE2X+=t2L`Nw|Q gU-x|TIJbFS`e)Ur*SWb1td9IOpWo(#834`y0}~_?@c;k- diff --git a/docs/_images/lsp_directive_snippets_markdown.gif b/docs/_images/lsp_directive_snippets_markdown.gif deleted file mode 100644 index 8eaf7da0911c73508814089b279d1a8f529ca791..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 75079 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 A=>Px# diff --git a/docs/_images/lsp_need_role_need_suggestion_markdown.gif b/docs/_images/lsp_need_role_need_suggestion_markdown.gif deleted file mode 100644 index e70f9d18bb50eef71e729aa723a65c158f3681a0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 81374 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 p8XJi7@U*6cr_*NQY2Vq(~?tO{9oo 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 diff --git a/docs/_images/lsp_snippets.gif b/docs/_images/lsp_snippets.gif deleted file mode 100644 index 579be4c45e8b86a1f0d289011c9f8ab001ccffd2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21741 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 diff --git a/docs/changelog.rst b/docs/changelog.rst index 45d8be822..ee75cb204 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -26,6 +26,11 @@ Released: under development (`#912 `_) * Bugfix: Supports "None" body in Github services. (`#903 `_) +* Removed esbonio for :ref:`ide`. +* Removed configuration option **needs_ide_snippets_id** to support custom need ID for :ref:`ide` snippets. +* Removed configuration **needs_ide_directive_snippets** to support custom directive snippets for IDE features. +* Provided new IDE support option: VsCode extension + `Sphinx-Needs-VsCode `_. 1.2.2 ----- @@ -163,14 +168,14 @@ Released: 22.09.2022 * Improvement: Added `filter` function for :ref:`needuml`. * Improvement: Renamed jinja function `need` to `flow` for :ref:`needuml`. * Improvement: Added directive :ref:`needarch`. -* Improvement: Added configuration option :ref:`needs_ide_snippets_id` to support custom need ID for :ref:`ide` snippets. +* Improvement: Added configuration option **needs_ide_snippets_id** to support custom need ID for :ref:`ide` snippets. * Improvement: Provides jinja function :ref:`needarch_jinja_import` for :ref:`needarch` to execute :ref:`needuml_jinja_uml` automatically for all the links defined in the need :ref:`need_links` options. -* Improvement: Added configuration :ref:`needs_ide_directive_snippets` to support custom directive snippets for IDE features. +* Improvement: Added configuration **needs_ide_directive_snippets** to support custom directive snippets for IDE features. (`#640 `_) * Bugfix: Updated pip install URLs in Dockerfile. (`#673 `_) -* Improvement: Providing IDE features support for :ref:`ide_myst`. +* Improvement: Providing IDE features support for **ide_myst**. 1.0.1 ----- diff --git a/docs/configuration.rst b/docs/configuration.rst index 0f06eb750..a0a813644 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -1197,91 +1197,6 @@ The ID length must be at least 3 characters. If you change the regular expression, you should also set :ref:`needs_id_required` so that authors are forced to set an valid ID. -.. _needs_ide_snippets_id: - -needs_ide_snippets_id -~~~~~~~~~~~~~~~~~~~~~ - -A jinja-string defines a custom need ID for :ref:`ide` snippets. - -Default value: ``""`` - -``needs_ide_snippets_id`` provides two jinja functions to generate need ID: - - * ``from_title()``: replaces all whitespaces with `_` and converts all to lowevercase from need title - * ``random()``: generates a random string - -It also supports Pre/Postfix. - -If ``needs_ide_snippets_id`` is not configured or empty, then a random string will be generated for :ref:`ide` snippets id. - -**Example**: -{% raw %} - -.. code-block:: python - - needs_ide_snippets_id = "{{random()}}" - -or - -.. code-block:: python - - needs_ide_snippets_id = "Test_{{random()}}_Test" - -or - -.. code-block:: python - - needs_ide_snippets_id = "{{from_title()}}" - -or - -.. code-block:: python - - needs_ide_snippets_id = "TEST_{{from_title()}}_TEST" - -{% endraw %} - -.. _needs_ide_directive_snippets: - -needs_ide_directive_snippets -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Allows to define customized directive snippets for :ref:`ide`. - -Default value: ``{}`` - -In your **conf.py** file, use it like this: - -.. code-block:: python - - needs_ide_directive_snippets = { - "req": """\ - .. req:: REQ Example - :id: ID - :status: - :custom_option_1: - - random content. - """, - "test": """\ - .. test:: Test Title - :id: TEST_ - :status: open - :custom_option: something - - test directive content. - """, - } - -If ``needs_ide_directive_snippets`` is not configured or empty, the default directive snippets -will be used. - -.. hint:: - - The snippets are not automatically synced with the need definitions in **conf.py** and it is - up to the user to keep them in sync. - .. _needs_functions: needs_functions diff --git a/docs/contributing.rst b/docs/contributing.rst index 0c32d2fee..4e6777650 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -181,102 +181,6 @@ The tag must follow the format: ``[0-9].[0-9]+.[0-9]``. Otherwise the release jo The release jobs will build the source and wheel distribution and try to upload them to ``test.pypi.org`` and ``pypy.org``. -Debugging Sphinx-Needs Language Server features ------------------------------------------------ -Sphinx-Needs provides some language server functions for the `Esbonio Language Server `_. - -The complete functionality can used in VsCode by using the extension -`vscode-restructuredtext `_. -The whole configuration is done automatically and Sphinx-Needs features gets loaded, if the Sphinx-Needs extension -is part of ´extensions` variable inside `conf.py`. - -Debugging -~~~~~~~~~ -Most information is coming from https://docs.restructuredtext.net/articles/development.html. - -1. Check out the source code of all the following projects: - - * *vscode-restructuredtext*: links... - * *esbonio* - -2. Follow https://docs.restructuredtext.net/articles/development.html to install all dependencies, compile it and get - the Development host running in VsCode. - -3. Create a test folder inside the project with a Sphinx projects using Sphinx-Needs, for example under **/docs** by using - ``sphinx-quickstart``. - -4. Add the following to **docs/.vscode/settings.json**: - - .. code-block:: - - { - "esbonio.server.sourceFolder": "/Path/to/checked_out/esbonio/lib/esbonio", # absolute path - "esbonio.server.debugLaunch": true, - "esbonio.server.logLevel": "debug", - } - -5. Add the args ``${workspaceFolder}/docs`` to configuration *Launch Extension* in **.vscode/launch.json** like this: - - .. code-block:: - - { - "name": "Launch Extension", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "--extensionDevelopmentPath=${workspaceRoot}", - "${workspaceFolder}/docs", - ], - "sourceMaps": true, - "outFiles": ["${workspaceRoot}/out/extension.js"], - "preLaunchTask": "watch" - }, - -6. Test it by pressing F5 (running the preconfigured tasks *Launch Extension*) - - * In the opened *extensionDevelopmentHost* instance, select the correct Python interpreter. e.g. vscode-restructuredtext/.venv/bin/python - -7. Open another instance of VsCode for the checked out esbonio folder. -8. Add this to **.vscode/launch.json** under ``configurations``: - - .. code-block:: - - { - "name": "Python: Remote Attach", - "type": "python", - "request": "attach", - "connect": { - "host": "localhost", - "port": 5678 - }, - "pathMappings": [ - { - "localRoot": "${workspaceFolder}/lib/esbonio", - "remoteRoot": "." - } - ] - }, - -9. Test it by running the new task *Python: Remote Attach*. For this the task *Launch Extension* from - VsCode-restructuredText Extension must be already running, as this one starts a python debug server. - -10. Now you set set breakpoints anywhere in the esbonio code. - - -Debugging Sphinx-Needs functions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -To debugging Sphinx-Needs Language Server functions, you can repeat the steps 7-10 from above with the Sphinx-Needs -repository. - -Note: - -* For step 8: adapt the localRoot path accordingly, e.g. "${workspaceFolder}/../esbonio/lib/esbonio" - -* If it doesn't stop at breakpoints, set a breakpoint at **sphinx_needs/__init__.py**, where you import `esbonio_setup`. - When debugger stops there, choose **step into** to continue debug. - .. Include our contributors and maintainers. .. include:: ../AUTHORS diff --git a/docs/ide/index.rst b/docs/ide/index.rst index c8b33280d..fc2de276a 100644 --- a/docs/ide/index.rst +++ b/docs/ide/index.rst @@ -3,170 +3,13 @@ IDE Support =========== -.. _lsp_features: +The `Sphinx-Needs `_ ecosystem provides IDE support to enhance user's experience +of editing, navigating. -Features --------- +.. _ide_vscode: -The following features are supported when using an `Esbonio `_ based IDE -extension, like VsCode extension `reStructuredText `_, -in your **Sphinx-Needs** project. +Visula Studio Code +------------------ -.. grid:: - - .. grid-item-card:: Auto-generated IDs - :img-bottom: /_images/lsp_auto_ids.gif - - .. grid-item-card:: Snippets - :img-bottom: /_images/lsp_snippets.gif - -.. grid:: - - .. grid-item:: - - .. card:: ID Selection - :width: 75% - :img-bottom: /_images/lsp_id_selection.gif - - .. card:: Goto Definition - :width: 75% - :img-bottom: /_images/lsp_goto.gif - - .. card:: Need Preview - :width: 100% - :img-bottom: /_images/lsp_preview.gif - -.. _ide_installation: - -Installation ------------- - -VsCode -~~~~~~ - -The VsCode extension `reStructuredText `_ supports all the Sphinx-Needs -language features and is available at `Visual Studio Marketplace `_. - -To install and configure this extension, see details in -`How to install reStructuredText from Marketplace `_ and - -`How to use it `_. - -.. _ide_usage: - -Usage ------ - -To use all the Sphinx-Needs language featues, - -#. Install IDE extension or plugin, see current supported IDE extension in :ref:`ide_installation`. - -#. Build `needs.json` file in your Sphinx-Needs project: - - * automatically build `needs.json` if configure `needs_build_json = True` in conf.py. See details in :ref:`needs_build_json`. - * manually build `needs.json` using `sphinx-build -b needs source_dir build_dir`. See details in :ref:`builders`. - -Auto-generated need IDs -~~~~~~~~~~~~~~~~~~~~~~~ - -.. image:: /_images/lsp_auto_ids.gif - :align: center - -Type ``:`` in the line directly below a need directive like ``.. req::`` and select ``:id:`` in the IntelliSense interface. - -.. hint:: - - * If needls can't detect the type of the need it will just output `ID`. - * The ID is calculated using a hash function of the current user, doc URI, line number and the need prefix (e.g.). - To lower the risk of ID conflicts further a pseudo-randomization is part of the ID generation.s - -Predefined Snippets -~~~~~~~~~~~~~~~~~~~ - -.. image:: /_images/lsp_snippets.gif - :align: center - -Type ``..`` and choose to auto-complete the directive in the IntelliSense interface. - -ID Selection -~~~~~~~~~~~~ - -.. image:: /_images/lsp_id_selection.gif - :align: center - -#. After `:need:` role or `:links:` option type `->` which triggers the auto-completion of needs -#. Select a need type from the IntelliSense dialog (use arrow keys) - - * Type `>` again to trigger the doc completion (file in which needs are specified) - * Type `/` to complete the doc path, continue until the doc path is completed to a `*.rst` file - * Type `>` to trigger completion of a specfic need by ID, expand the completion item info to see the content of the selected need - -Goto Definition for need IDs -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. image:: /_images/lsp_goto.gif - :align: center - -Move cursor to a need ID and hit `F12` - -Alternatively right click on a need ID and choose "Go to Definition" from the context menu - -Need information on mouse hover -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. image:: /_images/lsp_preview.gif - :align: center - -Move the mouse cursor over any need ID - -.. _ide_myst: - -MyST/Markdown -------------- - -Directives and roles can be used in `MyST `_ in -this `Syntax `_. - -All the above IDE :ref:`lsp_features` can also be supported for MyST/Markdown. - -Usage -~~~~~ - -* Install MyST Parser using pip. - - .. code-block:: python - - pip install myst-parser - -* Enable and active the MyST Parser extension in your Sphinx-Needs project by simply adding the following in your `conf.py` file: - - .. code-block:: python - - extensions = ["sphinx_needs", "myst_parser"] - - source_suffix = [".rst", ".md"] - -* All the above IDE :ref:`lsp_features` are supported and used the same way like editing in rst files from above :ref:`ide_usage`, - when you editing your markdown files. e.g. `myfile.md`: - - * Directive snippets and role completion will be automatically translated into MyST/Markdown supported syntax style, see the following :ref:`ide_myst_example` - -.. _ide_myst_example: - -Example -~~~~~~~ - -Directive snippets - -.. image:: /_images/lsp_directive_snippets_markdown.gif - :align: center - -Directive snippets used inside `{eval-rst}` block - -.. image:: /_images/lsp_directive_snippets_inside_eval_rst_block_markdown.gif - :align: center - -Role need completion - -.. image:: /_images/lsp_need_role_need_suggestion_markdown.gif - :align: center +VsCode extension `Sphinx-Needs-VsCode `_ provides +support for Sphinx-Needs. See more details in the `Documentation `_. diff --git a/docs/requirements.txt b/docs/requirements.txt index a13591993..d08b317e5 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -7,5 +7,4 @@ sphinxcontrib-programoutput sphinx-design click tabulate -sphinx-immaterial==0.11.2 -esbonio>=0.13.0 \ No newline at end of file +sphinx-immaterial==0.11.2 \ No newline at end of file diff --git a/noxfile.py b/noxfile.py index f69c57bd7..01c35262a 100644 --- a/noxfile.py +++ b/noxfile.py @@ -14,8 +14,6 @@ TEST_DEPENDENCIES = [ "pytest", "pytest-xdist", - "pytest_lsp", - "myst-parser", "responses", "lxml", "pyparsing!=3.0.4", diff --git a/poetry.lock b/poetry.lock index 83f6d6be0..e2a68f25a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -12,18 +12,6 @@ files = [ {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"}, ] -[[package]] -name = "appdirs" -version = "1.4.4" -description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -category = "main" -optional = false -python-versions = "*" -files = [ - {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"}, - {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, -] - [[package]] name = "attrs" version = "22.2.0" @@ -296,29 +284,6 @@ files = [ [package.dependencies] docutils = ">=0.14" -[[package]] -name = "esbonio" -version = "0.14.1" -description = "A Language Server for Sphinx projects." -category = "main" -optional = false -python-versions = "*" -files = [ - {file = "esbonio-0.14.1-py3-none-any.whl", hash = "sha256:b83f415070068b396fceb16cff7abf1979e81dea4aadd57daedd6223e45bf795"}, - {file = "esbonio-0.14.1.tar.gz", hash = "sha256:edbeeb22022472d936769f9fc58b96372f71ae2b490f6d4d12b2f7587cb75051"}, -] - -[package.dependencies] -appdirs = "*" -pygls = ">=0.11.0" -pyspellchecker = "*" -sphinx = "*" -typing-extensions = "*" - -[package.extras] -debug = ["lsp-devtools"] -dev = ["black", "flake8", "lsp-devtools", "mypy", "pre-commit", "pytest", "pytest-cov", "pytest-lsp", "pytest-timeout", "tox", "types-appdirs", "types-docutils", "types-pygments"] - [[package]] name = "exceptiongroup" version = "1.1.0" @@ -393,14 +358,14 @@ woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] [[package]] name = "identify" -version = "2.5.17" +version = "2.5.18" description = "File identification library for Python" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "identify-2.5.17-py2.py3-none-any.whl", hash = "sha256:7d526dd1283555aafcc91539acc061d8f6f59adb0a7bba462735b0a318bff7ed"}, - {file = "identify-2.5.17.tar.gz", hash = "sha256:93cc61a861052de9d4c541a7acb7e3dcc9c11b398a2144f6e52ae5285f5f4f06"}, + {file = "identify-2.5.18-py2.py3-none-any.whl", hash = "sha256:93aac7ecf2f6abf879b8f29a8002d3c6de7086b8c28d88e1ad15045a15ab63f9"}, + {file = "identify-2.5.18.tar.gz", hash = "sha256:89e144fa560cc4cffb6ef2ab5e9fb18ed9f9b3cb054384bab4b95c12f6c309fe"}, ] [package.extras] @@ -857,26 +822,6 @@ pillow = ">=6.2.0" pyparsing = ">=2.2.1" python-dateutil = ">=2.7" -[[package]] -name = "mdit-py-plugins" -version = "0.3.3" -description = "Collection of plugins for markdown-it-py" -category = "dev" -optional = false -python-versions = ">=3.7" -files = [ - {file = "mdit-py-plugins-0.3.3.tar.gz", hash = "sha256:5cfd7e7ac582a594e23ba6546a2f406e94e42eb33ae596d0734781261c251260"}, - {file = "mdit_py_plugins-0.3.3-py3-none-any.whl", hash = "sha256:36d08a29def19ec43acdcd8ba471d3ebab132e7879d442760d963f19913e04b9"}, -] - -[package.dependencies] -markdown-it-py = ">=1.0.0,<3.0.0" - -[package.extras] -code-style = ["pre-commit"] -rtd = ["attrs", "myst-parser (>=0.16.1,<0.17.0)", "sphinx-book-theme (>=0.1.0,<0.2.0)"] -testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] - [[package]] name = "mdurl" version = "0.1.2" @@ -994,33 +939,6 @@ files = [ {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, ] -[[package]] -name = "myst-parser" -version = "0.18.1" -description = "An extended commonmark compliant parser, with bridges to docutils & sphinx." -category = "dev" -optional = false -python-versions = ">=3.7" -files = [ - {file = "myst-parser-0.18.1.tar.gz", hash = "sha256:79317f4bb2c13053dd6e64f9da1ba1da6cd9c40c8a430c447a7b146a594c246d"}, - {file = "myst_parser-0.18.1-py3-none-any.whl", hash = "sha256:61b275b85d9f58aa327f370913ae1bec26ebad372cc99f3ab85c8ec3ee8d9fb8"}, -] - -[package.dependencies] -docutils = ">=0.15,<0.20" -jinja2 = "*" -markdown-it-py = ">=1.0.0,<3.0.0" -mdit-py-plugins = ">=0.3.1,<0.4.0" -pyyaml = "*" -sphinx = ">=4,<6" -typing-extensions = "*" - -[package.extras] -code-style = ["pre-commit (>=2.12,<3.0)"] -linkify = ["linkify-it-py (>=1.0,<2.0)"] -rtd = ["ipython", "sphinx-book-theme", "sphinx-design", "sphinxcontrib.mermaid (>=0.7.1,<0.8.0)", "sphinxext-opengraph (>=0.6.3,<0.7.0)", "sphinxext-rediraffe (>=0.2.7,<0.3.0)"] -testing = ["beautifulsoup4", "coverage[toml]", "pytest (>=6,<7)", "pytest-cov", "pytest-param-files (>=0.3.4,<0.4.0)", "pytest-regressions", "sphinx (<5.2)", "sphinx-pytest"] - [[package]] name = "nodeenv" version = "1.7.0" @@ -1273,78 +1191,57 @@ files = [ [[package]] name = "pydantic" -version = "1.9.2" +version = "1.10.5" description = "Data validation and settings management using python type hints" -category = "main" -optional = false -python-versions = ">=3.6.1" +category = "dev" +optional = true +python-versions = ">=3.7" files = [ - {file = "pydantic-1.9.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9c9e04a6cdb7a363d7cb3ccf0efea51e0abb48e180c0d31dca8d247967d85c6e"}, - {file = "pydantic-1.9.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fafe841be1103f340a24977f61dee76172e4ae5f647ab9e7fd1e1fca51524f08"}, - {file = "pydantic-1.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afacf6d2a41ed91fc631bade88b1d319c51ab5418870802cedb590b709c5ae3c"}, - {file = "pydantic-1.9.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3ee0d69b2a5b341fc7927e92cae7ddcfd95e624dfc4870b32a85568bd65e6131"}, - {file = "pydantic-1.9.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ff68fc85355532ea77559ede81f35fff79a6a5543477e168ab3a381887caea76"}, - {file = "pydantic-1.9.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c0f5e142ef8217019e3eef6ae1b6b55f09a7a15972958d44fbd228214cede567"}, - {file = "pydantic-1.9.2-cp310-cp310-win_amd64.whl", hash = "sha256:615661bfc37e82ac677543704437ff737418e4ea04bef9cf11c6d27346606044"}, - {file = "pydantic-1.9.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:328558c9f2eed77bd8fffad3cef39dbbe3edc7044517f4625a769d45d4cf7555"}, - {file = "pydantic-1.9.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bd446bdb7755c3a94e56d7bdfd3ee92396070efa8ef3a34fab9579fe6aa1d84"}, - {file = "pydantic-1.9.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e0b214e57623a535936005797567231a12d0da0c29711eb3514bc2b3cd008d0f"}, - {file = "pydantic-1.9.2-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:d8ce3fb0841763a89322ea0432f1f59a2d3feae07a63ea2c958b2315e1ae8adb"}, - {file = "pydantic-1.9.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:b34ba24f3e2d0b39b43f0ca62008f7ba962cff51efa56e64ee25c4af6eed987b"}, - {file = "pydantic-1.9.2-cp36-cp36m-win_amd64.whl", hash = "sha256:84d76ecc908d917f4684b354a39fd885d69dd0491be175f3465fe4b59811c001"}, - {file = "pydantic-1.9.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4de71c718c9756d679420c69f216776c2e977459f77e8f679a4a961dc7304a56"}, - {file = "pydantic-1.9.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5803ad846cdd1ed0d97eb00292b870c29c1f03732a010e66908ff48a762f20e4"}, - {file = "pydantic-1.9.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a8c5360a0297a713b4123608a7909e6869e1b56d0e96eb0d792c27585d40757f"}, - {file = "pydantic-1.9.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:cdb4272678db803ddf94caa4f94f8672e9a46bae4a44f167095e4d06fec12979"}, - {file = "pydantic-1.9.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19b5686387ea0d1ea52ecc4cffb71abb21702c5e5b2ac626fd4dbaa0834aa49d"}, - {file = "pydantic-1.9.2-cp37-cp37m-win_amd64.whl", hash = "sha256:32e0b4fb13ad4db4058a7c3c80e2569adbd810c25e6ca3bbd8b2a9cc2cc871d7"}, - {file = "pydantic-1.9.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:91089b2e281713f3893cd01d8e576771cd5bfdfbff5d0ed95969f47ef6d676c3"}, - {file = "pydantic-1.9.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e631c70c9280e3129f071635b81207cad85e6c08e253539467e4ead0e5b219aa"}, - {file = "pydantic-1.9.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b3946f87e5cef3ba2e7bd3a4eb5a20385fe36521d6cc1ebf3c08a6697c6cfb3"}, - {file = "pydantic-1.9.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5565a49effe38d51882cb7bac18bda013cdb34d80ac336428e8908f0b72499b0"}, - {file = "pydantic-1.9.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:bd67cb2c2d9602ad159389c29e4ca964b86fa2f35c2faef54c3eb28b4efd36c8"}, - {file = "pydantic-1.9.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4aafd4e55e8ad5bd1b19572ea2df546ccace7945853832bb99422a79c70ce9b8"}, - {file = "pydantic-1.9.2-cp38-cp38-win_amd64.whl", hash = "sha256:d70916235d478404a3fa8c997b003b5f33aeac4686ac1baa767234a0f8ac2326"}, - {file = "pydantic-1.9.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f0ca86b525264daa5f6b192f216a0d1e860b7383e3da1c65a1908f9c02f42801"}, - {file = "pydantic-1.9.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1061c6ee6204f4f5a27133126854948e3b3d51fcc16ead2e5d04378c199b2f44"}, - {file = "pydantic-1.9.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e78578f0c7481c850d1c969aca9a65405887003484d24f6110458fb02cca7747"}, - {file = "pydantic-1.9.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5da164119602212a3fe7e3bc08911a89db4710ae51444b4224c2382fd09ad453"}, - {file = "pydantic-1.9.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ead3cd020d526f75b4188e0a8d71c0dbbe1b4b6b5dc0ea775a93aca16256aeb"}, - {file = "pydantic-1.9.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7d0f183b305629765910eaad707800d2f47c6ac5bcfb8c6397abdc30b69eeb15"}, - {file = "pydantic-1.9.2-cp39-cp39-win_amd64.whl", hash = "sha256:f1a68f4f65a9ee64b6ccccb5bf7e17db07caebd2730109cb8a95863cfa9c4e55"}, - {file = "pydantic-1.9.2-py3-none-any.whl", hash = "sha256:78a4d6bdfd116a559aeec9a4cfe77dda62acc6233f8b56a716edad2651023e5e"}, - {file = "pydantic-1.9.2.tar.gz", hash = "sha256:8cb0bc509bfb71305d7a59d00163d5f9fc4530f0881ea32c74ff4f74c85f3d3d"}, + {file = "pydantic-1.10.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5920824fe1e21cbb3e38cf0f3dd24857c8959801d1031ce1fac1d50857a03bfb"}, + {file = "pydantic-1.10.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3bb99cf9655b377db1a9e47fa4479e3330ea96f4123c6c8200e482704bf1eda2"}, + {file = "pydantic-1.10.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2185a3b3d98ab4506a3f6707569802d2d92c3a7ba3a9a35683a7709ea6c2aaa2"}, + {file = "pydantic-1.10.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f582cac9d11c227c652d3ce8ee223d94eb06f4228b52a8adaafa9fa62e73d5c9"}, + {file = "pydantic-1.10.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c9e5b778b6842f135902e2d82624008c6a79710207e28e86966cd136c621bfee"}, + {file = "pydantic-1.10.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:72ef3783be8cbdef6bca034606a5de3862be6b72415dc5cb1fb8ddbac110049a"}, + {file = "pydantic-1.10.5-cp310-cp310-win_amd64.whl", hash = "sha256:45edea10b75d3da43cfda12f3792833a3fa70b6eee4db1ed6aed528cef17c74e"}, + {file = "pydantic-1.10.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:63200cd8af1af2c07964546b7bc8f217e8bda9d0a2ef0ee0c797b36353914984"}, + {file = "pydantic-1.10.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:305d0376c516b0dfa1dbefeae8c21042b57b496892d721905a6ec6b79494a66d"}, + {file = "pydantic-1.10.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1fd326aff5d6c36f05735c7c9b3d5b0e933b4ca52ad0b6e4b38038d82703d35b"}, + {file = "pydantic-1.10.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6bb0452d7b8516178c969d305d9630a3c9b8cf16fcf4713261c9ebd465af0d73"}, + {file = "pydantic-1.10.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9a9d9155e2a9f38b2eb9374c88f02fd4d6851ae17b65ee786a87d032f87008f8"}, + {file = "pydantic-1.10.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f836444b4c5ece128b23ec36a446c9ab7f9b0f7981d0d27e13a7c366ee163f8a"}, + {file = "pydantic-1.10.5-cp311-cp311-win_amd64.whl", hash = "sha256:8481dca324e1c7b715ce091a698b181054d22072e848b6fc7895cd86f79b4449"}, + {file = "pydantic-1.10.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:87f831e81ea0589cd18257f84386bf30154c5f4bed373b7b75e5cb0b5d53ea87"}, + {file = "pydantic-1.10.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ce1612e98c6326f10888df951a26ec1a577d8df49ddcaea87773bfbe23ba5cc"}, + {file = "pydantic-1.10.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58e41dd1e977531ac6073b11baac8c013f3cd8706a01d3dc74e86955be8b2c0c"}, + {file = "pydantic-1.10.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:6a4b0aab29061262065bbdede617ef99cc5914d1bf0ddc8bcd8e3d7928d85bd6"}, + {file = "pydantic-1.10.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:36e44a4de37b8aecffa81c081dbfe42c4d2bf9f6dff34d03dce157ec65eb0f15"}, + {file = "pydantic-1.10.5-cp37-cp37m-win_amd64.whl", hash = "sha256:261f357f0aecda005934e413dfd7aa4077004a174dafe414a8325e6098a8e419"}, + {file = "pydantic-1.10.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b429f7c457aebb7fbe7cd69c418d1cd7c6fdc4d3c8697f45af78b8d5a7955760"}, + {file = "pydantic-1.10.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:663d2dd78596c5fa3eb996bc3f34b8c2a592648ad10008f98d1348be7ae212fb"}, + {file = "pydantic-1.10.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51782fd81f09edcf265823c3bf43ff36d00db246eca39ee765ef58dc8421a642"}, + {file = "pydantic-1.10.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c428c0f64a86661fb4873495c4fac430ec7a7cef2b8c1c28f3d1a7277f9ea5ab"}, + {file = "pydantic-1.10.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:76c930ad0746c70f0368c4596020b736ab65b473c1f9b3872310a835d852eb19"}, + {file = "pydantic-1.10.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:3257bd714de9db2102b742570a56bf7978e90441193acac109b1f500290f5718"}, + {file = "pydantic-1.10.5-cp38-cp38-win_amd64.whl", hash = "sha256:f5bee6c523d13944a1fdc6f0525bc86dbbd94372f17b83fa6331aabacc8fd08e"}, + {file = "pydantic-1.10.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:532e97c35719f137ee5405bd3eeddc5c06eb91a032bc755a44e34a712420daf3"}, + {file = "pydantic-1.10.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ca9075ab3de9e48b75fa8ccb897c34ccc1519177ad8841d99f7fd74cf43be5bf"}, + {file = "pydantic-1.10.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd46a0e6296346c477e59a954da57beaf9c538da37b9df482e50f836e4a7d4bb"}, + {file = "pydantic-1.10.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3353072625ea2a9a6c81ad01b91e5c07fa70deb06368c71307529abf70d23325"}, + {file = "pydantic-1.10.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:3f9d9b2be177c3cb6027cd67fbf323586417868c06c3c85d0d101703136e6b31"}, + {file = "pydantic-1.10.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b473d00ccd5c2061fd896ac127b7755baad233f8d996ea288af14ae09f8e0d1e"}, + {file = "pydantic-1.10.5-cp39-cp39-win_amd64.whl", hash = "sha256:5f3bc8f103b56a8c88021d481410874b1f13edf6e838da607dcb57ecff9b4594"}, + {file = "pydantic-1.10.5-py3-none-any.whl", hash = "sha256:7c5b94d598c90f2f46b3a983ffb46ab806a67099d118ae0da7ef21a2a4033b28"}, + {file = "pydantic-1.10.5.tar.gz", hash = "sha256:9e337ac83686645a46db0e825acceea8e02fca4062483f40e9ae178e8bd1103a"}, ] [package.dependencies] -typing-extensions = ">=3.7.4.3" +typing-extensions = ">=4.2.0" [package.extras] dotenv = ["python-dotenv (>=0.10.4)"] email = ["email-validator (>=1.0.3)"] -[[package]] -name = "pygls" -version = "0.12.2" -description = "a pythonic generic language server (pronounced like \"pie glass\")." -category = "main" -optional = false -python-versions = "<4,>=3.7" -files = [ - {file = "pygls-0.12.2-py3-none-any.whl", hash = "sha256:ad83aea5c45c915b6b0b47ef0faca3c3b4778d087110c8e912da14b9f1c9f9d7"}, - {file = "pygls-0.12.2.tar.gz", hash = "sha256:48465ba74a32d50fbc110111ee0b60721c169f5bd9d8eedc582931ff765d6bc6"}, -] - -[package.dependencies] -pydantic = ">=1.9.1,<1.10" -typeguard = ">=2.10.0,<3" - -[package.extras] -dev = ["bandit (==1.7.4)", "flake8 (==4.0.1)", "mypy (==0.961)"] -docs = ["sphinx (==5.0.1)", "sphinx-rtd-theme (==1.0.0)"] -test = ["mock (==4.0.3)", "pytest (==7.1.2)", "pytest-asyncio (==0.18.3)"] -ws = ["websockets (>=10.0.0,<11.0.0)"] - [[package]] name = "pygments" version = "2.14.0" @@ -1412,18 +1309,6 @@ files = [ {file = "pyrsistent-0.19.3.tar.gz", hash = "sha256:1a2994773706bbb4995c31a97bc94f1418314923bd1048c6d964837040376440"}, ] -[[package]] -name = "pyspellchecker" -version = "0.7.1" -description = "Pure python spell checker based on work by Peter Norvig" -category = "main" -optional = false -python-versions = ">=3.6" -files = [ - {file = "pyspellchecker-0.7.1-py3-none-any.whl", hash = "sha256:9fac7e3abf2a11eb1660906dc513bc9f92bd49795f136bb1a56ac1f59f5498b0"}, - {file = "pyspellchecker-0.7.1.tar.gz", hash = "sha256:ed46a7218a363ef1a348fac14c9fef95b0aca5daa7744389d70843fcc0961b31"}, -] - [[package]] name = "pytest" version = "7.2.1" @@ -1449,26 +1334,6 @@ tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} [package.extras] testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"] -[[package]] -name = "pytest-asyncio" -version = "0.20.3" -description = "Pytest support for asyncio" -category = "dev" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pytest-asyncio-0.20.3.tar.gz", hash = "sha256:83cbf01169ce3e8eb71c6c278ccb0574d1a7a3bb8eaaf5e50e0ad342afb33b36"}, - {file = "pytest_asyncio-0.20.3-py3-none-any.whl", hash = "sha256:f129998b209d04fcc65c96fc85c11e5316738358909a8399e93be553d7656442"}, -] - -[package.dependencies] -pytest = ">=6.1.0" -typing-extensions = {version = ">=3.7.2", markers = "python_version < \"3.8\""} - -[package.extras] -docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1.0)"] -testing = ["coverage (>=6.2)", "flaky (>=3.5.0)", "hypothesis (>=5.7.1)", "mypy (>=0.931)", "pytest-trio (>=0.7.0)"] - [[package]] name = "pytest-benchmark" version = "4.0.0" @@ -1490,28 +1355,6 @@ aspect = ["aspectlib"] elasticsearch = ["elasticsearch"] histogram = ["pygal", "pygaljs"] -[[package]] -name = "pytest-lsp" -version = "0.1.3" -description = "Pytest plugin for end-to-end testing of language servers" -category = "dev" -optional = false -python-versions = "*" -files = [ - {file = "pytest-lsp-0.1.3.tar.gz", hash = "sha256:5b14e1f46ded5b21b3631d6e1ee7e4c20de137a8d36d18e518b28947579436d6"}, - {file = "pytest_lsp-0.1.3-py3-none-any.whl", hash = "sha256:eb7883f04b834a04249c912d0c94fedc60bd41dd9cd674c40395f27cbb3d7e15"}, -] - -[package.dependencies] -appdirs = "*" -importlib-resources = {version = "*", markers = "python_version < \"3.9\""} -pygls = ">=0.11.0,<1.0" -pytest = "*" -pytest-asyncio = "*" - -[package.extras] -dev = ["black", "flake8", "mypy", "pre-commit", "pytest-cov", "pytest-timeout", "tox", "types-appdirs"] - [[package]] name = "pytest-xdist" version = "3.2.0" @@ -1712,14 +1555,14 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "setuptools" -version = "67.2.0" +version = "67.3.2" description = "Easily download, build, install, upgrade, and uninstall Python packages" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "setuptools-67.2.0-py3-none-any.whl", hash = "sha256:16ccf598aab3b506593c17378473978908a2734d7336755a8769b480906bec1c"}, - {file = "setuptools-67.2.0.tar.gz", hash = "sha256:b440ee5f7e607bb8c9de15259dba2583dd41a38879a7abc1d43a71c59524da48"}, + {file = "setuptools-67.3.2-py3-none-any.whl", hash = "sha256:bb6d8e508de562768f2027902929f8523932fcd1fb784e6d573d2cafac995a48"}, + {file = "setuptools-67.3.2.tar.gz", hash = "sha256:95f00380ef2ffa41d9bba85d95b27689d923c93dfbafed4aecd7cf988a25e012"}, ] [package.extras] @@ -2010,44 +1853,28 @@ files = [ {file = "typed_ast-1.5.4.tar.gz", hash = "sha256:39e21ceb7388e4bb37f4c679d72707ed46c2fbf2a5609b8b8ebc4b067d977df2"}, ] -[[package]] -name = "typeguard" -version = "2.13.3" -description = "Run-time type checker for Python" -category = "main" -optional = false -python-versions = ">=3.5.3" -files = [ - {file = "typeguard-2.13.3-py3-none-any.whl", hash = "sha256:5e3e3be01e887e7eafae5af63d1f36c849aaa94e3a0112097312aabfa16284f1"}, - {file = "typeguard-2.13.3.tar.gz", hash = "sha256:00edaa8da3a133674796cf5ea87d9f4b4c367d77476e185e80251cc13dfbb8c4"}, -] - -[package.extras] -doc = ["sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["mypy", "pytest", "typing-extensions"] - [[package]] name = "types-docutils" -version = "0.19.1.3" +version = "0.19.1.4" description = "Typing stubs for docutils" category = "dev" optional = false python-versions = "*" files = [ - {file = "types-docutils-0.19.1.3.tar.gz", hash = "sha256:36fe30de56f1ece1a9f7a990d47daa781b5af831d2b3f2dcb7dfd01b857cc3d4"}, - {file = "types_docutils-0.19.1.3-py3-none-any.whl", hash = "sha256:d608e6b91ccf0e8e01c586a0af5b0e0462382d3be65b734af82d40c9d010735d"}, + {file = "types-docutils-0.19.1.4.tar.gz", hash = "sha256:1b64b21b609ff1fc7791d3d930f14b56b36ad09029fd97e45e34cc889d671b5f"}, + {file = "types_docutils-0.19.1.4-py3-none-any.whl", hash = "sha256:870d71f3663141f67a3c59d26d2c54a8c478c842208bb0b345fbf6036f49f561"}, ] [[package]] name = "types-requests" -version = "2.28.11.12" +version = "2.28.11.13" description = "Typing stubs for requests" category = "dev" optional = false python-versions = "*" files = [ - {file = "types-requests-2.28.11.12.tar.gz", hash = "sha256:fd530aab3fc4f05ee36406af168f0836e6f00f1ee51a0b96b7311f82cb675230"}, - {file = "types_requests-2.28.11.12-py3-none-any.whl", hash = "sha256:dbc2933635860e553ffc59f5e264264981358baffe6342b925e3eb8261f866ee"}, + {file = "types-requests-2.28.11.13.tar.gz", hash = "sha256:3fd332842e8759ea5f7eb7789df8aa772ba155216ccf10ef4aa3b0e5b42e1b46"}, + {file = "types_requests-2.28.11.13-py3-none-any.whl", hash = "sha256:94896f6f8e9f3db11e422c6e3e4abbc5d7ccace853eac74b23bdd65eeee3cdee"}, ] [package.dependencies] @@ -2070,38 +1897,38 @@ types-docutils = "*" [[package]] name = "types-toml" -version = "0.10.8.3" +version = "0.10.8.4" description = "Typing stubs for toml" category = "dev" optional = false python-versions = "*" files = [ - {file = "types-toml-0.10.8.3.tar.gz", hash = "sha256:f37244eff4cd7eace9cb70d0bac54d3eba77973aa4ef26c271ac3d1c6503a48e"}, - {file = "types_toml-0.10.8.3-py3-none-any.whl", hash = "sha256:a2286a053aea6ab6ff814659272b1d4a05d86a1dd52b807a87b23511993b46c5"}, + {file = "types-toml-0.10.8.4.tar.gz", hash = "sha256:c8748dd225b28eb80ce712e2d7d61b57599815e7b48d07ef53df51ed148fa6b1"}, + {file = "types_toml-0.10.8.4-py3-none-any.whl", hash = "sha256:306b1bb8b5bbc5f1b60387dbcc4b489e79f8490ce20e93af5f422a68b470d94b"}, ] [[package]] name = "types-urllib3" -version = "1.26.25.5" +version = "1.26.25.6" description = "Typing stubs for urllib3" category = "dev" optional = false python-versions = "*" files = [ - {file = "types-urllib3-1.26.25.5.tar.gz", hash = "sha256:5630e578246d170d91ebe3901788cd28d53c4e044dc2e2488e3b0d55fb6895d8"}, - {file = "types_urllib3-1.26.25.5-py3-none-any.whl", hash = "sha256:e8f25c8bb85cde658c72ee931e56e7abd28803c26032441eea9ff4a4df2b0c31"}, + {file = "types-urllib3-1.26.25.6.tar.gz", hash = "sha256:35586727cbd7751acccf2c0f34a88baffc092f435ab62458f10776466590f2d5"}, + {file = "types_urllib3-1.26.25.6-py3-none-any.whl", hash = "sha256:a6c23c41bd03e542eaee5423a018f833077b51c4bf9ceb5aa544e12b812d5604"}, ] [[package]] name = "typing-extensions" -version = "4.4.0" +version = "4.5.0" description = "Backported and Experimental Type Hints for Python 3.7+" category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "typing_extensions-4.4.0-py3-none-any.whl", hash = "sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e"}, - {file = "typing_extensions-4.4.0.tar.gz", hash = "sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa"}, + {file = "typing_extensions-4.5.0-py3-none-any.whl", hash = "sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4"}, + {file = "typing_extensions-4.5.0.tar.gz", hash = "sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb"}, ] [[package]] @@ -2145,14 +1972,14 @@ test = ["covdefaults (>=2.2.2)", "coverage (>=7.1)", "coverage-enable-subprocess [[package]] name = "zipp" -version = "3.12.1" +version = "3.13.0" description = "Backport of pathlib-compatible object wrapper for zip files" category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "zipp-3.12.1-py3-none-any.whl", hash = "sha256:6c4fe274b8f85ec73c37a8e4e3fa00df9fb9335da96fb789e3b96b318e5097b3"}, - {file = "zipp-3.12.1.tar.gz", hash = "sha256:a3cac813d40993596b39ea9e93a18e8a2076d5c378b8bc88ec32ab264e04ad02"}, + {file = "zipp-3.13.0-py3-none-any.whl", hash = "sha256:e8b2a36ea17df80ffe9e2c4fda3f693c3dad6df1697d3cd3af232db680950b0b"}, + {file = "zipp-3.13.0.tar.gz", hash = "sha256:23f70e964bc11a34cef175bc90ba2914e1e4545ea1e3e2f67c079671883f9cb6"}, ] [package.extras] @@ -2166,4 +1993,4 @@ immaterial = [] [metadata] lock-version = "2.0" python-versions = ">=3.7.0,<4.0" -content-hash = "dbc8aff4a94d21cac3bf7813266c9d851d2c4cd1bd709fe7db689c60782746bc" +content-hash = "27f4d83ca2c7761c9440fc0979fe8975749d3b2ce6ff44c276fa9b2948f8deb8" diff --git a/pyproject.toml b/pyproject.toml index 56ac50761..a5283157f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,8 +41,6 @@ requests-file = "^1.5.1" # external links requests = "^2.25.1" # external_links jsonschema = ">=3.2.0" # needsimport schema validation sphinx-data-viewer = "^0.1.1" # needservice debug output -esbonio = ">=0.11.3" # IDE language features -pygls = "*" # esbonio dependency [tool.poetry.dev-dependencies] sphinxcontrib-plantuml = "^0" @@ -51,8 +49,6 @@ pre-commit = "^2" lxml = "^4.6.5" pytest = "^7" pytest-xdist="*" # parallelisation -pytest_lsp="*" -myst-parser="^0.18.0" responses = "^0.22.0" requests-mock = ">=1.9.3" tabulate = "^0.9.0" diff --git a/sphinx_needs/__init__.py b/sphinx_needs/__init__.py index 9431a31e8..61e4c9f42 100644 --- a/sphinx_needs/__init__.py +++ b/sphinx_needs/__init__.py @@ -1,2 +1 @@ -from sphinx_needs.lsp.esbonio import esbonio_setup # noqa: F401 from sphinx_needs.needs import setup # noqa: F401 diff --git a/sphinx_needs/lsp/__init__.py b/sphinx_needs/lsp/__init__.py deleted file mode 100644 index 38685332d..000000000 --- a/sphinx_needs/lsp/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# -------------------------------------------------------------------------- -# Licensed under the MIT license. -# See License.txt in the project root for further license information. -# -------------------------------------------------------------------------- diff --git a/sphinx_needs/lsp/esbonio.py b/sphinx_needs/lsp/esbonio.py deleted file mode 100644 index 237291e57..000000000 --- a/sphinx_needs/lsp/esbonio.py +++ /dev/null @@ -1,647 +0,0 @@ -"""Suport Sphinx-Needs language features.""" -import getpass -import os -import re -import typing -from hashlib import blake2b -from pathlib import Path -from typing import List, Optional, Tuple, Union - -from esbonio.lsp import LanguageFeature -from esbonio.lsp.rst import CompletionContext, DefinitionContext, HoverContext -from esbonio.lsp.sphinx import SphinxLanguageServer -from jinja2 import BaseLoader, Environment -from packaging import version -from pygls import __version__ - -if version.parse(__version__) < version.parse("1.0"): - from pygls.lsp.types import ( - CompletionItem, - CompletionItemKind, - InsertTextFormat, - Location, - Position, - Range, - TextEdit, - ) -else: - from lsprotocol.types import ( # type: ignore[no-redef] - CompletionItem, - CompletionItemKind, - InsertTextFormat, - Location, - Position, - Range, - TextEdit, - ) - -from sphinx.application import Sphinx - -from sphinx_needs.lsp.needs_store import NeedsStore - - -def get_needs_json(app: Sphinx) -> Optional[Path]: - """ - Get the location of needs.json. - """ - - needs_json = None - # check if needs.json is built automatically during each sphinx-build, - # which requres needs_build_json = True in conf.py - outdir = Path(app.outdir) - if getattr(app.config, "needs_build_json", False): - needs_json = outdir / "needs.json" - else: - # needs.json is manually built, need to check directory buildDir - # check buildDir/needs.json, e,g, _build/needs.json, when user using: sphinx-build -b needs srcdir buiddir - if app.builder and hasattr(app.builder, "name"): - curr_builder = app.builder.name - builddir = Path(app.outdir[: -len(curr_builder)]) - needs_json = builddir / "needs.json" - - return needs_json - - -class NeedlsFeatures(LanguageFeature): - """Sphinx-Needs features support for the language server.""" - - def __init__(self, rst: SphinxLanguageServer) -> None: - super().__init__(rst) - self.needs_store = NeedsStore() - - # Open-Needs-IDE language features completion triggers: '>', '/', ':', '.' - completion_triggers = [re.compile(r"(>)|(\.\.)|(:)|(\/)")] - - def complete(self, context: CompletionContext) -> List[CompletionItem]: - - if isinstance(self.rst, SphinxLanguageServer) and self.rst.app: - # get and check needs.json path - needs_json = get_needs_json(self.rst.app) - if not (needs_json and needs_json.exists()): - self.logger.warning(f"needs.json {needs_json} not exists. No Sphinx-Needs language features activated.") - return [] - - # load needs.json - self.needs_store.load_needs(needs_json) - - # check and set conf.py path - conf_py_path = Path(self.rst.app.srcdir) / "conf.py" - self.needs_store.set_conf_py(conf_py_path) - # set declared need types - self.needs_store.set_declared_types() - - self.logger.debug(f"NeedsStore needs: {self.needs_store.needs}") - # check if needs initialzed - if not self.needs_store.needs_initialized: - return [] - - lines, word = get_lines_and_word(self, context) - line_number = context.position.line - if line_number >= len(lines): - self.logger.info(f"line {line_number} is empty, no completion trigger characters detected") - return [] - line = lines[line_number] - - # if word starts with '->' or ':need:->', complete_need_link - if word.startswith("->") or word.startswith(":need:`->") or word.startswith("{need}`->"): - new_word = word.replace(":need:`->", "->") - if new_word != "->": - new_word = word.replace("{need}`->", "->") - new_word = new_word.replace("`", "") # in case need:`->...>...` - return complete_need_link(self, context, lines, line, new_word) - - # if word starts with ':', complete_role_or_option - if word.startswith(":"): - return complete_role_or_option(self, context, lines, word) - - # if word starts with '..', complete_directive - if word.startswith(".."): - return complete_directive(self, context, lines, word) - - return [] - - return [] - - hover_triggers = [re.compile(r".*")] - - def hover(self, context: HoverContext) -> str: - """Return textDocument/hover response value.""" - self.logger.debug(f"hover params: {context}") - - if isinstance(self.rst, SphinxLanguageServer) and self.rst.app: - # get and check needs.json path - needs_json = get_needs_json(self.rst.app) - if not (needs_json and needs_json.exists()): - self.logger.warning(f"needs.json {needs_json} not exists. No Sphinx-Needs language features activated.") - return "" - - # load needs.json - self.needs_store.load_needs(needs_json) - - try: - need_id = get_need_type_and_id(self, context)[1] - except IndexError: - return "" - if not need_id: - return "" - - try: - title = self.needs_store.needs[need_id]["title"] - description = self.needs_store.needs[need_id]["description"] - hover_value = f"**{title}**\n\n```\n{description}\n```" - return hover_value - except KeyError: - # need is not in the database - return "" - return "" - - definition_triggers = [re.compile(r".*")] - - def definition(self, context: DefinitionContext) -> List[Location]: - """Return location of definition of a need.""" - if isinstance(self.rst, SphinxLanguageServer) and self.rst.app: - # get and check needs.json path - needs_json = get_needs_json(self.rst.app) - if not (needs_json and needs_json.exists()): - self.logger.warning(f"needs.json {needs_json} not exists. No Sphinx-Needs language features activated.") - return [] - - # load needs.json - self.needs_store.load_needs(needs_json) - - if not self.needs_store.is_setup(): - return [] - - need_type, need_id = get_need_type_and_id(self, context) - - # get need defining doc - try: - need = self.needs_store.needs[need_id] - except KeyError: - return [] - - doc_path = Path(self.rst.app.srcdir) / typing.cast(str, need["docname"]) - if doc_path.with_suffix(".rst").exists(): - doc_path = doc_path.with_suffix(".rst") - elif doc_path.with_suffix(".rest").exists(): - doc_path = doc_path.with_suffix(".rest") - elif doc_path.with_suffix(".md").exists(): - doc_path = doc_path.with_suffix(".md") - else: - return [] - - # get the need definition position (line, col) from file - with open(doc_path) as file: - source_lines = file.readlines() - # get the line number - line_count = 0 - line_no = None - pattern = f":id: {need_id}" - for line in source_lines: - if pattern in line: - line_no = line_count - break - line_count = line_count + 1 - if not line_no: - return [] - - # get line of directive (e.g., .. req::) - line_directive = None - directive_patterns = [f".. {need_type}::", f"```{{{need_type}}}"] - for line_count in range(line_no - 1, -1, -1): - if any(dp in source_lines[line_count] for dp in directive_patterns): - line_directive = line_count - break - if not line_directive: - return [] - - pos = Position(line=line_directive, character=0) - return [Location(uri=doc_path.as_uri(), range=Range(start=pos, end=pos))] - return [] - - -def col_to_word_index(col: int, words: List[str]) -> int: - """Return the index of a word in a list of words for a given line character column.""" - length = 0 - index = 0 - for word in words: - length = length + len(word) - if col <= length + index: - return index - index = index + 1 - return index - 1 - - -def get_lines(ls: NeedlsFeatures, params: Union[CompletionContext, DefinitionContext, HoverContext]) -> List[str]: - """Get all text lines in the current document.""" - text_doc = params.doc - ls.logger.debug(f"text_doc: {text_doc}") - source = text_doc.source - return source.splitlines() - - -def get_word(ls: NeedlsFeatures, params: Union[CompletionContext, DefinitionContext, HoverContext]) -> str: - """Return the word in a line of text at a character position.""" - line_no, col = params.position - lines = get_lines(ls, params) - if line_no >= len(lines): - return "" - line = lines[line_no] - words = line.split() - index = col_to_word_index(col, words) - word: str = words[index] - return word - - -def get_lines_and_word(ls: NeedlsFeatures, params: CompletionContext) -> Tuple[List[str], str]: - return (get_lines(ls, params), get_word(ls, params)) - - -def get_need_type_and_id( - ls: NeedlsFeatures, params: Union[DefinitionContext, HoverContext] -) -> Tuple[Optional[str], Optional[str]]: - """Return tuple (need_type, need_id) for a given document position.""" - word = get_word(ls, params) - for need in ls.needs_store.needs.values(): - if need["id"] in word: - return (need["type"], need["id"]) - return (None, None) - - -def doc_completion_items(ls: NeedlsFeatures, docs: List[str], doc_pattern: str) -> List[CompletionItem]: - """Return completion items for a given doc pattern.""" - - # calc all doc paths that start with the given pattern - all_paths = [doc for doc in docs if doc.startswith(doc_pattern)] - - if len(all_paths) == 0: - return [] - - # leave if there is just one path - if len(all_paths) == 1: - insert_text = all_paths[0][len(doc_pattern) :] - return [ - CompletionItem( - label=insert_text, - insert_text=insert_text, - kind=CompletionItemKind.File, - detail="needs doc", - ) - ] - - # look at increasingly longer paths - # stop if there are at least two options - max_path_length = max(path.count("/") for path in all_paths) - current_path_length = doc_pattern.count("/") - - if max_path_length == current_path_length == 0: - sub_paths = all_paths - return [ - CompletionItem(label=sub_path, kind=CompletionItemKind.File, detail="path to needs doc") - for sub_path in sub_paths - ] - - # create list that contains only paths up to current path length - sub_paths = [] - for path in all_paths: - if path.count("/") >= current_path_length: - new_path = "/".join(path.split("/")[current_path_length : current_path_length + 1]) - if new_path not in sub_paths: - sub_paths.append(new_path) - sub_paths.sort() - - items = [] - for sub_path in sub_paths: - if sub_path.find(".rst") > -1 or sub_path.find(".md") > -1: - kind = CompletionItemKind.File - else: - kind = CompletionItemKind.Folder - items.append(CompletionItem(label=sub_path, kind=kind, detail="path to needs doc")) - return items - - -def complete_need_link( - ls: NeedlsFeatures, params: CompletionContext, lines: List[str], line: str, word: str -) -> List[CompletionItem]: - # specify the need type, e.g., - # ->req - if word.count(">") == 1: - return [CompletionItem(label=need_type, detail="need type") for need_type in ls.needs_store.types] - - word_parts = word.split(">") - - # specify doc in which need is specified, e.g., - # ->req>fusion/index.rst - if word.count(">") == 2: - requested_type = word_parts[1] # e.g., req, test, ... - if requested_type in ls.needs_store.types: - return doc_completion_items(ls, ls.needs_store.docs_per_type[requested_type], word_parts[2]) - - # specify the exact need, e.g., - # ->req>fusion/index.rst>REQ_001 - if word.count(">") == 3: - requested_type = word_parts[1] # e.g., req, test, ... - requested_doc = word_parts[2] # [0:-4] # without `.rst` file extension - if requested_doc in ls.needs_store.needs_per_doc: - substitution = word[word.find("->") :] - start_char = line.find(substitution) - line_number = params.position.line - return [ - CompletionItem( - label=need["id"], - insert_text=need["id"], - documentation=need["description"], - detail=need["title"], - additional_text_edits=[ - TextEdit( - range=Range( - start=Position(line=line_number, character=start_char), - end=Position( - line=line_number, - character=start_char + len(substitution), - ), - ), - new_text="", - ) - ], - ) - for need in ls.needs_store.needs_per_doc[requested_doc] - if need["type"] == requested_type - ] - - return [] - - -def generate_hash(user_name: str, doc_uri: str, need_prefix: str, line_number: int) -> str: - salt = os.urandom(blake2b.SALT_SIZE) # pylint: disable=no-member - return blake2b( - f"{user_name}{doc_uri}{need_prefix}{line_number}".encode(), - digest_size=4, - salt=salt, - ).hexdigest() - - -class JinjaHelperFunction: - """ - Jinja helper functions. - """ - - def __init__( - self, ls: NeedlsFeatures, params: CompletionContext, lines: List[str], need_type: Optional[str] = None - ) -> None: - self.ls = ls - self.params = params - self.lines = lines - self.need_type = need_type - - def random(self) -> str: - """Generate a random need ID including hash suffix..""" - - user_name = getpass.getuser() - doc_uri = self.params.doc.uri - line_number = self.params.position.line - - need_type = self.need_type - if not need_type: - match = re.search(".. ([a-z]+)::", self.lines[line_number - 1]) - # Check for MyST/Markdown style - if not match and self.params.doc.filename.endswith(".md"): - match = re.search("```{([a-z]+)}", self.lines[line_number - 1]) - - if match: - need_type = match.group(1) - if not need_type: - return "ID" - else: - return "ID" - - need_prefix = need_type.upper() - - hash_part = generate_hash(user_name, doc_uri, need_prefix, line_number) - need_id = need_prefix + "_" + hash_part - # re-generate hash if ID is already in use - while need_id in self.ls.needs_store.needs: - hash_part = generate_hash(user_name, doc_uri, need_prefix, line_number) - need_id = need_prefix + "_" + hash_part - return need_id - - def from_title(self) -> str: - """Generate a need ID from title.""" - - # default id from title if not exists - id_from_title = "title" - line_number = self.params.position.line - match = re.search(r".. ([a-z]+):: ([\w\s]+)", self.lines[line_number - 1]) - # check for MyST/Markdown style - if not match and self.params.doc.filename.endswith(".md"): - match = re.search(r"```{([a-z]+)} ([\w\s]+)", self.lines[line_number - 1]) - - if match: - matched_title = match.group(2) - if matched_title: - id_from_title = matched_title.rstrip().replace(" ", "_").lower() - else: - # check if previous line is empty, which means it's not used in directives - if not self.lines[line_number - 1]: - id_from_title = "ID" - - return id_from_title - - -def generate_need_id( - ls: NeedlsFeatures, params: CompletionContext, lines: List[str], need_type: Optional[str] = None -) -> str: - """Generate a need ID.""" - - # check custom id from conf.py - if isinstance(ls.rst, SphinxLanguageServer) and ls.rst.app: - custom_snippets_id = ls.rst.app.config.needs_ide_snippets_id - - if not custom_snippets_id: - # default to generate random need ID - custom_snippets_id = "{{random()}}" - - # handled by jinja - templ = Environment(loader=BaseLoader()).from_string(custom_snippets_id) - - jinja_util = JinjaHelperFunction(ls, params, lines, need_type) - data = {"random": jinja_util.random, "from_title": jinja_util.from_title} - need_id = templ.render(**data) - - return need_id - - -def found_eval_rst_block(lines: List[str], params: CompletionContext) -> bool: - # check if current line inside {eval-rst} block - # ```{eval-rst} - # - # ``` - found_eval_rst = False - # check if used in MyST/Markdown file - if not params.doc.filename.endswith(".md"): - return found_eval_rst - - curr_line_no = params.position.line - if curr_line_no > 0: - # check if open block {eval-rst} exits - cnt_block_eval_rst = 0 - cnt = 0 - for line in lines[:curr_line_no]: - if line.startswith("```"): - cnt += 1 - if line.startswith("```{eval-rst}"): - cnt_block_eval_rst += 1 - - # check if opened block {eval-rst} exists - if cnt % 2 != 0 and cnt_block_eval_rst % 2 != 0: - found_eval_rst = True - - return found_eval_rst - - -def calc_snippets_completion_item_text_edit(params: CompletionContext, lines: List[str], word: str) -> TextEdit: - line_number = params.position.line - substitution = word[word.find("..") :] - start_char = lines[line_number].find(substitution) - - text_edit = TextEdit( - range=Range( - start=Position(line=line_number, character=start_char), - end=Position( - line=line_number, - character=start_char + len(substitution), - ), - ), - new_text="", - ) - return text_edit - - -def complete_directive( - ls: NeedlsFeatures, params: CompletionContext, lines: List[str], word: str -) -> List[CompletionItem]: - # need_type ~ req, work, act, ... - items = [] - - # calculate completion item text edits - text_edit = calc_snippets_completion_item_text_edit(params, lines, word) - - # check custom directive snippets from conf.py - if isinstance(ls.rst, SphinxLanguageServer) and ls.rst.app: - custom_directive_snippets = ls.rst.app.config.needs_ide_directive_snippets - - for need_type, title in ls.needs_store.declared_types.items(): - # calculate directive snippets completion label - label = f".. {need_type}::" - if params.doc.filename.endswith(".md") and not found_eval_rst_block(lines, params): - # adapte label for MyST/Markdwon - label = f"md:.. {need_type}::" - - if custom_directive_snippets and need_type in custom_directive_snippets: - # use custom snippets - custom_text = custom_directive_snippets[need_type] - items.append( - CompletionItem( - label=label, - detail=title, - insert_text=custom_text, - insert_text_format=InsertTextFormat.Snippet, - kind=CompletionItemKind.Snippet, - additional_text_edits=[text_edit], - ) - ) - elif params.doc.filename.endswith(".md") and not found_eval_rst_block(lines, params): - # support for MySt/Markdown file - md_text = ( - "```{" + need_type + "} " + "${1:title}\n" - ":id: ${2:" + generate_need_id(ls, params, lines, need_type=need_type) + "}\n" - ":status: open\n\n" - "${3:content}.\n" - "```$0" - ) - md_detail = "Markdown directive snippet" - items.append( - CompletionItem( - label=label, - detail=md_detail, - insert_text=md_text, - insert_text_format=InsertTextFormat.Snippet, - kind=CompletionItemKind.Snippet, - additional_text_edits=[text_edit], - ) - ) - else: - text = ( - " " + need_type + ":: ${1:title}\n" - "\t:id: ${2:" + generate_need_id(ls, params, lines, need_type=need_type) + "}\n" - "\t:status: open\n\n" - "\t${3:content}.\n$0" - ) - items.append( - CompletionItem( - label=label, - detail=title, - insert_text=text, - insert_text_format=InsertTextFormat.Snippet, - kind=CompletionItemKind.Snippet, - ) - ) - - return items - - -def complete_role_or_option( - ls: NeedlsFeatures, params: CompletionContext, lines: List[str], word: str -) -> List[CompletionItem]: - # Calculate need role snippet for MySt/Markdown and rst - if params.doc.filename.endswith(".md"): - # support MyST/Markdown - # in MySz/Markdowm file, role looks like, e.g. {need}`content` - # triggered like noraml rst by :, replaced with markdown style - line_number = params.position.line - substitution = word[word.find(":") :] - start_char = lines[line_number].find(substitution) - need_role_item = CompletionItem( - label="md::need:", - detail="Markdown need role", - insert_text="{need}`${1:ID}`$0", - insert_text_format=InsertTextFormat.Snippet, - kind=CompletionItemKind.Snippet, - additional_text_edits=[ - TextEdit( - range=Range( - start=Position(line=line_number, character=start_char), - end=Position( - line=line_number, - character=start_char + len(substitution), - ), - ), - new_text="", - ) - ], - ) - else: - need_role_item = CompletionItem( - label=":need:", - detail="need role", - insert_text="need:`${1:ID}` $0", - insert_text_format=InsertTextFormat.Snippet, - kind=CompletionItemKind.Snippet, - ) - - return [ - CompletionItem( - label=":id:", - detail="needs option", - insert_text="id: ${1:" + generate_need_id(ls, params, lines) + "}\n$0", - insert_text_format=InsertTextFormat.Snippet, - kind=CompletionItemKind.Snippet, - ), - need_role_item, - ] - - -def esbonio_setup(rst: SphinxLanguageServer) -> None: - rst.logger.debug("Starting register Sphinx-Needs language features...") - needls_features = NeedlsFeatures(rst) - rst.add_feature(needls_features) diff --git a/sphinx_needs/lsp/exceptions.py b/sphinx_needs/lsp/exceptions.py deleted file mode 100644 index cb73aa331..000000000 --- a/sphinx_needs/lsp/exceptions.py +++ /dev/null @@ -1,2 +0,0 @@ -class NeedlsConfigException(BaseException): - """Errors in used configuration""" diff --git a/sphinx_needs/lsp/needs_store.py b/sphinx_needs/lsp/needs_store.py deleted file mode 100644 index 91c7fa36a..000000000 --- a/sphinx_needs/lsp/needs_store.py +++ /dev/null @@ -1,110 +0,0 @@ -# -------------------------------------------------------------------------- -# Licensed under the MIT license. -# See License.txt in the project root for further license information. -# -------------------------------------------------------------------------- - -import importlib.util -import json -import logging -import os -import sys -from contextlib import contextmanager -from pathlib import Path -from typing import Any, Dict, Generator, List, Optional - -from sphinx_needs.lsp.exceptions import NeedlsConfigException - - -@contextmanager -def set_directory(path: Path) -> Generator[None, None, None]: - origin = Path().cwd() - try: - os.chdir(path) - yield - finally: - os.chdir(origin) - - -class NeedsStore: - """Abstraction of needs database.""" - - def __init__(self) -> None: - self.docs_per_type: Dict[str, List[str]] = {} # key: need type, val: list of doc names (str) - self.needs_per_doc: Dict[Optional[str], List[Dict[Optional[str], Any]]] = {} # key: docname; val: list of needs - self.types: List[str] = [] # list of need types actually defined in needs.json - self.declared_types: Dict[str, str] = {} # types declared in conf.py: {'need directive': 'need title'} - self.needs: Dict[Optional[str], Dict[Optional[str], Any]] = {} - self.needs_initialized: bool = False - self.conf_py_path: Path = Path() - - def is_setup(self) -> bool: - """Return True if database is ready for use.""" - - return self.needs_initialized - - def set_conf_py(self, conf_py: Path) -> None: - if not conf_py.exists(): - raise FileNotFoundError(f"Given custom configuration file {conf_py} not found.") - self.conf_py_path = conf_py - - def set_declared_types(self) -> None: - module_name = "conf" - conf_py = self.conf_py_path - with set_directory(conf_py.parent): - logging.info(f"Loading need_types from {conf_py.name}...") - - spec = importlib.util.spec_from_file_location(module_name, conf_py) - if spec is None: - raise ImportError(f"Created module spec {spec} from {conf_py.name} not exists.") - - module = importlib.util.module_from_spec(spec) - sys.modules[module_name] = module - - if spec.loader: - try: - spec.loader.exec_module(module) - except Exception as e: - logging.error(f"Failed to exccute module {module} -> {e}") - else: - raise ImportError(f"Python ModuleSpec Loader{spec.loader} not found.") - - need_types = getattr(module, "needs_types", []) - if not need_types: - raise NeedlsConfigException(f"No 'need_types' defined on {conf_py.name}") - - self.declared_types = {} - for item in need_types: - self.declared_types[item["directive"]] = item["title"] - - def load_needs(self, json_file: Path) -> None: - - self.docs_per_type = {} - self.needs_per_doc = {} - self.types = [] - self.needs = {} - - with open(json_file, encoding="utf-8") as file: - needs_json = json.load(file) - - versions = needs_json["versions"] - # get the latest version - version = versions[sorted(versions)[-1]] - - self.needs = version["needs"] - - for need in self.needs.values(): - need_type = need["type"] - docname = need["docname"] + need["doctype"] - - if need_type not in self.docs_per_type: - self.types.append(need_type) - self.docs_per_type[need_type] = [] - - if docname not in self.docs_per_type[need_type]: - self.docs_per_type[need_type].append(docname) - - if docname not in self.needs_per_doc: - self.needs_per_doc[docname] = [] - self.needs_per_doc[docname].append(need) - - self.needs_initialized = True diff --git a/sphinx_needs/needs.py b/sphinx_needs/needs.py index 6def6afc3..d3334630e 100644 --- a/sphinx_needs/needs.py +++ b/sphinx_needs/needs.py @@ -163,8 +163,6 @@ def setup(app: Sphinx) -> Dict[str, Any]: app.add_config_value("needs_id_prefix_specs", "", "html", types=[str]) app.add_config_value("needs_id_length", 5, "html", types=[int]) app.add_config_value("needs_id_from_title", False, "html", types=[bool]) - app.add_config_value("needs_ide_snippets_id", "", "html", types=[str]) - app.add_config_value("needs_ide_directive_snippets", {}, "html", types=[dict]) app.add_config_value("needs_specs_show_needlist", False, "html", types=[bool]) app.add_config_value("needs_id_required", False, "html", types=[bool]) app.add_config_value( diff --git a/tests/test_lsp/doc_example_lsp/Makefile b/tests/test_lsp/doc_example_lsp/Makefile deleted file mode 100644 index d4bb2cbb9..000000000 --- a/tests/test_lsp/doc_example_lsp/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line, and also -# from the environment for the first two. -SPHINXOPTS ?= -SPHINXBUILD ?= sphinx-build -SOURCEDIR = . -BUILDDIR = _build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/tests/test_lsp/doc_example_lsp/conf.py b/tests/test_lsp/doc_example_lsp/conf.py deleted file mode 100644 index c6b43c0f1..000000000 --- a/tests/test_lsp/doc_example_lsp/conf.py +++ /dev/null @@ -1,62 +0,0 @@ -# Configuration file for the Sphinx documentation builder. -# -# This file only contains a selection of the most common options. For a full -# list see the documentation: -# https://www.sphinx-doc.org/en/master/usage/configuration.html - -# -- Path setup -------------------------------------------------------------- - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -# import os -# import sys -# sys.path.insert(0, os.path.abspath('.')) - - -# -- Project information ----------------------------------------------------- - -project = "Test Env" -copyright = "2022, open-needs community" -author = "open-needs community" - - -# -- General configuration --------------------------------------------------- - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = ["sphinx_needs"] - -needs_types = [ - {"directive": "req", "title": "Requirement", "prefix": "R_", "color": "#BFD8D2", "style": "node"}, - {"directive": "spec", "title": "Specification", "prefix": "S_", "color": "#FEDCD2", "style": "node"}, - {"directive": "impl", "title": "Implementation", "prefix": "I_", "color": "#DF744A", "style": "node"}, - {"directive": "test", "title": "Test Case", "prefix": "T_", "color": "#DCB239", "style": "node"}, - # Kept for backwards compatibility - {"directive": "need", "title": "Need", "prefix": "N_", "color": "#9856a5", "style": "node"}, -] - -needs_build_json = True - -# Add any paths that contain templates here, relative to this directory. -templates_path = ["_templates"] - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This pattern also affects html_static_path and html_extra_path. -exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] - - -# -- Options for HTML output ------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# -html_theme = "alabaster" - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -# html_static_path = ["_static"] diff --git a/tests/test_lsp/doc_example_lsp/index.rst b/tests/test_lsp/doc_example_lsp/index.rst deleted file mode 100644 index 02e1ba4cd..000000000 --- a/tests/test_lsp/doc_example_lsp/index.rst +++ /dev/null @@ -1,31 +0,0 @@ -Test-Env project -================ - -Just a test project for tests (tataaaa!). - - -Needs ------ - - -.. req:: First requirement - :id: REQ_1 - :status: open - - Requirement content - - -.. spec:: First specification - :id: SPEC_1 - :status: open - - Specification content - - -:need:`REQ_1` - -:need:`->` - -:need:`->req>` - -:need:`->req>index.rst>` diff --git a/tests/test_lsp/doc_example_lsp/make.bat b/tests/test_lsp/doc_example_lsp/make.bat deleted file mode 100644 index 8084272b4..000000000 --- a/tests/test_lsp/doc_example_lsp/make.bat +++ /dev/null @@ -1,35 +0,0 @@ -@ECHO OFF - -pushd %~dp0 - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set SOURCEDIR=. -set BUILDDIR=_build - -if "%1" == "" goto help - -%SPHINXBUILD% >NUL 2>NUL -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.https://www.sphinx-doc.org/ - exit /b 1 -) - -%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% -goto end - -:help -%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% - -:end -popd diff --git a/tests/test_lsp/doc_lsp_custom_directive_snippets/Makefile b/tests/test_lsp/doc_lsp_custom_directive_snippets/Makefile deleted file mode 100644 index d4bb2cbb9..000000000 --- a/tests/test_lsp/doc_lsp_custom_directive_snippets/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line, and also -# from the environment for the first two. -SPHINXOPTS ?= -SPHINXBUILD ?= sphinx-build -SOURCEDIR = . -BUILDDIR = _build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/tests/test_lsp/doc_lsp_custom_directive_snippets/conf.py b/tests/test_lsp/doc_lsp_custom_directive_snippets/conf.py deleted file mode 100644 index 9eff52b56..000000000 --- a/tests/test_lsp/doc_lsp_custom_directive_snippets/conf.py +++ /dev/null @@ -1,95 +0,0 @@ -# Configuration file for the Sphinx documentation builder. -# -# This file only contains a selection of the most common options. For a full -# list see the documentation: -# https://www.sphinx-doc.org/en/master/usage/configuration.html - -# -- Path setup -------------------------------------------------------------- - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -# import os -# import sys -# sys.path.insert(0, os.path.abspath('.')) - - -# -- Project information ----------------------------------------------------- - -project = "Test Env" -copyright = "2022, open-needs community" -author = "open-needs community" - - -# -- General configuration --------------------------------------------------- - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = ["sphinx_needs"] - -needs_types = [ - {"directive": "req", "title": "Requirement", "prefix": "R_", "color": "#BFD8D2", "style": "node"}, - {"directive": "spec", "title": "Specification", "prefix": "S_", "color": "#FEDCD2", "style": "node"}, - {"directive": "impl", "title": "Implementation", "prefix": "I_", "color": "#DF744A", "style": "node"}, - {"directive": "test", "title": "Test Case", "prefix": "T_", "color": "#DCB239", "style": "node"}, - # Kept for backwards compatibility - {"directive": "need", "title": "Need", "prefix": "N_", "color": "#9856a5", "style": "node"}, -] - -needs_build_json = True - -# custom IDE directive snippets per need_type -needs_ide_directive_snippets = { - "req": """\ -.. req:: REQ Example - :id: ID - :status: - :custom_option_1: - - random content. -""", - "test": """\ -.. test:: Test Title - :id: TEST_ - :status: open - :custom_option: something - - test directive content. -""", -} - -# Or maybe define like this -# needs_ide_directive_snippets = [ -# { -# "need_type": "req", -# "title": "My Custom req title", -# "options": { -# "id": "REQ_", -# "status": "open", -# }, -# "content": "My req snippets content." -# }, -# ] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ["_templates"] - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This pattern also affects html_static_path and html_extra_path. -exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] - - -# -- Options for HTML output ------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# -html_theme = "alabaster" - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -# html_static_path = ["_static"] diff --git a/tests/test_lsp/doc_lsp_custom_directive_snippets/index.rst b/tests/test_lsp/doc_lsp_custom_directive_snippets/index.rst deleted file mode 100644 index 02e1ba4cd..000000000 --- a/tests/test_lsp/doc_lsp_custom_directive_snippets/index.rst +++ /dev/null @@ -1,31 +0,0 @@ -Test-Env project -================ - -Just a test project for tests (tataaaa!). - - -Needs ------ - - -.. req:: First requirement - :id: REQ_1 - :status: open - - Requirement content - - -.. spec:: First specification - :id: SPEC_1 - :status: open - - Specification content - - -:need:`REQ_1` - -:need:`->` - -:need:`->req>` - -:need:`->req>index.rst>` diff --git a/tests/test_lsp/doc_lsp_custom_directive_snippets/make.bat b/tests/test_lsp/doc_lsp_custom_directive_snippets/make.bat deleted file mode 100644 index 8084272b4..000000000 --- a/tests/test_lsp/doc_lsp_custom_directive_snippets/make.bat +++ /dev/null @@ -1,35 +0,0 @@ -@ECHO OFF - -pushd %~dp0 - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set SOURCEDIR=. -set BUILDDIR=_build - -if "%1" == "" goto help - -%SPHINXBUILD% >NUL 2>NUL -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.https://www.sphinx-doc.org/ - exit /b 1 -) - -%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% -goto end - -:help -%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% - -:end -popd diff --git a/tests/test_lsp/doc_lsp_custom_need_id_generate_from_title/Makefile b/tests/test_lsp/doc_lsp_custom_need_id_generate_from_title/Makefile deleted file mode 100644 index d4bb2cbb9..000000000 --- a/tests/test_lsp/doc_lsp_custom_need_id_generate_from_title/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line, and also -# from the environment for the first two. -SPHINXOPTS ?= -SPHINXBUILD ?= sphinx-build -SOURCEDIR = . -BUILDDIR = _build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/tests/test_lsp/doc_lsp_custom_need_id_generate_from_title/conf.py b/tests/test_lsp/doc_lsp_custom_need_id_generate_from_title/conf.py deleted file mode 100644 index cb80c8af5..000000000 --- a/tests/test_lsp/doc_lsp_custom_need_id_generate_from_title/conf.py +++ /dev/null @@ -1,65 +0,0 @@ -# Configuration file for the Sphinx documentation builder. -# -# This file only contains a selection of the most common options. For a full -# list see the documentation: -# https://www.sphinx-doc.org/en/master/usage/configuration.html - -# -- Path setup -------------------------------------------------------------- - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -# import os -# import sys -# sys.path.insert(0, os.path.abspath('.')) - - -# -- Project information ----------------------------------------------------- - -project = "Test Env" -copyright = "2022, open-needs community" -author = "open-needs community" - - -# -- General configuration --------------------------------------------------- - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = ["sphinx_needs"] - -needs_types = [ - {"directive": "req", "title": "Requirement", "prefix": "R_", "color": "#BFD8D2", "style": "node"}, - {"directive": "spec", "title": "Specification", "prefix": "S_", "color": "#FEDCD2", "style": "node"}, - {"directive": "impl", "title": "Implementation", "prefix": "I_", "color": "#DF744A", "style": "node"}, - {"directive": "test", "title": "Test Case", "prefix": "T_", "color": "#DCB239", "style": "node"}, - # Kept for backwards compatibility - {"directive": "need", "title": "Need", "prefix": "N_", "color": "#9856a5", "style": "node"}, -] - -needs_build_json = True - -# Add custom need ID for snippets -needs_ide_snippets_id = "TEST_{{from_title()}}_TEST" - -# Add any paths that contain templates here, relative to this directory. -templates_path = ["_templates"] - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This pattern also affects html_static_path and html_extra_path. -exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] - - -# -- Options for HTML output ------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# -html_theme = "alabaster" - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -# html_static_path = ["_static"] diff --git a/tests/test_lsp/doc_lsp_custom_need_id_generate_from_title/index.rst b/tests/test_lsp/doc_lsp_custom_need_id_generate_from_title/index.rst deleted file mode 100644 index 02e1ba4cd..000000000 --- a/tests/test_lsp/doc_lsp_custom_need_id_generate_from_title/index.rst +++ /dev/null @@ -1,31 +0,0 @@ -Test-Env project -================ - -Just a test project for tests (tataaaa!). - - -Needs ------ - - -.. req:: First requirement - :id: REQ_1 - :status: open - - Requirement content - - -.. spec:: First specification - :id: SPEC_1 - :status: open - - Specification content - - -:need:`REQ_1` - -:need:`->` - -:need:`->req>` - -:need:`->req>index.rst>` diff --git a/tests/test_lsp/doc_lsp_custom_need_id_generate_from_title/make.bat b/tests/test_lsp/doc_lsp_custom_need_id_generate_from_title/make.bat deleted file mode 100644 index 8084272b4..000000000 --- a/tests/test_lsp/doc_lsp_custom_need_id_generate_from_title/make.bat +++ /dev/null @@ -1,35 +0,0 @@ -@ECHO OFF - -pushd %~dp0 - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set SOURCEDIR=. -set BUILDDIR=_build - -if "%1" == "" goto help - -%SPHINXBUILD% >NUL 2>NUL -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.https://www.sphinx-doc.org/ - exit /b 1 -) - -%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% -goto end - -:help -%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% - -:end -popd diff --git a/tests/test_lsp/doc_lsp_custom_need_id_generate_random/Makefile b/tests/test_lsp/doc_lsp_custom_need_id_generate_random/Makefile deleted file mode 100644 index d4bb2cbb9..000000000 --- a/tests/test_lsp/doc_lsp_custom_need_id_generate_random/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line, and also -# from the environment for the first two. -SPHINXOPTS ?= -SPHINXBUILD ?= sphinx-build -SOURCEDIR = . -BUILDDIR = _build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/tests/test_lsp/doc_lsp_custom_need_id_generate_random/conf.py b/tests/test_lsp/doc_lsp_custom_need_id_generate_random/conf.py deleted file mode 100644 index 4f5e2ec2e..000000000 --- a/tests/test_lsp/doc_lsp_custom_need_id_generate_random/conf.py +++ /dev/null @@ -1,65 +0,0 @@ -# Configuration file for the Sphinx documentation builder. -# -# This file only contains a selection of the most common options. For a full -# list see the documentation: -# https://www.sphinx-doc.org/en/master/usage/configuration.html - -# -- Path setup -------------------------------------------------------------- - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -# import os -# import sys -# sys.path.insert(0, os.path.abspath('.')) - - -# -- Project information ----------------------------------------------------- - -project = "Test Env" -copyright = "2022, open-needs community" -author = "open-needs community" - - -# -- General configuration --------------------------------------------------- - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = ["sphinx_needs"] - -needs_types = [ - {"directive": "req", "title": "Requirement", "prefix": "R_", "color": "#BFD8D2", "style": "node"}, - {"directive": "spec", "title": "Specification", "prefix": "S_", "color": "#FEDCD2", "style": "node"}, - {"directive": "impl", "title": "Implementation", "prefix": "I_", "color": "#DF744A", "style": "node"}, - {"directive": "test", "title": "Test Case", "prefix": "T_", "color": "#DCB239", "style": "node"}, - # Kept for backwards compatibility - {"directive": "need", "title": "Need", "prefix": "N_", "color": "#9856a5", "style": "node"}, -] - -needs_build_json = True - -# Add custom need ID for snippets -needs_ide_snippets_id = "Test_{{random()}}_Test" - -# Add any paths that contain templates here, relative to this directory. -templates_path = ["_templates"] - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This pattern also affects html_static_path and html_extra_path. -exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] - - -# -- Options for HTML output ------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# -html_theme = "alabaster" - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -# html_static_path = ["_static"] diff --git a/tests/test_lsp/doc_lsp_custom_need_id_generate_random/index.rst b/tests/test_lsp/doc_lsp_custom_need_id_generate_random/index.rst deleted file mode 100644 index 02e1ba4cd..000000000 --- a/tests/test_lsp/doc_lsp_custom_need_id_generate_random/index.rst +++ /dev/null @@ -1,31 +0,0 @@ -Test-Env project -================ - -Just a test project for tests (tataaaa!). - - -Needs ------ - - -.. req:: First requirement - :id: REQ_1 - :status: open - - Requirement content - - -.. spec:: First specification - :id: SPEC_1 - :status: open - - Specification content - - -:need:`REQ_1` - -:need:`->` - -:need:`->req>` - -:need:`->req>index.rst>` diff --git a/tests/test_lsp/doc_lsp_custom_need_id_generate_random/make.bat b/tests/test_lsp/doc_lsp_custom_need_id_generate_random/make.bat deleted file mode 100644 index 8084272b4..000000000 --- a/tests/test_lsp/doc_lsp_custom_need_id_generate_random/make.bat +++ /dev/null @@ -1,35 +0,0 @@ -@ECHO OFF - -pushd %~dp0 - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set SOURCEDIR=. -set BUILDDIR=_build - -if "%1" == "" goto help - -%SPHINXBUILD% >NUL 2>NUL -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.https://www.sphinx-doc.org/ - exit /b 1 -) - -%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% -goto end - -:help -%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% - -:end -popd diff --git a/tests/test_lsp/doc_lsp_support_MyST/Makefile b/tests/test_lsp/doc_lsp_support_MyST/Makefile deleted file mode 100644 index d4bb2cbb9..000000000 --- a/tests/test_lsp/doc_lsp_support_MyST/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line, and also -# from the environment for the first two. -SPHINXOPTS ?= -SPHINXBUILD ?= sphinx-build -SOURCEDIR = . -BUILDDIR = _build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/tests/test_lsp/doc_lsp_support_MyST/conf.py b/tests/test_lsp/doc_lsp_support_MyST/conf.py deleted file mode 100644 index 9a91c2ddd..000000000 --- a/tests/test_lsp/doc_lsp_support_MyST/conf.py +++ /dev/null @@ -1,64 +0,0 @@ -# Configuration file for the Sphinx documentation builder. -# -# This file only contains a selection of the most common options. For a full -# list see the documentation: -# https://www.sphinx-doc.org/en/master/usage/configuration.html - -# -- Path setup -------------------------------------------------------------- - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -# import os -# import sys -# sys.path.insert(0, os.path.abspath('.')) - - -# -- Project information ----------------------------------------------------- - -project = "Test Env" -copyright = "2022, open-needs community" -author = "open-needs community" - - -# -- General configuration --------------------------------------------------- - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = ["sphinx_needs", "myst_parser"] - -source_suffix = [".rst", ".md"] - -needs_types = [ - {"directive": "req", "title": "Requirement", "prefix": "R_", "color": "#BFD8D2", "style": "node"}, - {"directive": "spec", "title": "Specification", "prefix": "S_", "color": "#FEDCD2", "style": "node"}, - {"directive": "impl", "title": "Implementation", "prefix": "I_", "color": "#DF744A", "style": "node"}, - {"directive": "test", "title": "Test Case", "prefix": "T_", "color": "#DCB239", "style": "node"}, - # Kept for backwards compatibility - {"directive": "need", "title": "Need", "prefix": "N_", "color": "#9856a5", "style": "node"}, -] - -needs_build_json = True - -# Add any paths that contain templates here, relative to this directory. -templates_path = ["_templates"] - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This pattern also affects html_static_path and html_extra_path. -exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] - - -# -- Options for HTML output ------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# -html_theme = "alabaster" - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -# html_static_path = ["_static"] diff --git a/tests/test_lsp/doc_lsp_support_MyST/index.rst b/tests/test_lsp/doc_lsp_support_MyST/index.rst deleted file mode 100644 index 1f527651b..000000000 --- a/tests/test_lsp/doc_lsp_support_MyST/index.rst +++ /dev/null @@ -1,29 +0,0 @@ -Test-Env project -================ - -Just a test project for tests (tataaaa!). - - -Needs ------ - - -.. req:: First requirement - :id: REQ_1 - :status: open - - Requirement content - - -.. spec:: First specification - :id: SPEC_1 - :status: open - - Specification content - - -.. toctree:: - :maxdepth: 2 - - myfile.md - md_subfolder/MySecond.md diff --git a/tests/test_lsp/doc_lsp_support_MyST/make.bat b/tests/test_lsp/doc_lsp_support_MyST/make.bat deleted file mode 100644 index 8084272b4..000000000 --- a/tests/test_lsp/doc_lsp_support_MyST/make.bat +++ /dev/null @@ -1,35 +0,0 @@ -@ECHO OFF - -pushd %~dp0 - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set SOURCEDIR=. -set BUILDDIR=_build - -if "%1" == "" goto help - -%SPHINXBUILD% >NUL 2>NUL -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.https://www.sphinx-doc.org/ - exit /b 1 -) - -%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% -goto end - -:help -%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% - -:end -popd diff --git a/tests/test_lsp/doc_lsp_support_MyST/md_subfolder/MySecond.md b/tests/test_lsp/doc_lsp_support_MyST/md_subfolder/MySecond.md deleted file mode 100644 index 0b8389974..000000000 --- a/tests/test_lsp/doc_lsp_support_MyST/md_subfolder/MySecond.md +++ /dev/null @@ -1,15 +0,0 @@ -# Markdown file in subfolder - -```{req} Sub MD Req title -:id: REQ_3 -:status: open - -MD in Subfolder with some req content. -``` - -```{spec} Sub MD Spec title -:id: SPEC_3 -:status: open - -MD in Subfolder with some spec content. -``` diff --git a/tests/test_lsp/doc_lsp_support_MyST/myfile.md b/tests/test_lsp/doc_lsp_support_MyST/myfile.md deleted file mode 100644 index 2c6b882df..000000000 --- a/tests/test_lsp/doc_lsp_support_MyST/myfile.md +++ /dev/null @@ -1,48 +0,0 @@ -# My Markdown file example title - -Some **text**! - -```{eval-rst} -.. req:: MD REQ Title - :id: REQ_2 - :status: open - - some stuff from md req. -``` - -```{spec} MD SPEC title -:id: SPEC_2 -:status: open - -MD Spec test content. -``` - -:need:`SPEC_2` - -:need:`REQ_3` - -:need:`REQ_1` - -:need:`->` - -:need:`->req>` - -:need:`->req>myfile.md>` - -:need:`->req>md_subfolder/` - -:need:`->req>md_subfolder/MySecond.md>` - -{need}`->` - -{need}`->req>` - -{need}`->req>myfile.md>` - -{need}`->req>md_subfolder/` - -{need}`->req>md_subfolder/MySecond.md>` - -:need - -.. req diff --git a/tests/test_lsp/test_lsp.py b/tests/test_lsp/test_lsp.py deleted file mode 100644 index 5e16134b3..000000000 --- a/tests/test_lsp/test_lsp.py +++ /dev/null @@ -1,332 +0,0 @@ -"""Test Sphinx-Needs language features.""" - -import os -import sys - -import pytest -import pytest_lsp -from packaging import version -from pygls import __version__ - -if version.parse(__version__) < version.parse("1.0"): - from pygls.lsp.types import MarkupContent, MarkupKind, Position, Range -else: - from lsprotocol.types import MarkupContent, MarkupKind, Position, Range - -TEST_DOC_ROOT_URI = os.path.join("file://", os.path.abspath(os.path.dirname(__file__)), "doc_example_lsp") -TEST_FILE_URI = os.path.join(TEST_DOC_ROOT_URI, "index.rst") - - -@pytest_lsp.fixture( - config=pytest_lsp.ClientServerConfig(server_command=[sys.executable, "-m", "esbonio"], root_uri=TEST_DOC_ROOT_URI), -) -async def client(): - pass - - -@pytest.mark.skipif( - version.parse(__version__) >= version.parse("1.0"), reason="Esbonio version >=0.16.0 using pygls >= 1.0 not tested." -) -@pytest.mark.asyncio -async def test_need_directive_role_completion(client): - # check needs directive completion - need_directive_result = await client.completion_request(uri=TEST_FILE_URI, line=10, character=3) - assert len(need_directive_result.items) > 0 - - req_idx = None - spec_idx = None - impl_idx = None - test_idx = None - need_idx = None - needarch_idx = None - needlist_idx = None - needimport_idx = None - for index, item in enumerate(need_directive_result.items): - if item.label == "req": - req_idx = index - elif item.label == "spec": - spec_idx = index - elif item.label == "impl": - impl_idx = index - elif item.label == "test": - test_idx = index - elif item.label == "need": - need_idx = index - elif item.label == "needarch": - needarch_idx = index - elif item.label == "needlist": - needlist_idx = index - elif item.label == "needimport": - needimport_idx = index - - # check user in conf.py defined need directive req exists - assert req_idx is not None - need_req = need_directive_result.items[req_idx] - assert need_req.label == "req" - assert need_req.filter_text == ".. req::" - assert need_req.detail == "sphinx_needs.directives.need.NeedDirective" - assert need_req.kind == 7 # CompletionItemKind.Class - assert need_req.insert_text_format == 1 # InsertTextFormat.PlainText - assert need_req.data["source_feature"] == "esbonio.lsp.directives.Directives" - assert need_req.data["completion_type"] == "directive" - - # check user in conf.py need directive spec exists - assert spec_idx is not None - need_spec = need_directive_result.items[spec_idx] - assert need_spec.label == "spec" - assert need_spec.filter_text == ".. spec::" - assert need_spec.detail == "sphinx_needs.directives.need.NeedDirective" - assert need_spec.kind == 7 # CompletionItemKind.Class - assert need_spec.insert_text_format == 1 # InsertTextFormat.PlainText - assert need_spec.data["source_feature"] == "esbonio.lsp.directives.Directives" - assert need_spec.data["completion_type"] == "directive" - - # check other in conf.py defined need directives also exist - assert impl_idx is not None - need_impl = need_directive_result.items[impl_idx] - assert need_impl.label == "impl" - assert need_impl.filter_text == ".. impl::" - assert need_impl.detail == "sphinx_needs.directives.need.NeedDirective" - - assert test_idx is not None - need_test = need_directive_result.items[test_idx] - assert need_test.label == "test" - assert need_test.filter_text == ".. test::" - assert need_test.detail == "sphinx_needs.directives.need.NeedDirective" - - assert need_idx is not None - need_need = need_directive_result.items[need_idx] - assert need_need.label == "need" - assert need_need.filter_text == ".. need::" - assert need_need.detail == "sphinx_needs.directives.need.NeedDirective" - - # check Sphinx-Needs default supported derectives exist - assert needarch_idx is not None - need_needarch = need_directive_result.items[needarch_idx] - assert need_needarch.label == "needarch" - assert need_needarch.filter_text == ".. needarch::" - assert need_needarch.detail == "sphinx_needs.directives.needuml.NeedarchDirective" - assert need_needarch.kind == 7 # CompletionItemKind.Class - assert need_needarch.insert_text_format == 1 # InsertTextFormat.PlainText - assert need_needarch.data["source_feature"] == "esbonio.lsp.directives.Directives" - assert need_needarch.data["completion_type"] == "directive" - - assert needlist_idx is not None - need_needlist = need_directive_result.items[needlist_idx] - assert need_needlist.label == "needlist" - assert need_needlist.filter_text == ".. needlist::" - assert need_needlist.detail == "sphinx_needs.directives.needlist.NeedlistDirective" - assert need_needlist.kind == 7 # CompletionItemKind.Class - assert need_needlist.insert_text_format == 1 # InsertTextFormat.PlainText - assert need_needlist.data["source_feature"] == "esbonio.lsp.directives.Directives" - assert need_needlist.data["completion_type"] == "directive" - - assert needimport_idx is not None - need_needimport = need_directive_result.items[needimport_idx] - assert need_needimport.label == "needimport" - assert need_needimport.filter_text == ".. needimport::" - assert need_needimport.detail == "sphinx_needs.directives.needimport.NeedimportDirective" - - # check need options for need directive req - need_req_options_result = await client.completion_request(uri=TEST_FILE_URI, line=11, character=3) - assert len(need_req_options_result.items) > 0 - - req_id_idx = None - req_status_idx = None - for index, item in enumerate(need_req_options_result.items): - if item.label == "id": - req_id_idx = index - elif item.label == "status": - req_status_idx = index - - # check need directive option id exists - assert req_id_idx is not None - need_req_option_id = need_req_options_result.items[req_id_idx] - assert need_req_option_id.label == "id" - assert need_req_option_id.filter_text == ":id:" - assert need_req_option_id.detail == "sphinx_needs.directives.need.NeedDirective:id" - assert need_req_option_id.kind == 5 # CompletionItemKind.Field - assert need_req_option_id.data["source_feature"] == "esbonio.lsp.directives.Directives" - assert need_req_option_id.data["completion_type"] == "directive_option" - assert need_req_option_id.data["for_directive"] == "req" - - # check need directive option status exists - assert req_status_idx is not None - need_req_option_status = need_req_options_result.items[req_status_idx] - assert need_req_option_status.label == "status" - assert need_req_option_status.detail == "sphinx_needs.directives.need.NeedDirective:status" - assert need_req_option_status.kind == 5 # CompletionItemKind.Field - assert need_req_option_status.data["source_feature"] == "esbonio.lsp.directives.Directives" - assert need_req_option_status.data["completion_type"] == "directive_option" - assert need_req_option_status.data["for_directive"] == "req" - - # check need options for need directive spec - need_spec_options_result = await client.completion_request(uri=TEST_FILE_URI, line=18, character=3) - assert len(need_spec_options_result.items) > 0 - - spec_id_idx = None - spec_status_idx = None - for index, item in enumerate(need_spec_options_result.items): - if item.label == "id": - spec_id_idx = index - elif item.label == "status": - spec_status_idx = index - - assert spec_id_idx is not None - need_spec_option_id = need_spec_options_result.items[spec_id_idx] - assert need_spec_option_id.label == "id" - assert need_spec_option_id.filter_text == ":id:" - assert need_spec_option_id.detail == "sphinx_needs.directives.need.NeedDirective:id" - assert need_spec_option_id.kind == 5 # CompletionItemKind.Field - assert need_spec_option_id.data["source_feature"] == "esbonio.lsp.directives.Directives" - assert need_spec_option_id.data["completion_type"] == "directive_option" - assert need_spec_option_id.data["for_directive"] == "spec" - - assert spec_status_idx is not None - need_spec_option_status = need_spec_options_result.items[spec_status_idx] - assert need_spec_option_status.label == "status" - assert need_spec_option_status.filter_text == ":status:" - assert need_spec_option_status.detail == "sphinx_needs.directives.need.NeedDirective:status" - assert need_spec_option_status.kind == 5 # CompletionItemKind.Field - assert need_spec_option_status.data["source_feature"] == "esbonio.lsp.directives.Directives" - assert need_spec_option_status.data["completion_type"] == "directive_option" - assert need_spec_option_status.data["for_directive"] == "spec" - - # check need role completion - need_role_result = await client.completion_request(uri=TEST_FILE_URI, line=24, character=1) - assert len(need_role_result.items) > 0 - - need_role_idx = None - for index, item in enumerate(need_role_result.items): - if item.label == ":need:": - need_role_idx = index - - assert need_role_idx is not None - need_role_need = need_role_result.items[need_role_idx] - assert need_role_need.label == ":need:" - assert need_role_need.detail == "need role" - assert need_role_need.insert_text == "need:`${1:ID}` $0" - assert need_role_need.insert_text_format == 2 # InsertTextFormat.Snippet - assert need_role_need.kind == 15 # CompletionItemKind.Snippet - assert need_role_need.data["source_feature"] == "sphinx_needs.lsp.esbonio.NeedlsFeatures" - - -@pytest.mark.skipif( - version.parse(__version__) >= version.parse("1.0"), reason="Esbonio version >=0.16.0 using pygls >= 1.0 not tested." -) -@pytest.mark.asyncio -async def test_need_auto_generated_id_completion(client): - # check needs option id snippet, auto-generated need IDs, e.g. :id: REQ_e0bafd9b - need_req_options_result = await client.completion_request(uri=TEST_FILE_URI, line=11, character=3) - - option_id_idx = None - for index, item in enumerate(need_req_options_result.items): - if item.label == ":id:": - option_id_idx = index - - assert option_id_idx is not None - needs_option_id = need_req_options_result.items[option_id_idx] - assert needs_option_id.label == ":id:" - assert needs_option_id.detail == "needs option" - assert needs_option_id.insert_text.startswith("id: ${1:REQ_") - assert needs_option_id.insert_text.endswith("}\n$0") - assert needs_option_id.insert_text_format == 2 # InsertTextFormat.Snippet - assert needs_option_id.kind == 15 # CompletionItemKind.Snippet - - -@pytest.mark.skipif( - version.parse(__version__) >= version.parse("1.0"), reason="Esbonio version >=0.16.0 using pygls >= 1.0 not tested." -) -@pytest.mark.asyncio -async def test_need_directive_snippets_completion(client): - # check need directive snippets completion - need_directive_snippets = await client.completion_request(uri=TEST_FILE_URI, line=10, character=2) - assert len(need_directive_snippets.items) > 0 - - req_idx = None - for index, item in enumerate(need_directive_snippets.items): - if item.label == ".. req::": - req_idx = index - assert req_idx is not None - - need_directive_snippets_req = need_directive_snippets.items[req_idx] - assert need_directive_snippets_req.label == ".. req::" - assert need_directive_snippets_req.detail == "Requirement" - assert need_directive_snippets_req.insert_text.startswith(" req:: ${1:title}\n\t:id: ${2:REQ_") - assert need_directive_snippets_req.insert_text.endswith("}\n\t:status: open\n\n\t${3:content}.\n$0") - assert need_directive_snippets_req.insert_text_format == 2 # InsertTextFormat.Snippet - assert need_directive_snippets_req.kind == 15 # CompletionItemKind.Snippet - assert need_directive_snippets_req.data["source_feature"] == "sphinx_needs.lsp.esbonio.NeedlsFeatures" - - -@pytest.mark.skipif( - version.parse(__version__) >= version.parse("1.0"), reason="Esbonio version >=0.16.0 using pygls >= 1.0 not tested." -) -@pytest.mark.asyncio -async def test_need_id_selection_completion(client): - # check need ID selection completion for need type, e.g. :need:`->` - id_selection_need_type_result = await client.completion_request(uri=TEST_FILE_URI, line=26, character=9) - assert len(id_selection_need_type_result.items) == 2 - assert id_selection_need_type_result.items[0].label == "req" - assert id_selection_need_type_result.items[0].detail == "need type" - assert id_selection_need_type_result.items[1].label == "spec" - assert id_selection_need_type_result.items[1].detail == "need type" - - # check need ID selection completion for need file, e.g. :need:`->req>` - id_selection_need_file_result = await client.completion_request(uri=TEST_FILE_URI, line=28, character=13) - assert len(id_selection_need_file_result.items) == 1 - id_selection_need_file = id_selection_need_file_result.items[0] - assert id_selection_need_file.label == "index.rst" - assert id_selection_need_file.detail == "needs doc" - assert id_selection_need_file.insert_text == "index.rst" - assert id_selection_need_file.kind == 17 # CompletionItemKind.File - assert id_selection_need_file.data["source_feature"] == "sphinx_needs.lsp.esbonio.NeedlsFeatures" - - # check need ID selection completion for need ID, e.g. :need:`->req>index.rst>` - id_selection_need_id_result = await client.completion_request(uri=TEST_FILE_URI, line=30, character=23) - assert len(id_selection_need_id_result.items) == 1 - id_selection_need_id = id_selection_need_id_result.items[0] - assert id_selection_need_id.label == "REQ_1" - assert id_selection_need_id.insert_text == "REQ_1" - assert id_selection_need_id.detail == "First requirement" - assert id_selection_need_id.documentation == "Requirement content" - assert id_selection_need_id.data["source_feature"] == "sphinx_needs.lsp.esbonio.NeedlsFeatures" - - -@pytest.mark.skipif( - version.parse(__version__) >= version.parse("1.0"), reason="Esbonio version >=0.16.0 using pygls >= 1.0 not tested." -) -@pytest.mark.asyncio -async def test_goto_definition(client): - # check goto defintion results - location_result = await client.definition_request(uri=TEST_FILE_URI, position=Position(line=24, character=8)) - defined_location = location_result[0] - - assert defined_location.range - assert type(defined_location.range) == Range - - # check defintion location range, e.g. for :need:`REQ_1` at line 25, go to definiton for REQ_1 will - # jump to begining of the definition of REQ_1, which is at line 11, character 0 - assert defined_location.range.start.line == 10 - assert defined_location.range.start.character == 0 - assert defined_location.range.end.line == 10 - assert defined_location.range.end.character == 0 - - -@pytest.mark.skipif( - version.parse(__version__) >= version.parse("1.0"), reason="Esbonio version >=0.16.0 using pygls >= 1.0 not tested." -) -@pytest.mark.asyncio -async def test_hover(client): - # check hover results - hover_directive_result = await client.hover_request(uri=TEST_FILE_URI, position=Position(line=18, character=9)) - assert type(hover_directive_result.contents) == MarkupContent - assert type(hover_directive_result.contents.kind) == MarkupKind - assert hover_directive_result.contents.kind == "markdown" # MarkupKind.Markdown - assert hover_directive_result.contents.value == "**First specification**\n\n```\nSpecification content\n```" - - hover_role_result = await client.hover_request(uri=TEST_FILE_URI, position=Position(line=24, character=8)) - assert type(hover_role_result.contents) == MarkupContent - assert type(hover_role_result.contents.kind) == MarkupKind - assert hover_role_result.contents.kind == "markdown" # MarkupKind.Markdown - assert hover_role_result.contents.value == "\n**First requirement**\n\n```\nRequirement content\n```" diff --git a/tests/test_lsp/test_lsp_custom_directive_snippets.py b/tests/test_lsp/test_lsp_custom_directive_snippets.py deleted file mode 100644 index 09941a70c..000000000 --- a/tests/test_lsp/test_lsp_custom_directive_snippets.py +++ /dev/null @@ -1,88 +0,0 @@ -"""Test Sphinx-Needs language features for custom directive snippets.""" - -import os -import sys - -import pytest -import pytest_lsp -from packaging import version -from pygls import __version__ - -TEST_DOC_ROOT_URI = os.path.join( - "file://", os.path.abspath(os.path.dirname(__file__)), "doc_lsp_custom_directive_snippets" -) -TEST_FILE_URI = os.path.join(TEST_DOC_ROOT_URI, "index.rst") -CONF_PY_CUSTOM_DIRECTIVE_SNIPPETS_REQ = """\ -.. req:: REQ Example - :id: ID - :status: - :custom_option_1: - - random content. -""" -CONF_PY_CUSTOM_DIRECTIVE_SNIPPETS_TEST = """\ -.. test:: Test Title - :id: TEST_ - :status: open - :custom_option: something - - test directive content. -""" - - -@pytest_lsp.fixture( - config=pytest_lsp.ClientServerConfig(server_command=[sys.executable, "-m", "esbonio"], root_uri=TEST_DOC_ROOT_URI), -) -async def client(): - pass - - -@pytest.mark.skipif( - version.parse(__version__) >= version.parse("1.0"), reason="Esbonio version >=0.16.0 using pygls >= 1.0 not tested." -) -@pytest.mark.asyncio -async def test_lsp_custom_directive_snippets(client): - # check need custom directive snippets completion - need_custom_directive_snippets = await client.completion_request(uri=TEST_FILE_URI, line=10, character=2) - assert need_custom_directive_snippets - - req_snippet_idx = None - test_snippet_idx = None - spec_snippet_idx = None - for index, item in enumerate(need_custom_directive_snippets.items): - if item.label == ".. req::": - req_snippet_idx = index - elif item.label == ".. test::": - test_snippet_idx = index - elif item.label == ".. spec::": - spec_snippet_idx = index - - # check custom directive snippets - assert req_snippet_idx is not None - need_custom_directive_snippets_req = need_custom_directive_snippets.items[req_snippet_idx] - assert need_custom_directive_snippets_req.label == ".. req::" - assert need_custom_directive_snippets_req.detail == "Requirement" - assert need_custom_directive_snippets_req.insert_text == CONF_PY_CUSTOM_DIRECTIVE_SNIPPETS_REQ - assert need_custom_directive_snippets_req.insert_text_format == 2 # InsertTextFormat.Snippet - assert need_custom_directive_snippets_req.kind == 15 # CompletionItemKind.Snippet - assert need_custom_directive_snippets_req.data["source_feature"] == "sphinx_needs.lsp.esbonio.NeedlsFeatures" - - assert test_snippet_idx is not None - need_custom_directive_snippets_test = need_custom_directive_snippets.items[test_snippet_idx] - assert need_custom_directive_snippets_test.label == ".. test::" - assert need_custom_directive_snippets_test.detail == "Test Case" - assert need_custom_directive_snippets_test.insert_text == CONF_PY_CUSTOM_DIRECTIVE_SNIPPETS_TEST - assert need_custom_directive_snippets_test.insert_text_format == 2 # nsertTextFormat.Snippet - assert need_custom_directive_snippets_test.kind == 15 # CompletionItemKind.Snippet - assert need_custom_directive_snippets_test.data["source_feature"] == "sphinx_needs.lsp.esbonio.NeedlsFeatures" - - # check default directive snippets - assert spec_snippet_idx is not None - need_custom_directive_snippets_spec = need_custom_directive_snippets.items[spec_snippet_idx] - assert need_custom_directive_snippets_spec.label == ".. spec::" - assert need_custom_directive_snippets_spec.detail == "Specification" - assert need_custom_directive_snippets_spec.insert_text.startswith(" spec:: ${1:title}\n\t:id: ${2:SPEC_") - assert need_custom_directive_snippets_spec.insert_text.endswith("}\n\t:status: open\n\n\t${3:content}.\n$0") - assert need_custom_directive_snippets_spec.insert_text_format == 2 # InsertTextFormat.Snippet - assert need_custom_directive_snippets_spec.kind == 15 # CompletionItemKind.Snippet - assert need_custom_directive_snippets_spec.data["source_feature"] == "sphinx_needs.lsp.esbonio.NeedlsFeatures" diff --git a/tests/test_lsp/test_lsp_custom_need_id_generate_from_title.py b/tests/test_lsp/test_lsp_custom_need_id_generate_from_title.py deleted file mode 100644 index b2336b92e..000000000 --- a/tests/test_lsp/test_lsp_custom_need_id_generate_from_title.py +++ /dev/null @@ -1,60 +0,0 @@ -"""Test Sphinx-Needs language features for custom need ID generation with from_title().""" - -import os -import sys - -import pytest -import pytest_lsp -from packaging import version -from pygls import __version__ - -TEST_DOC_ROOT_URI = os.path.join( - "file://", os.path.abspath(os.path.dirname(__file__)), "doc_lsp_custom_need_id_generate_from_title" -) -TEST_FILE_URI = os.path.join(TEST_DOC_ROOT_URI, "index.rst") - - -@pytest_lsp.fixture( - config=pytest_lsp.ClientServerConfig(server_command=[sys.executable, "-m", "esbonio"], root_uri=TEST_DOC_ROOT_URI), -) -async def client(): - pass - - -@pytest.mark.skipif( - version.parse(__version__) >= version.parse("1.0"), reason="Esbonio version >=0.16.0 using pygls >= 1.0 not tested." -) -@pytest.mark.asyncio -async def test_directive_snippets_with_custom_need_id_generate_from_title(client): - need_directive_snippets = await client.completion_request(uri=TEST_FILE_URI, line=10, character=2) - assert len(need_directive_snippets.items) > 0 - - req_snippet_idx = None - for index, item in enumerate(need_directive_snippets.items): - if item.label == ".. req::": - req_snippet_idx = index - - assert req_snippet_idx is not None - need_directive_snippets_req = need_directive_snippets.items[req_snippet_idx] - assert need_directive_snippets_req.label == ".. req::" - assert need_directive_snippets_req.detail == "Requirement" - assert need_directive_snippets_req.insert_text.startswith(" req:: ${1:title}\n\t:id: ${2:TEST_ID_TEST") - - -@pytest.mark.skipif( - version.parse(__version__) >= version.parse("1.0"), reason="Esbonio version >=0.16.0 using pygls >= 1.0 not tested." -) -@pytest.mark.asyncio -async def test_id_auto_generation_with_custom_id_generate_from_title(client): - need_req_options_result = await client.completion_request(uri=TEST_FILE_URI, line=11, character=3) - - option_id_idx = None - for index, item in enumerate(need_req_options_result.items): - if item.label == ":id:": - option_id_idx = index - - assert option_id_idx is not None - needs_option_id = need_req_options_result.items[option_id_idx] - assert needs_option_id.label == ":id:" - assert needs_option_id.detail == "needs option" - assert needs_option_id.insert_text.startswith("id: ${1:TEST_first_requirement_TEST") diff --git a/tests/test_lsp/test_lsp_custom_need_id_generate_random.py b/tests/test_lsp/test_lsp_custom_need_id_generate_random.py deleted file mode 100644 index 28fa23260..000000000 --- a/tests/test_lsp/test_lsp_custom_need_id_generate_random.py +++ /dev/null @@ -1,62 +0,0 @@ -"""Test Sphinx-Needs language features for custom need ID generation with random().""" - -import os -import sys - -import pytest -import pytest_lsp -from packaging import version -from pygls import __version__ - -TEST_DOC_ROOT_URI = os.path.join( - "file://", os.path.abspath(os.path.dirname(__file__)), "doc_lsp_custom_need_id_generate_random" -) -TEST_FILE_URI = os.path.join(TEST_DOC_ROOT_URI, "index.rst") - - -@pytest_lsp.fixture( - config=pytest_lsp.ClientServerConfig(server_command=[sys.executable, "-m", "esbonio"], root_uri=TEST_DOC_ROOT_URI), -) -async def client(): - pass - - -@pytest.mark.skipif( - version.parse(__version__) >= version.parse("1.0"), reason="Esbonio version >=0.16.0 using pygls >= 1.0 not tested." -) -@pytest.mark.asyncio -async def test_directive_snippets_with_custom_need_id_generate_random(client): - need_directive_snippets = await client.completion_request(uri=TEST_FILE_URI, line=10, character=2) - assert len(need_directive_snippets.items) > 0 - - req_snippet_idx = None - for index, item in enumerate(need_directive_snippets.items): - if item.label == ".. req::": - req_snippet_idx = index - - assert req_snippet_idx is not None - need_directive_snippets_req = need_directive_snippets.items[req_snippet_idx] - assert need_directive_snippets_req.label == ".. req::" - assert need_directive_snippets_req.detail == "Requirement" - assert need_directive_snippets_req.insert_text.startswith(" req:: ${1:title}\n\t:id: ${2:Test_REQ_") - assert "_Test" in need_directive_snippets_req.insert_text - - -@pytest.mark.skipif( - version.parse(__version__) >= version.parse("1.0"), reason="Esbonio version >=0.16.0 using pygls >= 1.0 not tested." -) -@pytest.mark.asyncio -async def test_id_auto_generation_with_custom_id_generate_random(client): - need_req_options_result = await client.completion_request(uri=TEST_FILE_URI, line=11, character=3) - - option_id_idx = None - for index, item in enumerate(need_req_options_result.items): - if item.label == ":id:": - option_id_idx = index - - assert option_id_idx is not None - needs_option_id = need_req_options_result.items[option_id_idx] - assert needs_option_id.label == ":id:" - assert needs_option_id.detail == "needs option" - assert needs_option_id.insert_text.startswith("id: ${1:Test_REQ_") - assert needs_option_id.insert_text.endswith("_Test}\n$0") diff --git a/tests/test_lsp/test_lsp_support_MyST.py b/tests/test_lsp/test_lsp_support_MyST.py deleted file mode 100644 index 328e98b6e..000000000 --- a/tests/test_lsp/test_lsp_support_MyST.py +++ /dev/null @@ -1,308 +0,0 @@ -"""Test Sphinx-Needs language features MyST/Markdown support.""" - -import os -import sys - -import pytest -import pytest_lsp -from packaging import version -from pygls import __version__ - -if version.parse(__version__) < version.parse("1.0"): - from pygls.lsp.types import MarkupContent, MarkupKind, Position, Range -else: - from lsprotocol.types import MarkupContent, MarkupKind, Position, Range - -TEST_DOC_ROOT_URI = os.path.join("file://", os.path.abspath(os.path.dirname(__file__)), "doc_lsp_support_MyST") -TEST_MD_FILE_URI = os.path.join(TEST_DOC_ROOT_URI, "myfile.md") - - -@pytest_lsp.fixture( - config=pytest_lsp.ClientServerConfig(server_command=[sys.executable, "-m", "esbonio"], root_uri=TEST_DOC_ROOT_URI), -) -async def client(): - pass - - -@pytest.mark.skipif( - version.parse(__version__) >= version.parse("1.0"), reason="Esbonio version >=0.16.0 using pygls >= 1.0 not tested." -) -@pytest.mark.asyncio -async def test_lsp_goto_definition_support_for_myst(client): - # Check Goto Defintion support for MySt/Markdown file, e.g. myfile.md - goto_md = await client.definition_request(uri=TEST_MD_FILE_URI, position=Position(line=19, character=8)) - goto_md_location = goto_md[0] - - assert goto_md_location.range - assert type(goto_md_location.range) == Range - - # check defintion location range, e.g. location of SPEC_2 - assert goto_md_location.range.start.line == 12 - assert goto_md_location.range.start.character == 0 - assert goto_md_location.range.end.line == 12 - assert goto_md_location.range.end.character == 0 - - # Check Goto defintion jump location in another markdown file, e.g. md_subfolder/MySecond.md - goto_md_subfolder = await client.definition_request(uri=TEST_MD_FILE_URI, position=Position(line=21, character=8)) - goto_md_subfolder_location = goto_md_subfolder[0] - - assert goto_md_subfolder_location.range - assert type(goto_md_subfolder_location.range) == Range - - # check defintion location range, e.g. location of REQ_3 - assert goto_md_subfolder_location.uri.endswith("MySecond.md") - assert goto_md_subfolder_location.range.start.line == 2 - assert goto_md_subfolder_location.range.start.character == 0 - assert goto_md_subfolder_location.range.end.line == 2 - assert goto_md_subfolder_location.range.end.character == 0 - - # Check Goto definition jump location in another rst file, e.g. index.rst - goto_rst = await client.definition_request(uri=TEST_MD_FILE_URI, position=Position(line=23, character=8)) - goto_rst_location = goto_rst[0] - - assert goto_rst_location.range - assert type(goto_rst_location.range) == Range - - # check defintion location range, e.g. location of REQ_1 - assert goto_rst_location.uri.endswith("index.rst") - assert goto_rst_location.range.start.line == 10 - assert goto_rst_location.range.start.character == 0 - assert goto_rst_location.range.end.line == 10 - assert goto_rst_location.range.end.character == 0 - - -@pytest.mark.skipif( - version.parse(__version__) >= version.parse("1.0"), reason="Esbonio version >=0.16.0 using pygls >= 1.0 not tested." -) -@pytest.mark.asyncio -async def test_lsp_hover_support_for_myst(client): - # Check Hover support for MyST/Markdown file - hover_directive_result = await client.hover_request(uri=TEST_MD_FILE_URI, position=Position(line=6, character=9)) - assert type(hover_directive_result.contents) == MarkupContent - assert type(hover_directive_result.contents.kind) == MarkupKind - assert hover_directive_result.contents.kind == "markdown" # MarkupKind.Markdown - assert hover_directive_result.contents.value == "**MD REQ Title**\n\n```\nsome stuff from md req.\n```" - - # Check Hover support for need in another markdown file, e.g. REQ_3 - hover_directive_another_file = await client.hover_request( - uri=TEST_MD_FILE_URI, position=Position(line=21, character=8) - ) - assert type(hover_directive_another_file.contents) == MarkupContent - assert type(hover_directive_another_file.contents.kind) == MarkupKind - assert hover_directive_another_file.contents.kind == "markdown" # MarkupKind.Markdown - assert ( - hover_directive_another_file.contents.value - == "\n**Sub MD Req title**\n\n```\nMD in Subfolder with some req content.\n```" - ) - - -@pytest.mark.skipif( - version.parse(__version__) >= version.parse("1.0"), reason="Esbonio version >=0.16.0 using pygls >= 1.0 not tested." -) -@pytest.mark.asyncio -async def test_lsp_id_selection_completion_support_for_myst(client): - # Check ID selection completion support for MyST/Markdown file - # 1. for rst/Sphinx style: :need:`->` - # 2. for MyST/Markdown style: {need}`->` - - # check need type suggestion for :need:`->` - need_type_rst = await client.completion_request(uri=TEST_MD_FILE_URI, line=25, character=9) - assert len(need_type_rst.items) == 2 - assert need_type_rst.items[0].label == "req" - assert need_type_rst.items[0].detail == "need type" - assert need_type_rst.items[1].label == "spec" - assert need_type_rst.items[1].detail == "need type" - - # check need file path suggestion for :need:`->req>` - need_file_path_rst = await client.completion_request(uri=TEST_MD_FILE_URI, line=27, character=13) - assert len(need_file_path_rst.items) == 3 - - need_file_path_rst_option_1 = need_file_path_rst.items[0] - assert need_file_path_rst_option_1.label == "index.rst" - assert need_file_path_rst_option_1.detail == "path to needs doc" - assert need_file_path_rst_option_1.kind == 17 # CompletionItemKind.File - assert need_file_path_rst_option_1.data["source_feature"] == "sphinx_needs.lsp.esbonio.NeedlsFeatures" - - need_file_path_rst_option_2 = need_file_path_rst.items[1] - assert need_file_path_rst_option_2.label == "md_subfolder" - assert need_file_path_rst_option_2.kind == 19 # CompletionItemKind.Folder - - need_file_path_rst_option_3 = need_file_path_rst.items[2] - assert need_file_path_rst_option_3.label == "myfile.md" - assert need_file_path_rst_option_3.kind == 17 # CompletionItemKind.File - - # check need file path suggestion containing subfolder for :need:`->req>md_subfolder/` - need_file_path_subfolder_rst = await client.completion_request(uri=TEST_MD_FILE_URI, line=31, character=26) - assert len(need_file_path_subfolder_rst.items) == 1 - assert need_file_path_subfolder_rst.items[0].label == "MySecond.md" - assert need_file_path_subfolder_rst.items[0].detail == "needs doc" - assert need_file_path_subfolder_rst.items[0].insert_text == "MySecond.md" - assert need_file_path_subfolder_rst.items[0].kind == 17 # CompletionItemKind.File - - # check need ID suggestion for :need:`->req>md_subfolder/MySecond.md>` - need_id_rst = await client.completion_request(uri=TEST_MD_FILE_URI, line=33, character=38) - assert len(need_id_rst.items) == 1 - assert need_id_rst.items[0].label == "REQ_3" - assert need_id_rst.items[0].insert_text == "REQ_3" - assert need_id_rst.items[0].detail == "Sub MD Req title" - assert need_id_rst.items[0].documentation == "MD in Subfolder with some req content." - - # check need type suggestion for {need}`->` - need_type_md = await client.completion_request(uri=TEST_MD_FILE_URI, line=35, character=9) - assert len(need_type_md.items) == 2 - assert need_type_md.items[0].label == "req" - assert need_type_md.items[0].detail == "need type" - assert need_type_md.items[1].label == "spec" - assert need_type_md.items[1].detail == "need type" - - # check need file path suggestion for {need}`->req>` - need_file_path_md = await client.completion_request(uri=TEST_MD_FILE_URI, line=37, character=13) - assert len(need_file_path_md.items) == 3 - - need_file_path_md_option_1 = need_file_path_md.items[0] - assert need_file_path_md_option_1.label == "index.rst" - assert need_file_path_md_option_1.detail == "path to needs doc" - assert need_file_path_md_option_1.kind == 17 # CompletionItemKind.File - assert need_file_path_md_option_1.data["source_feature"] == "sphinx_needs.lsp.esbonio.NeedlsFeatures" - - need_file_path_md_option_2 = need_file_path_md.items[1] - assert need_file_path_md_option_2.label == "md_subfolder" - assert need_file_path_md_option_2.kind == 19 # CompletionItemKind.Folder - - need_file_path_md_option_3 = need_file_path_md.items[2] - assert need_file_path_md_option_3.label == "myfile.md" - assert need_file_path_md_option_3.kind == 17 # CompletionItemKind.File - - # check need ID suggestion for :need:`->req>myfile.md>` - need_id_md = await client.completion_request(uri=TEST_MD_FILE_URI, line=29, character=23) - assert len(need_id_md.items) == 1 - need_id_md_result = need_id_md.items[0] - assert need_id_md_result.label == "REQ_2" - assert need_id_md_result.insert_text == "REQ_2" - assert need_id_md_result.detail == "MD REQ Title" - assert need_id_md_result.documentation == "some stuff from md req." - assert need_id_md_result.data["source_feature"] == "sphinx_needs.lsp.esbonio.NeedlsFeatures" - - -@pytest.mark.skipif( - version.parse(__version__) >= version.parse("1.0"), reason="Esbonio version >=0.16.0 using pygls >= 1.0 not tested." -) -@pytest.mark.asyncio -async def test_lsp_need_directive_snippets_completion_for_myst(client): - # Check need directive snippets support for MyST/Markdown - needs_directive_snippets_suggestion = await client.completion_request(uri=TEST_MD_FILE_URI, line=47, character=2) - assert needs_directive_snippets_suggestion.items - - req_md_idx = None - spec_md_idx = None - for index, item in enumerate(needs_directive_snippets_suggestion.items): - if item.label == "md:.. req::": - req_md_idx = index - elif item.label == "md:.. spec::": - spec_md_idx = index - - assert req_md_idx is not None - needs_directive_req_md = needs_directive_snippets_suggestion.items[req_md_idx] - assert needs_directive_req_md.label == "md:.. req::" - assert needs_directive_req_md.detail == "Markdown directive snippet" - assert needs_directive_req_md.insert_text.startswith("```{req} ${1:title}\n:id: ${2:REQ_") - assert needs_directive_req_md.insert_text.endswith("}\n:status: open\n\n${3:content}.\n```$0") - assert needs_directive_req_md.insert_text_format == 2 # InsertTextFormat.Snippet - assert needs_directive_req_md.kind == 15 # CompletionItemKind.Snippet - assert needs_directive_req_md.data["source_feature"] == "sphinx_needs.lsp.esbonio.NeedlsFeatures" - - assert spec_md_idx is not None - needs_directive_spec_md = needs_directive_snippets_suggestion.items[spec_md_idx] - assert needs_directive_spec_md.label == "md:.. spec::" - assert needs_directive_spec_md.detail == "Markdown directive snippet" - assert needs_directive_spec_md.insert_text.startswith("```{spec} ${1:title}\n:id: ${2:SPEC_") - assert needs_directive_spec_md.insert_text.endswith("}\n:status: open\n\n${3:content}.\n```$0") - assert needs_directive_spec_md.insert_text_format == 2 # InsertTextFormat.Snippet - assert needs_directive_spec_md.kind == 15 # CompletionItemKind.Snippet - assert needs_directive_spec_md.data["source_feature"] == "sphinx_needs.lsp.esbonio.NeedlsFeatures" - - # check need directive snippets inside block {eval-rst} - needs_directive_snippets_inside_eval_rst_suggestion = await client.completion_request( - uri=TEST_MD_FILE_URI, line=5, character=2 - ) - assert needs_directive_snippets_inside_eval_rst_suggestion.items - - req_md_in_eval_rst_idx = None - spec_md_in_eval_rst_idx = None - for index, item in enumerate(needs_directive_snippets_inside_eval_rst_suggestion.items): - if item.label == ".. req::": - req_md_in_eval_rst_idx = index - elif item.label == ".. spec::": - spec_md_in_eval_rst_idx = index - - assert req_md_in_eval_rst_idx is not None - needs_directive_req_md_inside_eval_rst = needs_directive_snippets_inside_eval_rst_suggestion.items[ - req_md_in_eval_rst_idx - ] - assert needs_directive_req_md_inside_eval_rst.label == ".. req::" - assert needs_directive_req_md_inside_eval_rst.detail == "Requirement" - assert needs_directive_req_md_inside_eval_rst.insert_text.startswith(" req:: ${1:title}\n\t:id: ${2:REQ_") - assert needs_directive_req_md_inside_eval_rst.insert_text.endswith("}\n\t:status: open\n\n\t${3:content}.\n$0") - assert needs_directive_req_md_inside_eval_rst.insert_text_format == 2 # InsertTextFormat.Snippet - assert needs_directive_req_md_inside_eval_rst.kind == 15 # CompletionItemKind.Snippet - assert needs_directive_req_md_inside_eval_rst.data["source_feature"] == "sphinx_needs.lsp.esbonio.NeedlsFeatures" - - assert spec_md_in_eval_rst_idx is not None - needs_directive_spec_md_inside_eval_rst = needs_directive_snippets_inside_eval_rst_suggestion.items[ - spec_md_in_eval_rst_idx - ] - assert needs_directive_spec_md_inside_eval_rst.label == ".. spec::" - assert needs_directive_spec_md_inside_eval_rst.detail == "Specification" - assert needs_directive_spec_md_inside_eval_rst.insert_text.startswith(" spec:: ${1:title}\n\t:id: ${2:SPEC_") - assert needs_directive_spec_md_inside_eval_rst.insert_text.endswith("}\n\t:status: open\n\n\t${3:content}.\n$0") - assert needs_directive_spec_md_inside_eval_rst.insert_text_format == 2 # InsertTextFormat.Snippet - assert needs_directive_spec_md_inside_eval_rst.kind == 15 # CompletionItemKind.Snippet - assert needs_directive_spec_md_inside_eval_rst.data["source_feature"] == "sphinx_needs.lsp.esbonio.NeedlsFeatures" - - -@pytest.mark.skipif( - version.parse(__version__) >= version.parse("1.0"), reason="Esbonio version >=0.16.0 using pygls >= 1.0 not tested." -) -@pytest.mark.asyncio -async def test_lsp_needs_option_id_completion_for_myst(client): - # Needs option id suggestion is the same for MyST/Markdown as for rst/Sphinx file, e.g. :id: - needs_option_suggestion = await client.completion_request(uri=TEST_MD_FILE_URI, line=13, character=1) - assert needs_option_suggestion.items - - option_id_idx = None - for index, item in enumerate(needs_option_suggestion.items): - if item.label == ":id:": - option_id_idx = index - - assert option_id_idx is not None - needs_option_id = needs_option_suggestion.items[option_id_idx] - assert needs_option_id.label == ":id:" - assert needs_option_id.detail == "needs option" - assert needs_option_id.insert_text.startswith("id: ${1:SPEC_") - assert needs_option_id.insert_text.endswith("}\n$0") - assert needs_option_id.insert_text_format == 2 # InsertTextFormat.Snippet - assert needs_option_id.kind == 15 # CompletionItemKind.Snippet - - -@pytest.mark.skipif( - version.parse(__version__) >= version.parse("1.0"), reason="Esbonio version >=0.16.0 using pygls >= 1.0 not tested." -) -@pytest.mark.asyncio -async def test_lsp_need_role_need_completion_for_myst(client): - # Need role need support for MyST/Markdown file - # Same usage like rst file, but will be adapted to MyST/Markdown style, which isinsert {need}`` instead of :need: - need_role_need_suggestion = await client.completion_request(uri=TEST_MD_FILE_URI, line=45, character=1) - assert need_role_need_suggestion.items - - need_role_idx = None - for index, item in enumerate(need_role_need_suggestion.items): - if item.label == "md::need:": - need_role_idx = index - - assert need_role_idx is not None - need_role_need = need_role_need_suggestion.items[need_role_idx] - assert need_role_need.label == "md::need:" - assert need_role_need.detail == "Markdown need role" - assert need_role_need.insert_text == "{need}`${1:ID}`$0" - assert need_role_need.insert_text_format == 2 # InsertTextFormat.Snippet - assert need_role_need.kind == 15 # CompletionItemKind.Snippet From 390dd3643909afe5bfe2d675c0a79d4b6b65d429 Mon Sep 17 00:00:00 2001 From: Christian Polzer Date: Wed, 31 May 2023 09:48:46 +0200 Subject: [PATCH 15/48] enable docker arm builds --- .github/workflows/docker.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index 536d309ee..027c58503 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -67,6 +67,8 @@ jobs: with: push: ${{ github.event_name != 'pull_request' && steps.deploycheck.outputs.value == 'y' }} file: docker/Dockerfile + context: ci + platforms: linux/amd64,linux/arm64 build-args: | NEEDS_VERSION=${{ env.NEEDS_VERSION }} BASE_IMAGE=${{ matrix.base-image }} From 7177c0346608eb6c0e45b2886a24047a42c127cc Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Wed, 2 Aug 2023 14:59:50 +0200 Subject: [PATCH 16/48] =?UTF-8?q?=F0=9F=94=A7=20Add=20.nox=20to=20gitignor?= =?UTF-8?q?e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 981b47541..76e8f917d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ .idea .venv* .pvenv - +.nox node_modules .envrc From 61dcbef93b2331ffd810cb4337b4e7b90e28d662 Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Thu, 3 Aug 2023 16:42:23 +0200 Subject: [PATCH 17/48] Update pyproject.toml --- pyproject.toml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index a5283157f..44c395208 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -127,10 +127,6 @@ module = [ ] ignore_errors = true -[tool.poetry.extras] -docs = ["sphinx"] -immaterial = ["sphinx-immaterial"] - [build-system] requires = ["setuptools", "poetry_core>=1.0.8"] # setuptools for deps like plantuml build-backend = "poetry.core.masonry.api" From 98030a86c12e6e31fb576d46e9af07f7486e5793 Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Thu, 3 Aug 2023 16:42:43 +0200 Subject: [PATCH 18/48] Update pyproject.toml --- pyproject.toml | 2 -- 1 file changed, 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 44c395208..f948649dd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -59,8 +59,6 @@ types-requests = "^2.27.25" types-setuptools = "^65.6.0.2" docutils-stubs = "^0.0.22" -sphinx-immaterial = { version = "==0.7.3", optional = true } - # formatting dependencies black = "^22.3" isort = "^5.7.0" From 25d42f0f60a817dd790938cf2a1cb7530f7bf8fe Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Thu, 3 Aug 2023 16:48:27 +0200 Subject: [PATCH 19/48] Update requirements.txt --- docs/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index d08b317e5..b99f33ee9 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -7,4 +7,4 @@ sphinxcontrib-programoutput sphinx-design click tabulate -sphinx-immaterial==0.11.2 \ No newline at end of file +sphinx-immaterial==0.11.6 \ No newline at end of file From 994b6b109c4a54d25c911a0d453209de1857eeb2 Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Thu, 3 Aug 2023 16:55:14 +0200 Subject: [PATCH 20/48] Update api.rst --- docs/api.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api.rst b/docs/api.rst index ec967bdab..ab24b442b 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -11,7 +11,7 @@ to keep the final configuration transparent for the Sphinx project authors. For some implementation ideas, take a look into the Sphinx extension `Sphinx-Test-Reports `_ and its -`source code `_. +`source code `_. .. _api_configuration: From 4f5d1857a9808afea0b55b5fe9bb11fbb6850aaa Mon Sep 17 00:00:00 2001 From: Haiyang Date: Thu, 3 Aug 2023 17:39:37 +0200 Subject: [PATCH 21/48] Added config allow unsafe filter for filter_func (#949) * Added config allow unsafe filter for filter_func * Fixed review * Updated sphinx-immaterial to fix CI * Fix linkcheck anchor issue --------- Co-authored-by: Daniel Woste --- docs/changelog.rst | 3 + docs/configuration.rst | 21 +++++++ docs/requirements.txt | 2 +- sphinx_needs/filter_common.py | 14 +++-- sphinx_needs/needs.py | 1 + .../Makefile | 20 +++++++ .../conf.py | 57 +++++++++++++++++++ .../filter_func.py | 14 +++++ .../index.rst | 31 ++++++++++ .../make.bat | 36 ++++++++++++ tests/test_unsafe_filter_for_filter_func.py | 20 +++++++ 11 files changed, 213 insertions(+), 6 deletions(-) create mode 100644 tests/doc_test/doc_needs_filter_func_allow_dirty_filter/Makefile create mode 100644 tests/doc_test/doc_needs_filter_func_allow_dirty_filter/conf.py create mode 100644 tests/doc_test/doc_needs_filter_func_allow_dirty_filter/filter_func.py create mode 100644 tests/doc_test/doc_needs_filter_func_allow_dirty_filter/index.rst create mode 100644 tests/doc_test/doc_needs_filter_func_allow_dirty_filter/make.bat create mode 100644 tests/test_unsafe_filter_for_filter_func.py diff --git a/docs/changelog.rst b/docs/changelog.rst index ee75cb204..0214052a6 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -31,6 +31,9 @@ Released: under development * Removed configuration **needs_ide_directive_snippets** to support custom directive snippets for IDE features. * Provided new IDE support option: VsCode extension `Sphinx-Needs-VsCode `_. +* Improvement: Configuration option :ref:`needs_allow_unsafe_filters` added, which allows unsafe filter for + :ref:`filter_func`. + (`#831 `_) 1.2.2 ----- diff --git a/docs/configuration.rst b/docs/configuration.rst index a0a813644..2d4b80534 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -520,6 +520,27 @@ The defined extra filter data can also be used like: :style: green_border +.. _needs_allow_unsafe_filters: + +needs_allow_unsafe_filters +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Allow unsafe filter for :ref:`filter_func`. Default is ``False``. + +If set to True, the filtered results will keep all fields as they are returned by the dynamic functions. +Fields can be added or existing fields can even be manipulated. + +.. note:: + + Keep in mind this only affects the filter results, original needs as displayed somewhere else are not modified. + +If set to False, the filter results contains the original need fields and any manipulations of need fields are lost. + +|ex| + +.. code-block:: python + + needs_allow_unsafe_filters = True .. _needs_flow_show_links: diff --git a/docs/requirements.txt b/docs/requirements.txt index b99f33ee9..633d78ae6 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -7,4 +7,4 @@ sphinxcontrib-programoutput sphinx-design click tabulate -sphinx-immaterial==0.11.6 \ No newline at end of file +sphinx-immaterial==0.11.6 diff --git a/sphinx_needs/filter_common.py b/sphinx_needs/filter_common.py index 98a827dcc..250bc40aa 100644 --- a/sphinx_needs/filter_common.py +++ b/sphinx_needs/filter_common.py @@ -173,11 +173,15 @@ def process_filters(app: Sphinx, all_needs, current_needlist, include_external: found_dirty_needs = context["results"] found_needs = [] - # Just take the ids from search result and use the related, but original need - found_need_ids = [x["id_complete"] for x in found_dirty_needs] - for need in all_needs_incl_parts: - if need["id_complete"] in found_need_ids: - found_needs.append(need) + # Check if config allow unsafe filters + if app.config.needs_allow_unsafe_filters: + found_needs = found_dirty_needs + else: + # Just take the ids from search result and use the related, but original need + found_need_ids = [x["id_complete"] for x in found_dirty_needs] + for need in all_needs_incl_parts: + if need["id_complete"] in found_need_ids: + found_needs.append(need) # Store basic filter configuration and result global list. # Needed mainly for exporting the result to needs.json (if builder "needs" is used). diff --git a/sphinx_needs/needs.py b/sphinx_needs/needs.py index d3334630e..559f1c230 100644 --- a/sphinx_needs/needs.py +++ b/sphinx_needs/needs.py @@ -225,6 +225,7 @@ def setup(app: Sphinx) -> Dict[str, Any]: app.add_config_value("needs_extra_links", [], "html") app.add_config_value("needs_filter_data", {}, "html") + app.add_config_value("needs_allow_unsafe_filters", False, "html") app.add_config_value("needs_flow_show_links", False, "html") app.add_config_value("needs_flow_link_types", ["links"], "html") diff --git a/tests/doc_test/doc_needs_filter_func_allow_dirty_filter/Makefile b/tests/doc_test/doc_needs_filter_func_allow_dirty_filter/Makefile new file mode 100644 index 000000000..47330b89c --- /dev/null +++ b/tests/doc_test/doc_needs_filter_func_allow_dirty_filter/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +SPHINXPROJ = needstestdocs +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file diff --git a/tests/doc_test/doc_needs_filter_func_allow_dirty_filter/conf.py b/tests/doc_test/doc_needs_filter_func_allow_dirty_filter/conf.py new file mode 100644 index 000000000..26ae8d25a --- /dev/null +++ b/tests/doc_test/doc_needs_filter_func_allow_dirty_filter/conf.py @@ -0,0 +1,57 @@ +# Configuration file for Sphinx-Needs Documentation. + +import os +import sys + +sys.path.insert(0, os.path.abspath(os.path.dirname(__file__))) + +# -- General configuration ------------------------------------------------ + +project = "Useblocks Sphinx-Needs Test" +copyright = "2023, Useblocks GmbH" +author = "Teams Useblocks" +version = "1.0" + +extensions = ["sphinx_needs", "sphinxcontrib.plantuml"] + +needs_id_regex = "^[A-Za-z0-9_]*" + +needs_types = [ + {"directive": "feature", "title": "Feature", "prefix": "FE_", "color": "#FEDCD2", "style": "node"}, + {"directive": "usecase", "title": "Use Case", "prefix": "USE_", "color": "#DF744A", "style": "node"}, +] + +needs_extra_options = ["ti", "tcl"] + +needs_extra_links = [ + { + "option": "features", + "incoming": "featured by", + "outgoing": "features", + "copy": False, + "style": "#Gold", + "style_part": "#Gold", + }, +] + +needs_allow_unsafe_filters = True + +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] + +# Doc info +source_suffix = ".rst" +master_doc = "index" +language = "en" + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This patterns also effect to html_static_path and html_extra_path +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = "alabaster" diff --git a/tests/doc_test/doc_needs_filter_func_allow_dirty_filter/filter_func.py b/tests/doc_test/doc_needs_filter_func_allow_dirty_filter/filter_func.py new file mode 100644 index 000000000..da1341200 --- /dev/null +++ b/tests/doc_test/doc_needs_filter_func_allow_dirty_filter/filter_func.py @@ -0,0 +1,14 @@ +def my_own_filter(needs, results, **kwargs): + needs_dict = {x["id"]: x for x in needs} + curr_need_id = kwargs["arg1"] + link_type = kwargs["arg2"] + + for link_id in needs_dict[curr_need_id][link_type]: + if needs_dict[curr_need_id]["ti"] == "1": + needs_dict[link_id]["tcl"] = "10" + elif needs_dict[curr_need_id]["ti"] == "3": + needs_dict[link_id]["tcl"] = "30" + else: + needs_dict[link_id]["tcl"] = "unknown" + + results.append(needs_dict[link_id]) diff --git a/tests/doc_test/doc_needs_filter_func_allow_dirty_filter/index.rst b/tests/doc_test/doc_needs_filter_func_allow_dirty_filter/index.rst new file mode 100644 index 000000000..8f86c9479 --- /dev/null +++ b/tests/doc_test/doc_needs_filter_func_allow_dirty_filter/index.rst @@ -0,0 +1,31 @@ +Needs Data to be filtered +========================= + +.. feature:: Feature 001 + :id: FE_001 + + Example feature 001 content. + +.. usecase:: Usecase 001 + :id: USE_001 + :ti: 1 + :features: FE_001 + + Example tesusecaset 001 content. + + .. needtable:: Filter func table 001 + :style: table + :columns: id, title, tcl + :filter-func: filter_func.my_own_filter(USE_001,features) + +.. usecase:: Usecase 002 + :id: USE_002 + :ti: 3 + :features: FE_001 + + Example usecase 002 content. + + .. needtable:: Filter func table 002 + :style: table + :columns: id, title, tcl + :filter-func: filter_func.my_own_filter(USE_002,features) diff --git a/tests/doc_test/doc_needs_filter_func_allow_dirty_filter/make.bat b/tests/doc_test/doc_needs_filter_func_allow_dirty_filter/make.bat new file mode 100644 index 000000000..489ed7dfd --- /dev/null +++ b/tests/doc_test/doc_needs_filter_func_allow_dirty_filter/make.bat @@ -0,0 +1,36 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build +set SPHINXPROJ=needstestdocs + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% + +:end +popd diff --git a/tests/test_unsafe_filter_for_filter_func.py b/tests/test_unsafe_filter_for_filter_func.py new file mode 100644 index 000000000..006784f09 --- /dev/null +++ b/tests/test_unsafe_filter_for_filter_func.py @@ -0,0 +1,20 @@ +from pathlib import Path + +import pytest + + +@pytest.mark.parametrize( + "test_app", [{"buildername": "html", "srcdir": "doc_test/doc_needs_filter_func_allow_dirty_filter"}], indirect=True +) +def test_doc_allow_unsafe_filter_for_filter_func(test_app): + app = test_app + app.build() + index_html = Path(app.outdir, "index.html").read_text() + + assert 'Filter func table 001' in index_html + assert '

Feature 001

' in index_html + assert '

10

' in index_html + + assert 'Filter func table 002' in index_html + assert '

Feature 001

' in index_html + assert '

30

' in index_html From 78aedd7cc9b02e1231a03978478ea78edc0e4862 Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Fri, 4 Aug 2023 09:17:54 +0200 Subject: [PATCH 22/48] =?UTF-8?q?=F0=9F=94=A7=20Update=20pre-commit=20hook?= =?UTF-8?q?s=20(#956)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 8 ++++---- noxfile.py | 7 +++++++ sphinx_needs/api/need.py | 3 --- sphinx_needs/directives/needextend.py | 1 - sphinx_needs/directives/needextract.py | 1 - sphinx_needs/need_constraints.py | 4 ---- sphinx_needs/services/open_needs.py | 1 - tests/test_layouts.py | 1 - tests/test_needs_external_needs_build.py | 2 -- tests/test_role_need_max_title_length.py | 2 -- tests/test_services/test_service_basics.py | 2 -- tests/test_title_from_content.py | 1 - tests/test_title_optional.py | 1 - 13 files changed, 11 insertions(+), 23 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 016660f79..fcc989675 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,11 +1,11 @@ repos: - repo: https://github.com/psf/black - rev: 22.12.0 + rev: 23.7.0 hooks: - id: black - repo: https://github.com/PyCQA/flake8 - rev: 6.0.0 + rev: 6.1.0 hooks: - id: flake8 additional_dependencies: @@ -20,7 +20,7 @@ repos: - id: isort - repo: https://github.com/asottile/pyupgrade - rev: v3.3.1 + rev: v3.10.1 hooks: - id: pyupgrade args: @@ -36,6 +36,6 @@ repos: pass_filenames: false - repo: https://github.com/python-poetry/poetry - rev: 1.3.0 + rev: 1.5.0 hooks: - id: poetry-check diff --git a/noxfile.py b/noxfile.py index 01c35262a..0310406d5 100644 --- a/noxfile.py +++ b/noxfile.py @@ -97,3 +97,10 @@ def benchmark_memory(session): env={"ON_CI": "true", "FAST_BUILD": "true"}, ) session.run("memray", "flamegraph", "-o", "mem_out.html", "mem_out.bin") + + +@session(python="3.8") +def pre_commit(session): + session.run_always("poetry", "install", external=True) + session.install("pre-commit") + session.run("pre-commit", "run", "--all-files", external=True) diff --git a/sphinx_needs/api/need.py b/sphinx_needs/api/need.py index a143bde28..7ff872d94 100644 --- a/sphinx_needs/api/need.py +++ b/sphinx_needs/api/need.py @@ -210,7 +210,6 @@ def run(): if tags is None: tags = [] if len(tags) > 0: - # tags should be a string, but it can also be already a list, which can be used. if isinstance(tags, str): tags = [tag.strip() for tag in re.split("[;,]", tags)] @@ -238,7 +237,6 @@ def run(): if constraints is None: constraints = [] if len(constraints) > 0: - # tags should be a string, but it can also be already a list,which can be used. if isinstance(constraints, str): constraints = [constraint.strip() for constraint in re.split("[;,]", constraints)] @@ -733,7 +731,6 @@ def _merge_global_options(app: Sphinx, needs_info, global_options) -> None: if global_options is None: return for key, value in global_options.items(): - # If key already exists in needs_info, this global_option got overwritten manually in current need if key in needs_info and needs_info[key]: continue diff --git a/sphinx_needs/directives/needextend.py b/sphinx_needs/directives/needextend.py index b7d8e1b5e..4bb7400fb 100644 --- a/sphinx_needs/directives/needextend.py +++ b/sphinx_needs/directives/needextend.py @@ -94,7 +94,6 @@ def process_needextend(app: Sphinx, doctree: nodes.document, fromdocname: str) - link_names = [x["option"] for x in app.config.needs_extra_links] for current_needextend in env.need_all_needextend.values(): - # Check if filter is just a need-id. # In this case create the needed filter string need_filter = current_needextend["filter"] diff --git a/sphinx_needs/directives/needextract.py b/sphinx_needs/directives/needextract.py index 7a732633e..c02c10cb1 100644 --- a/sphinx_needs/directives/needextract.py +++ b/sphinx_needs/directives/needextract.py @@ -79,7 +79,6 @@ def process_needextract(app: Sphinx, doctree: nodes.document, fromdocname: str, env = unwrap(app.env) for node in found_nodes: - if not app.config.needs_include_needs: # Ok, this is really dirty. # If we replace a node, docutils checks, if it will not lose any attributes. diff --git a/sphinx_needs/need_constraints.py b/sphinx_needs/need_constraints.py index 87cf6b8ae..ca5f2ebe4 100644 --- a/sphinx_needs/need_constraints.py +++ b/sphinx_needs/need_constraints.py @@ -24,14 +24,12 @@ def process_constraints(app: Sphinx, need: Dict[str, Any]) -> None: constraints = need["constraints"] for constraint in constraints: - # check if constraint is defined in config if constraint not in config_constraints.keys(): raise NeedsConstraintNotAllowed( f"Constraint {constraint} of need id {need_id} is not allowed by config value 'needs_constraints'." ) else: - # access constraints defined in conf.py executable_constraints = config_constraints[constraint] @@ -42,7 +40,6 @@ def process_constraints(app: Sphinx, need: Dict[str, Any]) -> None: for name, cmd in executable_constraints.items(): # compile constraint and check single need if it fulfills constraint if name != "severity": - # check current need if it meets constraint given in check_0, check_1 in conf.py ... constraint_passed = filter_single_need(app, need, cmd) results_list.append(constraint_passed) @@ -76,7 +73,6 @@ def process_constraints(app: Sphinx, need: Dict[str, Any]) -> None: ) if "break" in actions_on_fail: - raise NeedsConstraintFailed( f"FAILED a breaking constraint: >> {cmd} << for need " f"{need_id} FAILED! breaking build process" diff --git a/sphinx_needs/services/open_needs.py b/sphinx_needs/services/open_needs.py index 4733eb7e2..a5d9512ae 100644 --- a/sphinx_needs/services/open_needs.py +++ b/sphinx_needs/services/open_needs.py @@ -22,7 +22,6 @@ class OpenNeedsService(BaseService): options = CONFIG_OPTIONS + EXTRA_DATA_OPTIONS + EXTRA_LINK_OPTIONS def __init__(self, app: Sphinx, name: str, config: Dict[str, Any], **kwargs: Any) -> None: - self.app = app self.name = name self.config = config diff --git a/tests/test_layouts.py b/tests/test_layouts.py index 28639c679..e20aca3f7 100644 --- a/tests/test_layouts.py +++ b/tests/test_layouts.py @@ -8,7 +8,6 @@ @pytest.mark.parametrize("test_app", [{"buildername": "html", "srcdir": "doc_test/doc_layout"}], indirect=True) def test_doc_build_html(test_app): - # Somehow the xml-tree in extract_needs_from_html() works not correctly with py37 and specific # extracts, which are needed for sphinx >3.0 only. # Everything with Py3.8 is fine again and also Py3.7 with sphinx<3 works here. diff --git a/tests/test_needs_external_needs_build.py b/tests/test_needs_external_needs_build.py index 785887d56..4dfc21878 100644 --- a/tests/test_needs_external_needs_build.py +++ b/tests/test_needs_external_needs_build.py @@ -85,7 +85,6 @@ def test_external_needs_base_url_relative_path(test_app): # check needflow usage for base_url in root level if not sphinx.__version__.startswith("3.5"): - if int(doc_ver.split(".")[1]) >= 18: root_flow_hrefs = root_tree.xpath("//figure/p/object/a/img") assert root_tree.xpath("//figure/figcaption/p/span/a")[0].text == "My needflow" @@ -192,7 +191,6 @@ def test_external_needs_base_url_relative_path(test_app): # check needflow usage for base_url in subsubfolder level if not sphinx.__version__.startswith("3.5"): - if int(doc_ver.split(".")[1]) >= 18: sub_sub_flow_hrefs = sub_sub_tree.xpath("//figure/p/object/a/img") assert sub_sub_tree.xpath("//figure/figcaption/p/span/a")[0].text == "My needflow" diff --git a/tests/test_role_need_max_title_length.py b/tests/test_role_need_max_title_length.py index ea4808b41..c8a9c1616 100644 --- a/tests/test_role_need_max_title_length.py +++ b/tests/test_role_need_max_title_length.py @@ -10,7 +10,6 @@ indirect=True, ) def test_max_title_length_unlimited(test_app): - os.environ["MAX_TITLE_LENGTH"] = "-1" app = test_app @@ -27,7 +26,6 @@ def test_max_title_length_unlimited(test_app): "test_app", [{"buildername": "html", "srcdir": "doc_test/doc_role_need_max_title_length"}], indirect=True ) def test_max_title_length_10(test_app): - os.environ["MAX_TITLE_LENGTH"] = "10" app = test_app diff --git a/tests/test_services/test_service_basics.py b/tests/test_services/test_service_basics.py index ddedcb116..af961353a 100644 --- a/tests/test_services/test_service_basics.py +++ b/tests/test_services/test_service_basics.py @@ -8,7 +8,6 @@ class ServiceTest(BaseService): - options = ["custom_option", "exists"] def __init__(self, _app: Sphinx, _name: str, config, **kwargs) -> None: @@ -42,7 +41,6 @@ def debug(self, options): class NoDebugService(BaseService): - options = [] def __init__(self, _app: Sphinx, _name: str, config, **kwargs): diff --git a/tests/test_title_from_content.py b/tests/test_title_from_content.py index f11c67e68..fe860bed0 100644 --- a/tests/test_title_from_content.py +++ b/tests/test_title_from_content.py @@ -9,7 +9,6 @@ @pytest.mark.parametrize("test_app", [{"buildername": "html", "srcdir": "doc_test/title_from_content"}], indirect=True) def test_title_from_content_scenarios(test_app): - # Somehow the xml-tree in extract_needs_from_html() works not correctly with py37 and specific # extracts, which are needed for sphinx >3.0 only. # Everything with Py3.8 is fine again and also Py3.7 with sphinx<3 works here. diff --git a/tests/test_title_optional.py b/tests/test_title_optional.py index d79cf7392..8bc715add 100644 --- a/tests/test_title_optional.py +++ b/tests/test_title_optional.py @@ -28,7 +28,6 @@ def title(self): @pytest.mark.parametrize("test_app", [{"buildername": "html", "srcdir": "doc_test/title_optional"}], indirect=True) def test_title_optional_scenarios(test_app): - # Somehow the xml-tree in extract_needs_from_html() works not correctly with py37 and specific # extracts, which are needed for sphinx >3.0 only. # Everything with Py3.8 is fine again and also Py3.7 with sphinx<3 works here. From e86bb39d91a83b2d3691c020888ada982b159e16 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Jun 2023 05:04:06 +0000 Subject: [PATCH 23/48] Bump actions/checkout from 3.3.0 to 3.5.3 Bumps [actions/checkout](https://github.com/actions/checkout) from 3.3.0 to 3.5.3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3.3.0...v3.5.3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/benchmark.yaml | 2 +- .github/workflows/ci.yaml | 4 ++-- .github/workflows/docker.yaml | 2 +- .github/workflows/docs.yaml | 2 +- .github/workflows/js_test.yml | 2 +- .github/workflows/release.yaml | 6 +++--- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/benchmark.yaml b/.github/workflows/benchmark.yaml index 43a4a85ef..2973de69c 100644 --- a/.github/workflows/benchmark.yaml +++ b/.github/workflows/benchmark.yaml @@ -8,7 +8,7 @@ jobs: name: "Benchmark time & memory" runs-on: "ubuntu-latest" steps: - - uses: actions/checkout@v3.3.0 + - uses: actions/checkout@v3.5.3 - name: Set Up Python uses: actions/setup-python@v4 with: diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 94f9ddb8b..d0cbbaeae 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -23,7 +23,7 @@ jobs: sphinx-version: "4.5.0" docutils-version: "0.15" steps: - - uses: actions/checkout@v3.3.0 + - uses: actions/checkout@v3.5.3 - name: Set Up Python ${{ matrix.python-version }} uses: actions/setup-python@v4 with: @@ -50,7 +50,7 @@ jobs: name: Lint runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v3.3.0 + - uses: actions/checkout@v3.5.3 - name: Set Up Python uses: actions/setup-python@v4 with: diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index 027c58503..5cf369cf4 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -31,7 +31,7 @@ jobs: steps: # Checks-out your repository under $GITHUB_WORKSPACE - name: Checkout 🛎️ - uses: actions/checkout@v3.3.0 + uses: actions/checkout@v3.5.3 - name: Set up Docker Build 🐋 uses: docker/setup-buildx-action@v1 diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index b69aaf1f4..9caef877f 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -9,7 +9,7 @@ jobs: env: ON_CI: true steps: - - uses: actions/checkout@v3.3.0 + - uses: actions/checkout@v3.5.3 - name: Set Up Python uses: actions/setup-python@v4 with: diff --git a/.github/workflows/js_test.yml b/.github/workflows/js_test.yml index 6412f24ab..b0dd73154 100644 --- a/.github/workflows/js_test.yml +++ b/.github/workflows/js_test.yml @@ -15,7 +15,7 @@ jobs: uses: actions/setup-node@v3 with: node-version: 18 - - uses: actions/checkout@v3.3.0 + - uses: actions/checkout@v3.5.3 - name: Update pip run: | pip install -U wheel diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index ecc211ba3..6197a97ce 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -8,7 +8,7 @@ jobs: name: Build packages runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3.3.0 + - uses: actions/checkout@v3.5.3 - name: Set up Python 3.9 uses: actions/setup-python@v4 with: @@ -28,7 +28,7 @@ jobs: runs-on: ubuntu-latest needs: build steps: - - uses: actions/checkout@v3.3.0 + - uses: actions/checkout@v3.5.3 - name: Set up Python 3.9 uses: actions/setup-python@v4 with: @@ -55,7 +55,7 @@ jobs: runs-on: ubuntu-latest needs: publish_test steps: - - uses: actions/checkout@v3.3.0 + - uses: actions/checkout@v3.5.3 - name: Set up Python 3.9 uses: actions/setup-python@v4 with: From 3a0f2709db26fb472d6457c3c4e3ddf58c95e749 Mon Sep 17 00:00:00 2001 From: Tim Nordell Date: Mon, 21 Nov 2022 15:19:25 -0600 Subject: [PATCH 24/48] needs: Remove some of the extra IDs in the output Inside the LaTeX generator, it looks for the attributes ids and refid for creating link targets. When a new layer with a wrapper was added in commit e51fc1f, for an unknown reason this triggered these additional IDs to generate links within the LaTeX output. A test case has been added to ensure only one hyperref within LaTeX is encountered as well. (https://github.com/useblocks/sphinx-needs/issues/808) --- sphinx_needs/api/need.py | 2 +- tests/test_doc_build_latex.py | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/sphinx_needs/api/need.py b/sphinx_needs/api/need.py index 7ff872d94..3f0432d26 100644 --- a/sphinx_needs/api/need.py +++ b/sphinx_needs/api/need.py @@ -197,7 +197,7 @@ def run(): if is_external: target_node = None else: - target_node = nodes.target("", "", ids=[need_id], refid=need_id) + target_node = nodes.target("", "", ids=[need_id], refid=need_id, anonymous="") external_url = None # Handle status diff --git a/tests/test_doc_build_latex.py b/tests/test_doc_build_latex.py index 20bdef806..a8e763ee0 100644 --- a/tests/test_doc_build_latex.py +++ b/tests/test_doc_build_latex.py @@ -19,3 +19,7 @@ def test_doc_build_latex(test_app): "\\sphinxcaption{Table from sphinxneeds\\sphinxhyphen{}contrib \\textquotesingle" "{}needtable\\textquotesingle{} directive}" in latex_content ) + + # Check that the USER_STORY_001 label is only created once in the LaTeX output. Split + # on the string, which should split latex_content into two. + assert len(latex_content.split(r"\label{\detokenize{index:USER_STORY_001}}")) == 2 From c6f0c2d525b04a4c28004b93bc5d9cc0f7ae4ebe Mon Sep 17 00:00:00 2001 From: Haiyang Date: Fri, 4 Aug 2023 09:43:00 +0200 Subject: [PATCH 25/48] Added config option needs_report_dead_links (#937) Co-authored-by: Daniel Woste --- docs/changelog.rst | 3 + docs/configuration.rst | 15 ++ sphinx_needs/needs.py | 3 + sphinx_needs/roles/need_outgoing.py | 31 +-- .../doc_report_dead_links_false/Makefile | 20 ++ .../doc_report_dead_links_false/conf.py | 178 ++++++++++++++++++ .../doc_report_dead_links_false/index.rst | 47 +++++ .../doc_report_dead_links_false/make.bat | 36 ++++ .../doc_report_dead_links_true/Makefile | 20 ++ .../doc_report_dead_links_true/conf.py | 176 +++++++++++++++++ .../doc_report_dead_links_true/index.rst | 47 +++++ .../doc_report_dead_links_true/make.bat | 36 ++++ tests/test_report_dead_links.py | 66 +++++++ 13 files changed, 664 insertions(+), 14 deletions(-) create mode 100644 tests/doc_test/doc_report_dead_links_false/Makefile create mode 100644 tests/doc_test/doc_report_dead_links_false/conf.py create mode 100644 tests/doc_test/doc_report_dead_links_false/index.rst create mode 100644 tests/doc_test/doc_report_dead_links_false/make.bat create mode 100644 tests/doc_test/doc_report_dead_links_true/Makefile create mode 100644 tests/doc_test/doc_report_dead_links_true/conf.py create mode 100644 tests/doc_test/doc_report_dead_links_true/index.rst create mode 100644 tests/doc_test/doc_report_dead_links_true/make.bat create mode 100644 tests/test_report_dead_links.py diff --git a/docs/changelog.rst b/docs/changelog.rst index 0214052a6..f07bf6d9e 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -31,6 +31,9 @@ Released: under development * Removed configuration **needs_ide_directive_snippets** to support custom directive snippets for IDE features. * Provided new IDE support option: VsCode extension `Sphinx-Needs-VsCode `_. +* Improvement: Added configuration option :ref:`needs_report_dead_links`, which can deactivate log messages of + outgoing dead links. + (`#920 `_) * Improvement: Configuration option :ref:`needs_allow_unsafe_filters` added, which allows unsafe filter for :ref:`filter_func`. (`#831 `_) diff --git a/docs/configuration.rst b/docs/configuration.rst index 2d4b80534..0efcd5001 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -289,6 +289,21 @@ In this cases, you can provide a list of tuples. If you need access to other needs for complex filtering, you can maybe provide your own :ref:`dynamic_functions` and perform the filtering there. +.. _needs_report_dead_links: + +needs_report_dead_links +~~~~~~~~~~~~~~~~~~~~~~~ + +Deactivate/activate log messages of outgoing dead links. If set to ``False``, then deactivate. + +Default value is ``True``. + +Configuration example: + +.. code-block:: python + + needs_report_dead_links = False + .. _needs_extra_links: needs_extra_links diff --git a/sphinx_needs/needs.py b/sphinx_needs/needs.py index 559f1c230..c7621519e 100644 --- a/sphinx_needs/needs.py +++ b/sphinx_needs/needs.py @@ -224,6 +224,9 @@ def setup(app: Sphinx) -> Dict[str, Any]: # Example: [{"name": "blocks, "incoming": "is blocked by", "copy_link": True, "color": "#ffcc00"}] app.add_config_value("needs_extra_links", [], "html") + # Deactivate log msgs of dead links if set to False, default is True + app.add_config_value("needs_report_dead_links", True, "html", types=[bool]) + app.add_config_value("needs_filter_data", {}, "html") app.add_config_value("needs_allow_unsafe_filters", False, "html") diff --git a/sphinx_needs/roles/need_outgoing.py b/sphinx_needs/roles/need_outgoing.py index d2dab04f9..79d0f32c0 100644 --- a/sphinx_needs/roles/need_outgoing.py +++ b/sphinx_needs/roles/need_outgoing.py @@ -27,6 +27,8 @@ def process_need_outgoing( needs_all_needs = getattr(env, "needs_all_needs", {}) ref_need = needs_all_needs[node_need_ref["reftarget"]] + report_dead_links = getattr(env.config, "needs_report_dead_links", True) + # Let's check if NeedIncoming shall follow a specific link type if "link_type" in node_need_ref.attributes: links = ref_need[node_need_ref.attributes["link_type"]] @@ -120,20 +122,21 @@ def process_need_outgoing( dead_link_para.attributes["classes"].append("forbidden") log_level = "WARNING" - if node_need_ref and node_need_ref.line: - log.log( - log_level, - f"Needs: linked need {link} not found " - f"(Line {node_need_ref.line} of file {node_need_ref.source})", - ) - else: - log.log( - log_level, - "Needs: outgoing linked need {} not found (document: {}, " - "source need {} on line {} )".format( - link, ref_need["docname"], ref_need["id"], ref_need["lineno"] - ), - ) + if report_dead_links: + if node_need_ref and node_need_ref.line: + log.log( + log_level, + f"Needs: linked need {link} not found " + f"(Line {node_need_ref.line} of file {node_need_ref.source})", + ) + else: + log.log( + log_level, + "Needs: outgoing linked need {} not found (document: {}, " + "source need {} on line {} )".format( + link, ref_need["docname"], ref_need["id"], ref_need["lineno"] + ), + ) # If we have several links, we add an empty text between them if (index + 1) < len(link_list): diff --git a/tests/doc_test/doc_report_dead_links_false/Makefile b/tests/doc_test/doc_report_dead_links_false/Makefile new file mode 100644 index 000000000..47330b89c --- /dev/null +++ b/tests/doc_test/doc_report_dead_links_false/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +SPHINXPROJ = needstestdocs +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file diff --git a/tests/doc_test/doc_report_dead_links_false/conf.py b/tests/doc_test/doc_report_dead_links_false/conf.py new file mode 100644 index 000000000..792b4e0f7 --- /dev/null +++ b/tests/doc_test/doc_report_dead_links_false/conf.py @@ -0,0 +1,178 @@ +# +# needs test docs documentation build configuration file, created by +# sphinx-quickstart on Tue Mar 28 11:37:14 2017. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os +import sys + +sys.path.insert(0, os.path.abspath("../../sphinxcontrib")) + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. + +extensions = ["sphinx_needs", "sphinxcontrib.plantuml"] + +needs_types = [ + {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"}, + {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"}, + {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"}, + {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"}, +] + +needs_report_dead_links = False + +needs_extra_links = [ + { + "option": "blocks", + "incoming": "is blocked by", + "outgoing": "blocks", + "copy": False, + "style": "bold,#AA0000", + "allow_dead_links": True, + }, + { + "option": "tests", + "incoming": "is tested by", + "outgoing": "tests", + "copy": True, + "style": "dashed,#00AA00", + "style_part": "dotted,#00AA00", + }, +] + +plantuml = "java -jar %s" % os.path.join(os.path.dirname(__file__), "..", "utils", "plantuml.jar") +plantuml_output_format = "svg" + +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = ".rst" + +# The master toctree document. +master_doc = "index" + +# General information about the project. +project = "needs test docs" +copyright = "2017, team useblocks" +author = "team useblocks" + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = "1.0" +# The full version, including alpha/beta/rc tags. +release = "1.0" + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = "en" + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This patterns also effect to html_static_path and html_extra_path +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = "sphinx" + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = False + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = "alabaster" + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +# html_static_path = ["_static"] + +# -- Options for HTMLHelp output ------------------------------------------ + +# Output file base name for HTML help builder. +htmlhelp_basename = "needstestdocsdoc" + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, "needstestdocs.tex", "needs test docs Documentation", "team useblocks", "manual"), +] + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [(master_doc, "needstestdocs", "needs test docs Documentation", [author], 1)] + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ( + master_doc, + "needstestdocs", + "needs test docs Documentation", + author, + "needstestdocs", + "One line description of project.", + "Miscellaneous", + ), +] diff --git a/tests/doc_test/doc_report_dead_links_false/index.rst b/tests/doc_test/doc_report_dead_links_false/index.rst new file mode 100644 index 000000000..6b225d613 --- /dev/null +++ b/tests/doc_test/doc_report_dead_links_false/index.rst @@ -0,0 +1,47 @@ +EXTRA LINKS DOCUMENT +==================== + +Stories +------- + +.. story:: My requirement + :id: REQ_001 + :blocks: REQ_003, DEAD_LINK_ALLOWED + +.. story:: My requirement 2 + :id: REQ_002 + +.. story:: My requirement 3 + :id: REQ_003 + +.. story:: My requirement 4 + :id: REQ_004 + :links: ANOTHER_DEAD_LINK + +.. story:: Req 5 + :id: REQ_005 + :blocks: REQ_001 + + :need_part:`(1) awesome part` + + :need_part:`(cool) a cool part` + + +Tests +----- + +.. test:: Test of requirements + :id: TEST_001 + :tests: REQ_001, REQ_003 + +.. test:: Test of requirements2 + :id: TEST_002 + :tests: REQ_001 + +.. test:: Test of requirements 5 + :id: TEST_003 + :tests: REQ_005.1,REQ_005.cool + +.. test:: Test of invalid need_part links + :id: TEST_004 + :tests: REQ_005.1,REQ_005.invalid diff --git a/tests/doc_test/doc_report_dead_links_false/make.bat b/tests/doc_test/doc_report_dead_links_false/make.bat new file mode 100644 index 000000000..489ed7dfd --- /dev/null +++ b/tests/doc_test/doc_report_dead_links_false/make.bat @@ -0,0 +1,36 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build +set SPHINXPROJ=needstestdocs + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% + +:end +popd diff --git a/tests/doc_test/doc_report_dead_links_true/Makefile b/tests/doc_test/doc_report_dead_links_true/Makefile new file mode 100644 index 000000000..47330b89c --- /dev/null +++ b/tests/doc_test/doc_report_dead_links_true/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +SPHINXPROJ = needstestdocs +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file diff --git a/tests/doc_test/doc_report_dead_links_true/conf.py b/tests/doc_test/doc_report_dead_links_true/conf.py new file mode 100644 index 000000000..147829ca9 --- /dev/null +++ b/tests/doc_test/doc_report_dead_links_true/conf.py @@ -0,0 +1,176 @@ +# +# needs test docs documentation build configuration file, created by +# sphinx-quickstart on Tue Mar 28 11:37:14 2017. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os +import sys + +sys.path.insert(0, os.path.abspath("../../sphinxcontrib")) + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. + +extensions = ["sphinx_needs", "sphinxcontrib.plantuml"] + +needs_types = [ + {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"}, + {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"}, + {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"}, + {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"}, +] + +needs_extra_links = [ + { + "option": "blocks", + "incoming": "is blocked by", + "outgoing": "blocks", + "copy": False, + "style": "bold,#AA0000", + "allow_dead_links": True, + }, + { + "option": "tests", + "incoming": "is tested by", + "outgoing": "tests", + "copy": True, + "style": "dashed,#00AA00", + "style_part": "dotted,#00AA00", + }, +] + +plantuml = "java -jar %s" % os.path.join(os.path.dirname(__file__), "..", "utils", "plantuml.jar") +plantuml_output_format = "svg" + +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = ".rst" + +# The master toctree document. +master_doc = "index" + +# General information about the project. +project = "needs test docs" +copyright = "2017, team useblocks" +author = "team useblocks" + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = "1.0" +# The full version, including alpha/beta/rc tags. +release = "1.0" + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = "en" + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This patterns also effect to html_static_path and html_extra_path +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = "sphinx" + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = False + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = "alabaster" + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +# html_static_path = ["_static"] + +# -- Options for HTMLHelp output ------------------------------------------ + +# Output file base name for HTML help builder. +htmlhelp_basename = "needstestdocsdoc" + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, "needstestdocs.tex", "needs test docs Documentation", "team useblocks", "manual"), +] + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [(master_doc, "needstestdocs", "needs test docs Documentation", [author], 1)] + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ( + master_doc, + "needstestdocs", + "needs test docs Documentation", + author, + "needstestdocs", + "One line description of project.", + "Miscellaneous", + ), +] diff --git a/tests/doc_test/doc_report_dead_links_true/index.rst b/tests/doc_test/doc_report_dead_links_true/index.rst new file mode 100644 index 000000000..6b225d613 --- /dev/null +++ b/tests/doc_test/doc_report_dead_links_true/index.rst @@ -0,0 +1,47 @@ +EXTRA LINKS DOCUMENT +==================== + +Stories +------- + +.. story:: My requirement + :id: REQ_001 + :blocks: REQ_003, DEAD_LINK_ALLOWED + +.. story:: My requirement 2 + :id: REQ_002 + +.. story:: My requirement 3 + :id: REQ_003 + +.. story:: My requirement 4 + :id: REQ_004 + :links: ANOTHER_DEAD_LINK + +.. story:: Req 5 + :id: REQ_005 + :blocks: REQ_001 + + :need_part:`(1) awesome part` + + :need_part:`(cool) a cool part` + + +Tests +----- + +.. test:: Test of requirements + :id: TEST_001 + :tests: REQ_001, REQ_003 + +.. test:: Test of requirements2 + :id: TEST_002 + :tests: REQ_001 + +.. test:: Test of requirements 5 + :id: TEST_003 + :tests: REQ_005.1,REQ_005.cool + +.. test:: Test of invalid need_part links + :id: TEST_004 + :tests: REQ_005.1,REQ_005.invalid diff --git a/tests/doc_test/doc_report_dead_links_true/make.bat b/tests/doc_test/doc_report_dead_links_true/make.bat new file mode 100644 index 000000000..489ed7dfd --- /dev/null +++ b/tests/doc_test/doc_report_dead_links_true/make.bat @@ -0,0 +1,36 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build +set SPHINXPROJ=needstestdocs + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% + +:end +popd diff --git a/tests/test_report_dead_links.py b/tests/test_report_dead_links.py new file mode 100644 index 000000000..6380dcee1 --- /dev/null +++ b/tests/test_report_dead_links.py @@ -0,0 +1,66 @@ +from pathlib import Path + +import pytest + + +@pytest.mark.parametrize( + "test_app", [{"buildername": "html", "srcdir": "doc_test/doc_report_dead_links_true"}], indirect=True +) +def test_needs_report_dead_links_true(test_app): + import subprocess + + app = test_app + + # Check config value of needs_report_dead_links + assert app.config.needs_report_dead_links + + src_dir = Path(app.srcdir) + out_dir = Path(app.outdir) + output = subprocess.run(["sphinx-build", "-M", "html", src_dir, out_dir], capture_output=True) + + # Check log info msg of dead links + assert ( + "Needs: outgoing linked need DEAD_LINK_ALLOWED not found (document: index, source need REQ_001 on line 7 )" + in output.stdout.decode("utf-8") + ) + # Check log warning msg of dead links + assert ( + "WARNING: Needs: outgoing linked need ANOTHER_DEAD_LINK not found (document: index, " + "source need REQ_004 on line 17 )" in output.stderr.decode("utf-8") + ) + assert ( + "WARNING: Needs: outgoing linked need REQ_005 not found (document: index, source need TEST_004 on line 45 )" + in output.stderr.decode("utf-8") + ) + + +@pytest.mark.parametrize( + "test_app", [{"buildername": "html", "srcdir": "doc_test/doc_report_dead_links_false"}], indirect=True +) +def test_needs_report_dead_links_false(test_app): + import subprocess + + app = test_app + + # Check config value of needs_report_dead_links + assert not app.config.needs_report_dead_links + + src_dir = Path(app.srcdir) + out_dir = Path(app.outdir) + output = subprocess.run(["sphinx-build", "-M", "html", src_dir, out_dir], capture_output=True) + + # Check log info msg of dead links deactivated + assert ( + "Needs: outgoing linked need DEAD_LINK_ALLOWED not found (document: index, source need REQ_001 on line 7 )" + not in output.stdout.decode("utf-8") + ) + # Check log warning msg of dead links deactivated + assert ( + "WARNING: Needs: outgoing linked need ANOTHER_DEAD_LINK not found (document: index, " + "source need REQ_004 on line 17 )" not in output.stderr.decode("utf-8") + ) + assert ( + "WARNING: Needs: outgoing linked need REQ_005 not found (document: index, source need TEST_004 on line 45 )" + not in output.stderr.decode("utf-8") + ) + assert not output.stderr From 4babb2de57273179269325eaf233c415bfa82b02 Mon Sep 17 00:00:00 2001 From: Daniel Woste Date: Wed, 16 Aug 2023 18:05:06 +0200 Subject: [PATCH 26/48] Raises version to 1.3.0 --- .github/workflows/docker.yaml | 2 +- docs/changelog.rst | 11 ++++++++++- docs/conf.py | 15 +++++++++++++-- pyproject.toml | 2 +- sphinx_needs/directives/need.py | 1 + sphinx_needs/needs.py | 2 +- 6 files changed, 27 insertions(+), 6 deletions(-) diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index 5cf369cf4..19a5fe902 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -13,7 +13,7 @@ on: tags: - '*.*.*' env: - NEEDS_VERSION: 1.2.2 + NEEDS_VERSION: 1.3.0 jobs: build: diff --git a/docs/changelog.rst b/docs/changelog.rst index f07bf6d9e..c230b2445 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -12,10 +12,19 @@ License Released: under development * Improvement: Added Builder :ref:`needs_lut_builder` and config option :ref:`needs_lut_build_json` in `conf.py`. -1.3.0 +2.0.0 +----- +Released: under development + +1.4.0 ----- Released: under development + +1.3.0 +----- +Released: 16.08.2023 + * Improvement: Configuration option :ref:`needs_debug_measurement` added, which creates a runtime report for debugging purposes. (`#917 `_) diff --git a/docs/conf.py b/docs/conf.py index 41f3b1815..cbe2e7827 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -40,9 +40,9 @@ # built documents. # # The short X.Y version. -version = "1.2" +version = "1.3" # The full version, including alpha/beta/rc tags. -release = "1.2.2" +release = "1.3.0" on_rtd = os.environ.get("READTHEDOCS") == "True" @@ -301,6 +301,17 @@ "meta": ["<>", "<>"], }, }, + "detail_view": { + "grid": "simple", + "layout": { + "head": [ + '<>: **<>** <> <> <> ' + '<>' + ], + "meta": ["<>", "<>"], + }, + }, } needs_service_all_data = True diff --git a/pyproject.toml b/pyproject.toml index f948649dd..f5c25395d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,7 +2,7 @@ name = "sphinx-needs" # !! Don't miss updates in needs.py, conf.py, changelog.rst, and .github/workflows/docker !!! -version = "1.2.2" +version = "1.3.0" description = "Sphinx needs extension for managing needs/requirements and specifications" authors = ["team useblocks "] diff --git a/sphinx_needs/directives/need.py b/sphinx_needs/directives/need.py index 78ba599cd..b48bed484 100644 --- a/sphinx_needs/directives/need.py +++ b/sphinx_needs/directives/need.py @@ -394,6 +394,7 @@ def process_need_nodes(app: Sphinx, doctree: nodes.document, fromdocname: str) - # We call process_needextend here by our own, so that we are able # to give print_need_nodes the already found need_nodes. process_needextend(app, doctree, fromdocname) + print_need_nodes(app, doctree, fromdocname, found_needs_nodes) diff --git a/sphinx_needs/needs.py b/sphinx_needs/needs.py index c7621519e..75bd26200 100644 --- a/sphinx_needs/needs.py +++ b/sphinx_needs/needs.py @@ -107,7 +107,7 @@ from sphinx_needs.utils import INTERNALS, NEEDS_FUNCTIONS, node_match from sphinx_needs.warnings import process_warnings -VERSION = "1.2.2" +VERSION = "1.3.0" NEEDS_FUNCTIONS.clear() From 4cec93b2dbb12d716567dbf5b394cf3121198577 Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Fri, 11 Aug 2023 02:38:51 +0200 Subject: [PATCH 27/48] =?UTF-8?q?=F0=9F=91=8C=20Performance:=20Memoize=20I?= =?UTF-8?q?nline=20Parser?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sphinx_needs/layout.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/sphinx_needs/layout.py b/sphinx_needs/layout.py index 98be25f56..6e6430214 100644 --- a/sphinx_needs/layout.py +++ b/sphinx_needs/layout.py @@ -3,11 +3,13 @@ Based on https://github.com/useblocks/sphinxcontrib-needs/issues/102 """ +from functools import lru_cache +from optparse import Values import os import re import uuid from contextlib import suppress -from typing import List, Optional +from typing import List, Optional, Tuple from urllib.parse import urlparse import requests @@ -169,6 +171,14 @@ def build_need(layout, node, app: Sphinx, style=None, fromdocname: Optional[str] node.parent.replace(node, node_container) +@lru_cache(1) +def _generate_inline_parser() -> Tuple[Values, Inliner]: + doc_settings = OptionParser(components=(Parser,)).get_default_values() + inline_parser = Inliner() + inline_parser.init_customizations(doc_settings) + return doc_settings, inline_parser + + class LayoutHandler: """ Cares about the correct layout handling @@ -267,7 +277,7 @@ def __init__(self, app: Sphinx, need, layout, node, style=None, fromdocname: Opt } # Dummy Document setup - self.doc_settings = OptionParser(components=(Parser,)).get_default_values() + self.doc_settings, self.inline_parser = _generate_inline_parser() self.dummy_doc = new_document("dummy", self.doc_settings) self.doc_language = languages.get_language(self.dummy_doc.settings.language_code) self.doc_memo = Struct( @@ -352,9 +362,7 @@ def _parse(self, line: str) -> List[nodes.Node]: :param line: string to parse :return: nodes """ - inline_parser = Inliner() - inline_parser.init_customizations(self.doc_settings) - result, message = inline_parser.parse(line, 0, self.doc_memo, self.dummy_doc) + result, message = self.inline_parser.parse(line, 0, self.doc_memo, self.dummy_doc) if message: raise SphinxNeedLayoutException(message) return result From 09b14caa17526046f20090849e1bc89ccd84623a Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Wed, 16 Aug 2023 14:21:29 +0200 Subject: [PATCH 28/48] fix linting --- sphinx_needs/layout.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sphinx_needs/layout.py b/sphinx_needs/layout.py index 6e6430214..0beb2151e 100644 --- a/sphinx_needs/layout.py +++ b/sphinx_needs/layout.py @@ -3,12 +3,12 @@ Based on https://github.com/useblocks/sphinxcontrib-needs/issues/102 """ -from functools import lru_cache -from optparse import Values import os import re import uuid from contextlib import suppress +from functools import lru_cache +from optparse import Values from typing import List, Optional, Tuple from urllib.parse import urlparse From 0230f3d5164d6c86258a22adc53d667392ca8d3c Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Wed, 16 Aug 2023 19:10:29 +0200 Subject: [PATCH 29/48] Add to changelog --- AUTHORS | 2 ++ docs/changelog.rst | 1 + 2 files changed, 3 insertions(+) diff --git a/AUTHORS b/AUTHORS index 5822e0c4c..821726ea2 100644 --- a/AUTHORS +++ b/AUTHORS @@ -35,3 +35,5 @@ Jörg Kreuzberger Duodu Randy Christian Wappler + +Chris Sewell diff --git a/docs/changelog.rst b/docs/changelog.rst index c230b2445..c6db51cc5 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -20,6 +20,7 @@ Released: under development ----- Released: under development +* Improvement: Reduce document build time, by memoizing the inline parse in ``build_need`` (`#968 `_) 1.3.0 ----- From 271f6a6c1e3bd5f198be0066584dbcd91ab81b4f Mon Sep 17 00:00:00 2001 From: Daniel Woste Date: Fri, 18 Aug 2023 11:35:28 +0200 Subject: [PATCH 30/48] Easier Sphinx-Needs docs builds * Removes needservice dependency to external services like github * Shows images instead of real fetch external data * Removes on_ci and fast_build ENV vars and logic * Adds "make needs" command to get a needs.json file --- .github/workflows/docs.yaml | 2 - .github/workflows/js_test.yml | 3 -- Makefile | 4 ++ docs/_images/github_issue_1.png | Bin 0 -> 28252 bytes docs/_images/github_issue_2.png | Bin 0 -> 89028 bytes docs/_images/github_issue_3.png | Bin 0 -> 18518 bytes docs/_images/github_issue_4.png | Bin 0 -> 13981 bytes docs/_static/custom.css | 4 ++ docs/conf.py | 65 ++++-------------------------- docs/configuration.rst | 6 +-- docs/directives/needuml.rst | 2 +- docs/layout_styles.rst | 6 +-- docs/performance/index.rst | 1 + docs/performance/script.rst | 2 +- docs/services/github.rst | 60 ++++++++------------------- docs/services/open_needs.rst | 17 +------- noxfile.py | 2 - sphinx_needs/functions/common.py | 2 +- tests/benchmarks/test_official.py | 7 ---- 19 files changed, 44 insertions(+), 139 deletions(-) create mode 100644 docs/_images/github_issue_1.png create mode 100644 docs/_images/github_issue_2.png create mode 100644 docs/_images/github_issue_3.png create mode 100644 docs/_images/github_issue_4.png diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 9caef877f..42390fd39 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -6,8 +6,6 @@ jobs: linkcheck: name: Docs-Linkcheck runs-on: ubuntu-20.04 - env: - ON_CI: true steps: - uses: actions/checkout@v3.5.3 - name: Set Up Python diff --git a/.github/workflows/js_test.yml b/.github/workflows/js_test.yml index b0dd73154..3e0e6d23d 100644 --- a/.github/workflows/js_test.yml +++ b/.github/workflows/js_test.yml @@ -3,9 +3,6 @@ on: [pull_request] jobs: js_tests: runs-on: ubuntu-latest - env: - ON_CI: true - FAST_BUILD: true steps: - name: Set Up Python 3.10.8 uses: actions/setup-python@v4 diff --git a/Makefile b/Makefile index af66bd23c..554dddd4c 100644 --- a/Makefile +++ b/Makefile @@ -36,6 +36,10 @@ docs-html: docs-html-fast: poetry run sphinx-build -j auto -b html docs/ docs/_build +.PHONY: needs +needs: + poetry run sphinx-build -a -E -j auto -b needs docs/ docs/_build + .PHONY: docs-pdf docs-pdf: poetry run make --directory docs/ clean && make --directory docs/ latexpdf diff --git a/docs/_images/github_issue_1.png b/docs/_images/github_issue_1.png new file mode 100644 index 0000000000000000000000000000000000000000..99018c98ee414e921a0ecd01a99393c0ff709be0 GIT binary patch literal 28252 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 Kt$p$4um1)X+`fPS literal 0 HcmV?d00001 diff --git a/docs/_images/github_issue_2.png b/docs/_images/github_issue_2.png new file mode 100644 index 0000000000000000000000000000000000000000..9f553644090ca109b11875768f73534a5a047956 GIT binary patch literal 89028 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 literal 0 HcmV?d00001 diff --git a/docs/_images/github_issue_4.png b/docs/_images/github_issue_4.png new file mode 100644 index 0000000000000000000000000000000000000000..1271157c9685f6f0bef5396540b3f0cd624a2e64 GIT binary patch literal 13981 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 KfKt)#zW)s=#iKz0 literal 0 HcmV?d00001 diff --git a/docs/_static/custom.css b/docs/_static/custom.css index 1de3a1e16..828315217 100644 --- a/docs/_static/custom.css +++ b/docs/_static/custom.css @@ -181,4 +181,8 @@ div.dt-button-collection button.dt-button.active:not(.disabled) { } details.sd-dropdown .sd-summary-up, details.sd-dropdown .sd-summary-down { display: none; +} +/* Image width fix in need-sidebars. */ +tbody div.needs_side img.needs_image { + max-width: 100px; } \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py index cbe2e7827..874669839 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -58,6 +58,8 @@ "sphinx_immaterial", ] +# smartquotes = False + needs_debug_measurement = True add_module_names = False # Used to shorten function name output @@ -128,6 +130,8 @@ # Absolute path to the needs_report_template_file based on the conf.py directory # needs_report_template = "/needs_templates/report_template.need" # Use custom report template +needs_report_dead_links = False + needs_types = [ # Architecture types { @@ -316,41 +320,7 @@ needs_service_all_data = True -needs_services = { - "github-issues": { - "url": "https://api.github.com/", - "max_content_lines": 20, - "id_prefix": "GH_ISSUE_", - }, - "github-prs": { - "url": "https://api.github.com/", - "max_content_lines": 20, - "id_prefix": "GH_PR_", - }, - "github-commits": { - "url": "https://api.github.com/", - "max_content_lines": 20, - "id_prefix": "GH_COM_", - }, - "open-needs": { - "url": "http://127.0.0.1:9595", - "user": os.environ.get("ONS_USERNAME", ""), - "password": os.environ.get("ONS_PASSWORD", ""), - "id_prefix": "ONS_", - "mappings": { - "id": "{{key}}", - "type": ["type"], - "title": "{{title}}", - "status": ["options", "status"], - "links": ["references", "links"], - }, - "extra_data": { - "Priority": ["options", "priority"], - "Approval": ["options", "approved"], - "Cost": ["options", "costs"], - }, - }, -} +needs_services = {} needs_string_links = { "config_link": { @@ -394,19 +364,8 @@ def custom_defined_func(): # build needs_lut.json to make permalinks work needs_lut_build_json = False -# Get and maybe set GitHub credentials for services. -# This is needed as the rate limit for not authenticated users is too low for the amount of requests we -# need to perform for this documentation -github_username = os.environ.get("GITHUB_USERNAME", "") -github_token = os.environ.get("GITHUB_TOKEN", "") - -if github_username != "" and github_token != "": - print(f"---> GITHUB: Using as username: {github_username}. length token: {len(github_token)}") - for service in ["github-issues", "github-prs", "github-commits"]: - needs_services[service]["username"] = github_username - needs_services[service]["token"] = github_token -else: - print("---> GITHUB: No auth provided") +# build needs_lut.json to make permalinks work +needs_lut_build_json = False # Add any paths that contain templates here, relative to this directory. templates_path = ["_templates"] @@ -595,13 +554,7 @@ def custom_defined_func(): """ -# Check, if docs get built on ci. -# If this is the case, external services like Open-Needs are not available and -# docs will show images instead of getting real data. -on_ci = os.environ.get("ON_CI", "False").upper() == "TRUE" -fast_build = os.environ.get("FAST_BUILD", "False").upper() == "TRUE" - -html_context = {"on_ci": on_ci, "fast_build": fast_build} +html_context = {} def rstjinja(app: Sphinx, _docname: str, source: List[str]) -> None: @@ -620,8 +573,6 @@ def rstjinja(app: Sphinx, _docname: str, source: List[str]) -> None: def setup(app: Sphinx) -> None: - print(f"---> ON_CI is: {on_ci}") - print(f"---> FAST_BUILD is: {fast_build}") app.connect("source-read", rstjinja) diff --git a/docs/configuration.rst b/docs/configuration.rst index 0efcd5001..84dbedd2b 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -646,7 +646,7 @@ needs_report_template .. versionadded:: 1.0.1 -You can customize the layout of :ref:`needreport` using `Jinja `_. +You can customize the layout of :ref:`needreport` using `Jinja `__. Set the value of ``needs_report_template`` to the path of the template you want to use. @@ -2041,7 +2041,7 @@ needs_render_context ~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 1.0.3 -This option allows you to use custom data as context when rendering `Jinja `_ templates or strings. +This option allows you to use custom data as context when rendering `Jinja `__ templates or strings. Configuration example: @@ -2135,7 +2135,7 @@ needs_template *removed: 0.3.0* -The layout of needs can be fully customized by using `jinja `_. +The layout of needs can be fully customized by using `jinja `__. If nothing is set, the following default template is used: diff --git a/docs/directives/needuml.rst b/docs/directives/needuml.rst index e49f6c8f8..7670839b3 100644 --- a/docs/directives/needuml.rst +++ b/docs/directives/needuml.rst @@ -111,7 +111,7 @@ Allows to inject additional key-value pairs into the ``needuml`` rendering. It is not available in code loaded via :ref:`needuml_jinja_uml`. So we suggest to use them only in non-embedded needuml directives. In an embedded needuml, you can store the information in the options - of the need and access them with :ref:`needflow_need` like in + of the need and access them with :ref:`needflow` like in :ref:`needuml` introduction. diff --git a/docs/layout_styles.rst b/docs/layout_styles.rst index 9106a202f..61fb39b3a 100644 --- a/docs/layout_styles.rst +++ b/docs/layout_styles.rst @@ -371,11 +371,11 @@ Available layout functions are: .. autofunction:: sphinx_needs.layout.LayoutHandler.meta_links_all(prefix='', postfix='', exclude=None) -.. autofunction:: sphinx_needs.layout.LayoutHandler.image(url, height=None, width=None, align=None, no_link=False) +.. autofunction:: sphinx_needs.layout.LayoutHandler.image(url, height=None, width=None, align=None, no_link=False, prefix="", is_external=False, img_class="") -.. autofunction:: sphinx_needs.layout.LayoutHandler.link(url, text=None, image_url=None, image_height=None, image_width=None) +.. autofunction:: sphinx_needs.layout.LayoutHandler.link(url, text=None, image_url=None, image_height=None, image_width=None, prefix="", is_dynamic=False) -.. autofunction:: sphinx_needs.layout.LayoutHandler.permalink(image_url=None, image_height=None, image_width=None, text=None) +.. autofunction:: sphinx_needs.layout.LayoutHandler.permalink(image_url=None, image_height=None, image_width=None, text=None, prefix="") .. autofunction:: sphinx_needs.layout.LayoutHandler.collapse_button(target='meta', collapsed='Show', visible='Close', initial=False) diff --git a/docs/performance/index.rst b/docs/performance/index.rst index bb8f9014e..178e37d1f 100644 --- a/docs/performance/index.rst +++ b/docs/performance/index.rst @@ -7,4 +7,5 @@ Performance & Profiling :maxdepth: 2 script + debug diff --git a/docs/performance/script.rst b/docs/performance/script.rst index a9c9c9f0e..e2587aaca 100644 --- a/docs/performance/script.rst +++ b/docs/performance/script.rst @@ -1,4 +1,4 @@ -.. _performance: +.. _performance_script: Performance & Profiling script ============================== diff --git a/docs/services/github.rst b/docs/services/github.rst index 515a48125..e72605722 100644 --- a/docs/services/github.rst +++ b/docs/services/github.rst @@ -22,14 +22,13 @@ Each services creates normally multiple need objects for each element found by q .. needservice:: github-issues :query: repo:useblocks/sphinx-needs node latexpdf + :max_amount: 1 :max_content_lines: 4 -{% if fast_build != true %} -.. needservice:: github-issues - :query: repo:useblocks/sphinx-needs node latexpdf - :max_amount: 1 - :max_content_lines: 4 -{% endif %} +.. figure:: /_images/github_issue_1.png + :scale: 80% + + Example of a github Issue collected with Sphinx-Needs. Directive options, which can also used for normal needs, can also be set for ``needservice`` directive. Also the content part of ``needservice`` is added as extra data to the end of the finally created needs. @@ -51,20 +50,10 @@ Also the content part of ``needservice`` is added as extra data to the end of th Extra content for each new need -{% if fast_build != true %} -.. needservice:: github-issues - :type: spec - :author: Me - :tags: awesome, issue - :query: repo:useblocks/sphinx-needs node latexpdf - :id_prefix: GH_ - :max_amount: 1 - :max_content_lines: 4 - :layout: clean - :style: discreet - - Extra content for each new need -{%endif%} +.. figure:: /_images/github_issue_2.png + :scale: 80% + + Example of a github Issue collected with Sphinx-Needs. Querying objects ---------------- @@ -101,10 +90,6 @@ This loads all open issues, which have the strings *needtable* and *viewports* i .. needservice:: github-issues :query: repo:useblocks/sphinx-needs state:open needtable viewports -{% if fast_build != true %} -.. needservice:: github-issues - :query: repo:useblocks/sphinx-needs state:open needtable viewports -{%endif%} specific ++++++++ @@ -123,10 +108,10 @@ This query fetches a specific pull request with the id 161. .. needservice:: github-prs :specific: useblocks/sphinx-needs/161 -{% if fast_build != true %} -.. needservice:: github-prs - :specific: useblocks/sphinx-needs/161 -{%endif%} +.. figure:: /_images/github_issue_3.png + :scale: 80% + + Example of a github Issue collected with Sphinx-Needs. .. _service_github_config: @@ -193,15 +178,10 @@ directive :ref:`needservice`. :layout: focus_l :style: blue_border -{% if fast_build != true %} -.. needservice:: github-issues - :query: repo:useblocks/sphinx-needs node latexpdf - :max_amount: 1 - :max_content_lines: 4 - :id_prefix: GH2_ - :layout: focus_l - :style: blue_border -{%endif%} +.. figure:: /_images/github_issue_4.png + :scale: 80% + + Example of a github Issue collected with Sphinx-Needs. Need type +++++++++ @@ -273,10 +253,6 @@ Search for all commits of Sphinx-Needs, which have ``Python`` in their message. :query: repo:useblocks/sphinx-needs python :max_amount: 2 -.. needservice:: github-commits - :query: repo:useblocks/sphinx-needs python - :max_amount: 2 - **Specific commit** Document commit ``a4a596`` of **Sphinx-Needs**. @@ -286,8 +262,6 @@ Document commit ``a4a596`` of **Sphinx-Needs**. .. needservice:: github-commits :specific: useblocks/sphinx-needs/a4a596 -.. needservice:: github-commits - :specific: useblocks/sphinx-needs/a4a596113 Filtering +++++++++ diff --git a/docs/services/open_needs.rst b/docs/services/open_needs.rst index 55663ce61..5b5f72979 100644 --- a/docs/services/open_needs.rst +++ b/docs/services/open_needs.rst @@ -216,22 +216,9 @@ Examples **Result** -{% if on_ci != true %} - -.. needservice:: open-needs - :prefix: ONS_ - :params: skip=0;limit=10 - -.. needtable:: - :filter: "ONS" in id - :columns: id, title, status, type - :style: table - -{% else %} .. hint:: The below examples are just images, as no Open-Needs Server instance was available during documentation build. - In order for this to work, you must set the ``ON_CI`` environment variable to ``True`` .. image:: /_images/ons_example.png :align: center @@ -239,6 +226,4 @@ Examples .. image:: /_images/ons_table.png :align: center - :width: 60% - -{% endif %} \ No newline at end of file + :width: 60% \ No newline at end of file diff --git a/noxfile.py b/noxfile.py index 0310406d5..85f54d0cb 100644 --- a/noxfile.py +++ b/noxfile.py @@ -77,7 +77,6 @@ def benchmark_time(session): "--benchmark-json", "output.json", external=True, - env={"ON_CI": "true", "FAST_BUILD": "true"}, ) @@ -94,7 +93,6 @@ def benchmark_memory(session): "--benchmark-json", "output.json", external=True, - env={"ON_CI": "true", "FAST_BUILD": "true"}, ) session.run("memray", "flamegraph", "-o", "mem_out.html", "mem_out.bin") diff --git a/sphinx_needs/functions/common.py b/sphinx_needs/functions/common.py index 230eb339a..a256834a6 100644 --- a/sphinx_needs/functions/common.py +++ b/sphinx_needs/functions/common.py @@ -112,7 +112,7 @@ def copy(app: Sphinx, need, needs, option, need_id=None, lower: bool = False, up .. test:: test of current_need value :id: copy_4 - The following copy command copies the title of the first need found under the same highest + The es the title of the first need found under the same highest section (headline): [[copy('title', filter='current_need["sections"][-1]==sections[-1]')]] diff --git a/tests/benchmarks/test_official.py b/tests/benchmarks/test_official.py index ce2b47a45..b2f3ba6a8 100644 --- a/tests/benchmarks/test_official.py +++ b/tests/benchmarks/test_official.py @@ -1,4 +1,3 @@ -import os import re from pathlib import Path @@ -20,9 +19,6 @@ def test_official_time(test_app, benchmark): ) responses.add(responses.GET, re.compile(r"https://avatars.githubusercontent.com/.*"), body="") - os.environ["ON_CI"] = "true" - os.environ["FAST_BUILD"] = "true" - app = test_app benchmark.pedantic(app.builder.build_all, rounds=1, iterations=1) @@ -43,9 +39,6 @@ def test_official_memory(test_app): ) responses.add(responses.GET, re.compile(r"https://avatars.githubusercontent.com/.*"), body="") - os.environ["ON_CI"] = "true" - os.environ["FAST_BUILD"] = "true" - app = test_app # Okay, that's really ugly. From 036c723a779422843d30e8e3f4cecf4077d30497 Mon Sep 17 00:00:00 2001 From: Daniel Woste Date: Fri, 18 Aug 2023 13:32:27 +0200 Subject: [PATCH 31/48] Docker fix --- .github/workflows/docker.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index 19a5fe902..cfd696659 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -34,7 +34,7 @@ jobs: uses: actions/checkout@v3.5.3 - name: Set up Docker Build 🐋 - uses: docker/setup-buildx-action@v1 + uses: docker/setup-buildx-action@v2 - name: Extract metadata (tags, labels) for Docker id: meta From d3e0f901a166f850214e1aab4f87c0dd78f9d2d9 Mon Sep 17 00:00:00 2001 From: Daniel Woste Date: Fri, 18 Aug 2023 13:45:04 +0200 Subject: [PATCH 32/48] Removing docker context: ci --- .github/workflows/docker.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index cfd696659..ed8258380 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -67,7 +67,6 @@ jobs: with: push: ${{ github.event_name != 'pull_request' && steps.deploycheck.outputs.value == 'y' }} file: docker/Dockerfile - context: ci platforms: linux/amd64,linux/arm64 build-args: | NEEDS_VERSION=${{ env.NEEDS_VERSION }} From e144909c19967370e75a48252e829af86fc415eb Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Mon, 21 Aug 2023 09:54:30 +0200 Subject: [PATCH 33/48] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Change=20`NeedsBuild?= =?UTF-8?q?er`=20format=20to=20`needs`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sphinx_needs/builder.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sphinx_needs/builder.py b/sphinx_needs/builder.py index 08285ff2f..648b921ae 100644 --- a/sphinx_needs/builder.py +++ b/sphinx_needs/builder.py @@ -16,7 +16,7 @@ class NeedsBuilder(Builder): name = "needs" - format = "json" + format = "needs" file_suffix = ".txt" links_suffix = None From d229036625ecc7095b1e37a22c9475d3f7f9d224 Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Mon, 21 Aug 2023 10:01:28 +0200 Subject: [PATCH 34/48] Update changelog.rst --- docs/changelog.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/changelog.rst b/docs/changelog.rst index c6db51cc5..60def9be2 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -22,6 +22,8 @@ Released: under development * Improvement: Reduce document build time, by memoizing the inline parse in ``build_need`` (`#968 `_) +* Change `NeedsBuilder` format to `needs` (`#978 `_) + 1.3.0 ----- Released: 16.08.2023 From 4ead31a94cf3287a91626e5f4cd86bc6a45f2a30 Mon Sep 17 00:00:00 2001 From: Namnn07 Date: Tue, 18 Jul 2023 13:34:51 +0700 Subject: [PATCH 35/48] add builder needs look up for permalink --- docs/conf.py | 3 --- sphinx_needs/needs.py | 7 ++++++- sphinx_needs/templates/permalink.html | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 874669839..7542a8c9d 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -364,9 +364,6 @@ def custom_defined_func(): # build needs_lut.json to make permalinks work needs_lut_build_json = False -# build needs_lut.json to make permalinks work -needs_lut_build_json = False - # Add any paths that contain templates here, relative to this directory. templates_path = ["_templates"] diff --git a/sphinx_needs/needs.py b/sphinx_needs/needs.py index 75bd26200..e68ab67e8 100644 --- a/sphinx_needs/needs.py +++ b/sphinx_needs/needs.py @@ -14,9 +14,11 @@ NeedsBuilder, NeedsLookUpTableBuilder, NeedumlsBuilder, + NeedsLookUpTableBuilder, build_needs_json, build_needs_look_up_json, build_needumls_pumls, + build_needs_look_up_json ) from sphinx_needs.config import NEEDS_CONFIG from sphinx_needs.defaults import ( @@ -286,6 +288,9 @@ def setup(app: Sphinx) -> Dict[str, Any]: # app.add_config_value("needs_debug_measurement", False, "html", types=[dict]) + app.add_config_value("needs_lut_build", False, "html", types=[bool]) + app.add_config_value("needs_lut_file", "needs_lut.json", "html") + app.add_config_value("needs_permalink_url", None, "html") # Define nodes app.add_node(Need, html=(html_visit, html_depart), latex=(latex_visit, latex_depart)) app.add_node( @@ -381,7 +386,7 @@ def setup(app: Sphinx) -> Dict[str, Any]: app.connect("build-finished", debug.process_timing) app.connect("env-updated", install_lib_static_files) app.connect("env-updated", install_permalink_file) - + # This should be called last, so that need-styles can override styles from used libraries app.connect("env-updated", install_styles_static_files) diff --git a/sphinx_needs/templates/permalink.html b/sphinx_needs/templates/permalink.html index 13aa57a3a..433e834fc 100644 --- a/sphinx_needs/templates/permalink.html +++ b/sphinx_needs/templates/permalink.html @@ -21,7 +21,7 @@ } function main() { - loadJSON('{{ needs_file }}', function (response) { + loadJSON('needs_lut.json', function (response) { const needs = JSON.parse(response); if(needs.hasOwnProperty("current_version")) { const needs = JSON.parse(response); From c6723eadfb5f751d284e6722dc5d237b622f1554 Mon Sep 17 00:00:00 2001 From: Namnn07 Date: Thu, 10 Aug 2023 14:47:55 +0700 Subject: [PATCH 36/48] fix ci test --- sphinx_needs/needs.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sphinx_needs/needs.py b/sphinx_needs/needs.py index e68ab67e8..4fc4c47bc 100644 --- a/sphinx_needs/needs.py +++ b/sphinx_needs/needs.py @@ -14,11 +14,9 @@ NeedsBuilder, NeedsLookUpTableBuilder, NeedumlsBuilder, - NeedsLookUpTableBuilder, build_needs_json, build_needs_look_up_json, build_needumls_pumls, - build_needs_look_up_json ) from sphinx_needs.config import NEEDS_CONFIG from sphinx_needs.defaults import ( @@ -269,7 +267,7 @@ def setup(app: Sphinx) -> Dict[str, Any]: # path to permalink.html; absolute path from web-root app.add_config_value("needs_permalink_file", "permalink.html", "html") # path to needs.json relative to permalink.html - app.add_config_value("needs_permalink_data", "needs.json", "html") + app.add_config_value("needs_permalink_data", "needs_lut.json", "html") # path to needs_report_template file which is based on the conf.py directory. app.add_config_value("needs_report_template", "", "html", types=[str]) @@ -386,7 +384,7 @@ def setup(app: Sphinx) -> Dict[str, Any]: app.connect("build-finished", debug.process_timing) app.connect("env-updated", install_lib_static_files) app.connect("env-updated", install_permalink_file) - + # This should be called last, so that need-styles can override styles from used libraries app.connect("env-updated", install_styles_static_files) From d0e7849e0b28b44e4b11d2a54ade2755fbf3ea38 Mon Sep 17 00:00:00 2001 From: Namnn07 Date: Fri, 11 Aug 2023 11:19:59 +0700 Subject: [PATCH 37/48] update confiration for needs_lut --- docs/configuration.rst | 1 - sphinx_needs/needs.py | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/configuration.rst b/docs/configuration.rst index 84dbedd2b..b461a1756 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -1853,7 +1853,6 @@ an absolute path (on the web server) or an URL. Default value: ``needs.json`` -You can choose needs_lut_build_json ``needs_lut.json`` after setting :ref:`needs_lut_build_json` .. _needs_constraints: diff --git a/sphinx_needs/needs.py b/sphinx_needs/needs.py index 4fc4c47bc..a4dfde8e1 100644 --- a/sphinx_needs/needs.py +++ b/sphinx_needs/needs.py @@ -268,6 +268,8 @@ def setup(app: Sphinx) -> Dict[str, Any]: app.add_config_value("needs_permalink_file", "permalink.html", "html") # path to needs.json relative to permalink.html app.add_config_value("needs_permalink_data", "needs_lut.json", "html") + # add config mode permalink + app.add_config_value("needs_lut_mode", False, "html", types=[bool]) # path to needs_report_template file which is based on the conf.py directory. app.add_config_value("needs_report_template", "", "html", types=[str]) @@ -287,7 +289,7 @@ def setup(app: Sphinx) -> Dict[str, Any]: app.add_config_value("needs_debug_measurement", False, "html", types=[dict]) app.add_config_value("needs_lut_build", False, "html", types=[bool]) - app.add_config_value("needs_lut_file", "needs_lut.json", "html") + app.add_config_value("needs_permalink_url", None, "html") # Define nodes app.add_node(Need, html=(html_visit, html_depart), latex=(latex_visit, latex_depart)) From 2faeec3b2caa7a6d61451566e37c8fc00f34149e Mon Sep 17 00:00:00 2001 From: Namnn07 Date: Tue, 15 Aug 2023 13:26:24 +0700 Subject: [PATCH 38/48] add test-case and fix some setting for need per id builder --- docs/configuration.rst | 1 + sphinx_needs/needs.py | 1 - sphinx_needs/templates/permalink.html | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/configuration.rst b/docs/configuration.rst index b461a1756..84dbedd2b 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -1853,6 +1853,7 @@ an absolute path (on the web server) or an URL. Default value: ``needs.json`` +You can choose needs_lut_build_json ``needs_lut.json`` after setting :ref:`needs_lut_build_json` .. _needs_constraints: diff --git a/sphinx_needs/needs.py b/sphinx_needs/needs.py index a4dfde8e1..3105a8fb1 100644 --- a/sphinx_needs/needs.py +++ b/sphinx_needs/needs.py @@ -290,7 +290,6 @@ def setup(app: Sphinx) -> Dict[str, Any]: app.add_config_value("needs_lut_build", False, "html", types=[bool]) - app.add_config_value("needs_permalink_url", None, "html") # Define nodes app.add_node(Need, html=(html_visit, html_depart), latex=(latex_visit, latex_depart)) app.add_node( diff --git a/sphinx_needs/templates/permalink.html b/sphinx_needs/templates/permalink.html index 433e834fc..13aa57a3a 100644 --- a/sphinx_needs/templates/permalink.html +++ b/sphinx_needs/templates/permalink.html @@ -21,7 +21,7 @@ } function main() { - loadJSON('needs_lut.json', function (response) { + loadJSON('{{ needs_file }}', function (response) { const needs = JSON.parse(response); if(needs.hasOwnProperty("current_version")) { const needs = JSON.parse(response); From de90ff29f8ba50a50b1b7cf0f6c1b8d3494196e8 Mon Sep 17 00:00:00 2001 From: Namnn07 Date: Tue, 22 Aug 2023 14:27:45 +0700 Subject: [PATCH 39/48] fix merge version 1.3.0 --- docs/builders.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/builders.rst b/docs/builders.rst index 2a9dd13c8..ed243b732 100644 --- a/docs/builders.rst +++ b/docs/builders.rst @@ -168,7 +168,7 @@ or needs_lut -------- -.. versionadded:: 1.3.0 +.. versionadded:: 1.4.0 The **needs_lut** builder exports all found needs to a single json file, which only include list of key ``id`` and value of ``docname`` or ``external_url``. From 569d5a69427220a6378b94720686278496389f07 Mon Sep 17 00:00:00 2001 From: Namnn07 Date: Tue, 22 Aug 2023 14:29:27 +0700 Subject: [PATCH 40/48] fix merge version 1.3.0 --- docs/builders.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/builders.rst b/docs/builders.rst index ed243b732..857bc8603 100644 --- a/docs/builders.rst +++ b/docs/builders.rst @@ -167,7 +167,7 @@ or .. _needs_lut_builder: needs_lut --------- +--------- .. versionadded:: 1.4.0 The **needs_lut** builder exports all found needs to a single json file, which only include list of key ``id`` and value of ``docname`` or ``external_url``. From 830c12a865454e720d15772963258bd6a337dbee Mon Sep 17 00:00:00 2001 From: Namnn07 Date: Thu, 24 Aug 2023 09:11:38 +0700 Subject: [PATCH 41/48] update format builder --- sphinx_needs/builder.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sphinx_needs/builder.py b/sphinx_needs/builder.py index 648b921ae..8729c7718 100644 --- a/sphinx_needs/builder.py +++ b/sphinx_needs/builder.py @@ -162,7 +162,7 @@ def build_needumls_pumls(app: Sphinx, _exception: Exception) -> None: class NeedsLookUpTableBuilder(Builder): name = "needs_lut" - format = "json" + format = "needs" file_suffix = ".txt" links_suffix = None From ff74834efb6590910d89a043d50e757adea5dbd8 Mon Sep 17 00:00:00 2001 From: Namnn07 Date: Mon, 11 Sep 2023 16:40:18 +0700 Subject: [PATCH 42/48] turn off needs_lut_build_json --- docs/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index bdec87478..aca818241 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -365,7 +365,7 @@ def custom_defined_func(): needs_build_json_per_id = False # build needs_lut.json to make permalinks work -needs_lut_build_json = True +needs_lut_build_json = False # Add any paths that contain templates here, relative to this directory. templates_path = ["_templates"] From b69da59282985ef2d2b1775aef8c1ba3da526547 Mon Sep 17 00:00:00 2001 From: Namnn07 Date: Mon, 11 Sep 2023 16:42:03 +0700 Subject: [PATCH 43/48] change test case name --- tests/test_needs_look_up.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_needs_look_up.py b/tests/test_needs_look_up.py index bb618ea4e..f8ff1677a 100644 --- a/tests/test_needs_look_up.py +++ b/tests/test_needs_look_up.py @@ -7,7 +7,7 @@ @pytest.mark.parametrize( "test_app", [{"buildername": "needs_lut", "srcdir": "doc_test/doc_needs_builder"}], indirect=True ) -def test_doc_needs_id_builder(test_app): +def test_doc_needs_lut_builder(test_app): app = test_app app.build() From c77162c57a5bbe884277fa4900a0c0f478ce704d Mon Sep 17 00:00:00 2001 From: Namnn07 Date: Mon, 18 Sep 2023 20:10:46 +0700 Subject: [PATCH 44/48] refix needs look up builder, test_case --- docs/changelog.rst | 2 +- docs/conf.py | 2 +- docs/configuration.rst | 7 ++- sphinx_needs/builder.py | 18 ++++--- sphinx_needs/config.py | 2 +- sphinx_needs/templates/permalink.html | 60 ++++++++------------- tests/__snapshots__/test_needs_look_up.ambr | 32 +++++++++++ tests/test_needs_look_up.py | 14 +++-- 8 files changed, 76 insertions(+), 61 deletions(-) create mode 100644 tests/__snapshots__/test_needs_look_up.ambr diff --git a/docs/changelog.rst b/docs/changelog.rst index 0e956265f..826bafa4c 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -15,7 +15,7 @@ Released: under development 1.4.0 ----- Released: under development -* Improvement: Added Builder :ref:`needs_lut_builder` and config option :ref:`needs_lut_build_json` in `conf.py`. +* Improvement: Added Builder :ref:`needs_lut_builder` and config option :ref:`needs_build_lut_json` in `conf.py`. * Improvement: Added Builder :ref:`needs_id_builder` added and config option :ref:`needs_build_json_per_id` in `conf.py`. diff --git a/docs/conf.py b/docs/conf.py index aca818241..9189ba1cb 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -365,7 +365,7 @@ def custom_defined_func(): needs_build_json_per_id = False # build needs_lut.json to make permalinks work -needs_lut_build_json = False +needs_build_lut_json = False # Add any paths that contain templates here, relative to this directory. templates_path = ["_templates"] diff --git a/docs/configuration.rst b/docs/configuration.rst index b721d002a..00867b7ca 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -1897,7 +1897,6 @@ an absolute path (on the web server) or an URL. Default value: ``needs.json`` -You can choose needs_lut_build_json ``needs_lut.json`` after setting :ref:`needs_lut_build_json` .. _needs_constraints: @@ -2335,9 +2334,9 @@ Default value: True Can be overwritten for each single need by setting :ref:`need_collapse`. -.. __needs_lut_build_json: +.. _needs_build_lut_json: -needs_lut_build_json +needs_build_lut_json ~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 1.4.0 @@ -2350,7 +2349,7 @@ Example: .. code-block:: python - needs_lut_build_json = False + needs_build_lut_json = False .. hint:: diff --git a/sphinx_needs/builder.py b/sphinx_needs/builder.py index 8cd26d333..06b59ca26 100644 --- a/sphinx_needs/builder.py +++ b/sphinx_needs/builder.py @@ -248,22 +248,24 @@ def write_doc(self, docname: str, doctree: nodes.document) -> None: def finish(self) -> None: env = self.env data = SphinxNeedsData(env) - needs = data.get_or_create_needs().values() # We need a list of needs for later filter checks needs_dict = {} needs_config = NeedsSphinxConfig(env.config) filter_string = needs_config.builder_filter from sphinx_needs.filter_common import filter_needs - filtered_needs = filter_needs(self.app, needs, filter_string) + version = getattr(env.config, "version", "unset") + needs_list = NeedsList(env.config, self.outdir, self.srcdir) + needs_list.wipe_version(version) + filtered_needs: List[NeedsInfoType] = filter_needs(self.app, data.get_or_create_needs().values(), filter_string) for need in filtered_needs: if need["is_external"]: - needs_dict[need["id"]] = need["external_url"] + needs_dict = {"id": need["id"], "docname": need["external_url"], "content": need["content"]} + else: - needs_dict[need["id"]] = need["docname"] + needs_dict = {"id": need["id"], "docname": need["docname"], "content": need["content"]} + need["docname"] = need["external_url"] - version = getattr(env.config, "version", "unset") - needs_list = NeedsList(env.config, self.outdir, self.srcdir) - needs_list.add_lut_need(version, needs_dict) + needs_list.add_need(version, needs_dict) try: needs_list.write_json("needs_lut.json") except Exception as e: @@ -290,7 +292,7 @@ def get_target_uri(self, _docname: str, _typ: Optional[str] = None) -> str: def build_needs_look_up_json(app: Sphinx, _exception: Exception) -> None: env = app.env - if not NeedsSphinxConfig(env.config).lut_build_json: + if not NeedsSphinxConfig(env.config).build_lut_json: return # Do not create an additional look up table json, if builder is already in use. diff --git a/sphinx_needs/config.py b/sphinx_needs/config.py index f3bad6254..8a14b4cc3 100644 --- a/sphinx_needs/config.py +++ b/sphinx_needs/config.py @@ -252,7 +252,7 @@ def __setattr__(self, name: str, value: Any) -> None: # add config for needs_id_builder build_json_per_id: bool = field(default=False, metadata={"rebuild": "html", "types": (bool,)}) build_json_per_id_path: str = field(default="needs_id", metadata={"rebuild": "html", "types": (str,)}) - lut_build_json: bool = field(default=False, metadata={"rebuild": "html", "types": (bool,)}) + build_lut_json: bool = field(default=False, metadata={"rebuild": "html", "types": (bool,)}) @classmethod def add_config_values(cls, app: Sphinx) -> None: diff --git a/sphinx_needs/templates/permalink.html b/sphinx_needs/templates/permalink.html index 13aa57a3a..1438036f5 100644 --- a/sphinx_needs/templates/permalink.html +++ b/sphinx_needs/templates/permalink.html @@ -23,51 +23,35 @@ function main() { loadJSON('{{ needs_file }}', function (response) { const needs = JSON.parse(response); - if(needs.hasOwnProperty("current_version")) { - const needs = JSON.parse(response); - const current_version = needs['current_version']; - const versions = needs['versions']; - const version = versions[current_version]; - const needs_obj = version['needs']; + const current_version = needs['current_version']; + const versions = needs['versions']; + const version = versions[current_version]; + const needs_obj = version['needs']; - const id = getParameterByName('id'); - var pathname = new URL(window.location.href).pathname; - pathname = pathname.substring(0, pathname.lastIndexOf('{{ permalink_file }}')); + const id = getParameterByName('id'); + var pathname = new URL(window.location.href).pathname; - const keys = Object.keys(needs_obj); + pathname = pathname.substring(0, pathname.lastIndexOf('{{ permalink_file }}')); - var docname = 'index'; + const keys = Object.keys(needs_obj); - keys.forEach((key, index) => { - if (key === id) { - const need = needs_obj[key]; - docname = need['docname']; - return; - } - }); + var docname = 'index'; - window.location.replace(pathname + docname + '.html#' + id); - } - else { - const needs = JSON.parse(response); - const id = getParameterByName('id'); - var pathname = new URL(window.location.href).pathname; - pathname = pathname.substring(0, pathname.lastIndexOf('permalink.html')); - const keys = Object.keys(needs); - var docname = 'index'; - keys.forEach((key, index) => { - if (key === id) { - docname = needs[key]; - return; - } - }); - - if (docname.includes("#" + id)) { - window.location.replace(pathname + docname); - } else { - window.location.replace(pathname + docname + '.html#' + id); + keys.forEach((key, index) => { + if (key === id) { + const need = needs_obj[key]; + docname = need['docname']; + return; } + }); + + if (docname.includes("#" + id)) { + window.location.replace(pathname + docname); + } else { + window.location.replace(pathname + docname + '.html#' + id); } + + }); diff --git a/tests/__snapshots__/test_needs_look_up.ambr b/tests/__snapshots__/test_needs_look_up.ambr new file mode 100644 index 000000000..7a6465458 --- /dev/null +++ b/tests/__snapshots__/test_needs_look_up.ambr @@ -0,0 +1,32 @@ +# serializer version: 1 +# name: test_doc_needs_lut_builder[test_app0] + dict({ + 'current_version': '1.0', + 'project': 'Python', + 'versions': dict({ + '1.0': dict({ + 'filters': dict({ + }), + 'filters_amount': 0, + 'needs': dict({ + 'TC_001': dict({ + 'description': '', + 'docname': 'index', + 'id': 'TC_001', + }), + 'TC_NEG_001': dict({ + 'description': '', + 'docname': 'index', + 'id': 'TC_NEG_001', + }), + 'US_63252': dict({ + 'description': '', + 'docname': 'index', + 'id': 'US_63252', + }), + }), + 'needs_amount': 3, + }), + }), + }) +# --- diff --git a/tests/test_needs_look_up.py b/tests/test_needs_look_up.py index f8ff1677a..e4f3dd834 100644 --- a/tests/test_needs_look_up.py +++ b/tests/test_needs_look_up.py @@ -2,18 +2,16 @@ from pathlib import Path import pytest +from syrupy.filters import props @pytest.mark.parametrize( "test_app", [{"buildername": "needs_lut", "srcdir": "doc_test/doc_needs_builder"}], indirect=True ) -def test_doc_needs_lut_builder(test_app): +def test_doc_needs_lut_builder(test_app, snapshot): app = test_app app.build() - - needs_json = Path(app.outdir, "needs_lut.json") - with open(needs_json) as needs_file: - needs_file_content = needs_file.read() - - needs_list = json.loads(needs_file_content) - assert needs_list["TC_NEG_001"] + needs_list = json.loads(Path(app.outdir, "needs_lut.json").read_text()) + print(needs_list) + print(snapshot(exclude=props("created"))) + assert needs_list == snapshot(exclude=props("created")) From 5fdcd3cdf6a48f705567efb2e73b81671c79ebe4 Mon Sep 17 00:00:00 2001 From: Daniel Woste Date: Wed, 20 Sep 2023 09:58:38 +0200 Subject: [PATCH 45/48] =?UTF-8?q?=F0=9F=91=8C=20Optimize=20needextend=20fi?= =?UTF-8?q?lter=5Fneeds=20usage=20(#1030)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of using `filter_needs()` for a single need (`id == ""XY`) , the need is taken directly from `all_needs`, so that we do not need to perform any filtering. --- docs/changelog.rst | 13 +++++++------ sphinx_needs/directives/needextend.py | 15 ++++++++------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 826bafa4c..7dfdd90aa 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -18,12 +18,13 @@ Released: under development * Improvement: Added Builder :ref:`needs_lut_builder` and config option :ref:`needs_build_lut_json` in `conf.py`. * Improvement: Added Builder :ref:`needs_id_builder` added and config option :ref:`needs_build_json_per_id` in `conf.py`. - -* Improvement: Reduce document build time, by memoizing the inline parse in ``build_need`` (`#968 `_) - -* Change `NeedsBuilder` format to `needs` (`#978 `_) - -* Improvement: Suffix all warnings with ``[needs]``, and allow them to be suppressed (`#975 `_) +* Improvement: Reduce document build time, by memoizing the inline parse in ``build_need`` + (`#968 `_) +* Change `NeedsBuilder` format to `needs` + (`#978 `_) +* Improvement: Suffix all warnings with ``[needs]``, and allow them to be suppressed + (`#975 `_) +* Improvement: :ref:`needextend` for single needs is much faster. 1.3.0 ----- diff --git a/sphinx_needs/directives/needextend.py b/sphinx_needs/directives/needextend.py index 8be299274..2697e975e 100644 --- a/sphinx_needs/directives/needextend.py +++ b/sphinx_needs/directives/needextend.py @@ -97,7 +97,7 @@ def process_needextend(app: Sphinx, doctree: nodes.document, fromdocname: str) - # In this case create the needed filter string need_filter = current_needextend["filter"] if need_filter in all_needs: - need_filter = f'id == "{need_filter}"' + found_needs = [all_needs[need_filter]] # If it looks like a need id, but we haven't found one, raise an exception elif need_filter is not None and re.fullmatch(needs_config.id_regex, need_filter): error = f"Provided id {need_filter} for needextend does not exist." @@ -106,12 +106,13 @@ def process_needextend(app: Sphinx, doctree: nodes.document, fromdocname: str) - else: logger.info(error) continue - try: - found_needs = filter_needs(app, all_needs.values(), need_filter) - except NeedsInvalidFilter as e: - raise NeedsInvalidFilter( - f"Filter not valid for needextend on page {current_needextend['docname']}:\n{e}" - ) + else: + try: + found_needs = filter_needs(app, all_needs.values(), need_filter) + except NeedsInvalidFilter as e: + raise NeedsInvalidFilter( + f"Filter not valid for needextend on page {current_needextend['docname']}:\n{e}" + ) for found_need in found_needs: # Work in the stored needs, not on the search result From fd1f612516904eab0fa8e2f783709bd9fd318e71 Mon Sep 17 00:00:00 2001 From: Namnn07 Date: Mon, 25 Sep 2023 14:48:07 +0700 Subject: [PATCH 46/48] change logic write_lut_json and test case --- docs/builders.rst | 2 +- sphinx_needs/builder.py | 16 ++++------------ sphinx_needs/needsfile.py | 20 +++++++++++++++++--- sphinx_needs/templates/permalink.html | 9 ++++++++- tests/__snapshots__/test_needs_look_up.ambr | 18 +++--------------- tests/test_needs_look_up.py | 2 -- 6 files changed, 33 insertions(+), 34 deletions(-) diff --git a/docs/builders.rst b/docs/builders.rst index c738a39b2..e284aa949 100644 --- a/docs/builders.rst +++ b/docs/builders.rst @@ -173,7 +173,7 @@ needs_id The **needs_id** builder exports all found needs and selected filter results to a set json files of each need with the name is ``id`` of need. -The build creates a folder called :ref:``needs_build_json_per_id_path`` and all file json of each need inside the given build-folder. +The build creates a folder called :ref:`needs_build_json_per_id_path` and all file json of each need inside the given build-folder. Usage +++++ diff --git a/sphinx_needs/builder.py b/sphinx_needs/builder.py index 06b59ca26..d986eeaf0 100644 --- a/sphinx_needs/builder.py +++ b/sphinx_needs/builder.py @@ -248,26 +248,18 @@ def write_doc(self, docname: str, doctree: nodes.document) -> None: def finish(self) -> None: env = self.env data = SphinxNeedsData(env) - needs_dict = {} + needs = data.get_or_create_needs().values() # We need a list of needs for later filter checks needs_config = NeedsSphinxConfig(env.config) filter_string = needs_config.builder_filter from sphinx_needs.filter_common import filter_needs version = getattr(env.config, "version", "unset") needs_list = NeedsList(env.config, self.outdir, self.srcdir) - needs_list.wipe_version(version) - filtered_needs: List[NeedsInfoType] = filter_needs(self.app, data.get_or_create_needs().values(), filter_string) + filtered_needs = filter_needs(self.app, needs, filter_string) for need in filtered_needs: - if need["is_external"]: - needs_dict = {"id": need["id"], "docname": need["external_url"], "content": need["content"]} - - else: - needs_dict = {"id": need["id"], "docname": need["docname"], "content": need["content"]} - need["docname"] = need["external_url"] - - needs_list.add_need(version, needs_dict) + needs_list.add_need(version, need) try: - needs_list.write_json("needs_lut.json") + needs_list.write_lut_json(version, "needs_lut.json") except Exception as e: log.error(f"Error during writing json file: {e}") else: diff --git a/sphinx_needs/needsfile.py b/sphinx_needs/needsfile.py index cf281abf4..d82077036 100644 --- a/sphinx_needs/needsfile.py +++ b/sphinx_needs/needsfile.py @@ -7,7 +7,7 @@ import os import sys from datetime import datetime -from typing import Any, Dict, List +from typing import Any, List from jsonschema import Draft7Validator from sphinx.config import Config @@ -131,8 +131,22 @@ def load_json(self, file: str) -> None: self.log.debug(f"needs.json file loaded: {file}") - def add_lut_need(self, version: str, needs_lut: Dict[str, Any]) -> None: - self.needs_list = needs_lut + def write_lut_json(self, version: str, needs_file: str = "needs.json") -> None: + self.needs_list["created"] = datetime.now().isoformat() + self.needs_list["current_version"] = self.current_version + self.needs_list["project"] = self.project + needs_lut = self.needs_list["versions"][version]["needs"] + + for need_id in list(needs_lut.keys()): + if needs_lut[need_id].get("is_external"): + self.needs_list["versions"][version]["needs"][need_id] = needs_lut[need_id].get("external") + else: + self.needs_list["versions"][version]["needs"][need_id] = needs_lut[need_id].get("docname") + + needs_dir = self.outdir + + with open(os.path.join(needs_dir, needs_file), "w") as f: + json.dump(self.needs_list, f, indent=4, sort_keys=True) class Errors: diff --git a/sphinx_needs/templates/permalink.html b/sphinx_needs/templates/permalink.html index 1438036f5..8f324d6b2 100644 --- a/sphinx_needs/templates/permalink.html +++ b/sphinx_needs/templates/permalink.html @@ -40,7 +40,14 @@ keys.forEach((key, index) => { if (key === id) { const need = needs_obj[key]; - docname = need['docname']; + if (typeof need === "object"){ + // need.json file + docname = need['docname']; + } + else { + // need_lut file only value is docname or external_link + docname = need + } return; } }); diff --git a/tests/__snapshots__/test_needs_look_up.ambr b/tests/__snapshots__/test_needs_look_up.ambr index 7a6465458..d0fbfd623 100644 --- a/tests/__snapshots__/test_needs_look_up.ambr +++ b/tests/__snapshots__/test_needs_look_up.ambr @@ -9,21 +9,9 @@ }), 'filters_amount': 0, 'needs': dict({ - 'TC_001': dict({ - 'description': '', - 'docname': 'index', - 'id': 'TC_001', - }), - 'TC_NEG_001': dict({ - 'description': '', - 'docname': 'index', - 'id': 'TC_NEG_001', - }), - 'US_63252': dict({ - 'description': '', - 'docname': 'index', - 'id': 'US_63252', - }), + 'TC_001': 'index', + 'TC_NEG_001': 'index', + 'US_63252': 'index', }), 'needs_amount': 3, }), diff --git a/tests/test_needs_look_up.py b/tests/test_needs_look_up.py index e4f3dd834..6843cb8cc 100644 --- a/tests/test_needs_look_up.py +++ b/tests/test_needs_look_up.py @@ -12,6 +12,4 @@ def test_doc_needs_lut_builder(test_app, snapshot): app = test_app app.build() needs_list = json.loads(Path(app.outdir, "needs_lut.json").read_text()) - print(needs_list) - print(snapshot(exclude=props("created"))) assert needs_list == snapshot(exclude=props("created")) From 6649155d9c30f7bb54c28b7b07f9f6478c61f34d Mon Sep 17 00:00:00 2001 From: Namnn07 Date: Mon, 25 Sep 2023 17:53:50 +0700 Subject: [PATCH 47/48] git commit -m"fix conflict changelog.rst" --- docs/builders.rst | 68 ++++++++++++++++----------- docs/changelog.rst | 2 +- sphinx_needs/external_needs.py | 15 +++++- sphinx_needs/templates/permalink.html | 2 +- 4 files changed, 56 insertions(+), 31 deletions(-) diff --git a/docs/builders.rst b/docs/builders.rst index e284aa949..3410853a1 100644 --- a/docs/builders.rst +++ b/docs/builders.rst @@ -192,6 +192,7 @@ needs_lut The **needs_lut** (Needs Lookup Table) builder exports all found needs to a single json file, which only include list of key ``id`` and value of ``docname`` or ``external_url``. The build creates a file called **needs_lut.json** inside the given build-folder. + Usage +++++ @@ -203,32 +204,45 @@ Format ++++++ .. code-block:: python - - { - "extend_test_001": "directives/needextend", - "extend_test_002": "directives/needextend", - - "req_arch_001": "directives/needarch", - "req_arch_004": "directives/needarch", - - "spec_arch_001": "directives/needarch", - "test_arch_001": "directives/needarch", - "COMP_T_001": "directives/needarch", - "COMP_T_002": "directives/needarch", - "EX_REQ_1": "examples/index", - "EX_REQ_2": "examples/index", - - "R_F4722": "examples/index", - "OWN_ID_123": "examples/index", - "IMPL_01": "examples/index", - "T_C3893": "examples/index", - "R_2A9D0": "filter", - "R_22EB2": "filter", - "S_D70B0": "filter", - "S_01A67": "filter", - "T_5CCAA": "filter", - "R_17EB4": "filter", - "req_flow_001": "directives/needflow", - "spec_flow_001": "directives/needflow", + { + "created": "2023-09-25T17:11:03.162346", + "current_version": "1.3", + "project": "Sphinx-Needs", + "versions": { + "1.3": { + "created": "2023-09-25T17:11:03.162329", + "filters": {}, + "filters_amount": 0, + "needs": { + "extend_test_001": "directives/needextend", + "extend_test_002": "directives/needextend", + + "req_arch_001": "directives/needarch", + "req_arch_004": "directives/needarch", + + "spec_arch_001": "directives/needarch", + "test_arch_001": "directives/needarch", + "COMP_T_001": "directives/needarch", + "COMP_T_002": "directives/needarch", + + "EX_REQ_1": "examples/index", + "EX_REQ_2": "examples/index", + + "R_F4722": "examples/index", + "OWN_ID_123": "examples/index", + "IMPL_01": "examples/index", + "T_C3893": "examples/index", + "R_2A9D0": "filter", + "R_22EB2": "filter", + "S_D70B0": "filter", + "S_01A67": "filter", + "T_5CCAA": "filter", + "R_17EB4": "filter", + "req_flow_001": "directives/needflow", + "spec_flow_001": "directives/needflow", + } + } + } + } \ No newline at end of file diff --git a/docs/changelog.rst b/docs/changelog.rst index 7dfdd90aa..526d8b113 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -16,7 +16,6 @@ Released: under development ----- Released: under development * Improvement: Added Builder :ref:`needs_lut_builder` and config option :ref:`needs_build_lut_json` in `conf.py`. - * Improvement: Added Builder :ref:`needs_id_builder` added and config option :ref:`needs_build_json_per_id` in `conf.py`. * Improvement: Reduce document build time, by memoizing the inline parse in ``build_need`` (`#968 `_) @@ -25,6 +24,7 @@ Released: under development * Improvement: Suffix all warnings with ``[needs]``, and allow them to be suppressed (`#975 `_) * Improvement: :ref:`needextend` for single needs is much faster. +* Improvement: external_needs is using cached templates to save generation time. 1.3.0 ----- diff --git a/sphinx_needs/external_needs.py b/sphinx_needs/external_needs.py index 2c3af8c50..f46f7bd1f 100644 --- a/sphinx_needs/external_needs.py +++ b/sphinx_needs/external_needs.py @@ -1,8 +1,9 @@ import json import os +from functools import lru_cache import requests -from jinja2 import Environment +from jinja2 import Environment, Template from requests_file import FileAdapter from sphinx.application import Sphinx from sphinx.environment import BuildEnvironment @@ -17,6 +18,16 @@ log = get_logger(__name__) +@lru_cache(maxsize=20) +def get_target_template(target_url: str) -> Template: + """ + Provides template for target_link style + Can be cached, as the template is always the same for a given target_url + """ + mem_template = Environment().from_string(target_url) + return mem_template + + def load_external_needs(app: Sphinx, env: BuildEnvironment, _docname: str) -> None: needs_config = NeedsSphinxConfig(app.config) for source in needs_config.external_needs: @@ -95,7 +106,7 @@ def load_external_needs(app: Sphinx, env: BuildEnvironment, _docname: str) -> No if target_url: # render jinja content - mem_template = Environment().from_string(target_url) + mem_template = get_target_template(target_url) cal_target_url = mem_template.render(**{"need": need}) need_params["external_url"] = f'{source["base_url"]}/{cal_target_url}' else: diff --git a/sphinx_needs/templates/permalink.html b/sphinx_needs/templates/permalink.html index 8f324d6b2..b329e16cf 100644 --- a/sphinx_needs/templates/permalink.html +++ b/sphinx_needs/templates/permalink.html @@ -29,7 +29,7 @@ const needs_obj = version['needs']; const id = getParameterByName('id'); - var pathname = new URL(window.location.href).pathname; + var pathname = new URL(window.location.href).pathname; pathname = pathname.substring(0, pathname.lastIndexOf('{{ permalink_file }}')); From 4472aeda0b2674302b279b671f98932e2515ca7c Mon Sep 17 00:00:00 2001 From: agn8hc Date: Mon, 9 Oct 2023 16:43:36 +0700 Subject: [PATCH 48/48] refactor filter_needs in need_lut_builder --- sphinx_needs/builder.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sphinx_needs/builder.py b/sphinx_needs/builder.py index 56e9ee759..66e17d3e7 100644 --- a/sphinx_needs/builder.py +++ b/sphinx_needs/builder.py @@ -257,7 +257,7 @@ def finish(self) -> None: version = getattr(env.config, "version", "unset") needs_list = NeedsList(env.config, self.outdir, self.srcdir) - filtered_needs = filter_needs(self.app, needs, filter_string) + filtered_needs: List[NeedsInfoType] = filter_needs(needs, needs_config, filter_string) for need in filtered_needs: needs_list.add_need(version, need) try: