-
-
Notifications
You must be signed in to change notification settings - Fork 63
fix(no-extraneous-dependencies): merge deps from closest package.json #482
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
B4nan
wants to merge
2
commits into
un-ts:master
Choose a base branch
from
B4nan:fix/no-extraneous-deps-merge-closest
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -69,45 +69,57 @@ function getDependencies(context: RuleContext, packageDir?: string | string[]) { | |
| let paths: string[] = [] | ||
|
|
||
| try { | ||
| let packageContent: PackageDeps = { | ||
| const packageContent: PackageDeps = { | ||
| dependencies: {}, | ||
| devDependencies: {}, | ||
| optionalDependencies: {}, | ||
| peerDependencies: {}, | ||
| bundledDependencies: [], | ||
| } | ||
|
|
||
| // Always merge in deps from the closest `package.json` relative to the | ||
| // linted file. Without this, setting `packageDir` to point at a root | ||
| // (shared) `package.json` in a monorepo makes the rule ignore the | ||
| // workspace package's own deps — every dep declared in the workspace | ||
| // package's `package.json` gets flagged as "should be listed in the | ||
| // project's dependencies". Checking the closest package.json first | ||
| // restores the expected behavior in lerna / npm-workspaces / pnpm- | ||
| // workspaces layouts. | ||
| const closestPackageJsonPath = pkgUp({ | ||
| cwd: context.physicalFilename, | ||
| }) | ||
|
|
||
| if (closestPackageJsonPath) { | ||
| const closestPackageContent = getPackageDepFields( | ||
| closestPackageJsonPath, | ||
| false, | ||
| ) | ||
| if (closestPackageContent) { | ||
| for (const depsKey of Object.keys(packageContent)) { | ||
| const key = depsKey as keyof PackageDeps | ||
| Object.assign(packageContent[key], closestPackageContent[key]) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if (packageDir && packageDir.length > 0) { | ||
| paths = Array.isArray(packageDir) | ||
| ? packageDir.map(dir => path.resolve(dir)) | ||
| : [path.resolve(packageDir)] | ||
| } | ||
|
|
||
| if (paths.length > 0) { | ||
| // use rule config to find package.json | ||
| for (const dir of paths) { | ||
| const packageJsonPath = path.resolve(dir, 'package.json') | ||
| const packageContent_ = getPackageDepFields( | ||
| packageJsonPath, | ||
| paths.length === 1, | ||
| ) | ||
| if (packageContent_) { | ||
| for (const depsKey of Object.keys(packageContent)) { | ||
| const key = depsKey as keyof PackageDeps | ||
| Object.assign(packageContent[key], packageContent_[key]) | ||
| } | ||
| } | ||
| } | ||
| } else { | ||
| // use closest package.json | ||
| const packageJsonPath = pkgUp({ | ||
| cwd: context.physicalFilename, | ||
| })! | ||
|
|
||
| const packageContent_ = getPackageDepFields(packageJsonPath, false) | ||
|
|
||
| // Layer in any deps from `packageDir` on top of the closest match. | ||
| for (const dir of paths) { | ||
| const packageJsonPath = path.resolve(dir, 'package.json') | ||
| const packageContent_ = getPackageDepFields( | ||
| packageJsonPath, | ||
| paths.length === 1, | ||
| ) | ||
| if (packageContent_) { | ||
| packageContent = packageContent_ | ||
| for (const depsKey of Object.keys(packageContent)) { | ||
| const key = depsKey as keyof PackageDeps | ||
| Object.assign(packageContent[key], packageContent_[key]) | ||
| } | ||
|
Comment on lines
+119
to
+122
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same The same 🐛 Proposed fix if (packageContent_) {
for (const depsKey of Object.keys(packageContent)) {
const key = depsKey as keyof PackageDeps
- Object.assign(packageContent[key], packageContent_[key])
+ if (key === 'bundledDependencies') {
+ packageContent[key] = [
+ ...new Set([...packageContent[key], ...packageContent_[key]]),
+ ]
+ } else {
+ Object.assign(packageContent[key], packageContent_[key])
+ }
}
}🤖 Prompt for AI Agents |
||
| } | ||
| } | ||
|
|
||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Object.assigncorruptsbundledDependenciesarray during merge.bundledDependenciesis an array, butObject.assignon arrays overwrites by numeric index rather than concatenating. For example:This loses
'dep1'and will cause false positives when the closest package.json declares bundled deps that get overwritten by a shorter array frompackageDir.🐛 Proposed fix: Handle array and object merging separately
if (closestPackageContent) { for (const depsKey of Object.keys(packageContent)) { const key = depsKey as keyof PackageDeps - Object.assign(packageContent[key], closestPackageContent[key]) + if (key === 'bundledDependencies') { + packageContent[key] = [ + ...new Set([...packageContent[key], ...closestPackageContent[key]]), + ] + } else { + Object.assign(packageContent[key], closestPackageContent[key]) + } } }Apply the same pattern at lines 119-121 for the
packageDirmerge loop.🤖 Prompt for AI Agents