diff --git a/docs/builders.rst b/docs/builders.rst index 0833fd2e8..bd208ef5d 100644 --- a/docs/builders.rst +++ b/docs/builders.rst @@ -61,6 +61,11 @@ This allows to export specified filter results only. 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, +and can be one of: ``core``, ``links``, ``extra``, ``global`` ``bool``. + .. code-block:: python { @@ -71,65 +76,108 @@ Format "1.0": { "created": "2017-07-03T11:54:42.433868", "filters": { - "FILTER_1": { - "amount": 1, - "export_id": "FILTER_1", - "filter": "", - "result": [ - "IMPL_01", - ], - "status": [], - "tags": "", - "types": [] + "FILTER_1": { + "amount": 1, + "export_id": "FILTER_1", + "filter": "", + "result": ["IMPL_01"], + "status": [], + "tags": "", + "types": [] + }, + "needs_schema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "id": { + "description": "ID of the data.", + "field_type": "core", + "type": "string" + }, + "type": { + "description": "Type of the need.", + "field_type": "core", + "type": "string" + }, + "links": { + "description": "Link field", + "field_type": "links", + "items": { + "type": "string" + }, + "type": "array" + }, + "status": { + "description": "Status of the need.", + "field_type": "core", + "type": [ + "string", + "null" + ] + }, + ... + } }, "needs": { "IMPL_01": { - "description": "Incoming links of this spec: :need_incoming:`IMPL_01`.", "id": "IMPL_01", - "links": [ - "OWN_ID_123" - ], - "sections": [ - "Examples" - ], - "status": null, - "tags": [], - "title": "Implementation for specification", "type": "impl", - "type_name": "Implementation" - } + "links": ["OWN_ID_123"], + "status": null, + ... + }, + ... } }, "1.5": { "created": "2017-07-03T16:10:31.633425", "filters": { - "FILTER_1": { - "amount": 1, - "export_id": "FILTER_1", - "filter": "", - "result": [ - "IMPL_01", - ], - "status": [], - "tags": "", - "types": [] + "FILTER_1": { + "amount": 1, + "export_id": "FILTER_1", + "filter": "", + "result": ["IMPL_01"], + "status": [], + "tags": "", + "types": [] + }, + "needs_schema": { + "id": { + "description": "ID of the data.", + "field_type": "core", + "type": "string" + }, + "type": { + "description": "Type of the need.", + "field_type": "core", + "type": "string" + }, + "links": { + "description": "Link field", + "field_type": "links", + "items": { + "type": "string" + }, + "type": "array" + }, + "status": { + "description": "Status of the need.", + "field_type": "core", + "type": [ + "string", + "null" + ] + }, + ... }, "needs": { "IMPL_01": { - "description": "Incoming links", "id": "IMPL_01", - "links": [ - "OWN_ID_123" - ], - "sections": [ - "Examples" - ], - "status": "closed", - "tags": ["links","update"], - "title": "Implementation for specification", "type": "impl", - "type_name": "Implementation" - } + "links": ["OWN_ID_123"], + "status": "closed", + ... + }, + ... } } } diff --git a/sphinx_needs/builder.py b/sphinx_needs/builder.py index 21114c091..092fc7a38 100644 --- a/sphinx_needs/builder.py +++ b/sphinx_needs/builder.py @@ -196,7 +196,9 @@ def finish(self) -> None: if not os.path.exists(needs_dir): os.makedirs(needs_dir, exist_ok=True) for need in filtered_needs: - needs_list = NeedsList(self.env.config, self.outdir, self.srcdir) + needs_list = NeedsList( + self.env.config, self.outdir, self.srcdir, add_schema=False + ) needs_list.wipe_version(version) needs_list.add_need(version, need) id = need["id"] diff --git a/sphinx_needs/needsfile.py b/sphinx_needs/needsfile.py index c5c2960e4..cf4ec644b 100644 --- a/sphinx_needs/needsfile.py +++ b/sphinx_needs/needsfile.py @@ -15,13 +15,67 @@ from jsonschema import Draft7Validator from sphinx.config import Config -from sphinx_needs.config import NeedsSphinxConfig +from sphinx_needs.config import NEEDS_CONFIG, NeedsSphinxConfig from sphinx_needs.data import NeedsCoreFields, NeedsFilterType, NeedsInfoType from sphinx_needs.logging import get_logger log = get_logger(__name__) +def generate_needs_schema(config: Config) -> dict[str, Any]: + """Generate a JSON schema for all fields in each need item. + + It is based on: + * the core fields defined in NeedsCoreFields + * the extra options defined dynamically + * the global options defined dynamically + * the extra links defined dynamically + """ + properties: dict[str, Any] = {} + + for name, extra_params in NEEDS_CONFIG.extra_options.items(): + properties[name] = { + "type": "string", + "description": extra_params.description, + "field_type": "extra", + } + + # TODO currently extra options can overlap with core fields, + # in which case they are ignored, + # (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]["description"] = f"{core_params['description']}" + properties[name]["field_type"] = "core" + + needs_config = NeedsSphinxConfig(config) + + for link in needs_config.extra_links: + properties[link["option"]] = { + "type": "array", + "items": {"type": "string"}, + "description": "Link field", + "field_type": "links", + } + + for name in needs_config.global_options: + if name not in properties: + properties[name] = { + "type": "string", + "description": "Added by needs_global_options configuration", + "field_type": "global", + } + + return { + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": properties, + } + + class NeedsList: JSON_KEY_EXCLUSIONS_NEEDS = { name for name, params in NeedsCoreFields.items() if params.get("exclude_json") @@ -42,11 +96,14 @@ class NeedsList: "content_node", } - def __init__(self, config: Config, outdir: str, confdir: str) -> None: + def __init__( + self, config: Config, outdir: str, confdir: str, add_schema: bool = True + ) -> None: self.config = config self.needs_config = NeedsSphinxConfig(config) self.outdir = outdir self.confdir = confdir + self._add_schema = add_schema self.current_version = config.version self.project = config.project self.needs_list = { @@ -70,6 +127,10 @@ def update_or_add_version(self, version: str) -> None: "filters_amount": 0, "filters": {}, } + if self._add_schema: + self.needs_list["versions"][version]["needs_schema"] = ( + generate_needs_schema(self.config) + ) 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 ec7240651..94c3bf373 100644 --- a/tests/__snapshots__/test_basic_doc.ambr +++ b/tests/__snapshots__/test_basic_doc.ambr @@ -143,6 +143,359 @@ }), }), 'needs_amount': 2, + 'needs_schema': dict({ + '$schema': 'http://json-schema.org/draft-07/schema#', + 'properties': dict({ + 'arch': dict({ + 'additionalProperties': dict({ + 'type': 'string', + }), + 'description': 'Mapping of uml key to uml content.', + 'field_type': 'core', + 'type': 'object', + }), + 'avatar': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'closed_at': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'completion': dict({ + 'description': 'Added for needgantt functionality', + 'field_type': 'extra', + 'type': 'string', + }), + 'constraints': dict({ + 'description': 'List of constraint names, which are defined for this need.', + 'field_type': 'core', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'constraints_error': dict({ + 'description': 'An error message set if any constraint failed, and `error_message` field is set in config.', + 'field_type': 'core', + 'type': 'string', + }), + 'constraints_passed': dict({ + 'description': 'True if all constraints passed, False if any failed, None if not yet checked.', + 'field_type': 'core', + 'type': list([ + 'boolean', + 'null', + ]), + }), + 'constraints_results': dict({ + 'additionalProperties': dict({ + 'type': 'object', + }), + 'description': 'Mapping of constraint name, to check name, to result.', + 'field_type': 'core', + 'type': 'object', + }), + 'content_id': dict({ + 'description': 'ID of the content node.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'created_at': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'delete': dict({ + 'description': 'If true, the need is deleted entirely.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'docname': dict({ + 'description': 'Name of the document where the need is defined (None if external).', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'doctype': dict({ + 'description': "Type of the document where the need is defined, e.g. '.rst'.", + 'field_type': 'core', + 'type': 'string', + }), + 'duration': dict({ + 'description': 'Added for needgantt functionality', + 'field_type': 'extra', + 'type': 'string', + }), + 'external_css': dict({ + 'description': 'CSS class name, added to the external reference.', + 'field_type': 'core', + 'type': 'string', + }), + 'external_url': dict({ + 'description': 'URL of the need, if it is an external need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'full_title': dict({ + 'description': 'Title of the need, of unlimited length.', + 'field_type': 'core', + 'type': 'string', + }), + 'has_dead_links': dict({ + 'description': 'True if any links reference need ids that are not found in the need list.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'has_forbidden_dead_links': dict({ + 'description': 'True if any links reference need ids that are not found in the need list, and the link type does not allow dead links.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'id': dict({ + 'description': 'ID of the data.', + 'field_type': 'core', + 'type': 'string', + }), + 'id_prefix': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'is_external': dict({ + 'description': 'If true, no node is created and need is referencing external url.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'is_modified': dict({ + 'description': 'Whether the need was modified by needextend.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'is_need': dict({ + 'description': 'Whether the need is a need.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'is_part': dict({ + 'description': 'Whether the need is a part.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'jinja_content': dict({ + 'description': 'Whether the content should be pre-processed by jinja.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'layout': dict({ + 'description': 'Key of the layout, which is used to render the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'links': dict({ + 'description': 'Link field', + 'field_type': 'links', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'max_amount': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'max_content_lines': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'modifications': dict({ + 'description': 'Number of modifications by needextend.', + 'field_type': 'core', + 'type': 'integer', + }), + 'params': dict({ + 'description': 'Added by service open-needs', + 'field_type': 'extra', + 'type': 'string', + }), + 'parent_need': dict({ + 'description': 'Simply the first parent id.', + 'field_type': 'core', + 'type': 'string', + }), + 'parent_needs': dict({ + 'description': 'Link field', + 'field_type': 'links', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'parts': dict({ + 'additionalProperties': dict({ + 'type': 'object', + }), + 'description': "Mapping of parts, a.k.a. sub-needs, IDs to data that overrides the need's data", + 'field_type': 'core', + 'type': 'object', + }), + 'post_content': dict({ + 'description': 'Post-content of the need.', + 'field_type': 'core', + 'type': 'string', + }), + 'post_template': dict({ + 'description': 'Post-template of the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'pre_content': dict({ + 'description': 'Pre-content of the need.', + 'field_type': 'core', + 'type': 'string', + }), + 'pre_template': dict({ + 'description': 'Pre-template of the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'prefix': dict({ + 'description': 'Added by service open-needs', + 'field_type': 'extra', + 'type': 'string', + }), + 'query': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'section_name': dict({ + 'description': 'Simply the first section.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'sections': dict({ + 'description': 'Sections of the need.', + 'field_type': 'core', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'service': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'signature': dict({ + 'description': 'Derived from a docutils desc_name node.', + 'field_type': 'core', + 'type': 'string', + }), + 'specific': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'status': dict({ + 'description': 'Status of the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'style': dict({ + 'description': 'Comma-separated list of CSS classes (all appended by `needs_style_`).', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'tags': dict({ + 'description': 'List of tags.', + 'field_type': 'core', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'target_id': dict({ + 'description': 'ID of the data.', + 'field_type': 'core', + 'type': 'string', + }), + 'template': dict({ + 'description': 'Template of the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'title': dict({ + 'description': 'Title of the need, trimmed to a maximum length.', + 'field_type': 'core', + 'type': 'string', + }), + 'type': dict({ + 'description': 'Type of the need.', + 'field_type': 'core', + 'type': 'string', + }), + 'type_name': dict({ + 'description': 'Name of the type.', + 'field_type': 'core', + 'type': 'string', + }), + 'updated_at': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'url': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'url_postfix': dict({ + 'description': 'Added by service open-needs', + 'field_type': 'extra', + 'type': 'string', + }), + 'user': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + }), + 'type': 'object', + }), }), }), }) diff --git a/tests/__snapshots__/test_export_id.ambr b/tests/__snapshots__/test_export_id.ambr index 940026c7f..fdc5c2031 100644 --- a/tests/__snapshots__/test_export_id.ambr +++ b/tests/__snapshots__/test_export_id.ambr @@ -729,6 +729,375 @@ }), }), 'needs_amount': 8, + 'needs_schema': dict({ + '$schema': 'http://json-schema.org/draft-07/schema#', + 'properties': dict({ + 'arch': dict({ + 'additionalProperties': dict({ + 'type': 'string', + }), + 'description': 'Mapping of uml key to uml content.', + 'field_type': 'core', + 'type': 'object', + }), + 'avatar': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'blocks': dict({ + 'description': 'Link field', + 'field_type': 'links', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'closed_at': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'completion': dict({ + 'description': 'Added for needgantt functionality', + 'field_type': 'extra', + 'type': 'string', + }), + 'constraints': dict({ + 'description': 'List of constraint names, which are defined for this need.', + 'field_type': 'core', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'constraints_error': dict({ + 'description': 'An error message set if any constraint failed, and `error_message` field is set in config.', + 'field_type': 'core', + 'type': 'string', + }), + 'constraints_passed': dict({ + 'description': 'True if all constraints passed, False if any failed, None if not yet checked.', + 'field_type': 'core', + 'type': list([ + 'boolean', + 'null', + ]), + }), + 'constraints_results': dict({ + 'additionalProperties': dict({ + 'type': 'object', + }), + 'description': 'Mapping of constraint name, to check name, to result.', + 'field_type': 'core', + 'type': 'object', + }), + 'content_id': dict({ + 'description': 'ID of the content node.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'created_at': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'delete': dict({ + 'description': 'If true, the need is deleted entirely.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'docname': dict({ + 'description': 'Name of the document where the need is defined (None if external).', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'doctype': dict({ + 'description': "Type of the document where the need is defined, e.g. '.rst'.", + 'field_type': 'core', + 'type': 'string', + }), + 'duration': dict({ + 'description': 'Added for needgantt functionality', + 'field_type': 'extra', + 'type': 'string', + }), + 'external_css': dict({ + 'description': 'CSS class name, added to the external reference.', + 'field_type': 'core', + 'type': 'string', + }), + 'external_url': dict({ + 'description': 'URL of the need, if it is an external need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'full_title': dict({ + 'description': 'Title of the need, of unlimited length.', + 'field_type': 'core', + 'type': 'string', + }), + 'has_dead_links': dict({ + 'description': 'True if any links reference need ids that are not found in the need list.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'has_forbidden_dead_links': dict({ + 'description': 'True if any links reference need ids that are not found in the need list, and the link type does not allow dead links.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'id': dict({ + 'description': 'ID of the data.', + 'field_type': 'core', + 'type': 'string', + }), + 'id_prefix': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'is_external': dict({ + 'description': 'If true, no node is created and need is referencing external url.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'is_modified': dict({ + 'description': 'Whether the need was modified by needextend.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'is_need': dict({ + 'description': 'Whether the need is a need.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'is_part': dict({ + 'description': 'Whether the need is a part.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'jinja_content': dict({ + 'description': 'Whether the content should be pre-processed by jinja.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'layout': dict({ + 'description': 'Key of the layout, which is used to render the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'links': dict({ + 'description': 'Link field', + 'field_type': 'links', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'max_amount': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'max_content_lines': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'modifications': dict({ + 'description': 'Number of modifications by needextend.', + 'field_type': 'core', + 'type': 'integer', + }), + 'params': dict({ + 'description': 'Added by service open-needs', + 'field_type': 'extra', + 'type': 'string', + }), + 'parent_need': dict({ + 'description': 'Simply the first parent id.', + 'field_type': 'core', + 'type': 'string', + }), + 'parent_needs': dict({ + 'description': 'Link field', + 'field_type': 'links', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'parts': dict({ + 'additionalProperties': dict({ + 'type': 'object', + }), + 'description': "Mapping of parts, a.k.a. sub-needs, IDs to data that overrides the need's data", + 'field_type': 'core', + 'type': 'object', + }), + 'post_content': dict({ + 'description': 'Post-content of the need.', + 'field_type': 'core', + 'type': 'string', + }), + 'post_template': dict({ + 'description': 'Post-template of the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'pre_content': dict({ + 'description': 'Pre-content of the need.', + 'field_type': 'core', + 'type': 'string', + }), + 'pre_template': dict({ + 'description': 'Pre-template of the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'prefix': dict({ + 'description': 'Added by service open-needs', + 'field_type': 'extra', + 'type': 'string', + }), + 'query': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'section_name': dict({ + 'description': 'Simply the first section.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'sections': dict({ + 'description': 'Sections of the need.', + 'field_type': 'core', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'service': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'signature': dict({ + 'description': 'Derived from a docutils desc_name node.', + 'field_type': 'core', + 'type': 'string', + }), + 'specific': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'status': dict({ + 'description': 'Status of the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'style': dict({ + 'description': 'Comma-separated list of CSS classes (all appended by `needs_style_`).', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'tags': dict({ + 'description': 'List of tags.', + 'field_type': 'core', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'target_id': dict({ + 'description': 'ID of the data.', + 'field_type': 'core', + 'type': 'string', + }), + 'template': dict({ + 'description': 'Template of the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'tests': dict({ + 'description': 'Link field', + 'field_type': 'links', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'title': dict({ + 'description': 'Title of the need, trimmed to a maximum length.', + 'field_type': 'core', + 'type': 'string', + }), + 'type': dict({ + 'description': 'Type of the need.', + 'field_type': 'core', + 'type': 'string', + }), + 'type_name': dict({ + 'description': 'Name of the type.', + 'field_type': 'core', + 'type': 'string', + }), + 'updated_at': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'url': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'url_postfix': dict({ + 'description': 'Added by service open-needs', + 'field_type': 'extra', + 'type': 'string', + }), + 'user': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + }), + 'type': 'object', + }), }), }), }) diff --git a/tests/__snapshots__/test_external.ambr b/tests/__snapshots__/test_external.ambr index c58fca3bb..6d2e92552 100644 --- a/tests/__snapshots__/test_external.ambr +++ b/tests/__snapshots__/test_external.ambr @@ -349,6 +349,359 @@ }), }), 'needs_amount': 5, + 'needs_schema': dict({ + '$schema': 'http://json-schema.org/draft-07/schema#', + 'properties': dict({ + 'arch': dict({ + 'additionalProperties': dict({ + 'type': 'string', + }), + 'description': 'Mapping of uml key to uml content.', + 'field_type': 'core', + 'type': 'object', + }), + 'avatar': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'closed_at': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'completion': dict({ + 'description': 'Added for needgantt functionality', + 'field_type': 'extra', + 'type': 'string', + }), + 'constraints': dict({ + 'description': 'List of constraint names, which are defined for this need.', + 'field_type': 'core', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'constraints_error': dict({ + 'description': 'An error message set if any constraint failed, and `error_message` field is set in config.', + 'field_type': 'core', + 'type': 'string', + }), + 'constraints_passed': dict({ + 'description': 'True if all constraints passed, False if any failed, None if not yet checked.', + 'field_type': 'core', + 'type': list([ + 'boolean', + 'null', + ]), + }), + 'constraints_results': dict({ + 'additionalProperties': dict({ + 'type': 'object', + }), + 'description': 'Mapping of constraint name, to check name, to result.', + 'field_type': 'core', + 'type': 'object', + }), + 'content_id': dict({ + 'description': 'ID of the content node.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'created_at': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'delete': dict({ + 'description': 'If true, the need is deleted entirely.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'docname': dict({ + 'description': 'Name of the document where the need is defined (None if external).', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'doctype': dict({ + 'description': "Type of the document where the need is defined, e.g. '.rst'.", + 'field_type': 'core', + 'type': 'string', + }), + 'duration': dict({ + 'description': 'Added for needgantt functionality', + 'field_type': 'extra', + 'type': 'string', + }), + 'external_css': dict({ + 'description': 'CSS class name, added to the external reference.', + 'field_type': 'core', + 'type': 'string', + }), + 'external_url': dict({ + 'description': 'URL of the need, if it is an external need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'full_title': dict({ + 'description': 'Title of the need, of unlimited length.', + 'field_type': 'core', + 'type': 'string', + }), + 'has_dead_links': dict({ + 'description': 'True if any links reference need ids that are not found in the need list.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'has_forbidden_dead_links': dict({ + 'description': 'True if any links reference need ids that are not found in the need list, and the link type does not allow dead links.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'id': dict({ + 'description': 'ID of the data.', + 'field_type': 'core', + 'type': 'string', + }), + 'id_prefix': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'is_external': dict({ + 'description': 'If true, no node is created and need is referencing external url.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'is_modified': dict({ + 'description': 'Whether the need was modified by needextend.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'is_need': dict({ + 'description': 'Whether the need is a need.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'is_part': dict({ + 'description': 'Whether the need is a part.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'jinja_content': dict({ + 'description': 'Whether the content should be pre-processed by jinja.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'layout': dict({ + 'description': 'Key of the layout, which is used to render the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'links': dict({ + 'description': 'Link field', + 'field_type': 'links', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'max_amount': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'max_content_lines': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'modifications': dict({ + 'description': 'Number of modifications by needextend.', + 'field_type': 'core', + 'type': 'integer', + }), + 'params': dict({ + 'description': 'Added by service open-needs', + 'field_type': 'extra', + 'type': 'string', + }), + 'parent_need': dict({ + 'description': 'Simply the first parent id.', + 'field_type': 'core', + 'type': 'string', + }), + 'parent_needs': dict({ + 'description': 'Link field', + 'field_type': 'links', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'parts': dict({ + 'additionalProperties': dict({ + 'type': 'object', + }), + 'description': "Mapping of parts, a.k.a. sub-needs, IDs to data that overrides the need's data", + 'field_type': 'core', + 'type': 'object', + }), + 'post_content': dict({ + 'description': 'Post-content of the need.', + 'field_type': 'core', + 'type': 'string', + }), + 'post_template': dict({ + 'description': 'Post-template of the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'pre_content': dict({ + 'description': 'Pre-content of the need.', + 'field_type': 'core', + 'type': 'string', + }), + 'pre_template': dict({ + 'description': 'Pre-template of the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'prefix': dict({ + 'description': 'Added by service open-needs', + 'field_type': 'extra', + 'type': 'string', + }), + 'query': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'section_name': dict({ + 'description': 'Simply the first section.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'sections': dict({ + 'description': 'Sections of the need.', + 'field_type': 'core', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'service': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'signature': dict({ + 'description': 'Derived from a docutils desc_name node.', + 'field_type': 'core', + 'type': 'string', + }), + 'specific': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'status': dict({ + 'description': 'Status of the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'style': dict({ + 'description': 'Comma-separated list of CSS classes (all appended by `needs_style_`).', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'tags': dict({ + 'description': 'List of tags.', + 'field_type': 'core', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'target_id': dict({ + 'description': 'ID of the data.', + 'field_type': 'core', + 'type': 'string', + }), + 'template': dict({ + 'description': 'Template of the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'title': dict({ + 'description': 'Title of the need, trimmed to a maximum length.', + 'field_type': 'core', + 'type': 'string', + }), + 'type': dict({ + 'description': 'Type of the need.', + 'field_type': 'core', + 'type': 'string', + }), + 'type_name': dict({ + 'description': 'Name of the type.', + 'field_type': 'core', + 'type': 'string', + }), + 'updated_at': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'url': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'url_postfix': dict({ + 'description': 'Added by service open-needs', + 'field_type': 'extra', + 'type': 'string', + }), + 'user': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + }), + 'type': 'object', + }), }), }), }) diff --git a/tests/__snapshots__/test_import.ambr b/tests/__snapshots__/test_import.ambr index 3dff032a9..465847e22 100644 --- a/tests/__snapshots__/test_import.ambr +++ b/tests/__snapshots__/test_import.ambr @@ -4542,6 +4542,359 @@ }), }), 'needs_amount': 63, + 'needs_schema': dict({ + '$schema': 'http://json-schema.org/draft-07/schema#', + 'properties': dict({ + 'arch': dict({ + 'additionalProperties': dict({ + 'type': 'string', + }), + 'description': 'Mapping of uml key to uml content.', + 'field_type': 'core', + 'type': 'object', + }), + 'avatar': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'closed_at': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'completion': dict({ + 'description': 'Added for needgantt functionality', + 'field_type': 'extra', + 'type': 'string', + }), + 'constraints': dict({ + 'description': 'List of constraint names, which are defined for this need.', + 'field_type': 'core', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'constraints_error': dict({ + 'description': 'An error message set if any constraint failed, and `error_message` field is set in config.', + 'field_type': 'core', + 'type': 'string', + }), + 'constraints_passed': dict({ + 'description': 'True if all constraints passed, False if any failed, None if not yet checked.', + 'field_type': 'core', + 'type': list([ + 'boolean', + 'null', + ]), + }), + 'constraints_results': dict({ + 'additionalProperties': dict({ + 'type': 'object', + }), + 'description': 'Mapping of constraint name, to check name, to result.', + 'field_type': 'core', + 'type': 'object', + }), + 'content_id': dict({ + 'description': 'ID of the content node.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'created_at': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'delete': dict({ + 'description': 'If true, the need is deleted entirely.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'docname': dict({ + 'description': 'Name of the document where the need is defined (None if external).', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'doctype': dict({ + 'description': "Type of the document where the need is defined, e.g. '.rst'.", + 'field_type': 'core', + 'type': 'string', + }), + 'duration': dict({ + 'description': 'Added for needgantt functionality', + 'field_type': 'extra', + 'type': 'string', + }), + 'external_css': dict({ + 'description': 'CSS class name, added to the external reference.', + 'field_type': 'core', + 'type': 'string', + }), + 'external_url': dict({ + 'description': 'URL of the need, if it is an external need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'full_title': dict({ + 'description': 'Title of the need, of unlimited length.', + 'field_type': 'core', + 'type': 'string', + }), + 'has_dead_links': dict({ + 'description': 'True if any links reference need ids that are not found in the need list.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'has_forbidden_dead_links': dict({ + 'description': 'True if any links reference need ids that are not found in the need list, and the link type does not allow dead links.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'id': dict({ + 'description': 'ID of the data.', + 'field_type': 'core', + 'type': 'string', + }), + 'id_prefix': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'is_external': dict({ + 'description': 'If true, no node is created and need is referencing external url.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'is_modified': dict({ + 'description': 'Whether the need was modified by needextend.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'is_need': dict({ + 'description': 'Whether the need is a need.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'is_part': dict({ + 'description': 'Whether the need is a part.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'jinja_content': dict({ + 'description': 'Whether the content should be pre-processed by jinja.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'layout': dict({ + 'description': 'Key of the layout, which is used to render the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'links': dict({ + 'description': 'Link field', + 'field_type': 'links', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'max_amount': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'max_content_lines': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'modifications': dict({ + 'description': 'Number of modifications by needextend.', + 'field_type': 'core', + 'type': 'integer', + }), + 'params': dict({ + 'description': 'Added by service open-needs', + 'field_type': 'extra', + 'type': 'string', + }), + 'parent_need': dict({ + 'description': 'Simply the first parent id.', + 'field_type': 'core', + 'type': 'string', + }), + 'parent_needs': dict({ + 'description': 'Link field', + 'field_type': 'links', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'parts': dict({ + 'additionalProperties': dict({ + 'type': 'object', + }), + 'description': "Mapping of parts, a.k.a. sub-needs, IDs to data that overrides the need's data", + 'field_type': 'core', + 'type': 'object', + }), + 'post_content': dict({ + 'description': 'Post-content of the need.', + 'field_type': 'core', + 'type': 'string', + }), + 'post_template': dict({ + 'description': 'Post-template of the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'pre_content': dict({ + 'description': 'Pre-content of the need.', + 'field_type': 'core', + 'type': 'string', + }), + 'pre_template': dict({ + 'description': 'Pre-template of the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'prefix': dict({ + 'description': 'Added by service open-needs', + 'field_type': 'extra', + 'type': 'string', + }), + 'query': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'section_name': dict({ + 'description': 'Simply the first section.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'sections': dict({ + 'description': 'Sections of the need.', + 'field_type': 'core', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'service': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'signature': dict({ + 'description': 'Derived from a docutils desc_name node.', + 'field_type': 'core', + 'type': 'string', + }), + 'specific': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'status': dict({ + 'description': 'Status of the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'style': dict({ + 'description': 'Comma-separated list of CSS classes (all appended by `needs_style_`).', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'tags': dict({ + 'description': 'List of tags.', + 'field_type': 'core', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'target_id': dict({ + 'description': 'ID of the data.', + 'field_type': 'core', + 'type': 'string', + }), + 'template': dict({ + 'description': 'Template of the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'title': dict({ + 'description': 'Title of the need, trimmed to a maximum length.', + 'field_type': 'core', + 'type': 'string', + }), + 'type': dict({ + 'description': 'Type of the need.', + 'field_type': 'core', + 'type': 'string', + }), + 'type_name': dict({ + 'description': 'Name of the type.', + 'field_type': 'core', + 'type': 'string', + }), + 'updated_at': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'url': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'url_postfix': dict({ + 'description': 'Added by service open-needs', + 'field_type': 'extra', + 'type': 'string', + }), + 'user': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + }), + 'type': 'object', + }), }), }), }) diff --git a/tests/__snapshots__/test_need_constraints.ambr b/tests/__snapshots__/test_need_constraints.ambr index d2f6a17f5..de47ef452 100644 --- a/tests/__snapshots__/test_need_constraints.ambr +++ b/tests/__snapshots__/test_need_constraints.ambr @@ -579,6 +579,359 @@ }), }), 'needs_amount': 8, + 'needs_schema': dict({ + '$schema': 'http://json-schema.org/draft-07/schema#', + 'properties': dict({ + 'arch': dict({ + 'additionalProperties': dict({ + 'type': 'string', + }), + 'description': 'Mapping of uml key to uml content.', + 'field_type': 'core', + 'type': 'object', + }), + 'avatar': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'closed_at': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'completion': dict({ + 'description': 'Added for needgantt functionality', + 'field_type': 'extra', + 'type': 'string', + }), + 'constraints': dict({ + 'description': 'List of constraint names, which are defined for this need.', + 'field_type': 'core', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'constraints_error': dict({ + 'description': 'An error message set if any constraint failed, and `error_message` field is set in config.', + 'field_type': 'core', + 'type': 'string', + }), + 'constraints_passed': dict({ + 'description': 'True if all constraints passed, False if any failed, None if not yet checked.', + 'field_type': 'core', + 'type': list([ + 'boolean', + 'null', + ]), + }), + 'constraints_results': dict({ + 'additionalProperties': dict({ + 'type': 'object', + }), + 'description': 'Mapping of constraint name, to check name, to result.', + 'field_type': 'core', + 'type': 'object', + }), + 'content_id': dict({ + 'description': 'ID of the content node.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'created_at': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'delete': dict({ + 'description': 'If true, the need is deleted entirely.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'docname': dict({ + 'description': 'Name of the document where the need is defined (None if external).', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'doctype': dict({ + 'description': "Type of the document where the need is defined, e.g. '.rst'.", + 'field_type': 'core', + 'type': 'string', + }), + 'duration': dict({ + 'description': 'Added for needgantt functionality', + 'field_type': 'extra', + 'type': 'string', + }), + 'external_css': dict({ + 'description': 'CSS class name, added to the external reference.', + 'field_type': 'core', + 'type': 'string', + }), + 'external_url': dict({ + 'description': 'URL of the need, if it is an external need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'full_title': dict({ + 'description': 'Title of the need, of unlimited length.', + 'field_type': 'core', + 'type': 'string', + }), + 'has_dead_links': dict({ + 'description': 'True if any links reference need ids that are not found in the need list.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'has_forbidden_dead_links': dict({ + 'description': 'True if any links reference need ids that are not found in the need list, and the link type does not allow dead links.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'id': dict({ + 'description': 'ID of the data.', + 'field_type': 'core', + 'type': 'string', + }), + 'id_prefix': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'is_external': dict({ + 'description': 'If true, no node is created and need is referencing external url.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'is_modified': dict({ + 'description': 'Whether the need was modified by needextend.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'is_need': dict({ + 'description': 'Whether the need is a need.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'is_part': dict({ + 'description': 'Whether the need is a part.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'jinja_content': dict({ + 'description': 'Whether the content should be pre-processed by jinja.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'layout': dict({ + 'description': 'Key of the layout, which is used to render the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'links': dict({ + 'description': 'Link field', + 'field_type': 'links', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'max_amount': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'max_content_lines': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'modifications': dict({ + 'description': 'Number of modifications by needextend.', + 'field_type': 'core', + 'type': 'integer', + }), + 'params': dict({ + 'description': 'Added by service open-needs', + 'field_type': 'extra', + 'type': 'string', + }), + 'parent_need': dict({ + 'description': 'Simply the first parent id.', + 'field_type': 'core', + 'type': 'string', + }), + 'parent_needs': dict({ + 'description': 'Link field', + 'field_type': 'links', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'parts': dict({ + 'additionalProperties': dict({ + 'type': 'object', + }), + 'description': "Mapping of parts, a.k.a. sub-needs, IDs to data that overrides the need's data", + 'field_type': 'core', + 'type': 'object', + }), + 'post_content': dict({ + 'description': 'Post-content of the need.', + 'field_type': 'core', + 'type': 'string', + }), + 'post_template': dict({ + 'description': 'Post-template of the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'pre_content': dict({ + 'description': 'Pre-content of the need.', + 'field_type': 'core', + 'type': 'string', + }), + 'pre_template': dict({ + 'description': 'Pre-template of the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'prefix': dict({ + 'description': 'Added by service open-needs', + 'field_type': 'extra', + 'type': 'string', + }), + 'query': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'section_name': dict({ + 'description': 'Simply the first section.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'sections': dict({ + 'description': 'Sections of the need.', + 'field_type': 'core', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'service': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'signature': dict({ + 'description': 'Derived from a docutils desc_name node.', + 'field_type': 'core', + 'type': 'string', + }), + 'specific': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'status': dict({ + 'description': 'Status of the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'style': dict({ + 'description': 'Comma-separated list of CSS classes (all appended by `needs_style_`).', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'tags': dict({ + 'description': 'List of tags.', + 'field_type': 'core', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'target_id': dict({ + 'description': 'ID of the data.', + 'field_type': 'core', + 'type': 'string', + }), + 'template': dict({ + 'description': 'Template of the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'title': dict({ + 'description': 'Title of the need, trimmed to a maximum length.', + 'field_type': 'core', + 'type': 'string', + }), + 'type': dict({ + 'description': 'Type of the need.', + 'field_type': 'core', + 'type': 'string', + }), + 'type_name': dict({ + 'description': 'Name of the type.', + 'field_type': 'core', + 'type': 'string', + }), + 'updated_at': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'url': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'url_postfix': dict({ + 'description': 'Added by service open-needs', + 'field_type': 'extra', + 'type': 'string', + }), + 'user': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + }), + 'type': 'object', + }), }), }), }) diff --git a/tests/__snapshots__/test_needextend.ambr b/tests/__snapshots__/test_needextend.ambr index 86bfc4865..800f34831 100644 --- a/tests/__snapshots__/test_needextend.ambr +++ b/tests/__snapshots__/test_needextend.ambr @@ -347,6 +347,359 @@ }), }), 'needs_amount': 5, + 'needs_schema': dict({ + '$schema': 'http://json-schema.org/draft-07/schema#', + 'properties': dict({ + 'arch': dict({ + 'additionalProperties': dict({ + 'type': 'string', + }), + 'description': 'Mapping of uml key to uml content.', + 'field_type': 'core', + 'type': 'object', + }), + 'avatar': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'closed_at': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'completion': dict({ + 'description': 'Added for needgantt functionality', + 'field_type': 'extra', + 'type': 'string', + }), + 'constraints': dict({ + 'description': 'List of constraint names, which are defined for this need.', + 'field_type': 'core', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'constraints_error': dict({ + 'description': 'An error message set if any constraint failed, and `error_message` field is set in config.', + 'field_type': 'core', + 'type': 'string', + }), + 'constraints_passed': dict({ + 'description': 'True if all constraints passed, False if any failed, None if not yet checked.', + 'field_type': 'core', + 'type': list([ + 'boolean', + 'null', + ]), + }), + 'constraints_results': dict({ + 'additionalProperties': dict({ + 'type': 'object', + }), + 'description': 'Mapping of constraint name, to check name, to result.', + 'field_type': 'core', + 'type': 'object', + }), + 'content_id': dict({ + 'description': 'ID of the content node.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'created_at': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'delete': dict({ + 'description': 'If true, the need is deleted entirely.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'docname': dict({ + 'description': 'Name of the document where the need is defined (None if external).', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'doctype': dict({ + 'description': "Type of the document where the need is defined, e.g. '.rst'.", + 'field_type': 'core', + 'type': 'string', + }), + 'duration': dict({ + 'description': 'Added for needgantt functionality', + 'field_type': 'extra', + 'type': 'string', + }), + 'external_css': dict({ + 'description': 'CSS class name, added to the external reference.', + 'field_type': 'core', + 'type': 'string', + }), + 'external_url': dict({ + 'description': 'URL of the need, if it is an external need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'full_title': dict({ + 'description': 'Title of the need, of unlimited length.', + 'field_type': 'core', + 'type': 'string', + }), + 'has_dead_links': dict({ + 'description': 'True if any links reference need ids that are not found in the need list.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'has_forbidden_dead_links': dict({ + 'description': 'True if any links reference need ids that are not found in the need list, and the link type does not allow dead links.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'id': dict({ + 'description': 'ID of the data.', + 'field_type': 'core', + 'type': 'string', + }), + 'id_prefix': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'is_external': dict({ + 'description': 'If true, no node is created and need is referencing external url.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'is_modified': dict({ + 'description': 'Whether the need was modified by needextend.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'is_need': dict({ + 'description': 'Whether the need is a need.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'is_part': dict({ + 'description': 'Whether the need is a part.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'jinja_content': dict({ + 'description': 'Whether the content should be pre-processed by jinja.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'layout': dict({ + 'description': 'Key of the layout, which is used to render the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'links': dict({ + 'description': 'Link field', + 'field_type': 'links', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'max_amount': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'max_content_lines': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'modifications': dict({ + 'description': 'Number of modifications by needextend.', + 'field_type': 'core', + 'type': 'integer', + }), + 'params': dict({ + 'description': 'Added by service open-needs', + 'field_type': 'extra', + 'type': 'string', + }), + 'parent_need': dict({ + 'description': 'Simply the first parent id.', + 'field_type': 'core', + 'type': 'string', + }), + 'parent_needs': dict({ + 'description': 'Link field', + 'field_type': 'links', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'parts': dict({ + 'additionalProperties': dict({ + 'type': 'object', + }), + 'description': "Mapping of parts, a.k.a. sub-needs, IDs to data that overrides the need's data", + 'field_type': 'core', + 'type': 'object', + }), + 'post_content': dict({ + 'description': 'Post-content of the need.', + 'field_type': 'core', + 'type': 'string', + }), + 'post_template': dict({ + 'description': 'Post-template of the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'pre_content': dict({ + 'description': 'Pre-content of the need.', + 'field_type': 'core', + 'type': 'string', + }), + 'pre_template': dict({ + 'description': 'Pre-template of the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'prefix': dict({ + 'description': 'Added by service open-needs', + 'field_type': 'extra', + 'type': 'string', + }), + 'query': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'section_name': dict({ + 'description': 'Simply the first section.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'sections': dict({ + 'description': 'Sections of the need.', + 'field_type': 'core', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'service': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'signature': dict({ + 'description': 'Derived from a docutils desc_name node.', + 'field_type': 'core', + 'type': 'string', + }), + 'specific': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'status': dict({ + 'description': 'Status of the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'style': dict({ + 'description': 'Comma-separated list of CSS classes (all appended by `needs_style_`).', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'tags': dict({ + 'description': 'List of tags.', + 'field_type': 'core', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'target_id': dict({ + 'description': 'ID of the data.', + 'field_type': 'core', + 'type': 'string', + }), + 'template': dict({ + 'description': 'Template of the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'title': dict({ + 'description': 'Title of the need, trimmed to a maximum length.', + 'field_type': 'core', + 'type': 'string', + }), + 'type': dict({ + 'description': 'Type of the need.', + 'field_type': 'core', + 'type': 'string', + }), + 'type_name': dict({ + 'description': 'Name of the type.', + 'field_type': 'core', + 'type': 'string', + }), + 'updated_at': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'url': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'url_postfix': dict({ + 'description': 'Added by service open-needs', + 'field_type': 'extra', + 'type': 'string', + }), + 'user': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + }), + 'type': 'object', + }), }), }), }) @@ -782,6 +1135,359 @@ }), }), 'needs_amount': 6, + 'needs_schema': dict({ + '$schema': 'http://json-schema.org/draft-07/schema#', + 'properties': dict({ + 'arch': dict({ + 'additionalProperties': dict({ + 'type': 'string', + }), + 'description': 'Mapping of uml key to uml content.', + 'field_type': 'core', + 'type': 'object', + }), + 'avatar': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'closed_at': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'completion': dict({ + 'description': 'Added for needgantt functionality', + 'field_type': 'extra', + 'type': 'string', + }), + 'constraints': dict({ + 'description': 'List of constraint names, which are defined for this need.', + 'field_type': 'core', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'constraints_error': dict({ + 'description': 'An error message set if any constraint failed, and `error_message` field is set in config.', + 'field_type': 'core', + 'type': 'string', + }), + 'constraints_passed': dict({ + 'description': 'True if all constraints passed, False if any failed, None if not yet checked.', + 'field_type': 'core', + 'type': list([ + 'boolean', + 'null', + ]), + }), + 'constraints_results': dict({ + 'additionalProperties': dict({ + 'type': 'object', + }), + 'description': 'Mapping of constraint name, to check name, to result.', + 'field_type': 'core', + 'type': 'object', + }), + 'content_id': dict({ + 'description': 'ID of the content node.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'created_at': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'delete': dict({ + 'description': 'If true, the need is deleted entirely.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'docname': dict({ + 'description': 'Name of the document where the need is defined (None if external).', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'doctype': dict({ + 'description': "Type of the document where the need is defined, e.g. '.rst'.", + 'field_type': 'core', + 'type': 'string', + }), + 'duration': dict({ + 'description': 'Added for needgantt functionality', + 'field_type': 'extra', + 'type': 'string', + }), + 'external_css': dict({ + 'description': 'CSS class name, added to the external reference.', + 'field_type': 'core', + 'type': 'string', + }), + 'external_url': dict({ + 'description': 'URL of the need, if it is an external need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'full_title': dict({ + 'description': 'Title of the need, of unlimited length.', + 'field_type': 'core', + 'type': 'string', + }), + 'has_dead_links': dict({ + 'description': 'True if any links reference need ids that are not found in the need list.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'has_forbidden_dead_links': dict({ + 'description': 'True if any links reference need ids that are not found in the need list, and the link type does not allow dead links.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'id': dict({ + 'description': 'ID of the data.', + 'field_type': 'core', + 'type': 'string', + }), + 'id_prefix': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'is_external': dict({ + 'description': 'If true, no node is created and need is referencing external url.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'is_modified': dict({ + 'description': 'Whether the need was modified by needextend.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'is_need': dict({ + 'description': 'Whether the need is a need.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'is_part': dict({ + 'description': 'Whether the need is a part.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'jinja_content': dict({ + 'description': 'Whether the content should be pre-processed by jinja.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'layout': dict({ + 'description': 'Key of the layout, which is used to render the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'links': dict({ + 'description': 'Link field', + 'field_type': 'links', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'max_amount': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'max_content_lines': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'modifications': dict({ + 'description': 'Number of modifications by needextend.', + 'field_type': 'core', + 'type': 'integer', + }), + 'params': dict({ + 'description': 'Added by service open-needs', + 'field_type': 'extra', + 'type': 'string', + }), + 'parent_need': dict({ + 'description': 'Simply the first parent id.', + 'field_type': 'core', + 'type': 'string', + }), + 'parent_needs': dict({ + 'description': 'Link field', + 'field_type': 'links', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'parts': dict({ + 'additionalProperties': dict({ + 'type': 'object', + }), + 'description': "Mapping of parts, a.k.a. sub-needs, IDs to data that overrides the need's data", + 'field_type': 'core', + 'type': 'object', + }), + 'post_content': dict({ + 'description': 'Post-content of the need.', + 'field_type': 'core', + 'type': 'string', + }), + 'post_template': dict({ + 'description': 'Post-template of the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'pre_content': dict({ + 'description': 'Pre-content of the need.', + 'field_type': 'core', + 'type': 'string', + }), + 'pre_template': dict({ + 'description': 'Pre-template of the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'prefix': dict({ + 'description': 'Added by service open-needs', + 'field_type': 'extra', + 'type': 'string', + }), + 'query': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'section_name': dict({ + 'description': 'Simply the first section.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'sections': dict({ + 'description': 'Sections of the need.', + 'field_type': 'core', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'service': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'signature': dict({ + 'description': 'Derived from a docutils desc_name node.', + 'field_type': 'core', + 'type': 'string', + }), + 'specific': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'status': dict({ + 'description': 'Status of the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'style': dict({ + 'description': 'Comma-separated list of CSS classes (all appended by `needs_style_`).', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'tags': dict({ + 'description': 'List of tags.', + 'field_type': 'core', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'target_id': dict({ + 'description': 'ID of the data.', + 'field_type': 'core', + 'type': 'string', + }), + 'template': dict({ + 'description': 'Template of the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'title': dict({ + 'description': 'Title of the need, trimmed to a maximum length.', + 'field_type': 'core', + 'type': 'string', + }), + 'type': dict({ + 'description': 'Type of the need.', + 'field_type': 'core', + 'type': 'string', + }), + 'type_name': dict({ + 'description': 'Name of the type.', + 'field_type': 'core', + 'type': 'string', + }), + 'updated_at': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'url': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'url_postfix': dict({ + 'description': 'Added by service open-needs', + 'field_type': 'extra', + 'type': 'string', + }), + 'user': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + }), + 'type': 'object', + }), }), }), }) diff --git a/tests/__snapshots__/test_needs_builder.ambr b/tests/__snapshots__/test_needs_builder.ambr index c27d690e6..7089f7853 100644 --- a/tests/__snapshots__/test_needs_builder.ambr +++ b/tests/__snapshots__/test_needs_builder.ambr @@ -211,6 +211,359 @@ }), }), 'needs_amount': 3, + 'needs_schema': dict({ + '$schema': 'http://json-schema.org/draft-07/schema#', + 'properties': dict({ + 'arch': dict({ + 'additionalProperties': dict({ + 'type': 'string', + }), + 'description': 'Mapping of uml key to uml content.', + 'field_type': 'core', + 'type': 'object', + }), + 'avatar': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'closed_at': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'completion': dict({ + 'description': 'Added for needgantt functionality', + 'field_type': 'extra', + 'type': 'string', + }), + 'constraints': dict({ + 'description': 'List of constraint names, which are defined for this need.', + 'field_type': 'core', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'constraints_error': dict({ + 'description': 'An error message set if any constraint failed, and `error_message` field is set in config.', + 'field_type': 'core', + 'type': 'string', + }), + 'constraints_passed': dict({ + 'description': 'True if all constraints passed, False if any failed, None if not yet checked.', + 'field_type': 'core', + 'type': list([ + 'boolean', + 'null', + ]), + }), + 'constraints_results': dict({ + 'additionalProperties': dict({ + 'type': 'object', + }), + 'description': 'Mapping of constraint name, to check name, to result.', + 'field_type': 'core', + 'type': 'object', + }), + 'content_id': dict({ + 'description': 'ID of the content node.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'created_at': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'delete': dict({ + 'description': 'If true, the need is deleted entirely.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'docname': dict({ + 'description': 'Name of the document where the need is defined (None if external).', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'doctype': dict({ + 'description': "Type of the document where the need is defined, e.g. '.rst'.", + 'field_type': 'core', + 'type': 'string', + }), + 'duration': dict({ + 'description': 'Added for needgantt functionality', + 'field_type': 'extra', + 'type': 'string', + }), + 'external_css': dict({ + 'description': 'CSS class name, added to the external reference.', + 'field_type': 'core', + 'type': 'string', + }), + 'external_url': dict({ + 'description': 'URL of the need, if it is an external need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'full_title': dict({ + 'description': 'Title of the need, of unlimited length.', + 'field_type': 'core', + 'type': 'string', + }), + 'has_dead_links': dict({ + 'description': 'True if any links reference need ids that are not found in the need list.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'has_forbidden_dead_links': dict({ + 'description': 'True if any links reference need ids that are not found in the need list, and the link type does not allow dead links.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'id': dict({ + 'description': 'ID of the data.', + 'field_type': 'core', + 'type': 'string', + }), + 'id_prefix': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'is_external': dict({ + 'description': 'If true, no node is created and need is referencing external url.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'is_modified': dict({ + 'description': 'Whether the need was modified by needextend.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'is_need': dict({ + 'description': 'Whether the need is a need.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'is_part': dict({ + 'description': 'Whether the need is a part.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'jinja_content': dict({ + 'description': 'Whether the content should be pre-processed by jinja.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'layout': dict({ + 'description': 'Key of the layout, which is used to render the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'links': dict({ + 'description': 'Link field', + 'field_type': 'links', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'max_amount': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'max_content_lines': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'modifications': dict({ + 'description': 'Number of modifications by needextend.', + 'field_type': 'core', + 'type': 'integer', + }), + 'params': dict({ + 'description': 'Added by service open-needs', + 'field_type': 'extra', + 'type': 'string', + }), + 'parent_need': dict({ + 'description': 'Simply the first parent id.', + 'field_type': 'core', + 'type': 'string', + }), + 'parent_needs': dict({ + 'description': 'Link field', + 'field_type': 'links', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'parts': dict({ + 'additionalProperties': dict({ + 'type': 'object', + }), + 'description': "Mapping of parts, a.k.a. sub-needs, IDs to data that overrides the need's data", + 'field_type': 'core', + 'type': 'object', + }), + 'post_content': dict({ + 'description': 'Post-content of the need.', + 'field_type': 'core', + 'type': 'string', + }), + 'post_template': dict({ + 'description': 'Post-template of the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'pre_content': dict({ + 'description': 'Pre-content of the need.', + 'field_type': 'core', + 'type': 'string', + }), + 'pre_template': dict({ + 'description': 'Pre-template of the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'prefix': dict({ + 'description': 'Added by service open-needs', + 'field_type': 'extra', + 'type': 'string', + }), + 'query': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'section_name': dict({ + 'description': 'Simply the first section.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'sections': dict({ + 'description': 'Sections of the need.', + 'field_type': 'core', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'service': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'signature': dict({ + 'description': 'Derived from a docutils desc_name node.', + 'field_type': 'core', + 'type': 'string', + }), + 'specific': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'status': dict({ + 'description': 'Status of the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'style': dict({ + 'description': 'Comma-separated list of CSS classes (all appended by `needs_style_`).', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'tags': dict({ + 'description': 'List of tags.', + 'field_type': 'core', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'target_id': dict({ + 'description': 'ID of the data.', + 'field_type': 'core', + 'type': 'string', + }), + 'template': dict({ + 'description': 'Template of the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'title': dict({ + 'description': 'Title of the need, trimmed to a maximum length.', + 'field_type': 'core', + 'type': 'string', + }), + 'type': dict({ + 'description': 'Type of the need.', + 'field_type': 'core', + 'type': 'string', + }), + 'type_name': dict({ + 'description': 'Name of the type.', + 'field_type': 'core', + 'type': 'string', + }), + 'updated_at': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'url': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'url_postfix': dict({ + 'description': 'Added by service open-needs', + 'field_type': 'extra', + 'type': 'string', + }), + 'user': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + }), + 'type': 'object', + }), }), '2.0': dict({ 'filters': dict({ @@ -594,6 +947,359 @@ }), }), 'needs_amount': 3, + 'needs_schema': dict({ + '$schema': 'http://json-schema.org/draft-07/schema#', + 'properties': dict({ + 'arch': dict({ + 'additionalProperties': dict({ + 'type': 'string', + }), + 'description': 'Mapping of uml key to uml content.', + 'field_type': 'core', + 'type': 'object', + }), + 'avatar': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'closed_at': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'completion': dict({ + 'description': 'Added for needgantt functionality', + 'field_type': 'extra', + 'type': 'string', + }), + 'constraints': dict({ + 'description': 'List of constraint names, which are defined for this need.', + 'field_type': 'core', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'constraints_error': dict({ + 'description': 'An error message set if any constraint failed, and `error_message` field is set in config.', + 'field_type': 'core', + 'type': 'string', + }), + 'constraints_passed': dict({ + 'description': 'True if all constraints passed, False if any failed, None if not yet checked.', + 'field_type': 'core', + 'type': list([ + 'boolean', + 'null', + ]), + }), + 'constraints_results': dict({ + 'additionalProperties': dict({ + 'type': 'object', + }), + 'description': 'Mapping of constraint name, to check name, to result.', + 'field_type': 'core', + 'type': 'object', + }), + 'content_id': dict({ + 'description': 'ID of the content node.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'created_at': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'delete': dict({ + 'description': 'If true, the need is deleted entirely.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'docname': dict({ + 'description': 'Name of the document where the need is defined (None if external).', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'doctype': dict({ + 'description': "Type of the document where the need is defined, e.g. '.rst'.", + 'field_type': 'core', + 'type': 'string', + }), + 'duration': dict({ + 'description': 'Added for needgantt functionality', + 'field_type': 'extra', + 'type': 'string', + }), + 'external_css': dict({ + 'description': 'CSS class name, added to the external reference.', + 'field_type': 'core', + 'type': 'string', + }), + 'external_url': dict({ + 'description': 'URL of the need, if it is an external need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'full_title': dict({ + 'description': 'Title of the need, of unlimited length.', + 'field_type': 'core', + 'type': 'string', + }), + 'has_dead_links': dict({ + 'description': 'True if any links reference need ids that are not found in the need list.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'has_forbidden_dead_links': dict({ + 'description': 'True if any links reference need ids that are not found in the need list, and the link type does not allow dead links.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'id': dict({ + 'description': 'ID of the data.', + 'field_type': 'core', + 'type': 'string', + }), + 'id_prefix': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'is_external': dict({ + 'description': 'If true, no node is created and need is referencing external url.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'is_modified': dict({ + 'description': 'Whether the need was modified by needextend.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'is_need': dict({ + 'description': 'Whether the need is a need.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'is_part': dict({ + 'description': 'Whether the need is a part.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'jinja_content': dict({ + 'description': 'Whether the content should be pre-processed by jinja.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'layout': dict({ + 'description': 'Key of the layout, which is used to render the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'links': dict({ + 'description': 'Link field', + 'field_type': 'links', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'max_amount': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'max_content_lines': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'modifications': dict({ + 'description': 'Number of modifications by needextend.', + 'field_type': 'core', + 'type': 'integer', + }), + 'params': dict({ + 'description': 'Added by service open-needs', + 'field_type': 'extra', + 'type': 'string', + }), + 'parent_need': dict({ + 'description': 'Simply the first parent id.', + 'field_type': 'core', + 'type': 'string', + }), + 'parent_needs': dict({ + 'description': 'Link field', + 'field_type': 'links', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'parts': dict({ + 'additionalProperties': dict({ + 'type': 'object', + }), + 'description': "Mapping of parts, a.k.a. sub-needs, IDs to data that overrides the need's data", + 'field_type': 'core', + 'type': 'object', + }), + 'post_content': dict({ + 'description': 'Post-content of the need.', + 'field_type': 'core', + 'type': 'string', + }), + 'post_template': dict({ + 'description': 'Post-template of the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'pre_content': dict({ + 'description': 'Pre-content of the need.', + 'field_type': 'core', + 'type': 'string', + }), + 'pre_template': dict({ + 'description': 'Pre-template of the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'prefix': dict({ + 'description': 'Added by service open-needs', + 'field_type': 'extra', + 'type': 'string', + }), + 'query': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'section_name': dict({ + 'description': 'Simply the first section.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'sections': dict({ + 'description': 'Sections of the need.', + 'field_type': 'core', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'service': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'signature': dict({ + 'description': 'Derived from a docutils desc_name node.', + 'field_type': 'core', + 'type': 'string', + }), + 'specific': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'status': dict({ + 'description': 'Status of the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'style': dict({ + 'description': 'Comma-separated list of CSS classes (all appended by `needs_style_`).', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'tags': dict({ + 'description': 'List of tags.', + 'field_type': 'core', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'target_id': dict({ + 'description': 'ID of the data.', + 'field_type': 'core', + 'type': 'string', + }), + 'template': dict({ + 'description': 'Template of the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'title': dict({ + 'description': 'Title of the need, trimmed to a maximum length.', + 'field_type': 'core', + 'type': 'string', + }), + 'type': dict({ + 'description': 'Type of the need.', + 'field_type': 'core', + 'type': 'string', + }), + 'type_name': dict({ + 'description': 'Name of the type.', + 'field_type': 'core', + 'type': 'string', + }), + 'updated_at': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'url': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'url_postfix': dict({ + 'description': 'Added by service open-needs', + 'field_type': 'extra', + 'type': 'string', + }), + 'user': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + }), + 'type': 'object', + }), }), '2.0': dict({ 'created': '2021-05-11T13:54:22.331724', diff --git a/tests/__snapshots__/test_service_github.ambr b/tests/__snapshots__/test_service_github.ambr index 28c3c2df5..1982a43c8 100644 --- a/tests/__snapshots__/test_service_github.ambr +++ b/tests/__snapshots__/test_service_github.ambr @@ -331,6 +331,354 @@ }), }), 'needs_amount': 4, + 'needs_schema': dict({ + '$schema': 'http://json-schema.org/draft-07/schema#', + 'properties': dict({ + 'arch': dict({ + 'additionalProperties': dict({ + 'type': 'string', + }), + 'description': 'Mapping of uml key to uml content.', + 'field_type': 'core', + 'type': 'object', + }), + 'closed_at': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'completion': dict({ + 'description': 'Added for needgantt functionality', + 'field_type': 'extra', + 'type': 'string', + }), + 'constraints': dict({ + 'description': 'List of constraint names, which are defined for this need.', + 'field_type': 'core', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'constraints_error': dict({ + 'description': 'An error message set if any constraint failed, and `error_message` field is set in config.', + 'field_type': 'core', + 'type': 'string', + }), + 'constraints_passed': dict({ + 'description': 'True if all constraints passed, False if any failed, None if not yet checked.', + 'field_type': 'core', + 'type': list([ + 'boolean', + 'null', + ]), + }), + 'constraints_results': dict({ + 'additionalProperties': dict({ + 'type': 'object', + }), + 'description': 'Mapping of constraint name, to check name, to result.', + 'field_type': 'core', + 'type': 'object', + }), + 'content_id': dict({ + 'description': 'ID of the content node.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'created_at': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'delete': dict({ + 'description': 'If true, the need is deleted entirely.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'docname': dict({ + 'description': 'Name of the document where the need is defined (None if external).', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'doctype': dict({ + 'description': "Type of the document where the need is defined, e.g. '.rst'.", + 'field_type': 'core', + 'type': 'string', + }), + 'duration': dict({ + 'description': 'Added for needgantt functionality', + 'field_type': 'extra', + 'type': 'string', + }), + 'external_css': dict({ + 'description': 'CSS class name, added to the external reference.', + 'field_type': 'core', + 'type': 'string', + }), + 'external_url': dict({ + 'description': 'URL of the need, if it is an external need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'full_title': dict({ + 'description': 'Title of the need, of unlimited length.', + 'field_type': 'core', + 'type': 'string', + }), + 'has_dead_links': dict({ + 'description': 'True if any links reference need ids that are not found in the need list.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'has_forbidden_dead_links': dict({ + 'description': 'True if any links reference need ids that are not found in the need list, and the link type does not allow dead links.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'id': dict({ + 'description': 'ID of the data.', + 'field_type': 'core', + 'type': 'string', + }), + 'id_prefix': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'is_external': dict({ + 'description': 'If true, no node is created and need is referencing external url.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'is_modified': dict({ + 'description': 'Whether the need was modified by needextend.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'is_need': dict({ + 'description': 'Whether the need is a need.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'is_part': dict({ + 'description': 'Whether the need is a part.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'jinja_content': dict({ + 'description': 'Whether the content should be pre-processed by jinja.', + 'field_type': 'core', + 'type': 'boolean', + }), + 'layout': dict({ + 'description': 'Key of the layout, which is used to render the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'links': dict({ + 'description': 'Link field', + 'field_type': 'links', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'max_amount': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'max_content_lines': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'modifications': dict({ + 'description': 'Number of modifications by needextend.', + 'field_type': 'core', + 'type': 'integer', + }), + 'params': dict({ + 'description': 'Added by service open-needs', + 'field_type': 'extra', + 'type': 'string', + }), + 'parent_need': dict({ + 'description': 'Simply the first parent id.', + 'field_type': 'core', + 'type': 'string', + }), + 'parent_needs': dict({ + 'description': 'Link field', + 'field_type': 'links', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'parts': dict({ + 'additionalProperties': dict({ + 'type': 'object', + }), + 'description': "Mapping of parts, a.k.a. sub-needs, IDs to data that overrides the need's data", + 'field_type': 'core', + 'type': 'object', + }), + 'post_content': dict({ + 'description': 'Post-content of the need.', + 'field_type': 'core', + 'type': 'string', + }), + 'post_template': dict({ + 'description': 'Post-template of the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'pre_content': dict({ + 'description': 'Pre-content of the need.', + 'field_type': 'core', + 'type': 'string', + }), + 'pre_template': dict({ + 'description': 'Pre-template of the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'prefix': dict({ + 'description': 'Added by service open-needs', + 'field_type': 'extra', + 'type': 'string', + }), + 'query': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'section_name': dict({ + 'description': 'Simply the first section.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'sections': dict({ + 'description': 'Sections of the need.', + 'field_type': 'core', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'service': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'signature': dict({ + 'description': 'Derived from a docutils desc_name node.', + 'field_type': 'core', + 'type': 'string', + }), + 'specific': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'status': dict({ + 'description': 'Status of the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'style': dict({ + 'description': 'Comma-separated list of CSS classes (all appended by `needs_style_`).', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'tags': dict({ + 'description': 'List of tags.', + 'field_type': 'core', + 'items': dict({ + 'type': 'string', + }), + 'type': 'array', + }), + 'target_id': dict({ + 'description': 'ID of the data.', + 'field_type': 'core', + 'type': 'string', + }), + 'template': dict({ + 'description': 'Template of the need.', + 'field_type': 'core', + 'type': list([ + 'string', + 'null', + ]), + }), + 'title': dict({ + 'description': 'Title of the need, trimmed to a maximum length.', + 'field_type': 'core', + 'type': 'string', + }), + 'type': dict({ + 'description': 'Type of the need.', + 'field_type': 'core', + 'type': 'string', + }), + 'type_name': dict({ + 'description': 'Name of the type.', + 'field_type': 'core', + 'type': 'string', + }), + 'updated_at': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'url': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + 'url_postfix': dict({ + 'description': 'Added by service open-needs', + 'field_type': 'extra', + 'type': 'string', + }), + 'user': dict({ + 'description': 'Added by service github-issues', + 'field_type': 'extra', + 'type': 'string', + }), + }), + 'type': 'object', + }), }), }), })