microsoft / microsoft/FluidFramework
Duplicate Code: repoPolicyCheck updatePackageJsonFile resolver boilerplate
@Abe27342 is already working on this.
Since Apr 7, 2026.
- #26961 by @copilot-swe-agent — closed without merging
- Dominant language
- TypeScript
- Stars
- 4.9k
- Forks
- 586
- Avg merge
- 1d 15h
- Merged PRs (30d)
- 146
Description
Analysis of commit 688c05dd39779ee023a5bb8fed97d59b64b4e6e2
Assignee: @copilot
Summary
Multiple repoPolicyCheck rules duplicate the same resolver boilerplate pattern: create a { resolved, message? } result, call updatePackageJsonFile(path.dirname(file), (json) => { ... }), sometimes mutate result on errors, then return result.
This repetition appears several times within npmPackages.ts and again in fluidBuildTasks.ts. It’s a maintainability smell: future adjustments to resolver behavior (error handling, logging, dry-run semantics, etc.) require updating many near-identical blocks.
Duplication Details
Pattern: “resolver wrapper around updatePackageJsonFile”
- Severity: Medium
- Occurrences: 7 (6 in
npmPackages.ts, 1 influidBuildTasks.ts) - Locations:
build-tools/packages/build-cli/src/library/repoPolicyCheck/npmPackages.ts- lines 840–863 (simple
updatePackageJsonFile(...)thenreturn { resolved: true }) - lines 1122–1160 (similar structure)
- lines 1292–1303 (
const result ... updatePackageJsonFile ... return result) - lines 1586–1604 (
const result ... updatePackageJsonFile ... return result) - lines 1723–1737 (
const result ... updatePackageJsonFile ... return result) - lines 1919–1965 (
const result ... updatePackageJsonFile ... return result)
- lines 840–863 (simple
build-tools/packages/build-cli/src/library/repoPolicyCheck/fluidBuildTasks.ts- lines 904–939 (
let result ... updatePackageJsonFile ... return result)
- lines 904–939 (
Code Sample (excerpt)
From npmPackages.ts (around 1722):
resolver: (file: string): { resolved: boolean; message?: string } => {
const result: { resolved: boolean; message?: string } = { resolved: true };
updatePackageJsonFile(path.dirname(file), (json) => {
if (shouldCheckExportsField(json)) {
try {
const exportsField = generateExportsField(json);
json.exports = exportsField;
} catch (error: unknown) {
result.resolved = false;
result.message = (error as Error).message;
}
}
});
return result;
}
From fluidBuildTasks.ts (around 904):
resolver: (file: string, root: string): { resolved: boolean; message?: string } => {
let result: { resolved: boolean; message?: string } = { resolved: true };
updatePackageJsonFile(path.dirname(file), (json) => {
// ...
try {
// compute/patch deps
} catch (error: unknown) {
result = { resolved: false, message: (error as Error).message };
return;
}
});
return result;
}
Impact Analysis
- Maintainability: Resolver behavior is spread across many copies; refactors require repetitive edits and risk inconsistency.
- Bug Risk: Small differences in copied patterns (e.g., whether errors are caught, whether
resultis reassigned vs mutated) can lead to inconsistent outcomes. - Code Bloat: The repeated scaffolding obscures the actual policy-specific logic.
Refactoring Recommendations
-
Extract a shared resolver helper
- Suggested location:
build-tools/packages/build-cli/src/library/repoPolicyCheck/common.ts - Example shape:
makeUpdatePackageJsonResolver((packageJson, ctx) => void, { onError?: ... })- or
runUpdatePackageJsonResolver(fileOrDir, (json) => { ... }) => { resolved, message? }
- Benefits: centralizes result creation, consistent error handling, and optionally supports async variants.
- Suggested location:
-
Normalize error handling semantics
- Decide whether resolver callbacks should throw (and be caught centrally) or mutate a result object.
- Benefits: fewer subtle differences, easier to test.
Implementation Checklist
- Identify all
updatePackageJsonFile(...)resolver call sites underrepoPolicyCheck/ - Add shared helper API in
common.ts - Refactor the duplicated resolvers to use the helper
- Ensure resolver return types and messages remain identical
- Run existing policy-check tests/commands to validate behavior
Analysis Metadata
- Analyzed Files: Top-churn + targeted cross-reference in
build-tools/packages/build-cli/src/library/repoPolicyCheck/andserver/routerlicious/ - Detection Method: Serena semantic symbol search + pattern search
- Commit: 688c05dd39779ee023a5bb8fed97d59b64b4e6e2
- Analysis Date: 2026-04-01T21:51:29.453Z
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.
Assessment
This issue has not been assessed yet.