microsoft / microsoft/FluidFramework
Duplicate Code: filterPackages duplicated in build-cli and build-infrastructure
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 4.9k
- Forks
- 586
- Avg merge
- 1d 15h
- Merged PRs (30d)
- 146
Description
🔍 Duplicate Code Detected: filterPackages package-filter logic duplicated
Analysis of commit c9659f0d8c6b7a7314eff8e5f0ad29f4c30e2aab
Assignee: @copilot
Summary
The filterPackages implementation (including its scopesToPrefix helper) is effectively identical in both @fluid-tools/build-cli and @fluid-tools/build-infrastructure. This is a >10-line duplication that increases the risk of divergence if filtering semantics need to change (e.g., scope handling, private filtering).
Duplication Details
Pattern: identical filterPackages + scopesToPrefix
-
Severity: Medium
-
Occurrences: 2
-
Locations:
build-tools/packages/build-cli/src/filter.ts(lines 290–339;filterPackagesat 298–335, helper at 337–339)build-tools/packages/build-infrastructure/src/filter.ts(lines 241–290;filterPackagesat 249–286, helper at 288–290)
-
Code Sample (from
build-tools/packages/build-cli/src/filter.ts):export async function filterPackages(T extends FilterablePackage)( packages: T[], filters: PackageFilterOptions, ): Promise(T[]) { const filtered = packages.filter((pkg) => { if (filters === undefined) { return true; } const isPrivate: boolean = pkg.private ?? false; if (filters.private !== undefined && filters.private !== isPrivate) { return false; } const scopeIn = scopesToPrefix(filters?.scope); const scopeOut = scopesToPrefix(filters?.skipScope); if (scopeIn !== undefined) { let found = false; for (const scope of scopeIn) { found ||= pkg.name.startsWith(scope); } if (!found) { return false; } } if (scopeOut !== undefined) { for (const scope of scopeOut) { if (pkg.name.startsWith(scope) === true) { return false; } } } return true; }); return filtered; } function scopesToPrefix(scopes: string[] | undefined): string[] | undefined { return scopes === undefined ? undefined : scopes.map((s) => `\$\{s}/`); }
Impact Analysis
- Maintainability: Changes to package filtering semantics must be made in two places.
- Bug Risk: High chance of inconsistency if one copy is updated without the other.
- Code Bloat: Small but avoidable; the larger cost is duplicated ownership and review surface.
Refactoring Recommendations
-
Make build-cli reuse build-infrastructure’s implementation
@fluid-tools/build-clialready depends on@fluid-tools/build-infrastructure.- Replace the local
filterPackages/scopesToPrefixinbuild-cli/src/filter.tswith imports from@fluid-tools/build-infrastructure(likely from itsfilter.tsmodule, or a new exported helper if needed). - Estimated effort: Low (≤1 hour) + test validation.
-
(Optional) Extract to a small shared helper module
- If
filter.tsexports are not intended for consumption, movefilterPackages+ helper into a dedicated shared module under build-infrastructure (or another shared build-tools package) and re-export from both.
- If
Implementation Checklist
- Confirm desired ownership for package-filtering semantics (build-infrastructure vs build-cli)
- Refactor build-cli to import shared implementation
- Remove duplicate implementation from build-cli
- Update any affected types (ensure
FilterablePackageremains compatible) - Run build-cli/build-infrastructure unit tests (or relevant build validation)
Analysis Metadata
- Analyzed Files: 135 (scoped to
build-cli,build-infrastructure, andazure-service-utilsTypeScript sources; excluding tests) - Detection Method: Serena symbol overview + semantic/structural duplicate-block scan
- Commit:
c9659f0d8c6b7a7314eff8e5f0ad29f4c30e2aab - Analysis Date: 2026-03-16T21:51:01.514Z
Generated by Duplicate Code Detector · ◷
To install this agentic workflow, run
gh aw add github/gh-aw/.github/workflows/duplicate-code-detector.md@94662b1dee8ce96c876ba9f33b3ab8be32de82a4
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Read build-tools/packages/build-cli/src/filter.ts and build-tools/packages/build-infrastructure/src/filter.ts, comparing the duplicated filterPackages and scopesToPrefix implementations and their exports and types. Confirm the shared ownership choice, then remove the duplicate and run the relevant build-cli and build-infrastructure unit tests or build validation; done means both packages use one compatible implementation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- build-system, tooling
- Issue type
- Refactor
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100