Repository navigation
Nest slices in packages via GenerationOptions, deprecate MatchingWithPackages - #513
Open
alexanderlinne wants to merge 1 commit into
Open
alexanderlinne wants to merge 1 commit into
alexanderlinne wants to merge 1 commit into
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## stop-deriving-namespace-from-slice #513 +/- ##
======================================================================
- Coverage 86.53% 86.36% -0.17%
======================================================================
Files 261 261
Lines 12713 12623 -90
Branches 1241 1226 -15
======================================================================
- Hits 11001 10902 -99
- Misses 1366 1374 +8
- Partials 346 347 +1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
alexanderlinne
force-pushed
the
nest-slices-in-packages-option
branch
from
October 24, 2026 20:08
d38ef64 to
e8f8233
Compare
alexanderlinne
marked this pull request as draft
October 25, 2026 19:39
alexanderlinne
force-pushed
the
nest-slices-in-packages-option
branch
from
October 28, 2026 19:54
e8f8233 to
8a2c09b
Compare
alexanderlinne
marked this pull request as ready for review
October 29, 2026 21:31
This was referenced Oct 29, 2026
…ngWithPackages MatchingWithPackages existed because a slice carried nothing but its name: the exporter worked out the nesting from that string, so it had to be fully qualified, while rules needed short names. The choice between the two had to be made when the slices were created, and the qualified names ended up in failure messages and frozen-rule stores as well. Both methods group types the same way: the namespace before the capture group is literal pattern text, so prefixing every name with it changes no grouping. Diagrams need no data from the pattern: the exporter nests every slice in the namespaces its types share. GenerationOptions.NestSlicesInPackages (default false) makes the exporter draw the namespace tree as packages and put each slice, under its name, in the package of the deepest namespace that contains all of its types. A package with no slice of its own and a single child package is merged with it, e.g. into "Orders.Domain". A slice whose types share no namespace is drawn outside any package. This applies to every slice, also to those of SlicedBy and of custom assignments. Focus mode takes the options too. MatchingWithPackages is obsolete. It creates the same slices as Matching, so its rules report the same names and violations. It only still nests its slices in diagrams by default; they are now boxes inside their namespaces rather than the namespaces themselves, and package arrows are gone. Packages now come from the types' namespaces, so "..DuplicatePrefix.Sub.(**)" no longer gets a package ".DuplicatePrefix.Sub.". Slices whose name is a prefix of another's, such as App.Order and App.Orders, are no longer mistaken for a package and dropped from the diagram. Focus mode focuses the slices whose types all lie in the given namespace, and draws the slices they depend on or that depend on them. LimitDependencies keeps the arrows between slices whose common namespaces are equally deep. Both rules now use the types rather than the diagram names, so they work the same flat and nested. The guide shows Matching with NestSlicesInPackages in its diagram examples and gains a migration section. Breaking changes: - MatchingWithPackages is obsolete, and creates Matching's slices, so its failure messages and frozen violations no longer use names qualified with the namespace before the capture group. - Slice.NameSpace, Slice.ContainsNamespace() and SliceIdentifier.NameSpace are removed, and SliceIdentifier.Of loses its nameSpace parameter. - Nested slice diagrams change: every slice is a box at its types' common namespace; no slice is drawn as a package and there are no package arrows. - Focus mode takes a namespace, also for flat diagrams, and matches it by segments. - Nested LimitDependencies keeps same-depth arrows instead of a sibling overview. - OneToOneCompact renders whatever the dots in its names; the exporter filters instead. Signed-off-by: Alexander Linne <alexander.linne@tngtech.com>
alexanderlinne
force-pushed
the
nest-slices-in-packages-option
branch
from
October 30, 2026 20:07
8a2c09b to
8a78006
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
MatchingWithPackagesexisted, and why it no longer has toOn
main, a slice carries a single string, its name, plus an optionalNameSpace. The PlantUML exporter works out everything from those strings:StartsWith),Contains),LimitDependenciesgoes (counting dots).For that it needs fully qualified names such as
App.Orders.Web. Rules need the opposite: short names for failure messages and freeze stores. Both requirements apply to the same string, so the choice has to be made when the slices are built, which is why there are two methods:Matchingproduces short names and draws flat.MatchingWithPackagesproducesprefix + nameand draws nested.The prefix is the literal pattern text before the capture group, so both methods group types the same way; only the names differ. In other words, a diagram option ends up in failure messages and frozen violations.
The exporter doesn't need anything from the pattern: it nests each slice in the deepest namespace its types share. So the flat vs. nested choice moves from slice creation to rendering, and one set of slices can be checked and drawn both ways.
This PR doesn't touch the matcher; it runs on
main's. Since the layout depends only on the types, the next two PRs can change naming and matching without touching it.What changes
GenerationOptions.NestSlicesInPackages(defaultfalse) draws the namespace tree aspackageblocks.MatchingWithPackagesis[Obsolete]and creates exactlyMatching's slices, so rule descriptions, slices, names, violations and freeze keys are the same as withMatching. Its slices still nest by default.MatchingWithPackagesTestschecks that both methods give the same slices, the same rule results and the same diagrams.Slices are boxes inside their namespaces. With nesting on, every slice is drawn under its name in the package of the deepest namespace that contains all of its types:
Orders.Domain.SlicedByslices and customSliceAssignments.Packages come from the types, not from the pattern text. With a leading
..,MatchingWithPackagesnested slices under the pattern text with one of its dots stripped...DuplicatePrefix.Sub.(**)thus got a package.DuplicatePrefix.Sub, which doesn't exist; the slice now sits in the namespace its types are in:A slice whose name is a prefix of another's is drawn. On
main, withApp.(*)overApp.OrderandApp.Orders,"Orders".StartsWith("Order"), soOrderwas taken for the package ofOrdersand drawn neither as a slice nor with its dependency onBilling. That check is gone along with package-slices:Focus mode takes a namespace.
WithDependenciesFromFocusOnand the fluentWithDependenciesFromSlices(slices, focusOnPackage)take an optionalGenerationOptionsfor the nesting. A slice is focused when all of its types lie in the given namespace or below it, matched by segments; the slices it depends on, or that depend on it, are drawn as well. Onmain, the focus string was a substring of the slice names, so flat diagrams were focused with a bare name ("Slice1"), which also matchedSlice10. Now flat and nested diagrams both take the full namespace and focus the same slices.LimitDependencieskeeps arrows between slices at the same depth, i.e. whose types share an equally deep namespace, flat or nested. For(**)patterns that is exactlymain's flat output. Nested,maindrew a sibling overview with package arrows instead; it now keeps the same arrows as flat, inside the tree. The exporter decides which arrows to draw, soOneToOneCompactno longer checks dots when it renders. The namespace overload filters the same way, and its output doesn't change; a new snapshot pins it.Guide. Sections 5.2–5.6 use
MatchingwithNestSlicesInPackagesand describe the new layout, focus and depth rules, and a new section 5.7 explains the migration. 5.6 also gets a missing semicolon.Every flat snapshot is unchanged. The nested snapshots were renamed (
BuildUmlBySlicesMatchingWithPackages_*→BuildUmlBySlicesNested_*), switched to the option and regenerated.Breaking changes
MatchingWithPackagesis obsolete. It createsMatching's slices, so its failure messages and frozen violations no longer use names qualified with the namespace before the capture group. Frozen violations ofMatchingWithPackagesrules have to be frozen again once.Slice.NameSpace,Slice.ContainsNamespace()andSliceIdentifier.NameSpaceare removed, andSliceIdentifier.Ofloses itsnameSpaceparameter.LimitDependencieskeeps same-depth arrows instead of a sibling overview.OneToOneCompactrenders whatever the dots in its names; the exporter filters instead.Migration: replace
MatchingWithPackages(pattern)withMatching(pattern)and draw the slices withnew GenerationOptions { NestSlicesInPackages = true }. Pass the full namespace to focus mode.How the images were made
All images render PlantUML that the exporter produced. The "before" sides were produced on
main(#512 doesn't touch slice diagrams), the "after" sides at this PR..verified.txtsnapshots of…MultipleSubnamespaces.(**)on either side.mainhas no snapshot for it; the "after" side isBuildUmlBySlicesNested_DuplicatePrefixSegment.App.Order,App.Orders,App.Billing).They were rendered with PlantUML 1.2025.4 and Graphviz, with the remote
!includeof C4-PlantUML replaced by PlantUML's bundled copy (!include <C4/C4_Container>).