Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,53 @@ Unreleased
Improvements
............

- ✨ Portable link and need-type styling for :ref:`needflow` (:pr:`1785`)

``needs_links`` gains ``line``, ``part_line``, ``arrow`` and ``part_color``, and
``needs_types`` gains ``shape``. Each says what is *meant* rather than naming one
engine's syntax, and each engine writes it in its own — so the same configuration
draws the same diagram wherever it is built:

.. code-block:: python

needs_types = [
dict(directive="req", title="Requirement", prefix="R_", shape="hexagon"),
]
needs_links = {
"blocks": {
"incoming": "is blocked by",
"outgoing": "blocks",
"line": "dashed",
"part_line": "dotted",
"arrow": "circle",
"color": "#AA0000",
"part_color": "#777777",
},
}

``line`` and ``part_line`` are ``solid``, ``dashed``, ``dotted``, ``thick`` or
``invisible``; ``arrow`` is ``normal``, ``none``, ``open``, ``circle``, ``cross`` or
``both``; ``shape`` is one of ten members every engine can draw, and also accepts the
legacy PlantUML keywords of ``needs_types[].style`` as aliases, so a value can be
moved across unchanged.

``needs_links[].color`` is **finally honoured** — an identical ``TODO`` had sat in
both emitters for years. It is now unset by default rather than ``#000000``, so a link
type that names no colour keeps the engine's own edge colour and draws byte-identical
source, while one that asks for black is given black. ``part_color`` and ``part_line``
fall back to ``color`` and ``line`` when unset, so a link type states the difference
once.

Where an engine has no form for a value it draws the nearest one and says so once for
the project: PlantUML has no ``diamond`` element and no crossed arrow head, so those
become a rectangle and a plain head. A diagram is never refused for naming a member of
its own vocabulary. An out-of-enum value is reported once and the deprecated spelling
stays in charge.

The stored environment version is bumped to 8, because the pickled link-display
configuration gained a field in the middle of its layout, so the first build after
upgrading re-reads every document.

- ✨ New :ref:`needflow` ``:direction:`` option and :ref:`needs_flow_direction`
configuration (:pr:`1782`)

Expand Down Expand Up @@ -244,6 +291,26 @@ These changes do not affect user-facing behaviour:
- ♻️ :ref:`needflow`'s two engines now share one graph-model pass, with no change to the
generated diagram source

Deprecations
............

- ⚠️ ``needs_links[].style``, ``.style_part``, ``.style_start`` and ``.style_end`` →
``.line``, ``.part_line``, ``.color``, ``.part_color`` and ``.arrow`` (:pr:`1785`)

The four old keys hold PlantUML tokens, which every other engine has to translate.
They keep working exactly as they did, and will keep working: they are aliases, not a
withdrawal. Using one emits a ``needs.deprecated`` warning naming the replacements, and
the warning names exactly the keys a link type actually wrote — so a project can
migrate one link type, and one key, at a time, and see what is left.

The fold is per key, not per link type: ``style`` is a compound of a colour and a line
keyword, so setting the neutral ``line`` beside a ``style`` of ``dotted,#FF0000``
displaces ``dotted`` and keeps ``#FF0000``.

Note that the ``arrow`` member reproducing today's default is ``open``, not
``normal`` — the default ``style_end`` of ``->`` has always rendered as an open "V"
head on the graphviz engine. See :ref:`needflow_arrow_migration` for the full mapping.

Bug fixes
.........

Expand Down
118 changes: 114 additions & 4 deletions docs/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,31 @@ By default it is set to:
* **prefix**: A prefix for generated IDs, to easily identify that an ID belongs to a specific type. Can also be ""
* **color**: A color as hex value. Used in diagrams and some days maybe in other representations as well. Can also be ""
* **style**: A plantuml node type, like node, artifact, frame, storage or database. See `plantuml documentation <http://plantuml.com/deployment-diagram>`__ for more.
* **shape** (optional): The shape to draw the need with, in *every* diagram engine --
one of ``rectangle``, ``rounded``, ``circle``, ``ellipse``, ``diamond``, ``hexagon``,
``cylinder``, ``document``, ``folder`` or ``box3d``.
Takes precedence over ``style``, and accepts the legacy plantuml keywords of ``style``
as aliases, so a value can be moved across unchanged. *New in version 8.4.0.*

.. code-block:: python

needs_types = [
dict(directive="req", title="Requirement", prefix="R_", color="#BFD8D2",
shape="rectangle"),
dict(directive="test", title="Test Case", prefix="T_", color="#DCB239",
shape="hexagon"),
]

Where an engine has no form for a shape it draws the nearest one it has, and says so
once for the project -- a diagram is never refused for asking.
An unknown shape is reported once and leaves ``style`` in charge.

.. note::

``hexagon`` is emitted to PlantUML as its ``hexagon`` element, which older PlantUML
releases do not have; such a release reports a diagram error rather than drawing a
different shape.
If you support PlantUML builds older than 1.2020.13, prefer another member.

