Skip to content

Sync upstream main to 65016e5b (2026-10) - #10

Merged
ViktorJannicke merged 13 commits into
mainfrom
sync/upstream/2026-10
Oct 19, 2026
Merged

ViktorJannicke merged 13 commits into
mainfrom
sync/upstream/2026-10

Conversation

@ViktorJannicke

Copy link
Copy Markdown

Brings the fork up to date with upstream main at 65016e5b (2026-10-13). The sync uses real merges, so no history was rewritten or force-pushed, and git merge-base --is-ancestor 65016e5b HEAD holds.

Upstream commits adopted

Upstream had 6 commits since the previous sync base c98ab809. They are merged in three pinned stages so each conflict set can be reviewed on its own:

Merge Upstream Conflicted files Resolution
663e51cb reactivemarbles#1195 delete DynamicData.Profile; reactivemarbles#1203 Central Package Management; reactivemarbles#1202 benchmarks NoWarn 4 CPM adopted. src/Directory.Packages.props holds the fork's versions (TUnit, Primitives through ReactiveUIPrimitivesVersion, SourceLink/NBGV). It is the nearest Directory.Packages.props, so it still keeps an enclosing workspace's central versions out. The root file still turns CPM off for eng/. Resolved package graphs are unchanged.
97ec2733 reactivemarbles#1201 Polyfill package; reactivemarbles#1171 list Transform/TransformAsync without indexes 247 The Polyfill package and System.Reactive references are not adopted, because on .NET 10 those APIs are built in. Hunks that only differed in guard spelling (468 of 597) take upstream's ArgumentNullException.ThrowIfNull. Upstream's new guards (others, Avg/StdDev helpers) are kept. The fork keeps its own structure (primary constructors, gate properties, DD-006/DD-032 guards) in the 7 files where upstream only reshaped fields. For reactivemarbles#1171 the fork's DD-018 implementation is kept; it is broader than upstream's.
65016e5b reactivemarbles#1197 global imports 610 src/DynamicData/Global.cs follows upstream but is flavour-aware: the DynamicData namespaces switch on REACTIVE_SHIM, the Rx imports stay in each csproj, and ImplicitUsings stays on. Per-file usings that are now global were removed from library sources. Tests and benchmarks keep the fork's TUnit/Primitives csproj imports, so upstream's xUnit and System.Reactive Global.cs files are not adopted.

Both stage-2 and stage-3 resolutions were audited file by file against the fork's previous version. Apart from the global-usings removal, the guard-spelling change and upstream's cosmetic line re-wraps, the only library differences are the upstream validation changes listed below.

Not taken: upstream/release/9.x (9.5.0) only contains backports of fixes already on main. Upstream PR reactivemarbles#1116 (MigrateToPrimitives) has no commits newer than the fork.

Behaviour changes from upstream

These come from reactivemarbles#1201 and none of them changes the public API surface. They only affect exception types and argument-validation edge cases:

  • And/Or/Xor/Except with an empty others array now throw ArgumentException instead of ArgumentNullException. A null array still throws ArgumentNullException.
  • Negative indexes in ChangeAwareList now throw ArgumentOutOfRangeException instead of ArgumentException. RemoveRange(Count, 0) is now a no-op, matching List<T>.
  • Cache Virtualise/Page size validation uses ArgumentOutOfRangeException.ThrowIfNegativeOrZero, so the exception message differs. List Top keeps the fork's message.

Fork follow-ups in this PR

  • ce4e05f5 ports upstream's four Fixed bogus lookup logic within list-land .TransformAsync(),… reactivemarbles/DynamicData#1171 regression tests to TUnit. They pass against DD-018 in both flavours.
  • b3a9ed01 changes the remaining ArgumentExceptionHelper.ThrowIfNull calls to the BCL form. On .NET 10 that helper was already an alias for ArgumentNullException, so behaviour is unchanged. The net4x-only helper classes and aliases are removed.
  • eaaf954b keeps SourceLink as a centrally versioned PackageReference. As a GlobalPackageReference it dropped the packages' commit provenance, which the acceptance gate requires.
  • 978a5fe1 updates register entries DD-001, DD-002, DD-003 and DD-018 and adapts upstream's usings guidance in .github/copilot-instructions.md.

Versioning

version.json is unchanged (10.0-runic.{height}). The next release from main will be 10.0.0-runic.N with N greater than 30; no new version line is needed. Nothing has been published.

Verification (local, Linux, runic-sdk locked shell)

All run on the final commit eaaf954b:

