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

feat(no-redundant-files): add new rule #721

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

michaelfaith
Copy link
Contributor

PR Checklist

Overview

This change adds a new rule for preventing inclusion of unnecessary or redundant files in a package.json's files list. It checks for two primary types of errors:

  1. Duplicate entries within the files array (the same file listed more than once)
  2. Files that are automatically included by npm, and don't need to be explicitly included.

Of the second type, there are two flavors that npm includes automatically

  1. Files that are always included, regardless of what else is present in the package.json (e.g. README.md)
  2. Files that are included because they're declared in other places in the package (e.g. file declared as the main entry)

The one thing I wasn't sure about, is whether this new rule should be included in recommended or not (which would technically be a breaking change...)

Closes: #686

Copy link

codecov bot commented Jan 5, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 98.00%. Comparing base (36ae418) to head (bd91522).
Report is 2 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #721      +/-   ##
==========================================
+ Coverage   97.62%   98.00%   +0.38%     
==========================================
  Files          17       18       +1     
  Lines        1177     1404     +227     
  Branches      112      132      +20     
==========================================
+ Hits         1149     1376     +227     
  Misses         28       28              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@michaelfaith michaelfaith force-pushed the feat/no-redundant-files branch from fd602d4 to 98de911 Compare January 5, 2025 23:17
Copy link
Owner

@JoshuaKGoldberg JoshuaKGoldberg left a comment

Choose a reason for hiding this comment

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

Whoohoo, this is awesome! 🥳 Very excited to see this working.

I ended up leaving comments mostly around refactoring for readability. Please push back if you think I'm being too nitpicky. But either way the functionality looks very good to me!

Thanks!

src/rules/no-redundant-files.ts Outdated Show resolved Hide resolved
src/rules/no-redundant-files.ts Outdated Show resolved Hide resolved
src/rules/no-redundant-files.ts Outdated Show resolved Hide resolved
src/rules/no-redundant-files.ts Outdated Show resolved Hide resolved
src/rules/no-redundant-files.ts Outdated Show resolved Hide resolved
src/rules/no-redundant-files.ts Outdated Show resolved Hide resolved
@JoshuaKGoldberg JoshuaKGoldberg added the status: waiting for author Needs an action taken by the original poster label Jan 13, 2025
@michaelfaith
Copy link
Contributor Author

Should we disable this rule on lint rules? I feel like the visitor functions are more intuitive when the exit functions follow the entry functions, with program:exit at the end. Happy to change it, but it kind of feels wrong haha
image

Copy link

Uh oh! @michaelfaith, at least one image you shared is missing helpful alt text. Check https://github.com//pull/721#issuecomment-2594302487 to fix the following violations:
  • Images should have meaningful alternative text (alt text) at line 2

Alt text is an invisible description that helps screen readers describe images to blind or low-vision users. If you are using markdown to display images, add your alt text inside the brackets of the markdown image.

Learn more about alt text at Basic writing and formatting syntax: images on GitHub Docs.

🤖 Beep boop! This comment was added automatically by github/accessibility-alt-text-bot.

@JoshuaKGoldberg
Copy link
Owner

JoshuaKGoldberg commented Jan 16, 2025

Uh oh! @michaelfaith, at least one image you shared is missing helpful alt text. Check https://github.com/[/pull/721](https://github.com//pull/721)#issuecomment-2594302487 to fix the following violations: * Images should have meaningful alternative text (alt text) at line 2

Aside: interesting bug in the action 🤔. Filed github/accessibility-alt-text-bot#62.

@JoshuaKGoldberg
Copy link
Owner

Should we disable this rule on lint rules? I feel like the visitor functions are more intuitive when the exit functions follow the entry functions, with program:exit at the end. Happy to change it, but it kind of feels wrong haha

Ha, yeah, it does feel odd. I do have a preference for the perfectionist plugin workin on the other parts of rule files though. Do you see a good way to configure it to always put :exit keys last? I haven't dug into its configurations deeply in a while, but suspect it's probably doable.

In the meantime I'd suggest putting an inline ESLint disable comment on the line.