.. note::

Expand Down Expand Up @@ -390,12 +415,31 @@ Each configured link can define:
Default: False.
- ``allow_dead_links`` (optional): True/False. If True, dead links are allowed and do not throw a warning.
See :ref:`allow_dead_links` for details. Default: False.
- ``line`` (optional): How the line is drawn in :ref:`needflow` diagrams --
``solid``, ``dashed``, ``dotted``, ``thick`` or ``invisible``.
Every engine draws all five. *New in version 8.4.0.*
- ``part_line`` (optional): Same as ``line``, for a link connected to a :ref:`need_part`.
Defaults to ``line``. *New in version 8.4.0.*
- ``arrow`` (optional): Which arrow heads the line carries --
``normal``, ``none``, ``open``, ``circle``, ``cross`` or ``both``.
See :ref:`needflow_arrow_migration`. *New in version 8.4.0.*
- ``color`` (optional): The line color, e.g. ``#FFCC00``. Unset by default, which leaves
the engine's own edge color alone. *Honoured since version 8.4.0; previously accepted
and ignored.*
- ``part_color`` (optional): Same as ``color``, for a link connected to a
:ref:`need_part`. Defaults to ``color``. *New in version 8.4.0.*
- ``style`` (optional): A plantuml style description, e.g. "#FFCC00". Used for :ref:`needflow`. See :ref:`links_style`.
- ``style_part`` (optional): Same as ``style``, but get used if link is connected to a :ref:`need_part`.
See :ref:`links_style`.
- ``style_start`` (optional): See :ref:`needflow_style_start`.
- ``style_end`` (optional): See :ref:`needflow_style_start`.

.. deprecated:: 8.4.0
``style``, ``style_part``, ``style_start`` and ``style_end`` hold PlantUML tokens,
which every other engine has to translate.
Use ``line``, ``part_line``, ``color``, ``part_color`` and ``arrow`` instead;
the old keys are still honoured, so a link type can move one key at a time.

Configuration example:

.. code-block:: python
Expand All @@ -412,10 +456,9 @@ Configuration example:
"outgoing": "triggers",
"copy": False,
"allow_dead_links": True,
"style": "#00AA00",
"style_part": "#00AA00",
"style_start": "-",
"style_end": "--o",
"line": "solid",
"color": "#00AA00",
"arrow": "circle",
},
}

Expand Down Expand Up @@ -500,11 +543,73 @@ with ``allow_dead_links`` not set or set to ``False``.

By default not allowed dead links will be shown in red , allowed ones in gray (see above example).

.. _`needflow_arrow_migration`:

Migrating style_start / style_end to arrow
++++++++++++++++++++++++++++++++++++++++++

.. versionadded:: 8.4.0

``arrow`` names the arrow heads a link carries, rather than spelling them as PlantUML
tokens that every other engine then has to translate.
Its members are the ones every engine can draw:

.. list-table::
:header-rows: 1
:widths: 20,40,40

- * ``arrow``
* Drawn as
* Replaces
- * ``normal``
* A solid arrow head
* ``style_start = "-"``, ``style_end = "->>"`` -- see the note below
- * ``none``
* No head at all
* ``style_start = "-"``, ``style_end = "-"``
- * ``open``
* An open "V" head -- **the default of today's diagrams**
* ``style_start = "-"``, ``style_end = "->"``
- * ``circle``
* A hollow circle
* ``style_start = "-"``, ``style_end = "-o"``
- * ``cross``
* A crossbar
* no PlantUML equivalent
- * ``both``
* A head at each end
* ``style_start = "<"``, ``style_end = "->"``

.. important::

The member that reproduces what a link type draws **today** is ``open``, not
``normal``.
The default ``style_end`` of ``->`` has always rendered as an open "V" head on the
graphviz engine, and ``normal`` is the solid head instead.
On the plantuml engine the two are identical, so the difference only shows once a
diagram is rendered with graphviz.

The ``normal`` row is a mapping of *intent*, not of rendered output.
``style_end = "->>"`` asks PlantUML for a solid head, and ``arrow: normal`` is how
that intent is spelled -- but the graphviz translation of the deprecated keys reads
only the first and last character of ``style_start + style_end``, so ``->>`` has in
fact been collapsing to the same open "V" as ``->``.
Migrating that spelling therefore *changes* graphviz output, from ``vee`` to
``normal``. That is the head the configuration always asked for, but it is a change;
``arrow: open`` keeps the arrowheads exactly as they are drawn today.

Where an engine cannot draw a member it degrades and says so once:
``cross`` has no PlantUML form, so PlantUML draws a plain head.

.. _`links_style`:

style / style_part
++++++++++++++++++

.. deprecated:: 8.4.0
Use ``line``, ``color`` and ``part_color`` instead, which every engine understands.
These keys are still honoured.

The style string can contain the following comma separated information:

