Skip to content

refactor(utilities): adopt MoreLINQ for DistinctBy and Shuffle#366

Closed
ChrisonSimtian wants to merge 7 commits into
spike/shim-migration-redesignfrom
refactor/355-morelinq
Closed

refactor(utilities): adopt MoreLINQ for DistinctBy and Shuffle#366
ChrisonSimtian wants to merge 7 commits into
spike/shim-migration-redesignfrom
refactor/355-morelinq

Conversation

@ChrisonSimtian

Copy link
Copy Markdown
Collaborator

Closes #355

What

  • Add morelinq (4.4.0) centrally and reference it from Fallout.Utilities.
  • Redirect the two helpers that have a true MoreLINQ equivalent, keeping [Obsolete] forwarders so consumer code still compiles:
    • Distinct(selector) -> MoreEnumerable.DistinctBy
    • Randomize() -> MoreEnumerable.Shuffle

Why

  • Drop reinvented collection helpers in favour of MoreLINQ (dependency-consolidation audit, tier 2).
  • Forwarders are [Obsolete], not deleted, to keep the break soft on the experimental line.

Scope notes (deviations from the issue's literal list)

  • TakeUntil/SkipUntil: kept. MoreLINQ's TakeUntil is inclusive (the matching item is returned); Fallout's is exclusive (TakeWhile(!cond)). Redirecting would silently change behaviour in ArgumentParser and CompletionUtility, so these are not genuine equivalents.
  • ForEach/ForEachLazy: kept. MoreLINQ has no ForEach(Action<T,int>) index overload and no lazy variant, and importing its ForEach would make ~70 call sites ambiguous.
  • Single-pick Random<T>(): kept. No MoreLINQ/BCL equivalent.
  • On net10 the BCL now ships DistinctBy/Shuffle; the forwarders call MoreLinq.MoreEnumerable.* explicitly so both netstandard2.0 and net10.0 resolve unambiguously.

⚠️ Breaking change

Public extension methods Distinct(selector) and Randomize() are now [Obsolete]. Migration: use DistinctBy / Shuffle from the morelinq package.

Tests

  • dotnet test tests/Fallout.Utilities.Tests -> 187 passed.
  • dotnet build fallout.slnx -> succeeded.

No CHANGELOG entry per task instructions.

ChrisonSimtian and others added 7 commits May 30, 2026 15:02
…330)

Implements the trigger/hygiene slice of milestone #18 (CI cost & pipeline
structure). #325 (publish-lane realignment) already landed in the ladder PR.

- #318/#326 Cross-platform gated to release intent. windows/macos no longer run
  on main/experimental pushes (or any routine push). They run only on PR-to-
  release/* or support/*, and on v* tag pushes. ("On main we've got our edge":
  the ubuntu-latest PR gate + alpha/preview pipelines.) workflow_dispatch is not
  emitted — the generator only writes it with inputs; GitHub's run re-run covers
  on-demand cross-platform.
- #322 concurrency cancel-in-progress on ubuntu/windows/macos (generator) +
  experimental.yml + preview.yml. NOT on release.yml (never cancel a publish).
- #323/#328 Canonical CI-ignore list (docs/**, .assets/**, **/*.md) on every
  PR/push trigger. (release.yml is tag-triggered, so path-ignore is N/A there.)
- #327 Codified "feature branches run zero CI until PR'd" + the trigger model in
  docs/agents/conventions.md, with what-not-to-do guards.
- #329 Dropped dead 'submodules: recursive' from all checkouts + the generator
  (no .gitmodules; full build passes without it) and the stale vendor comment.

Generated workflows regenerated from build/Build.CI.GitHubActions.cs.

Deferred (own follow-ups): #324 split Build/Test/Pack stages; #328 caching
deep-dive; #327 automated reflective guard-test (docs guard in place now).

Also unblocked publishing separately: the github-packages environment
deployment policy now allows experimental/main/release/*/support/* + v* tags.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…328) (#331)

#324 — experimental.yml and preview.yml ran `dotnet fallout Pack` only, publishing
alpha/preview packages WITHOUT running tests. Both now run `dotnet fallout Test Pack`
(release.yml + the PR gate already did). One invocation = NUKE's discrete internal
stages (Restore → Compile → Test → Pack), failing at the breaking stage; a test
failure stops the job before the push step, so untested packages never publish.
Separate per-step `dotnet fallout` invocations are avoided on purpose — each re-runs
the dependency graph (double-compile); the single invocation is the staged build.

#328 — added `restore-keys:` prefix fallback to the hand-written workflows' caches
for faster partial restores on key miss. Evaluation: current key (global.json +
*.csproj + Directory.Packages.props) is the right dependency set; no packages.lock.json
exists to add; build-output (bin/obj) caching deliberately not done (stale-artifact
risk). Canonical ignore list (docs/.assets/md) already applied in the trigger PR.

Codified both in docs/agents/conventions.md.

Deferred: #327 automated reflective guard-test (docs guard already in place).

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Repo moved ChrisonSimtian/Fallout → Fallout-build/Fallout. Owner-scoped refs that
don't auto-redirect, fixed on main:

- GitHub Packages feed URL nuget.pkg.github.com/ChrisonSimtian → /Fallout-build
  (release.yml, preview.yml, experimental.yml, + consumer docs: shim READMEs,
  from-nuke.md, release-and-versioning.md, CHANGELOG mention)
- CODEOWNERS @ChrisonSimtian@Fallout-build/maintainers (team now has Maintain access)

Feed stays PAT-gated (GitHub Packages has no anonymous access even when public; #344).
Web links / badges / issue refs redirect automatically and are left for a later sweep.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Updated star tracking links and attribution in README.
)

User feedback: AI-written issues are too complex and hard to read, especially for non-native English speakers. Require short, plain, bulleted output for issues, PR bodies/comments, and commit messages.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- add morelinq 4.4.0 to Directory.Packages.props; reference from Fallout.Utilities
- replace hand-rolled Distinct(selector) with a forward to MoreEnumerable.DistinctBy; mark [Obsolete]
- replace Randomize with a forward to MoreEnumerable.Shuffle; mark [Obsolete]
- keep TakeUntil/SkipUntil (MoreLINQ's TakeUntil is inclusive — different semantics)
- keep ForEach/ForEachLazy (MoreLINQ has no index overload or lazy variant)
- keep single-pick Random<T> (no MoreLINQ/BCL equivalent)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ChrisonSimtian ChrisonSimtian requested a review from a team as a code owner June 3, 2026 07:50
@ChrisonSimtian ChrisonSimtian added breaking-change Change is breaking — requires major version bump per CLAUDE.md semver policy. target/2026 Targets the 2026 calendar-version line (current). See ADR-0004. labels Jun 3, 2026
@ChrisonSimtian

Copy link
Copy Markdown
Collaborator Author

Discarding. The agent worktrees forked from the pre-rearchitecture tree (main), so this is implemented against old paths (Fallout.Build/Common/Utilities) and does not stack cleanly on #359. Will redo on the new onion structure after #359 merges. Issue stays open.

@ChrisonSimtian ChrisonSimtian deleted the refactor/355-morelinq branch June 3, 2026 08:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking-change Change is breaking — requires major version bump per CLAUDE.md semver policy. target/2026 Targets the 2026 calendar-version line (current). See ADR-0004.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant