needextend¶
Added 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, for 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 will be taken as, by order of priority:
a single need ID, if it is enclosed by
<>,a Filter string if it is enclosed by
"",a single need ID, if it is a single word (no spaces),
a Filter string otherwise.
needextend can modify the status, tags, style, layout, hide and collapse options,
and every extra field and link option, whatever its type;
+option works on string and list options only.
Also, you can add links or delete tags.
The needextend directives are applied in extend-priority order (lower first),
then in document-name and line order,
and a filter sees the needs as written, not the changes of the other ones
(see below and Processing order).
Example 1
.. 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 :ndf:`copy('status')`.
| Also author got changed from **Foo** to :ndf:`copy('author')`.
| And a tag was added.
| Finally all links got removed.
.. req:: needextend Example 2
:id: extend_test_002
:tags: extend_example
:status: open
Contents
.. needextend:: extend_test_001
:status: closed
:+author: and me
.. needextend:: <extend_test_001>
:+tags: new_tag
.. needextend:: id == "extend_test_002"
:status: New status
.. needextend:: ""extend_example" in tags"
:+tags: other
This requirement got modified. Status was open, now it is open.
Also author got changed from Foo to Foo and me.
And a tag was added.
Finally all links got removed.
|
Contents |
Options¶
strict¶
The purpose of the :strict: option is to handle whether an exception gets thrown or a warning log 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 warning-level message in the console, and the build continues.
Allowed values:
true or
false
Default: false
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.
extend_priority¶
Added in version 9.0.0.
The needextend directives of a project are applied one after the other,
sorted by :extend_priority:, then by document name, then by line.
A lower priority is applied first, as for Sphinx’s event handlers:
where two needextend directives set the same option, the one with the higher priority is applied last and its value is kept,
and +option values are appended in ascending priority.
Allowed values: an integer of 0 or more.
An invalid value is reported as needs.needextend, and that needextend is not applied.
Default: 500, so a project that never sets the option keeps applying its needextend directives
in document-name and line order.
Example 2
.. req:: needextend Example 7
:id: extend_test_007
:status: open
.. needextend:: extend_test_007
:extend_priority: 600
:status: late
:+tags: applied_second
.. needextend:: extend_test_007
:extend_priority: 400
:status: early
:+tags: applied_first
The status of extend_test_007 ends as late, and its tags as applied_first, applied_second,
whatever the order and the files the two needextend directives are written in.
:extend_priority: orders the modifications; it never changes what a filter matches
(see below).
Like :strict:, it is an option of the directive itself,
so a field named extend_priority or strict cannot be replaced by a needextend;
+extend_priority and -extend_priority still modify such a field.
Filters see the needs as written¶
Changed in version 9.0.0: A filter used to be evaluated when its needextend was applied,
against the needs as the needextend directives applied before it had left them.
A filter naming a field that a [[…]], <<…>> or <{…}> computes
is now reported as needs.derive_scope.
Every filter is evaluated against the needs as written, before any needextend is applied,
and its needextend modifies the needs it matched there.
So no needextend changes which needs another one’s filter matches,
whatever order they are applied in, whatever their priorities and whatever the names of their files:
a filter on a field that a needextend modifies matches the needs written with the value it names.
For a need REQ_1 written with :status: open:
.. needextend:: REQ_1
:status: closed
.. needextend:: status == "open"
:+tags: written_open
REQ_1 ends closed and tagged written_open:
the filter matches it as written, although the needextend applied before it closed it.
An ID argument names its need whatever the other needextend directives change.
To react to what another needextend set, write the value as a derivation:
a [[…]] or <<…>> sees the needs after every needextend is applied (Processing order),
where a second needextend whose filter names the changed field matches the needs as written.
A filter sees no value a [[…]], <<…>> or <{…}> computes,
as those are computed after every needextend (Processing order),
so a needextend whose filter names a field that one computes, on any need, is reported as needs.derive_scope.
A filter is evaluated once in each document it is written in, however many needextend directives there carry it.
A filter that cannot be evaluated is reported for each of them as needs.needextend, and none of them modifies a need;
a warning the filter gives for a need it cannot be evaluated on (needs.filter) is reported once,
at the first of them to be applied.
Extending needs in current page¶
Added in version 5.0.0.
The c.this_doc() function is made available,
to filter for needs only in the same document as the needextend.
The following example would set the status of all needs in the current document,
which do not have the status set explicitly, to open.
Example 3
.. needextend:: c.this_doc() and status is None
:status: open
To address all needs in the current document, use this syntax:
Example 4
.. needextend:: "c.this_doc()"
:status: open
See also, Filtering for needs on the current page and needs_fields for setting a default option value for all needs.
Changing links¶
Options containing links get handled in two steps:
Options for the need are set as above.
The referenced need get updated as well and incoming links may get deleted, added or replaced.
Example 5
.. 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``.
.. needextend:: extend_test_003
:links: extend_test_004
.. needextend:: extend_test_005
:-links:
.. 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.
.. needextend:: extend_test_006
:+links: extend_test_004
Had no outgoing links.
Got an outgoing link |
Had no links.
Got an incoming links |
Had the two links: |
Had the link |
Monitoring modifications¶
All needs have this two internal parameters:
is_modified: A boolean value. Defaults toFalsemodifications: A number. Defaults to0.
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 6
We have :need_count:`is_modified` modified needs.
.. needtable::
:filter: "needextend" in title
:columns: id, title, status, is_modified, modifications
:style: table
We have 12 modified needs.
ID |
Title |
Status |
Is Modified |
Modifications |
|---|---|---|---|---|
needextend Example 1 |
open |
True |
3 |
|
needextend Example 2 |
open |
True |
3 |
|
needextend Example 3 |
open |
True |
3 |
|
needextend Example 4 |
open |
True |
2 |
|
needextend Example 5 |
open |
True |
3 |
|
needextend Example 6 |
open |
True |
4 |
|
needextend Example 7 |
late |
True |
3 |