* **color**: #ffcc00 or red
Expand All @@ -523,6 +628,11 @@ An empty string uses the default plantuml settings.
style_start / style_end
+++++++++++++++++++++++

.. deprecated:: 8.4.0
Use ``arrow`` instead, which every engine understands --
see :ref:`needflow_arrow_migration` for the mapping.
These keys are still honoured.

These two options can define the arrow type, line type and line length.

See `Plantuml documentation page <https://plantuml.com/en/component-diagram>`_ for details about supported formats.
Expand Down
41 changes: 24 additions & 17 deletions docs/ubproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -249,59 +249,66 @@ style = "rectangle"
incoming = "is blocked by"
outgoing = "blocks"
copy = true
style = "#AA0000"
style_part = "dotted,#AA0000"
style_start = "-"
style_end = "-o"
part_line = "dotted"
arrow = "circle"
color = "#AA0000"
allow_dead_links = true

[needs.links.tests]
incoming = "is tested by"
outgoing = "tests"
copy = true
style = "#00AA00"
style_part = "dotted,#00AA00"
part_line = "dotted"
color = "#00AA00"

[needs.links.checks]
incoming = "is checked by"
outgoing = "checks"
copy = false
style = "#00AA00"
style_part = "dotted,#00AA00"
part_line = "dotted"
color = "#00AA00"

[needs.links.triggers]
incoming = "triggered by"
outgoing = "triggers"
copy = false
style = "#00AA00"
style_part = "solid,#777777"
line = "solid"
part_line = "solid"
color = "#00AA00"
part_color = "#777777"
allow_dead_links = true

[needs.links.starts_with]
incoming = "triggers directly"
outgoing = "starts with"
copy = false
style = "#00AA00"
style_part = "solid,#777777"
line = "solid"
part_line = "solid"
color = "#00AA00"
part_color = "#777777"

[needs.links.starts_after]
incoming = "triggers at end"
outgoing = "starts after"
copy = false
style = "#00AA00"
style_part = "solid,#777777"
line = "solid"
part_line = "solid"
color = "#00AA00"
part_color = "#777777"

[needs.links.ends_with]
incoming = "triggers to end with"
outgoing = "ends with"
copy = false
style = "#00AA00"
style_part = "solid,#777777"
line = "solid"
part_line = "solid"
color = "#00AA00"
part_color = "#777777"

[needs.links.tutorial_required_by]
incoming = "requires"
outgoing = "required by"
style = "#00AA00"
color = "#00AA00"

[needs.links.tutorial_specifies]
incoming = "specified by"
Expand Down
35 changes: 29 additions & 6 deletions sphinx_needs/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,15 +278,29 @@ class NeedLinksConfig(TypedDict, total=False):
copy: bool
"""Copy to common links data. Default: False"""
color: str
"""Used for needflow. Default: #000000"""
"""Used for needflow. Unset by default, i.e. the engine's own edge color."""
part_color: str
"""Used for needflow, for links to need parts. Defaults to ``color``."""
style: str
"""Used for needflow. Default: solid"""
"""Used for needflow (deprecated, use ``line``). Default: solid"""
style_part: str
"""Used for needflow. Default: '[dotted]'"""
"""Used for needflow (deprecated, use ``part_line``). Default: '[dotted]'"""
style_start: str
"""Used for needflow. Default: '-'"""
"""Used for needflow (deprecated, use ``arrow``). Default: '-'"""
style_end: str
"""Used for needflow. Default: '->'"""
"""Used for needflow (deprecated, use ``arrow``). Default: '->'"""
line: str
"""How the line is drawn in needflow diagrams.

One of 'solid', 'dashed', 'dotted', 'thick' or 'invisible'."""
part_line: str
"""How the line to a need part is drawn in needflow diagrams (see ``line``).

Defaults to ``line``."""
arrow: str
"""Which arrow heads the line carries in needflow diagrams.

One of 'normal', 'none', 'open', 'circle', 'cross' or 'both'."""
allow_dead_links: bool
"""If True, add a 'forbidden' class to dead links"""
schema: NotRequired[LinkSchemaType]
Expand Down Expand Up @@ -329,7 +343,16 @@ class NeedType(TypedDict):
"""The default color to use in diagrams.
If unset or empty, no color is applied and the diagram engine's default is used."""
style: NotRequired[str]
"""The default node style to use in diagrams (default: "node")."""
"""The default node style to use in diagrams (default: "node").

Holds a PlantUML element keyword; prefer ``shape``, which every engine
understands."""
shape: NotRequired[str]
"""The default shape to draw the need with, in every diagram engine.

One of ``rectangle``, ``rounded``, ``circle``, ``ellipse``, ``diamond``,
``hexagon``, ``cylinder``, ``document``, ``folder`` or ``box3d``; the legacy
PlantUML keywords of ``style`` are also accepted. Takes precedence over ``style``."""


class NeedFields(TypedDict):
Expand Down
Loading
Loading