Comment on lines +21 to +33
const cachedRegex = new Map<string, RegExp>();
const getCachedLocalFileRegex = (filename: string) => {
// Strip the leading `./`, if there is one, since we'll be incorporating
// it into the regex.
const baseFilename = filename.replace("./", "");
let regex = cachedRegex.get(baseFilename);
if (regex) {
return regex;
} else {
regex = new RegExp(`^(./)?${baseFilename}$`, "i");
cachedRegex.set(baseFilename, regex);
return regex;
}
};
Copy link
Owner

@JoshuaKGoldberg JoshuaKGoldberg Jan 16, 2025

Choose a reason for hiding this comment

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

[Refactor] I've seen this "make a Map for a single cache" pattern a bunch, I made a cached-factory package for it. Up for using it to reduce code here? IMO this is a bit more readable:

Suggested change
const cachedRegex = new Map<string, RegExp>();
const getCachedLocalFileRegex = (filename: string) => {
// Strip the leading `./`, if there is one, since we'll be incorporating
// it into the regex.
const baseFilename = filename.replace("./", "");
let regex = cachedRegex.get(baseFilename);
if (regex) {
return regex;
} else {
regex = new RegExp(`^(./)?${baseFilename}$`, "i");
cachedRegex.set(baseFilename, regex);
return regex;
}
};
import { CachedFactory } from "cached-factory";
const regexFactory = new CachedFactory(
(baseFilename: string) => new RegExp(`^(./)?${baseFilename}$`, "i"),
);
const getLocalFileRegex = (filename: string) =>
regexFactory.get(filename.replace("./", ""));

(not a blocker at all)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right on. Do you think it's worth the additional dependency?

Copy link
Owner

Choose a reason for hiding this comment

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

I'm a little biased because it's my package 😄 but yeah I do. It's very small.

src/rules/no-redundant-files.ts Outdated Show resolved Hide resolved
Copy link
Owner

@JoshuaKGoldberg JoshuaKGoldberg left a comment

Choose a reason for hiding this comment

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

This is shaping up very nicely! There's only one blocking request from me, the [Bug] from filtering away invalid elements in arrays.

#721 (comment) is a fun discussion and I'm enjoying iterating on the design. But as soon as you don't have energy/time to continue it, no worries, it's not blocking.

src/rules/no-redundant-files.ts Outdated Show resolved Hide resolved
@JoshuaKGoldberg JoshuaKGoldberg added the status: waiting for author Needs an action taken by the original poster label Jan 16, 2025
@michaelfaith
Copy link
Contributor Author

michaelfaith commented Jan 17, 2025

Do you see a good way to configure it to always put :exit keys last?

I put in a change to allow Program:exit to be last. That should be sufficient, since that's the one that's not like the others. The other :exit cases should sort correctly since x comes before x:exit lexicographically.

@michaelfaith michaelfaith force-pushed the feat/no-redundant-files branch 3 times, most recently from e8de066 to ed9f959 Compare January 17, 2025 10:24
This change adds a new rule for preventing inclusion of unnecessary or redundant files in a package.json's `files` list.  It checks for two primary types of errors:
1. Duplicate entries within the files array (the same file listed more than once)
1. Files that are automatically included by npm, and don't need to be explicitly included.

Of the second type, there are two flavors that npm includes automatically
1. Files that are always included, regardless of what else is present in the package.json (e.g. README.md)
1. Files that are included because they're declared in other places in the package (e.g. file declared as the `main` entry)
@michaelfaith michaelfaith force-pushed the feat/no-redundant-files branch from ed9f959 to bd91522 Compare January 17, 2025 10:28
@github-actions github-actions bot removed the status: waiting for author Needs an action taken by the original poster label Jan 17, 2025
Copy link
Owner

@JoshuaKGoldberg JoshuaKGoldberg left a comment

Choose a reason for hiding this comment

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

🚀 Awesome! This is looking great, and I'm really excited to get it in. Thanks so much for iterating on it a bunch @michaelfaith, you did great work here!

I can go ahead and merge this whenever you're happy with it. Since we have an open thread I'll wait for your decision on what to do about it. If you think it's perfect as-is, great, I can take it from here. 👍

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.

🚀 Feature: Rule to flag redundant entries in package.json "files"
2 participants