Build tag to remove/delete needs
use case
As author, I have a common documentation source for multiple software projects (also called variants). But my Need objects are project-specific so I also need a project-specific Sphinx build, which contains the relevant needs only.
problem
I have tried using the delete option of a need object. However, its attribute can't be set programmatically (global_option, dynamic functions), so its value must be hard coded, which is just a boolean and therefore can't be project-specific.
proposal
Provide a new need option build-tags, which takes a comma-separated list of strings.
Each element represents a build-tag.
If the Sphinx build is called with the tag-parameter sphinx-build -t my_tag and my_tag is part of build-tags, the related need object is internally created.
If build-tags does not match any given sphinx tag, the need object is deleted/removed from the build and does not show up in the HTML representation or in needtables and co. It just doesn't exist in the internal need-dictionary.
If build-tags is not set (internally none) or contains all, the need object is built under all circumstances, no matter what sphinx-build -t ... is telling.
So the change will be backward-compatible, as this is the case for all current docs.
Mapping
In bigger projects, the amount of build-tags, which are often used as feature flags, can be huge. To reduce the usage of -t my_tag in a sphinx-build call, a mapping shall be allowed.
Provide needs_build_mapping for conf.py
Example:
needs_build_mapping = {
"my_tag": ["feature_A", "feature_D"],
"another_tag": ["delete", "do_not_show"],
...
}
needs_build_mapping is a dictionary, where the key represents the sphinx tag from sphinx-build -t ....
The value is a list of strings, where each element can be used inside build-tags of a need object.
If sphinx-build -t my_tag is in the keys of needs_build_mapping, all elements are set internally as tag as well.
So in our example, the list of currently active build tags would be my_tag, feature_A, feature_D.
If one of these is used by build-tags, the related need gets not removed.
fast tagging
In some cases, a single need object shall get "activated" or "removed".
To support a fast, single need object related build tagging, the Need-ID can be also provided as build-tag. Example sphinx-build -t my_tag -t REQ_001.
This allows the steering of specific needs without setting build-tags to a just need-specific value.
drawbacks/open points
- There is no logic in
build-tags. One positive match is enough to take the need into account. Noandor negation support. - This still does not support
global_optionsordynamic functions.
use case source
The SCORE project does a similar, internal implementation of this: https://github.com/eclipse-score/score/pull/217
They are (miss)using hide to get the same result and do some nasty monkey-patching ;)
We should support them by providing this kind of feature.
Full example
index.rst
.. req:: My Requirement for Login
:id: REQ_LOGIN
:build-tags: login
Some content
.. req:: My Requirement for Printing
:id: REQ_PRINT
:build-tags: export
Some content
.. req:: My Requirement for Design
:id: REQ_DESIGN
Some content
.. needtable::
conf.py
needs_build_mapping = {
"security": ["login", "roles", "encryption", "monitoring"]
}
Call: sphinx-build -b html . _build/html
Result: REQ_DESIGN is part of the docs
Call: sphinx-build -b html -t security . _build/html
Result: REQ_DESIGN, REQ_LOGIN are part of the docs
Call: sphinx-build -b html -t security -t REQ_PRINT . _build/html
Result: REQ_DESIGN, REQ_LOGIN, REQ_PRINT are part of the docs
This indeed I think should provide the functionality required. One thing that might be a nice quality of life (although I'm unsure how easy it would be to implement) is to have the option to specify what attribute/option the build-tag should check. In case you want to have 'tags' used differently. But as said, not sure if this is an easy or even wanted addition.
But this looks great. 👍
This sounds like a variant management mechanism. We should reuse the already defined configuration interface needs-variants and we shall not introduce a new configuration interface needs_build_mapping.
So we can use the regular variant mechanisem on a new option to delete a need variant usage.
Good point and I agree, needs_variants is already capable of providing this kind of configuration.
In this case, we just need an option, which takes a variant/build information. And as @MaximilianSoerenPollak has pointed out, this should be configurable.
So I propose a new configuration option: needs_variants_keep.
Example: needs_variants_keep = [tags, keep]
It's a list, which takes option names.
It defines the options, which shall be checked during need-creation.
The options must contain a value from needs_variants and or not assigned string (then not taken into account)
The rule under needs_variants then defines, if the need gets finally created (positive eval) or not.
Drawbacks
-
needs_variantsis not allowed to use filter-string, which takes data from other needs and external sources into account.