Supported toolchain¶
ubCode and ubc were started as high-performance companion apps to efficiently develop and navigate Sphinx and Sphinx-Needs projects.
To achieve this, there are some focus areas:
Understand RST as docutils does, so it is 100% standards compliant
Understand what Sphinx adds on top, like directives, roles, domains and configuration
Support Sphinx-Needs specific directives, roles and configurations
The main goal is to ingest 100% of the primary data that Sphinx and Sphinx-Needs manage. Once that picture is complete, ubCode can provide a variety of features such as real-time indexing, previews, language server navigation, linting, formatting, schema validation, visualisations, MCP capabilities and much more.
A secondary goal is to improve the preview rendering so it becomes closer to how Sphinx renders HTML, but with outstanding performance. This means understanding more rendering-side features such as image embedding, Sphinx-Needs visualisations, rendering of certain directives and roles, etc.
This document describes which features of Sphinx and Sphinx-Needs are supported. If you stick to the features documented here, you can expect full support in ubCode and ubc. This will also have a positive impact on the qualification efforts of the overall toolchain at your organisation.
We will prioritise support for features that are widely used and requested by our users.
Configuration¶
ubCode and ubc require a declarative configuration style with TOML and JSON to fully understand Sphinx-Needs projects. Rationale:
Accessible outside of Python execution context (e.g., from Rust)
Reduces configuration complexity since the Sphinx configuration for large projects tends to become a whole software project on its own: many nested modules, 3rd party dependencies, long import time, dynamic code, etc.
Cacheable and fast-to-read configuration
Clear final state of configuration
Any configuration outside of this cannot be supported since ubCode and ubc do not execute any user Python code. There are efficient ways to deal with this by migrating your configuration or keeping the configuration in sync with what Sphinx/Sphinx-Needs would see at runtime. The new extension needs-config-writer might be worth a look.
Included features¶
Configuration¶
schemakey of needs_extra_optionsschemakey of needs_extra_linksneeds_build_json, needs_json_exclude_fields, needs_json_remove_defaults and needs_json_include_link_conditions — see [needs] JSON output.
needs_reproducible_json — accepted, but it has no effect: ubCode’s
needs.jsonnever carries a build timestamp, so it is already reproducible whatever the key is set to. See JSON output.needs_default_style — supported via a
defaulton thestylefield ([needs.fields.style]), which also gives per-condition styles throughpredicates.needs_default_layout — as [needs] default_layout, the same key in the same table a Sphinx build reads it from, so one
ubproject.tomlmeans one thing to both engines. Adefaulton thelayoutfield ([needs.fields.layout]) additionally gives per-condition designs throughpredicates, which Sphinx-Needs has no equivalent for (and whichneeds_from_tomlsilently skips). Two behaviours differ deliberately: an empty string is unset here rather than a build error, and an unknown design name is reported rather than aborting the build.needs_report_template — as [needs] report_template, and executed: needreport renders from the template you give it. One difference to know about is the path base — a relative path is taken from the directory holding
ubproject.toml(the convention every other path-valued ubCode key follows), where a Sphinx build resolves it against the source directory and strips a leading/instead of honouring it.
Directives¶
Roles¶
Data sources¶
sphinx-codelinks — source code tracing markers are ingested via the [codelinks] configuration section and the
.. src-trace::directive. See the codelinks guide for a walkthrough.
Upcoming features¶
A new form of dynamic functions that works for both Sphinx-Needs and ubCode/ubc. These functions will be limited in what they can do but will cover many use cases. More details will follow once this feature is designed. A reduced Python language subset such as Starlark looks promising.
Ingestion of other data sources:
Architecture data sources (concept work ongoing)
Excluded¶
Configuration¶
Dynamic conf.py configuration for Sphinx and Sphinx-Needs is not supported; see Configuration above.
Many of the configurations below are purely representational and do not impact the core data model of needs. More of these configurations will be supported in the future to improve the preview rendering.
needs_layouts —
:layout:itself is supported, and so is defining your own designs: see [needs.card_layouts]. What is excluded is upstream’s layout DSL — a grid of docutils table cells filled by<<meta_all(...)>>-style callables, which does not describe ubCode’s card markup at all, and in which an unknown name ends the build (SphinxNeedLayoutException) where ubCode warns and falls back. ubCode’s replacement is a declarative card spec: a named set of regions and typed elements, which its own built-in designs are written in too. A Sphinx-Needs project can use the same vocabulary with that project’sneeds_card_layouts, which compiles it down toneeds_layouts.needs_template_folder — the lookup root for need-content templates (the
:template:option on a need directive such as.. req::), which ubCode does not implement. It plays no part in needreport, whose own:template:is resolved as an ordinary document-relative path.needs_string_links — supported via [needs.string_links], in need cards and
needtablecells alike. What is excluded is what the two engines cannot share: patterns using look-ahead, look-behind or backreferences (ubCode’s regular expression engine trades them for a linear-time guarantee, and names the construct when it refuses one; a handful of rarer constructs — conditionals, atomic groups,\Z,(?#...)— are refused as parse errors), and needs_render_context, so a template sees the pattern’s named capture groups and nothing else. Several rendering behaviours deliberately differ — the trailing separator (Sphinx-Needs ≤ 8.3), list fields in the meta area, the value lost when a template raises, whitespace-only items, and a non-participating optional group — each listed in differences.needs_build_json_per_id and needs_build_json_per_id_path — the one-file-per-need variant of the JSON export. The whole-project export and its shaping keys are supported: see JSON output.
Directives¶
What is excluded here is the Sphinx-Needs implementation of these directives,
not necessarily their output:
the view directives — needlist, needtable, needflow,
needsequence, needpie, needbar and needgantt — are rendered by
ubCode’s own engine, with the deliberate differences listed in
differences.
needgantt is the widest of those carve-outs: ubCode SOLVES the
schedule itself and draws it as an inline SVG, where Sphinx-Needs generates
@startgantt text for PlantUML — so :config: (a PlantUML snippet) and
:scale: (raster sizing) are accepted and reported rather than applied, and
the two need fields it measures from must be declared rather than invented.
needreport is rendered by ubCode’s own engine too, including its
:template: surface: with no template it composes the same four sections a
Sphinx build’s packaged template produces, and with one it renders that template
against the same data a Sphinx build supplies. The
differences page lists what diverges.
list2need is implemented by ubCode’s own engine as well, and
without the Sphinx-Needs limitations: each bullet becomes a real need, every one
of them carries the source position of the item you wrote it on, and it works in
a Markdown document, where a Sphinx build creates no needs at all.
Its :presentation: option is read and reported rather than applied — see
differences.