microsoft / microsoft/FluidFramework
Duplicate Code: duplicated only-pnpm preinstall script across packages
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 4.9k
- Forks
- 586
- Avg merge
- 1d 15h
- Merged PRs (30d)
- 146
Description
Analysis of commit 258aa332a9ab237e8a72b6747968669be9d4db20
Assignee: @copilot
Summary
The same only-pnpm.cjs preinstall guard script is duplicated verbatim in multiple package subtrees. This creates unnecessary maintenance overhead and risk of divergence if the message/logic ever needs to change.
Duplication Details
Pattern: Identical only-pnpm.cjs preinstall guard script
-
Severity: Medium
-
Occurrences: 4 identical copies
-
Locations (entire file is duplicated):
scripts/only-pnpm.cjs(lines 1–30)server/gitrest/scripts/only-pnpm.cjs(lines 1–30)server/routerlicious/scripts/only-pnpm.cjs(lines 1–30)server/historian/scripts/only-pnpm.cjs(lines 1–30)
-
Code Sample (representative excerpt, identical in all 4 files):
const message = ` ╔══════════════════════════════════════════════════════════════════╗ ║ ║ ║ Use "pnpm install" for installation in this project. ║ ║ ║ ║ If you don't have pnpm, enable corepack via "corepack enable". ║ ║ Then run "pnpm install" to install dependencies. ║ ║ ║ ║ For more details, see the README. ║ ║ ║ ╚══════════════════════════════════════════════════════════════════╝ `; const used_pnpm = process.env.npm_config_user_agent.startsWith(`pnpm`); if (!used_pnpm) { console.error(message); process.exit(1); }
Impact Analysis
- Maintainability: Any future change (wording, behavior, guard conditions) must be repeated in 4 places.
- Bug Risk: Copies can drift, leading to inconsistent developer experience across packages.
- Code Bloat: Small but pure duplication (~30 LOC × 4).
Refactoring Recommendations
-
Use a single canonical implementation
- Keep
scripts/only-pnpm.cjsas the source of truth. - Replace the 3 server copies with tiny wrappers that just delegate, e.g.:
server/*/scripts/only-pnpm.cjs→require("../../../scripts/only-pnpm.cjs");
- Benefits: preserves per-package entrypoint paths while centralizing logic.
- Keep
-
(Alternative) Point package.json preinstall directly at the root script
- Update
server/*/package.jsonpreinstall scripts to reference../../scripts/only-pnpm.cjs(or equivalent). - Note: only viable if these packages are never installed outside the monorepo context.
- Update
Implementation Checklist
- Confirm whether
server/*packages must support standalone installs outside the monorepo - Choose wrapper vs direct-reference approach
- Update references and remove redundant copies (or keep wrappers)
- Validate
preinstallstill fails correctly under non-pnpm installers
Analysis Metadata
- Analyzed Files: 4 (CJS)
- Detection Method: Serena semantic/pattern analysis + manual verification
- Commit:
258aa332a9ab237e8a72b6747968669be9d4db20 - Analysis Date: 2026-04-06T21:49:32.084Z
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 scripts/only-pnpm.cjs and the copies under server/gitrest, server/routerlicious, and server/historian, then inspect the related package.json preinstall entries. Determine whether the server packages must support standalone installs before choosing wrappers or direct references. Done means one canonical guard remains, all preinstall paths work, and non-pnpm installation still fails correctly.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- tooling
- Issue type
- Refactor
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 57/100