Check Result
Build src/DynamicData.sln with Primitives 8.4.0 and 9.0.0 ✅ 0 errors; only the 7 existing benchmark CS0618 warnings
DynamicData.Tests (Primitives flavour), 8.4.0 / 9.0.0 ✅ 3,526 / 3,526 passed
DynamicData.Reactive.Tests (System.Reactive flavour), 8.4.0 / 9.0.0 ✅ 3,524 / 3,524 passed
Public API approval tests (part of the suites) ✅ baselines unchanged
dotnet pack + packaged acceptance gate (--asset-directory), managed and NativeAOT linux-x64 ✅ passed
External consumer probes (eng/verification), managed and NativeAOT ✅ 16 + 8 checks passed
Upstream-review fixtures (eng/upstream/test-*.mjs) ✅ passed

The acceptance gate caught one regression from the CPM adoption: a SourceLink GlobalPackageReference loses its buildTransitive targets, so packages lost their repository commit. eaaf954b fixes this.

Consumers

runic-sdk pins dynamicData.forkRevision to edd2d175 and is unaffected until that pin moves. ReactiveUI.Validation consumes the released 10.0.0-runic.30 pair and is unaffected until a new pair is published.

🤖 Generated with Claude Code

JakenVeina and others added 13 commits October 9, 2026 15:18
…hat the purpose of this used to be, but it hasn't been included in the main solution for years, and and doesn't even build anymore. (reactivemarbles#1195)
Package versions now live in src/Directory.Packages.props. Build tooling and analyzers (Nerdbank.GitVersioning, SourceLink, StyleCop, Roslynator) are GlobalPackageReferences with the same project conditions as before. Floating versions are enabled only for test and benchmark projects; their PackageVersion items are hidden from the library so any float there fails restore with NU1011. Microsoft.Bcl.AsyncInterfaces moves into DynamicData.csproj, the only netstandard2.0 project.
…bles#1202)

The benchmarks NoWarn replaced the list from Directory.Build.props instead of appending to it, so VSX1000 and CA1510 were not suppressed there.

Co-authored-by: Jake Meiergerd <jakenveina@gmail.com>
…fills library. (reactivemarbles#1201)

This library ships polyfill source code and uses MSBuild directives to inject it directly into the target projects, allowing them to be kept internal and to leverage the syntactic sugar of extension blocks: basically, accomplishing every goal we had by writing our own.

In turn, I eliminated all of the existing polyfills within the project, and where those polyfills were not actuallly drop-in polyfills for the missing APIs, I migrated existing code to target the proper native APIs. Mostly, this involved swapping to use proper "Throw" helper methods such as `ArgumentNullException.ThrowIfNull()`.

The other big adjustment is getting rid of all use of locks upon any type other than `System.Threading.Lock`. The `Lock` polyfill introduced ultimately just aliases normal `Monitor`-based `object` locking, so while we don't get any of the actual mechanical benefits of the true `Lock` class, we no longer need to litter the codebase with `#if` blocks to swap between using `Lock` or `object`, depending on the target framework. All target frameworks can just use code that targets `Lock` and compiles unconditionally.

Shoutout to Chris Pullman for putting us on to Simon's library, and building the initial draft of most of these changes.

As a small side-effect, several operators were discovered to be incorrectly throwing `ArgumentNullException` for an empty input collection: the `And`, `Except`, `Or`, and `Xor` operators upon `ObservableCacheEx`. These have been fixed to throw `ArgumentException` with an appropriate message.

---------

Co-authored-by: Chris Pulman <chris.pulman@yahoo.com>
…tivemarbles#1171)

* Fixed bogus lookup logic within list-land `.TransformAsync()`, for processing changes with unspecified indexes, which resulted in `Remove` and `RemoveRange` changes with unspecified indexes to be ignored completely.

* Added equivalent fixes (and tests) to `.Transform()`, and consolidated logic for handling index lookup, when indexes are missing from changesets, into a shared allocation-free helper method.
Consolidated namespace imports to a set of global definitions, across each project, and removed all redundant import definitions.

Co-authored-by: Chris Pulman <chris.pulman@yahoo.com>
Co-authored-by: Darrin Cullop <dacullop@microsoft.com>
Merge reactivemarbles/DynamicData main up to 663e51c (reactivemarbles#1195, reactivemarbles#1203, reactivemarbles#1202).

- reactivemarbles#1195 removes the unbuilt NonProduction/DynamicData.Profile project.
- reactivemarbles#1203 adopts Central Package Management. src/Directory.Packages.props
  carries the fork's versions (TUnit, ReactiveUI.Primitives via
  ReactiveUIPrimitivesVersion, current SourceLink/NBGV) instead of
  upstream's xUnit/System.Reactive set. Being the nearest
  Directory.Packages.props it still isolates the fork from an enclosing
  workspace; the root file keeps CPM off for eng/ probes.
- reactivemarbles#1202 makes the benchmarks NoWarn append to the inherited list.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merge reactivemarbles/DynamicData main up to 97ec273 (reactivemarbles#1201, reactivemarbles#1171).

reactivemarbles#1201 (Polyfill package):
- The Polyfill package and System.Reactive references are not adopted:
  the fork targets .NET 10 only, where the polyfilled APIs are native.
- Conflicting argument guards take upstream's spelling,
  ArgumentNullException.ThrowIfNull, instead of the fork's
  ArgumentExceptionHelper; upstream's additional guards (And/Or/Xor/
  Except `others`, Avg/StdDev helpers) are kept.
- Upstream's validation changes are adopted where they merged:
  empty `others` arrays throw ArgumentException, ChangeAwareList index
  checks throw ArgumentOutOfRangeException, and
  ArgumentOutOfRangeException.ThrowIfNegativeOrZero replaces custom
  messages.
- The pre-.NET 7 polyfill attributes, EnumEx and ListEnsureCapacity are
  deleted as upstream did; they were compiled out on .NET 10.
- BatchIf, DynamicCombiner, both ExpireAfter flavours, cache
  Filter.Dynamic and list Filter.WithPredicateState keep the fork's
  structure (primary constructors, gate properties, DD-006/DD-032
  disposal guards); upstream only reshaped fields there.

reactivemarbles#1171 (list Transform/TransformAsync without indexes):
- The fork's DD-018 implementation is kept: it removes one occurrence at
  a time, preferring reference and then equality, and also covers
  EditDiff and TransformMany. Upstream's regression tests are ported in
  a follow-up commit.

Test fixtures stay on the fork's TUnit translations.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merge reactivemarbles/DynamicData main up to 65016e5 (reactivemarbles#1197), the
current upstream main.

- src/DynamicData/Global.cs follows upstream's global imports, adapted
  to the shared-source flavours: the DynamicData namespaces switch on
  REACTIVE_SHIM, upstream's System.Reactive imports are left to each
  project's csproj (ReactiveUI.Primitives or System.Reactive), and the
  namespaces ImplicitUsings already provides are not repeated. The
  csproj imports it replaces are removed.
- Per-file imports covered by the global set, including the paired
  REACTIVE_SHIM using blocks, are removed from library sources; the
  flavour namespace declarations stay. Conflicted files are the fork's
  version with that transform plus upstream's shortened SuppressMessage
  attributes.
- InternalsVisibleTo moves from Attributes.cs to Global.cs as upstream
  did, keeping the fork's test and benchmark grants.
- ImplicitUsings stays enabled: the TUnit test and benchmark projects
  keep their csproj imports, so upstream's xUnit/System.Reactive
  Global.cs files for those projects are not adopted and their
  sources stay as the fork's.
- CacheChangeSetEx keeps its DynamicData.Cache namespace, which remains
  globally imported in the fork.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Translate the regression tests added by upstream reactivemarbles#1171 to TUnit:
Remove and RemoveRange changes without indexes remove the first
occurrence of each item through Transform and TransformAsync. The
fork's DD-018 implementation already passes them in both flavours.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Finish the move to upstream's guard spelling begun in the reactivemarbles#1201 merge:
the remaining ArgumentExceptionHelper.ThrowIfNull calls become
ArgumentNullException.ThrowIfNull. On .NET 10 the csproj already aliased
ArgumentExceptionHelper and ArgumentOutOfRangeExceptionHelper to the BCL
types, so behaviour is unchanged; the aliases and the net4x-only helper
classes are removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Update DD-001 (no Polyfill package), DD-002 (fork-owned src/
Directory.Packages.props), DD-003 (flavour-aware Global.cs) and DD-018
(upstream reactivemarbles#1171 merged, narrower than the fork). Adapt the merged
upstream usings guidance to the fork's project layout.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The CPM adoption turned Microsoft.SourceLink.GitHub into a
GlobalPackageReference. NuGet restores those without buildTransitive
assets (and ignores an IncludeAssets override), which drops the
Microsoft.SourceLink.Common and Microsoft.Build.Tasks.Git targets.
Packages then lost the repository commit in their nuspec, and the
packaged acceptance gate rejected them. Reference SourceLink from
Directory.Build.props with a central version instead, as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ViktorJannicke
ViktorJannicke merged commit c889b86 into main Oct 19, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants