needextend

New in version 0.7.0.

needextend allows to modify existing needs. It doesn’t provide any output, as the modifications get presented at the original location of the changing need.

Example

.. needextend:: <filter_string>
   :option: new value
   :+option: additional value
   :-option:

The following modifications are supported:

  • option: replaces the value of an option

  • +option: add new value to an existing value of an option.

  • -option: delete a complete option.

The argument of needextend must be a Filter string which defines the needs to modify.

needextend can modify all string-based and list-based options. Also, you can add links or delete tags.

Example

.. req:: needextend Example 1
   :id: extend_test_001
   :status: open
   :author: Foo
   :tags: tag_1, tag_2

   This requirement got modified.

   | Status was **open**, now it is **[[copy('status')]]**.
   | Also author got changed from **Foo** to **[[copy('author')]]**.
   | And a tag was added.
   | Finally all links got removed.

.. needextend:: id == "extend_test_001"
   :status: closed
   :+author: and me
   :+tags: new_tag

Result

Requirement: needextend Example 1 extend_test_001 ../_images/arrow-right-circle.svg
status: closed
tags: tag_1, tag_2, new_tag
author: Foo and me
links outgoing: FEATURE_1, FEATURE_2, FEATURE_3

This requirement got modified.

Status was open, now it is closed.
Also author got changed from Foo to Foo and me.
And a tag was added.
Finally all links got removed.

Options

strict

The purpose of the :strict: option is to handle whether an exception gets thrown or a log-info message gets written if there is no need object to match the needextend's required argument (e.g. an ID).

If you set the :strict: option value to true, needextend raises an exception because the given ID does not exist, and the build stops.

If you set the :strict: option value to false, needextend logs an info-level message in the console, and the build continues.

Allowed values:

  • true or

  • false

Default: true

Note

We have a configuration (conf.py) option called needs_needextend_strict that deactivates or activates the :strict: option behaviour for all needextend directives in a project.

Single need modification

If only one single need shall get modified, the argument of needextend can just be the need-id.

Example

.. req:: needextend Example 2
   :id: extend_test_002
   :status: open

.. needextend:: extend_test_002
   :status: New status

Result

Requirement: needextend Example 2 extend_test_002 ../_images/arrow-right-circle.svg
status: New status

Attention

The given argument must fully match the regular expression defined in needs_id_regex and a need with this ID must exist! Otherwise the argument is taken as normal filter string.

Setting default option values

You can use needextend’s filter string to set default option values for a group of needs.

Example

The following example would set the status of all needs in the document docs/directives/needextend.rst, which do not have the status set explicitly, to open.

.. needextend:: (docname == "docs/directives/needextend") and (status is None)
   :status: open

See also: needs_global_options for setting a default option value for all needs.

Options containing links get handled in two steps:

  1. Options for the need are set as above.

  2. The referenced need get updated as well and incoming links may get deleted, added or replaced.

Example

.. req:: needextend Example 3
   :id: extend_test_003

   Had no outgoing links.
   Got an outgoing link ``extend_test_004``.

.. req:: needextend Example 4
   :id: extend_test_004

   Had no links.
   Got an incoming links ``extend_test_003`` and ``extend_test_006``.

.. req:: needextend Example 5
   :id: extend_test_005
   :links: extend_test_003, extend_test_004

   Had the two links: ``extend_test_003`` and ``extend_test_004``.
   Both got deleted.

.. req:: needextend Example 6
   :id: extend_test_006
   :links: extend_test_003

   Had the link ``extend_test_003``, got another one ``extend_test_004``.

.. -- MANIPULATIONS --

.. needextend:: extend_test_003
   :links: extend_test_004

.. needextend:: extend_test_005
   :-links:

.. needextend:: extend_test_006
   :+links: extend_test_004

.. needextend:: extend_test_006
   :+links: extend_test_004

   Same as above, so it should not do anything.
   But it raises the modified-counter by one.

Result

Requirement: needextend Example 3 extend_test_003 ../_images/arrow-right-circle.svg
links outgoing: extend_test_004
links incoming: extend_test_006

Had no outgoing links. Got an outgoing link extend_test_004.

Requirement: needextend Example 4 extend_test_004 ../_images/arrow-right-circle.svg

Had no links. Got an incoming links extend_test_003 and extend_test_006.

Requirement: needextend Example 5 extend_test_005 ../_images/arrow-right-circle.svg

Had the two links: extend_test_003 and extend_test_004. Both got deleted.

Requirement: needextend Example 6 extend_test_006 ../_images/arrow-right-circle.svg

Had the link extend_test_003, got another one extend_test_004.

Monitoring modifications

All needs have this two internal parameters:

  • is_modified: A boolean value. Defaults to False

  • modifications: A number. Defaults to 0.

If a need gets changed by a needextend directive, is_modified is changed to True. Also, the modifications number is increased by one. +1 for each executed needextend on this need.

To see these values, use :layout: debug on the need or by Defining own layouts.

Also filtering for these values is supported:

Example

We have :need_count:`is_modified` modified needs.

.. needtable::
   :filter: "needextend" in title
   :columns: id, title, is_modified, modifications

Result

We have 6 modified needs.

ID

Title

Is Modified

Modifications

extend_test_001

needextend Example 1

True

1

extend_test_002

needextend Example 2

True

1

extend_test_003

needextend Example 3

True

1

extend_test_004

needextend Example 4

False

0

extend_test_005

needextend Example 5

True

1

extend_test_006

needextend Example 6

True

2