Skip to content
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

fix: evaluate all patterns before throwing EDUPLICATEWORKSPACE #32

Merged
merged 1 commit into from
Mar 10, 2022

Conversation

louis-bompart
Copy link
Contributor

Motivation

Currently, if duplicates packages are included by the n-th pattern of the workspaces field of a package.json, the algorithm will throw an EDUPLICATEWORKSPACE 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:

File patterns follow a similar syntax to .gitignore 2

The Git documentation explains that the '!' prefix is like this:

An optional prefix "!" which negates the pattern; any matching file excluded by a previous pattern will become included again 3

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 of glob, 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.

    • Pro: Faster to fail
    • Con: If the end-user has more than one duplicate, it will need to repeat the operation.
  • Either fail at the end and provide all the duplicates.

    • Pro: Exhaustive error, the user has all the information to go from ❌ to ✔️ in just 1 run.
    • Con: Slower to fail.

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 an EDUPLICATEWORKSPACE with a message from the concatenated error array. If there's no error, return the result array

References

Footnotes

  1. https://docs.npmjs.com/cli/v8/configuring-npm/package-json#workspaces

  2. https://docs.npmjs.com/cli/v8/configuring-npm/package-json#files

  3. https://git-scm.com/docs/gitignore

@louis-bompart louis-bompart requested a review from a team as a code owner March 10, 2022 11:22
)
})

test('match duplicates then exclude one', t => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This spec was ❌ prior to my change, the others (apart from the one checking the error message construction) were working already. I decided to include them nonetheless to help define the behavior of the function for the public.

@wraithgar wraithgar merged commit ca0bf18 into npm:main Mar 10, 2022
@wraithgar
Copy link
Member

Thanks for all the PRs lately!

@louis-bompart louis-bompart deleted the fix/ignore-wildcard branch March 10, 2022 18:00
@wraithgar
Copy link
Member

We are going to get this into today's npm release for you

@louis-bompart
Copy link
Contributor Author

We are going to get this into today's npm release for you

oh wow. I was not expecting that much 🎉 Thanks a bunch :D

@ruyadorno
Copy link
Contributor

Merci bcp @louis-bompart! it's out now in npm@8.5.4 🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants