fix: evaluate all patterns before throwing EDUPLICATEWORKSPACE
#32
+186
−18
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.
Motivation
Currently, if duplicates packages are included by the
n
-th pattern of theworkspaces
field of apackage.json
, the algorithm will throw anEDUPLICATEWORKSPACE
without evaluating the other patterns.So, for example, if the
n+1
-th pattern excludes all the duplicates, the workspaces should be considered valid.Reflexion
This is I think important because the
workspaces
field is described as an array of file patterns 1.The most historic occurrence to my knowledge of 'file pattern' for the package.json is the
files
field, and the behavior of those patterns is described as such:The Git documentation explains that the '!' prefix is like this:
I think that the keyword here is 'previous'. This means the patterns do need to be evaluated sequentially (so for example, we cannot leverage the
ignore
options ofglob
, otherwise subsequent inclusion would not work).Proposed solution
Short: Evaluate all patterns sequentially and check for duplicates at the end. List all duplicates on error.
Longish:
We evaluate the patterns one by one. At each match, we either store or remove the path from a Set associated with the packageName, depending on if the pattern is an exclusive or inclusive one.
Once that's done, we got a
Map<Name,Set<PackagePath>>
.We go through the Map entries to evaluate the presence of duplicates. If there's none for the current entries, we copy its key and the sole value of its associated Set to the result map (if the Set is empty, we skip the entry).
If there's a duplicate, we generate an error message stub and append it to the error array.
Here's that a choice I made:
Either we 'fail-fast' and provide only the first duplicate pair.
Either fail at the end and provide all the duplicates.
My personal preference leans towards the exhaustive error message, so I used it in this PR.
Finally, if the error array is not empty (ish, we check
length>1
to ignore the 'header' of the error message), throw anEDUPLICATEWORKSPACE
with a message from the concatenated error array. If there's no error, return the result arrayReferences
Footnotes
https://docs.npmjs.com/cli/v8/configuring-npm/package-json#workspaces ↩
https://docs.npmjs.com/cli/v8/configuring-npm/package-json#files ↩
https://git-scm.com/docs/gitignore ↩