Fix Cratis meta-package and Chronicle consumption for downstream apps#2310
Closed
woksin wants to merge 4 commits into
Closed
Fix Cratis meta-package and Chronicle consumption for downstream apps#2310woksin wants to merge 4 commits into
woksin wants to merge 4 commits into
Conversation
Arc 20.44.0 was compiled against a Chronicle whose IEventSequence.AppendMany signature differed from the released one consumers restore. 15.35.0 added a trailing optional 'Subject? subject' parameter to AppendMany/Append, which modifies the single method signature rather than adding an overload, so Arc compiled against the older signature bound to a method that no longer exists and threw MissingMethodException at runtime against released Chronicle. - Pin the Chronicle floor to released 15.35.0 and align the Microsoft.Extensions family to 10.0.9 (required by Chronicle 15.35.0) so a version mismatch fails restore instead of crashing at runtime. - Add a reflection guard spec pinning the AppendMany/Append overload signatures the command pipeline binds to, so a future Chronicle signature drift trips at build time instead of reaching consumers as a runtime crash.
The Cratis meta package bundles the Arc source generator into analyzers/dotnet/cs, and the individual packages (Cratis.Arc.Core, Cratis.Fundamentals) ship the same generator. A consumer referencing Cratis plus any package that transitively brings one of those (e.g. Cratis.Arc.MongoDB -> Cratis.Arc.Core) loaded the generator from two analyzer paths, ran it twice, and failed with CS0101 because the unconditional 'Cratis.Arc.Generated.GeneratedMarker' was emitted twice. - Add a buildTransitive target in Cratis.props that de-duplicates @(Analyzer) by file name before compilation, so every Cratis consumer collapses duplicate analyzer DLLs regardless of restore path (this also protects GeneratedQueryMetadata). - Make GeneratedMarker a partial type as defense-in-depth, so a duplicate emission merges instead of colliding even if an analyzer slips through de-duplication. - Cover the partial-merge defense with a unit spec that compiles two copies of the generated marker and asserts no CS0101.
Reproduce the analyzer double-load end to end: pack the meta-package closure into a local feed and build a consumer that references both Cratis and Cratis.Arc.MongoDB with a [ReadModel], asserting it builds clean with no CS0101. The read model makes the generator emit GeneratedQueryMetadata too, so the test specifically exercises the analyzer de-duplication rather than only the partial-marker defense.
ARCCHR0002 (ambiguous command event source id) only exempted commands whose Handle returns EventForEventSourceId directly, so it false-positived on commands that supply the event source explicitly through a tuple return. Do not report the diagnostic when the Handle return type is, or is a tuple containing, EventForEventSourceId / IEnumerable<EventForEventSourceId>, or is a tuple whose first element derives from EventSourceId<T> (new-stream create, where the event source is the returned/generated id rather than a command property and ICanProvideEventSourceId is neither needed nor implementable). The ambiguity warning still fires when a tuple return provides no event source.
|
NuGet packages for this PR, e.g. Cratis.Arc: |
| /// </summary> | ||
| static readonly string[] _projectsToPack = | ||
| [ | ||
| Path.Combine("Source", "DotNET", "Arc.Core", "Arc.Core.csproj"), |
| static readonly string[] _projectsToPack = | ||
| [ | ||
| Path.Combine("Source", "DotNET", "Arc.Core", "Arc.Core.csproj"), | ||
| Path.Combine("Source", "DotNET", "Arc", "Arc.csproj"), |
| [ | ||
| Path.Combine("Source", "DotNET", "Arc.Core", "Arc.Core.csproj"), | ||
| Path.Combine("Source", "DotNET", "Arc", "Arc.csproj"), | ||
| Path.Combine("Source", "DotNET", "Chronicle", "Chronicle.csproj"), |
| Path.Combine("Source", "DotNET", "Arc.Core", "Arc.Core.csproj"), | ||
| Path.Combine("Source", "DotNET", "Arc", "Arc.csproj"), | ||
| Path.Combine("Source", "DotNET", "Chronicle", "Chronicle.csproj"), | ||
| Path.Combine("Source", "DotNET", "Swagger", "Swagger.csproj"), |
| Path.Combine("Source", "DotNET", "Arc", "Arc.csproj"), | ||
| Path.Combine("Source", "DotNET", "Chronicle", "Chronicle.csproj"), | ||
| Path.Combine("Source", "DotNET", "Swagger", "Swagger.csproj"), | ||
| Path.Combine("Source", "DotNET", "Tools", "ProxyGenerator.Build", "ProxyGenerator.Build.csproj"), |
| Path.Combine("Source", "DotNET", "Chronicle", "Chronicle.csproj"), | ||
| Path.Combine("Source", "DotNET", "Swagger", "Swagger.csproj"), | ||
| Path.Combine("Source", "DotNET", "Tools", "ProxyGenerator.Build", "ProxyGenerator.Build.csproj"), | ||
| Path.Combine("Source", "DotNET", "MongoDB", "MongoDB.csproj"), |
| Path.Combine("Source", "DotNET", "Swagger", "Swagger.csproj"), | ||
| Path.Combine("Source", "DotNET", "Tools", "ProxyGenerator.Build", "ProxyGenerator.Build.csproj"), | ||
| Path.Combine("Source", "DotNET", "MongoDB", "MongoDB.csproj"), | ||
| Path.Combine("Source", "DotNET", "Cratis", "Cratis.csproj"), |
| public static CratisMetaConsumerBuildResult Execute() | ||
| { | ||
| var repositoryRoot = GetRepositoryRoot(); | ||
| var workingDirectory = Path.Combine(Path.GetTempPath(), "Cratis.Arc.MetaConsumer.Integration", Guid.NewGuid().ToString("N")); |
| { | ||
| var repositoryRoot = GetRepositoryRoot(); | ||
| var workingDirectory = Path.Combine(Path.GetTempPath(), "Cratis.Arc.MetaConsumer.Integration", Guid.NewGuid().ToString("N")); | ||
| var packageDirectory = Path.Combine(workingDirectory, "packages"); |
| var repositoryRoot = GetRepositoryRoot(); | ||
| var workingDirectory = Path.Combine(Path.GetTempPath(), "Cratis.Arc.MetaConsumer.Integration", Guid.NewGuid().ToString("N")); | ||
| var packageDirectory = Path.Combine(workingDirectory, "packages"); | ||
| var restoredPackagesDirectory = Path.Combine(workingDirectory, "restored-packages"); |
Contributor
Author
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.
Makes Arc consumable again from the
Cratismeta package alongside Arc.Chronicle. Arc 20.44.0 broke real consumers at build and runtime; this restores a clean restore-build-run path against released Chronicle.Changed
Cratis.Chronicleto15.35.0.Fixed
Cratismeta package together with a package that transitively bringsCratis.Arc.Core(such asCratis.Arc.MongoDB) no longer fails withCS0101 'Cratis.Arc.Generated.GeneratedMarker'caused by the Arc source generator being loaded and run twice.MissingMethodExceptionat runtime against released Chronicle. The Chronicle floor now matches theAppendMany/Appendoverloads Arc actually calls, so an incompatible Chronicle version failsdotnet restoreinstead of crashing at runtime.ARCCHR0002analyzer no longer reports an ambiguous command event source id when the command'sHandlesupplies the event source explicitly through a tuple return — including new-stream-create commands that return a generated id deriving fromEventSourceId<T>.