From 5dac61d7ada675f856273853acfe3072e9bbc1a7 Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Tue, 27 Aug 2024 14:05:48 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Add=20`needs=5Fjson=5Fexclude=5Ffie?= =?UTF-8?q?lds`=20configuration=20(#1246)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR replaces the hardcoded `NeedsList. JSON_KEY_EXCLUSIONS_NEEDS` with the `needs_json_exclude_fields` configuration, such that users can override what fields are excluded. Additionally, back links have been re-instated as being output as default (the size increase of the `needs.json` can now be mitigated by `needs_json_remove_defaults` and/or `needs_json_exclude_fields`) Finally, `"needs_defaults_removed": true` is now output in the `needs.json`, if defaults have been removed. This will allow tools reading the file to identify this. --- docs/builders.rst | 9 +- docs/conf.py | 12 + docs/configuration.rst | 14 + sphinx_needs/config.py | 19 +- sphinx_needs/data.py | 2 +- sphinx_needs/needsfile.py | 58 ++-- tests/__snapshots__/test_basic_doc.ambr | 28 ++ tests/__snapshots__/test_export_id.ambr | 116 +++++++ tests/__snapshots__/test_external.ambr | 66 ++++ tests/__snapshots__/test_import.ambr | 312 ++++++++++++++++++ .../__snapshots__/test_need_constraints.ambr | 54 +++ tests/__snapshots__/test_needextend.ambr | 93 ++++++ tests/__snapshots__/test_needs_builder.ambr | 85 +++++ .../__snapshots__/test_needs_id_builder.ambr | 12 + tests/__snapshots__/test_service_github.ambr | 36 ++ 15 files changed, 889 insertions(+), 27 deletions(-) diff --git a/docs/builders.rst b/docs/builders.rst index 8ea62ec9c..6743e0942 100644 --- a/docs/builders.rst +++ b/docs/builders.rst @@ -66,9 +66,11 @@ Format As well as the ``filters`` and ``needs`` data, the **needs.json** file also contains the ``needs_schema``. This is a JSON schema of for the data structure of a single need, and also includes a ``field_type`` for each field, to denote the source of the field, -that can be one of: ``core``, ``links``, ``extra``, ``global``. +that can be one of: ``core``, ``links``, ``backlinks``, ``extra``, ``global``. -See also :ref:`needs_build_json_per_id` and :ref:`needs_json_remove_defaults` for more options on modifying the content of the ``needs.json`` file. +See also :ref:`needs_json_exclude_fields`, :ref:`needs_json_remove_defaults`, and :ref:`needs_reproducible_json` for more options on modifying the content of the ``needs.json`` file. + +.. note:: ``needs_defaults_removed`` is a flag that is set to ``true`` if the defaults are removed from the needs. If it is missing or set to ``false``, the defaults are not removed. .. code-block:: python @@ -123,12 +125,12 @@ See also :ref:`needs_build_json_per_id` and :ref:`needs_json_remove_defaults` fo ... } }, + "needs_defaults_removed": true, "needs": { "IMPL_01": { "id": "IMPL_01", "type": "impl", "links": ["OWN_ID_123"], - "status": null, ... }, ... @@ -177,6 +179,7 @@ See also :ref:`needs_build_json_per_id` and :ref:`needs_json_remove_defaults` fo }, ... }, + "needs_defaults_removed": true, "needs": { "IMPL_01": { "id": "IMPL_01", diff --git a/docs/conf.py b/docs/conf.py index 0f8aa2399..485421fc2 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -643,6 +643,7 @@ def custom_defined_func(): # build needs.json to make permalinks work needs_build_json = True +needs_json_remove_defaults = True # build needs_json for every needs-id to make detail panel needs_build_json_per_id = False @@ -702,8 +703,10 @@ def custom_defined_func(): from docutils import nodes # noqa: E402 from sphinx.application import Sphinx # noqa: E402 from sphinx.directives import SphinxDirective # noqa: E402 +from sphinx.roles import SphinxRole # noqa: E402 from sphinx_needs.api.need import add_external_need # noqa: E402 +from sphinx_needs.config import NeedsSphinxConfig # noqa: E402 from sphinx_needs.data import SphinxNeedsData # noqa: E402 from sphinx_needs.needsfile import NeedsList # noqa: E402 @@ -741,6 +744,14 @@ def run(self): return [root] +class NeedConfigDefaultRole(SphinxRole): + """Role to add a default configuration value to the documentation.""" + + def run(self): + default = NeedsSphinxConfig.get_default(self.text) + return [[nodes.literal("", repr(default), language="python")], []] + + def create_tutorial_needs(app: Sphinx, _env, _docnames): """Create a JSON to import in the tutorial. @@ -771,4 +782,5 @@ def create_tutorial_needs(app: Sphinx, _env, _docnames): def setup(app: Sphinx): app.add_directive("need-example", NeedExampleDirective) + app.add_role("need_config_default", NeedConfigDefaultRole()) app.connect("env-before-read-docs", create_tutorial_needs, priority=600) diff --git a/docs/configuration.rst b/docs/configuration.rst index 7d0f0f8c3..8458622a2 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -1795,6 +1795,17 @@ needs_reproducible_json Setting ``needs_reproducible_json = True`` will ensure the ``needs.json`` output is reproducible, e.g. by removing timestamps from the output. +.. _needs_json_exclude_fields: + +needs_json_exclude_fields +~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. versionadded:: 2.2.0 + +Setting ``needs_json_exclude_fields = ["key1", "key2"]`` will exclude the given fields from all needs in the ``needs.json`` output. + +Default: :need_config_default:`json_exclude_fields` + .. _needs_json_remove_defaults: needs_json_remove_defaults @@ -1803,8 +1814,11 @@ needs_json_remove_defaults .. versionadded:: 2.1.0 Setting ``needs_json_remove_defaults = True`` will remove all need fields with default from ``needs.json``, greatly reducing its size. + The defaults can be retrieved from the ``needs_schema`` now also output in the JSON file (see :ref:`this section ` for the format). +Default: :need_config_default:`json_remove_defaults` + .. _needs_build_json_per_id: needs_build_json_per_id diff --git a/sphinx_needs/config.py b/sphinx_needs/config.py index 09fe967a0..4d7f538de 100644 --- a/sphinx_needs/config.py +++ b/sphinx_needs/config.py @@ -7,7 +7,7 @@ from sphinx.application import Sphinx from sphinx.config import Config as _SphinxConfig -from sphinx_needs.data import GraphvizStyleType +from sphinx_needs.data import GraphvizStyleType, NeedsCoreFields from sphinx_needs.defaults import DEFAULT_DIAGRAM_TEMPLATE if TYPE_CHECKING: @@ -442,6 +442,15 @@ def __setattr__(self, name: str, value: Any) -> None: default=False, metadata={"rebuild": "html", "types": (bool,)} ) """If True, the JSON needs file should be idempotent for multiple builds fo the same documentation.""" + json_exclude_fields: list[str] = field( + default_factory=lambda: [ + name + for name, params in NeedsCoreFields.items() + if params.get("exclude_json") + ], + metadata={"rebuild": "html", "types": (list,)}, + ) + """List of keys to exclude from the JSON needs file.""" json_remove_defaults: bool = field( default=False, metadata={"rebuild": "html", "types": (bool,)} ) @@ -525,3 +534,11 @@ def add_config_values(cls, app: Sphinx) -> None: item.metadata["rebuild"], types=item.metadata["types"], ) + + @classmethod + def get_default(cls, name: str) -> Any: + """Get the default value for a config item.""" + _field = next(field for field in fields(cls) if field.name == name) + if _field.default_factory is not MISSING: + return _field.default_factory() + return _field.default diff --git a/sphinx_needs/data.py b/sphinx_needs/data.py index 5a0ee79a2..26824c7c2 100644 --- a/sphinx_needs/data.py +++ b/sphinx_needs/data.py @@ -63,7 +63,7 @@ class CoreFieldParameters(TypedDict): show_in_layout: NotRequired[bool] """Whether to show the field in the rendered layout of the need by default (False if not present).""" exclude_json: NotRequired[bool] - """Whether to exclude the field from the JSON representation (False if not present).""" + """Whether field should be part of the default exclusions from the JSON representation (False if not present).""" NeedsCoreFields: Final[Mapping[str, CoreFieldParameters]] = { diff --git a/sphinx_needs/needsfile.py b/sphinx_needs/needsfile.py index fe247ba0d..ec78e4e85 100644 --- a/sphinx_needs/needsfile.py +++ b/sphinx_needs/needsfile.py @@ -9,8 +9,9 @@ import json import os import sys +from copy import deepcopy from datetime import datetime -from typing import Any +from typing import Any, Iterable from jsonschema import Draft7Validator from sphinx.config import Config @@ -22,7 +23,9 @@ log = get_logger(__name__) -def generate_needs_schema(config: Config) -> dict[str, Any]: +def generate_needs_schema( + config: Config, exclude_properties: Iterable[str] = () +) -> dict[str, Any]: """Generate a JSON schema for all fields in each need item. It is based on: @@ -46,9 +49,7 @@ def generate_needs_schema(config: Config) -> dict[str, Any]: # (this is the case for `type` added by the github service) # hence this is why we add the core options after the extra options for name, core_params in NeedsCoreFields.items(): - if core_params.get("exclude_json"): - continue - properties[name] = core_params["schema"] + properties[name] = deepcopy(core_params["schema"]) properties[name]["description"] = f"{core_params['description']}" properties[name]["field_type"] = "core" @@ -62,6 +63,13 @@ def generate_needs_schema(config: Config) -> dict[str, Any]: "field_type": "links", "default": [], } + properties[link["option"] + "_back"] = { + "type": "array", + "items": {"type": "string"}, + "description": "Backlink field", + "field_type": "backlinks", + "default": [], + } for name in needs_config.global_options: if name not in properties: @@ -72,6 +80,10 @@ def generate_needs_schema(config: Config) -> dict[str, Any]: "default": "", } + for name in exclude_properties: + if name in properties: + del properties[name] + return { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", @@ -80,10 +92,6 @@ def generate_needs_schema(config: Config) -> dict[str, Any]: class NeedsList: - JSON_KEY_EXCLUSIONS_NEEDS = { - name for name, params in NeedsCoreFields.items() if params.get("exclude_json") - } - def __init__( self, config: Config, outdir: str, confdir: str, add_schema: bool = True ) -> None: @@ -91,16 +99,6 @@ def __init__( self.needs_config = NeedsSphinxConfig(config) self.outdir = outdir self.confdir = confdir - self._schema = generate_needs_schema(config) if add_schema else None - self._need_defaults = ( - { - name: value["default"] - for name, value in self._schema["properties"].items() - if "default" in value - } - if self._schema - else {} - ) self.current_version = config.version self.project = config.project self.needs_list = { @@ -111,9 +109,23 @@ def __init__( if not self.needs_config.reproducible_json: self.needs_list["created"] = "" self.log = log - # also exclude back links for link types dynamically set by the user - back_link_keys = {x["option"] + "_back" for x in self.needs_config.extra_links} - self._exclude_need_keys = self.JSON_KEY_EXCLUSIONS_NEEDS | back_link_keys + + self._exclude_need_keys = set(self.needs_config.json_exclude_fields) + + self._schema = ( + generate_needs_schema(config, exclude_properties=self._exclude_need_keys) + if add_schema + else None + ) + self._need_defaults = ( + { + name: value["default"] + for name, value in self._schema["properties"].items() + if "default" in value + } + if self._schema + else {} + ) def update_or_add_version(self, version: str) -> None: if version not in self.needs_list["versions"].keys(): @@ -125,6 +137,8 @@ def update_or_add_version(self, version: str) -> None: } if self._schema: self.needs_list["versions"][version]["needs_schema"] = self._schema + if self.needs_config.json_remove_defaults: + self.needs_list["versions"][version]["needs_defaults_removed"] = True if not self.needs_config.reproducible_json: self.needs_list["versions"][version]["created"] = "" diff --git a/tests/__snapshots__/test_basic_doc.ambr b/tests/__snapshots__/test_basic_doc.ambr index 23d5a0a9a..87b93ae89 100644 --- a/tests/__snapshots__/test_basic_doc.ambr +++ b/tests/__snapshots__/test_basic_doc.ambr @@ -39,6 +39,8 @@ 'layout': '', 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -46,6 +48,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -105,6 +109,8 @@ 'layout': '', 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -112,6 +118,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -339,6 +347,16 @@ }), 'type': 'array', }), + 'links_back': dict({ + 'default': list([ + ]), + 'description': 'Backlink field', + 'field_type': 'backlinks', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), 'max_amount': dict({ 'default': '', 'description': 'Added by service github-issues', @@ -379,6 +397,16 @@ }), 'type': 'array', }), + 'parent_needs_back': dict({ + 'default': list([ + ]), + 'description': 'Backlink field', + 'field_type': 'backlinks', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), 'parts': dict({ 'additionalProperties': dict({ 'type': 'object', diff --git a/tests/__snapshots__/test_export_id.ambr b/tests/__snapshots__/test_export_id.ambr index b888cfc7a..d83286c24 100644 --- a/tests/__snapshots__/test_export_id.ambr +++ b/tests/__snapshots__/test_export_id.ambr @@ -74,6 +74,9 @@ 'blocks': list([ 'REQ_003', ]), + 'blocks_back': list([ + 'REQ_005', + ]), 'closed_at': '', 'completion': '', 'constraints': list([ @@ -105,6 +108,9 @@ 'REQ_004', 'REQ_003', ]), + 'links_back': list([ + 'REQ_005', + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -112,6 +118,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -134,6 +142,10 @@ 'template': None, 'tests': list([ ]), + 'tests_back': list([ + 'TEST_001', + 'TEST_002', + ]), 'title': 'My requirement', 'type': 'story', 'type_name': 'User Story', @@ -148,6 +160,8 @@ 'avatar': '', 'blocks': list([ ]), + 'blocks_back': list([ + ]), 'closed_at': '', 'completion': '', 'constraints': list([ @@ -176,6 +190,9 @@ 'layout': '', 'links': list([ ]), + 'links_back': list([ + 'REQ_001', + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -183,6 +200,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -205,6 +224,8 @@ 'template': None, 'tests': list([ ]), + 'tests_back': list([ + ]), 'title': 'My requirement 2', 'type': 'story', 'type_name': 'User Story', @@ -219,6 +240,9 @@ 'avatar': '', 'blocks': list([ ]), + 'blocks_back': list([ + 'REQ_001', + ]), 'closed_at': '', 'completion': '', 'constraints': list([ @@ -247,6 +271,9 @@ 'layout': '', 'links': list([ ]), + 'links_back': list([ + 'REQ_001', + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -254,6 +281,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -276,6 +305,9 @@ 'template': None, 'tests': list([ ]), + 'tests_back': list([ + 'TEST_001', + ]), 'title': 'My requirement 3', 'type': 'story', 'type_name': 'User Story', @@ -290,6 +322,8 @@ 'avatar': '', 'blocks': list([ ]), + 'blocks_back': list([ + ]), 'closed_at': '', 'completion': '', 'constraints': list([ @@ -318,6 +352,9 @@ 'layout': '', 'links': list([ ]), + 'links_back': list([ + 'REQ_001', + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -325,6 +362,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -347,6 +386,8 @@ 'template': None, 'tests': list([ ]), + 'tests_back': list([ + ]), 'title': 'My requirement 4', 'type': 'story', 'type_name': 'User Story', @@ -362,6 +403,8 @@ 'blocks': list([ 'REQ_001', ]), + 'blocks_back': list([ + ]), 'closed_at': '', 'completion': '', 'constraints': list([ @@ -396,6 +439,9 @@ 'REQ_001', 'REQ_001', ]), + 'links_back': list([ + 'TEST_003', + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -403,6 +449,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ '1': dict({ 'content': ' awesome part', @@ -448,6 +496,9 @@ 'template': None, 'tests': list([ ]), + 'tests_back': list([ + 'TEST_003', + ]), 'title': 'Req 5', 'type': 'story', 'type_name': 'User Story', @@ -462,6 +513,8 @@ 'avatar': '', 'blocks': list([ ]), + 'blocks_back': list([ + ]), 'closed_at': '', 'completion': '', 'constraints': list([ @@ -490,6 +543,9 @@ 'layout': '', 'links': list([ ]), + 'links_back': list([ + 'TEST_002', + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -497,6 +553,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -521,6 +579,8 @@ 'REQ_001', 'REQ_003', ]), + 'tests_back': list([ + ]), 'title': 'Test of requirements', 'type': 'test', 'type_name': 'Test Case', @@ -535,6 +595,8 @@ 'avatar': '', 'blocks': list([ ]), + 'blocks_back': list([ + ]), 'closed_at': '', 'completion': '', 'constraints': list([ @@ -564,6 +626,8 @@ 'links': list([ 'TEST_001', ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -571,6 +635,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -594,6 +660,8 @@ 'tests': list([ 'REQ_001', ]), + 'tests_back': list([ + ]), 'title': 'Test of requirements2', 'type': 'test', 'type_name': 'Test Case', @@ -608,6 +676,8 @@ 'avatar': '', 'blocks': list([ ]), + 'blocks_back': list([ + ]), 'closed_at': '', 'completion': '', 'constraints': list([ @@ -637,6 +707,8 @@ 'links': list([ 'REQ_005.1', ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -644,6 +716,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -668,6 +742,8 @@ 'REQ_005.1', 'REQ_005.cool', ]), + 'tests_back': list([ + ]), 'title': 'Test of requirements 5', 'type': 'test', 'type_name': 'Test Case', @@ -707,6 +783,16 @@ }), 'type': 'array', }), + 'blocks_back': dict({ + 'default': list([ + ]), + 'description': 'Backlink field', + 'field_type': 'backlinks', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), 'closed_at': dict({ 'default': '', 'description': 'Added by service github-issues', @@ -886,6 +972,16 @@ }), 'type': 'array', }), + 'links_back': dict({ + 'default': list([ + ]), + 'description': 'Backlink field', + 'field_type': 'backlinks', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), 'max_amount': dict({ 'default': '', 'description': 'Added by service github-issues', @@ -926,6 +1022,16 @@ }), 'type': 'array', }), + 'parent_needs_back': dict({ + 'default': list([ + ]), + 'description': 'Backlink field', + 'field_type': 'backlinks', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), 'parts': dict({ 'additionalProperties': dict({ 'type': 'object', @@ -1064,6 +1170,16 @@ }), 'type': 'array', }), + 'tests_back': dict({ + 'default': list([ + ]), + 'description': 'Backlink field', + 'field_type': 'backlinks', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), 'title': dict({ 'description': 'Title of the need, trimmed to a maximum length.', 'field_type': 'core', diff --git a/tests/__snapshots__/test_external.ambr b/tests/__snapshots__/test_external.ambr index 56e2bf3dd..f2f98d490 100644 --- a/tests/__snapshots__/test_external.ambr +++ b/tests/__snapshots__/test_external.ambr @@ -42,6 +42,7 @@ }), }), 'needs_amount': 2, + 'needs_defaults_removed': True, 'needs_schema': dict({ '$schema': 'http://json-schema.org/draft-07/schema#', 'properties': dict({ @@ -240,6 +241,16 @@ }), 'type': 'array', }), + 'links_back': dict({ + 'default': list([ + ]), + 'description': 'Backlink field', + 'field_type': 'backlinks', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), 'max_amount': dict({ 'default': '', 'description': 'Added by service github-issues', @@ -280,6 +291,16 @@ }), 'type': 'array', }), + 'parent_needs_back': dict({ + 'default': list([ + ]), + 'description': 'Backlink field', + 'field_type': 'backlinks', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), 'parts': dict({ 'additionalProperties': dict({ 'type': 'object', @@ -498,6 +519,10 @@ 'links': list([ 'SPEC_1', ]), + 'links_back': list([ + 'EXT_TEST_02', + 'SPEC_1', + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -505,6 +530,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -565,6 +592,8 @@ 'EXT_TEST_01', 'REQ_1', ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -572,6 +601,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -632,6 +663,10 @@ 'layout': '', 'links': list([ ]), + 'links_back': list([ + 'EXT_TEST_02', + 'SPEC_1', + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -639,6 +674,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -700,6 +737,9 @@ 'REQ_1', 'EXT_TEST_01', ]), + 'links_back': list([ + 'EXT_TEST_01', + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -707,6 +747,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -766,6 +808,8 @@ 'layout': '', 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -773,6 +817,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -1000,6 +1046,16 @@ }), 'type': 'array', }), + 'links_back': dict({ + 'default': list([ + ]), + 'description': 'Backlink field', + 'field_type': 'backlinks', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), 'max_amount': dict({ 'default': '', 'description': 'Added by service github-issues', @@ -1040,6 +1096,16 @@ }), 'type': 'array', }), + 'parent_needs_back': dict({ + 'default': list([ + ]), + 'description': 'Backlink field', + 'field_type': 'backlinks', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), 'parts': dict({ 'additionalProperties': dict({ 'type': 'object', diff --git a/tests/__snapshots__/test_import.ambr b/tests/__snapshots__/test_import.ambr index 4baa7cef2..4430110c3 100644 --- a/tests/__snapshots__/test_import.ambr +++ b/tests/__snapshots__/test_import.ambr @@ -40,6 +40,9 @@ 'links': list([ 'OWN_ID_123', ]), + 'links_back': list([ + 'T_C3893', + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -47,6 +50,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -107,6 +112,10 @@ 'links': list([ 'R_F4722', ]), + 'links_back': list([ + 'IMPL_01', + 'T_C3893', + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -114,6 +123,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -176,6 +187,9 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + 'S_503A1', + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -183,6 +197,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -243,6 +259,8 @@ 'layout': '', 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -250,6 +268,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -310,6 +330,9 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + 'ROLES_REQ_2', + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -317,6 +340,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -377,6 +402,8 @@ 'links': list([ 'ROLES_REQ_1', ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -384,6 +411,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -443,6 +472,8 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -450,6 +481,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -511,6 +544,8 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -518,6 +553,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -583,6 +620,9 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + 'OWN_ID_123', + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -590,6 +630,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -652,6 +694,8 @@ 'layout': '', 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -659,6 +703,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -719,6 +765,8 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -726,6 +774,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -794,6 +844,8 @@ 'links': list([ 'REQ_001', ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -801,6 +853,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -862,6 +916,8 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -869,6 +925,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -930,6 +988,8 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -937,6 +997,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -996,6 +1058,8 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -1003,6 +1067,9 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + 'T_C3893', + ]), 'parts': dict({ }), 'post_template': None, @@ -1069,6 +1136,8 @@ 'OWN_ID_123', 'IMPL_01', ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -1077,6 +1146,8 @@ 'parent_needs': list([ 'T_5CCAA', ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -1140,6 +1211,9 @@ 'links': list([ 'collapsed_OWN_ID_123', ]), + 'links_back': list([ + 'collapsed_T_C3893', + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -1147,6 +1221,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -1211,6 +1287,10 @@ 'links': list([ 'collapsed_R_F4722', ]), + 'links_back': list([ + 'collapsed_IMPL_01', + 'collapsed_T_C3893', + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -1218,6 +1298,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -1284,6 +1366,9 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + 'collapsed_S_503A1', + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -1291,6 +1376,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -1355,6 +1442,9 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + 'collapsed_ROLES_REQ_2', + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -1362,6 +1452,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -1426,6 +1518,8 @@ 'links': list([ 'collapsed_ROLES_REQ_1', ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -1433,6 +1527,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -1496,6 +1592,8 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -1503,6 +1601,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -1568,6 +1668,8 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -1575,6 +1677,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -1644,6 +1748,9 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + 'collapsed_OWN_ID_123', + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -1651,6 +1758,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -1717,6 +1826,8 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -1724,6 +1835,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -1796,6 +1909,8 @@ 'links': list([ 'collapsed_REQ_001', ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -1803,6 +1918,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -1868,6 +1985,8 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -1875,6 +1994,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -1940,6 +2061,8 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -1947,6 +2070,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -2010,6 +2135,8 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -2017,6 +2144,9 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + 'collapsed_T_C3893', + ]), 'parts': dict({ }), 'post_template': None, @@ -2087,6 +2217,8 @@ 'collapsed_OWN_ID_123', 'collapsed_IMPL_01', ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -2095,6 +2227,8 @@ 'parent_needs': list([ 'collapsed_T_5CCAA', ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -2162,6 +2296,9 @@ 'links': list([ 'hidden_OWN_ID_123', ]), + 'links_back': list([ + 'hidden_T_C3893', + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -2170,6 +2307,9 @@ 'parent_needs': list([ 'hidden_TEST_01', ]), + 'parent_needs_back': list([ + 'hidden_OWN_ID_123', + ]), 'parts': dict({ }), 'post_template': None, @@ -2232,6 +2372,10 @@ 'links': list([ 'hidden_R_F4722', ]), + 'links_back': list([ + 'hidden_IMPL_01', + 'hidden_T_C3893', + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -2240,6 +2384,9 @@ 'parent_needs': list([ 'hidden_IMPL_01', ]), + 'parent_needs_back': list([ + 'hidden_REQ_001', + ]), 'parts': dict({ }), 'post_template': None, @@ -2304,6 +2451,9 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + 'hidden_S_503A1', + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -2312,6 +2462,9 @@ 'parent_needs': list([ 'hidden_OWN_ID_123', ]), + 'parent_needs_back': list([ + 'hidden_ROLES_REQ_1', + ]), 'parts': dict({ }), 'post_template': None, @@ -2374,6 +2527,9 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + 'hidden_ROLES_REQ_2', + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -2382,6 +2538,9 @@ 'parent_needs': list([ 'hidden_REQ_001', ]), + 'parent_needs_back': list([ + 'hidden_ROLES_REQ_2', + ]), 'parts': dict({ }), 'post_template': None, @@ -2444,6 +2603,8 @@ 'links': list([ 'hidden_ROLES_REQ_1', ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -2452,6 +2613,9 @@ 'parent_needs': list([ 'hidden_ROLES_REQ_1', ]), + 'parent_needs_back': list([ + 'hidden_R_22EB2', + ]), 'parts': dict({ }), 'post_template': None, @@ -2513,6 +2677,8 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -2521,6 +2687,9 @@ 'parent_needs': list([ 'hidden_ROLES_REQ_2', ]), + 'parent_needs_back': list([ + 'hidden_R_2A9D0', + ]), 'parts': dict({ }), 'post_template': None, @@ -2584,6 +2753,8 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -2592,6 +2763,9 @@ 'parent_needs': list([ 'hidden_R_22EB2', ]), + 'parent_needs_back': list([ + 'hidden_R_F4722', + ]), 'parts': dict({ }), 'post_template': None, @@ -2659,6 +2833,9 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + 'hidden_OWN_ID_123', + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -2667,6 +2844,9 @@ 'parent_needs': list([ 'hidden_R_2A9D0', ]), + 'parent_needs_back': list([ + 'hidden_S_01A67', + ]), 'parts': dict({ }), 'post_template': None, @@ -2731,6 +2911,8 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -2739,6 +2921,9 @@ 'parent_needs': list([ 'hidden_R_F4722', ]), + 'parent_needs_back': list([ + 'hidden_S_503A1', + ]), 'parts': dict({ }), 'post_template': None, @@ -2809,6 +2994,8 @@ 'links': list([ 'hidden_REQ_001', ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -2817,6 +3004,9 @@ 'parent_needs': list([ 'hidden_S_01A67', ]), + 'parent_needs_back': list([ + 'hidden_S_D70B0', + ]), 'parts': dict({ }), 'post_template': None, @@ -2880,6 +3070,8 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -2888,6 +3080,9 @@ 'parent_needs': list([ 'hidden_S_503A1', ]), + 'parent_needs_back': list([ + 'hidden_T_5CCAA', + ]), 'parts': dict({ }), 'post_template': None, @@ -2951,6 +3146,8 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -2958,6 +3155,9 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + 'hidden_IMPL_01', + ]), 'parts': dict({ }), 'post_template': None, @@ -3019,6 +3219,8 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -3027,6 +3229,9 @@ 'parent_needs': list([ 'hidden_S_D70B0', ]), + 'parent_needs_back': list([ + 'hidden_T_C3893', + ]), 'parts': dict({ }), 'post_template': None, @@ -3095,6 +3300,8 @@ 'hidden_OWN_ID_123', 'hidden_IMPL_01', ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -3103,6 +3310,8 @@ 'parent_needs': list([ 'hidden_T_5CCAA', ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -3167,6 +3376,8 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -3174,6 +3385,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -3233,6 +3446,8 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -3240,6 +3455,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -3301,6 +3518,8 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -3308,6 +3527,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -3369,6 +3590,8 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -3376,6 +3599,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -3435,6 +3660,8 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -3442,6 +3669,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -3502,6 +3731,9 @@ 'links': list([ 'test_OWN_ID_123', ]), + 'links_back': list([ + 'test_T_C3893', + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -3509,6 +3741,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -3572,6 +3806,10 @@ 'links': list([ 'test_R_F4722', ]), + 'links_back': list([ + 'test_IMPL_01', + 'test_T_C3893', + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -3579,6 +3817,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -3644,6 +3884,9 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + 'test_S_503A1', + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -3651,6 +3894,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -3714,6 +3959,9 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + 'test_ROLES_REQ_2', + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -3721,6 +3969,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -3784,6 +4034,8 @@ 'links': list([ 'test_ROLES_REQ_1', ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -3791,6 +4043,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -3853,6 +4107,8 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -3860,6 +4116,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -3924,6 +4182,8 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -3931,6 +4191,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -3999,6 +4261,9 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + 'test_OWN_ID_123', + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -4006,6 +4271,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -4071,6 +4338,8 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -4078,6 +4347,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -4149,6 +4420,8 @@ 'links': list([ 'test_REQ_001', ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -4156,6 +4429,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -4220,6 +4495,8 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -4227,6 +4504,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -4291,6 +4570,8 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -4298,6 +4579,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -4360,6 +4643,8 @@ 'layout': None, 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -4367,6 +4652,9 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + 'test_T_C3893', + ]), 'parts': dict({ }), 'post_template': None, @@ -4436,6 +4724,8 @@ 'test_OWN_ID_123', 'test_IMPL_01', ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -4444,6 +4734,8 @@ 'parent_needs': list([ 'test_T_5CCAA', ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -4677,6 +4969,16 @@ }), 'type': 'array', }), + 'links_back': dict({ + 'default': list([ + ]), + 'description': 'Backlink field', + 'field_type': 'backlinks', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), 'max_amount': dict({ 'default': '', 'description': 'Added by service github-issues', @@ -4717,6 +5019,16 @@ }), 'type': 'array', }), + 'parent_needs_back': dict({ + 'default': list([ + ]), + 'description': 'Backlink field', + 'field_type': 'backlinks', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), 'parts': dict({ 'additionalProperties': dict({ 'type': 'object', diff --git a/tests/__snapshots__/test_need_constraints.ambr b/tests/__snapshots__/test_need_constraints.ambr index 393bdb1ad..38c2f7664 100644 --- a/tests/__snapshots__/test_need_constraints.ambr +++ b/tests/__snapshots__/test_need_constraints.ambr @@ -39,6 +39,10 @@ 'layout': '', 'links': list([ ]), + 'links_back': list([ + 'SP_109F4', + 'SP_3EBFA', + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -46,6 +50,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -110,6 +116,8 @@ 'links': list([ 'SECURITY_REQ', ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -117,6 +125,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -183,6 +193,8 @@ 'links': list([ 'SECURITY_REQ', ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -190,6 +202,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -253,6 +267,8 @@ 'layout': '', 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -260,6 +276,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -319,6 +337,8 @@ 'layout': '', 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -326,6 +346,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -392,6 +414,8 @@ 'layout': '', 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -399,6 +423,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -465,6 +491,8 @@ 'layout': '', 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -472,6 +500,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -535,6 +565,8 @@ 'layout': '', 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -542,6 +574,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -769,6 +803,16 @@ }), 'type': 'array', }), + 'links_back': dict({ + 'default': list([ + ]), + 'description': 'Backlink field', + 'field_type': 'backlinks', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), 'max_amount': dict({ 'default': '', 'description': 'Added by service github-issues', @@ -809,6 +853,16 @@ }), 'type': 'array', }), + 'parent_needs_back': dict({ + 'default': list([ + ]), + 'description': 'Backlink field', + 'field_type': 'backlinks', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), 'parts': dict({ 'additionalProperties': dict({ 'type': 'object', diff --git a/tests/__snapshots__/test_needextend.ambr b/tests/__snapshots__/test_needextend.ambr index 9bab7110a..971ba0a4e 100644 --- a/tests/__snapshots__/test_needextend.ambr +++ b/tests/__snapshots__/test_needextend.ambr @@ -42,6 +42,8 @@ 'REQ_D_1', 'REQ_B_1', ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 2, @@ -49,6 +51,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -108,6 +112,9 @@ 'layout': '', 'links': list([ ]), + 'links_back': list([ + 'REQ_1', + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -115,6 +122,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -174,6 +183,9 @@ 'layout': '', 'links': list([ ]), + 'links_back': list([ + 'REQ_1', + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -181,6 +193,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -240,6 +254,8 @@ 'layout': '', 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -247,6 +263,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -306,6 +324,9 @@ 'layout': '', 'links': list([ ]), + 'links_back': list([ + 'REQ_1', + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -313,6 +334,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -540,6 +563,16 @@ }), 'type': 'array', }), + 'links_back': dict({ + 'default': list([ + ]), + 'description': 'Backlink field', + 'field_type': 'backlinks', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), 'max_amount': dict({ 'default': '', 'description': 'Added by service github-issues', @@ -580,6 +613,16 @@ }), 'type': 'array', }), + 'parent_needs_back': dict({ + 'default': list([ + ]), + 'description': 'Backlink field', + 'field_type': 'backlinks', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), 'parts': dict({ 'additionalProperties': dict({ 'type': 'object', @@ -801,6 +844,10 @@ 'links': list([ 'extend_test_004', ]), + 'links_back': list([ + 'extend_test_006', + 'extend_test_007', + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 1, @@ -808,6 +855,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -870,6 +919,11 @@ 'layout': '', 'links': list([ ]), + 'links_back': list([ + 'extend_test_003', + 'extend_test_006', + 'extend_test_007', + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -877,6 +931,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -939,6 +995,9 @@ 'layout': '', 'links': list([ ]), + 'links_back': list([ + 'extend_test_007', + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 1, @@ -946,6 +1005,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -1007,6 +1068,8 @@ 'extend_test_003', 'extend_test_004', ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 2, @@ -1014,6 +1077,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -1076,6 +1141,8 @@ 'extend_test_004', 'extend_test_005', ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 1, @@ -1083,6 +1150,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -1142,6 +1211,8 @@ 'layout': '', 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 2, @@ -1149,6 +1220,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -1379,6 +1452,16 @@ }), 'type': 'array', }), + 'links_back': dict({ + 'default': list([ + ]), + 'description': 'Backlink field', + 'field_type': 'backlinks', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), 'max_amount': dict({ 'default': '', 'description': 'Added by service github-issues', @@ -1419,6 +1502,16 @@ }), 'type': 'array', }), + 'parent_needs_back': dict({ + 'default': list([ + ]), + 'description': 'Backlink field', + 'field_type': 'backlinks', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), 'parts': dict({ 'additionalProperties': dict({ 'type': 'object', diff --git a/tests/__snapshots__/test_needs_builder.ambr b/tests/__snapshots__/test_needs_builder.ambr index 48a709f0b..665a6c39f 100644 --- a/tests/__snapshots__/test_needs_builder.ambr +++ b/tests/__snapshots__/test_needs_builder.ambr @@ -39,6 +39,8 @@ 'layout': '', 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -46,6 +48,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -105,6 +109,8 @@ 'layout': '', 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -112,6 +118,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -171,6 +179,8 @@ 'layout': '', 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -178,6 +188,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -406,6 +418,16 @@ }), 'type': 'array', }), + 'links_back': dict({ + 'default': list([ + ]), + 'description': 'Backlink field', + 'field_type': 'backlinks', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), 'max_amount': dict({ 'default': '', 'description': 'Added by service github-issues', @@ -446,6 +468,16 @@ }), 'type': 'array', }), + 'parent_needs_back': dict({ + 'default': list([ + ]), + 'description': 'Backlink field', + 'field_type': 'backlinks', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), 'parts': dict({ 'additionalProperties': dict({ 'type': 'object', @@ -853,6 +885,7 @@ }), }), 'needs_amount': 3, + 'needs_defaults_removed': True, 'needs_schema': dict({ '$schema': 'http://json-schema.org/draft-07/schema#', 'properties': dict({ @@ -1051,6 +1084,16 @@ }), 'type': 'array', }), + 'links_back': dict({ + 'default': list([ + ]), + 'description': 'Backlink field', + 'field_type': 'backlinks', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), 'max_amount': dict({ 'default': '', 'description': 'Added by service github-issues', @@ -1091,6 +1134,16 @@ }), 'type': 'array', }), + 'parent_needs_back': dict({ + 'default': list([ + ]), + 'description': 'Backlink field', + 'field_type': 'backlinks', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), 'parts': dict({ 'additionalProperties': dict({ 'type': 'object', @@ -1474,6 +1527,8 @@ 'layout': '', 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -1481,6 +1536,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -1540,6 +1597,8 @@ 'layout': '', 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -1547,6 +1606,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -1606,6 +1667,8 @@ 'layout': '', 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -1613,6 +1676,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -1841,6 +1906,16 @@ }), 'type': 'array', }), + 'links_back': dict({ + 'default': list([ + ]), + 'description': 'Backlink field', + 'field_type': 'backlinks', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), 'max_amount': dict({ 'default': '', 'description': 'Added by service github-issues', @@ -1881,6 +1956,16 @@ }), 'type': 'array', }), + 'parent_needs_back': dict({ + 'default': list([ + ]), + 'description': 'Backlink field', + 'field_type': 'backlinks', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), 'parts': dict({ 'additionalProperties': dict({ 'type': 'object', diff --git a/tests/__snapshots__/test_needs_id_builder.ambr b/tests/__snapshots__/test_needs_id_builder.ambr index 2333be00c..0c3942c64 100644 --- a/tests/__snapshots__/test_needs_id_builder.ambr +++ b/tests/__snapshots__/test_needs_id_builder.ambr @@ -40,6 +40,8 @@ 'layout': '', 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -47,6 +49,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -119,6 +123,8 @@ 'layout': '', 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -126,6 +132,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -198,6 +206,8 @@ 'layout': '', 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -205,6 +215,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, diff --git a/tests/__snapshots__/test_service_github.ambr b/tests/__snapshots__/test_service_github.ambr index d9abc49fc..1a41b1fde 100644 --- a/tests/__snapshots__/test_service_github.ambr +++ b/tests/__snapshots__/test_service_github.ambr @@ -42,6 +42,8 @@ 'layout': 'github', 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '', 'max_content_lines': '', 'modifications': 0, @@ -49,6 +51,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -115,6 +119,8 @@ 'layout': 'github', 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '1', 'max_content_lines': '2', 'modifications': 0, @@ -122,6 +128,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -211,6 +219,8 @@ 'layout': 'github', 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '1', 'max_content_lines': '', 'modifications': 0, @@ -218,6 +228,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -291,6 +303,8 @@ 'layout': 'github', 'links': list([ ]), + 'links_back': list([ + ]), 'max_amount': '1', 'max_content_lines': '', 'modifications': 0, @@ -298,6 +312,8 @@ 'parent_need': '', 'parent_needs': list([ ]), + 'parent_needs_back': list([ + ]), 'parts': dict({ }), 'post_template': None, @@ -519,6 +535,16 @@ }), 'type': 'array', }), + 'links_back': dict({ + 'default': list([ + ]), + 'description': 'Backlink field', + 'field_type': 'backlinks', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), 'max_amount': dict({ 'default': '', 'description': 'Added by service github-issues', @@ -559,6 +585,16 @@ }), 'type': 'array', }), + 'parent_needs_back': dict({ + 'default': list([ + ]), + 'description': 'Backlink field', + 'field_type': 'backlinks', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), 'parts': dict({ 'additionalProperties': dict({ 'type': 'object',