FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Ensure earlier `@source` is not accidentally ignored by later `@source` by RobinMalfait · Pull Request #20335 · tailwindlabs/tailwindcss · GitHub

Ensure earlier @source is not accidentally ignored by later @source - #20335

Merged
RobinMalfait merged 3 commits into
mainfrom
fix/issue-20333
Jul 15, 2026
Merged

RobinMalfait merged 3 commits into
mainfrom
fix/issue-20333

Conversation

RobinMalfait commented Jul 15, 2026
edited
Loading

Copy link
Copy Markdown
Contributor

This PR fixes an issue where an @source pointing to a file in a nested folder was not scanned when a later @source pointed to a file in a parent folder.

E.g.:

@source "./nested/index.html";
@source "./index.html";

When using @source pointing to a specific file, then we want to make sure that we ignore other files since they are not listed explicitly. To ensure that these patterns don't read other files, we inject a * ignore pattern before it. You can think of the above being expanded to:

Ignored { base: "/project/src/nested", pattern: "*" }
Pattern { base: "/project/src/nested", pattern: "/index.html" }
Ignored { base: "/project/src", pattern: "*" }
Pattern { base: "/project/src", pattern: "/index.html" }

The problem with this is that the Ignored { base: "/project/src", pattern: "*" } pattern results in ignoring the nested folder as well. This means that we never even walk into the nested folder, so the earlier @source "./nested/index.html" never matches anything.

We could switch the order in user land, but that's going to be hard to maintain (and order matters for undoing/redoing earlier rules, so we can't re-order internally either). Instead, we can scope the ignore pattern to the current path only, and not deeply nested. In other words, the pattern should become:

- *
+ /*

It's a very subtle difference, but the pattern from above will now become:

  Ignored { base: "/project/src/nested", pattern: "*" }
  Pattern { base: "/project/src/nested", pattern: "/index.html" }
- Ignored { base: "/project/src", pattern: "*" }
+ Ignored { base: "/project/src", pattern: "/*" }
  Pattern { base: "/project/src", pattern: "/index.html" }

We already do this when an unrestricted root (e.g. @source "./nested") lives inside the base of a restricted pattern. This works because every source base is also its own walk root, and a /* pattern only matches direct children so it can't ignore anything when walking from the nested root itself.

This PR extends that same check to restricted pattern bases: if another @source pattern has its base nested inside the current base, we emit /* instead of *.

Note that we only relax the pattern to /* when such a nested root actually exists. Sibling folders that no @source points into (e.g. an ignore-me folder next to nested) are still direct children, so they still match /* and are never walked.

Fixes: #20333

Test plan

  1. Added a regression test with the reproduction setup
  2. Added a similar test with another sibling folder that should still be ignored
  3. Tested it against the actual reproduction:

Before:

After:

Notice that the text-green-500 now appears as expected.

When using `@source` pointing to a specific file, then we want to make
sure that we ignore _other_ files since they are not listed explicitly.

E.g.:
```css
@source "./nested/index.html";
@source "./index.html";
```

To ensure that these patterns don't read other files, we inject a `*`
ignore pattern before it. You can think of this being expanded to:
```rs
Ignored { base: "/project/src/nested", pattern: "*" }
Pattern { base: "/project/src/nested", pattern: "/index.html" }
Ignored { base: "/project/src", pattern: "*" }
Pattern { base: "/project/src", pattern: "/index.html" }
```

The problem with this is that the `Ignored { base: "/project/src", pattern: "*" }` pattern
results in ignoring the `nested` folder as well.

We could switch the order in user land, but that's going to be hard to
maintain. Instead we should scope the ignore pattern to the _current_
path only, and not deeply nested. In other words, the pattern should
become:

```diff
- *
+ /*
```
RobinMalfait requested a review from a team as a code owner July 15, 2026 11:23

coderabbitai Bot commented Jul 15, 2026
edited
Loading

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info ⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: ecc4091b-981f-4347-aa22-bb4a78685a09

📥 Commits

Reviewing files that changed from the base of the PR and between 75d69bd and 4a644a4.

📒 Files selected for processing (1)
  • CHANGELOG.md

Walkthrough

The scanner now precomputes restricted pattern roots and considers nested restricted roots when choosing ignore patterns. A new test verifies combining a nested explicit file source with a root-level restricted source in both source orders, along with the expected candidate and scanned file lists. The changelog documents the fix.

🚥 Pre-merge checks | ✅ 4 ✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the core fix: preventing earlier @source entries from being ignored by later ones.
Description check ✅ Passed The description matches the change set and explains the nested-vs-root @source regression being fixed.
Linked Issues check ✅ Passed The code and regression test address #20333 by preserving nested concrete sources when later root-level sources are added.
Out of Scope Changes check ✅ Passed The PR stays within scope with one logic change, a regression test, and a changelog note.

Comment @coderabbitai help to get the list of available commands.

greptile-apps Bot commented Jul 15, 2026
edited
Loading

Copy link
Copy Markdown
Contributor

Confidence Score: 5/5

The change is a minimal, well-scoped fix in expand_restricted_patterns with a matching regression test that validates both the fixed case and the boundary condition.

The fix is logically sound: pattern_roots gathers the same kind of base paths already handled for unrestricted_roots, and the root != base guard correctly prevents self-matching. Both declaration orderings are exercised by the new test.

No files require special attention.

Reviews (2): Last reviewed commit: "update changelog" | Re-trigger Greptile

RobinMalfait merged commit 7811d74 into main Jul 15, 2026
10 checks passed
RobinMalfait deleted the fix/issue-20333 branch July 15, 2026 11:35
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
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.

Root-level concrete @source hides nested concrete sources with source(none) in v4.3.2

1 participant


Back | FazBrowse Home | New Git URL