Skip to content

fix: prevent @tailwindcss/upgrade from rewriting node_modules when run from subdirectory#20341

Closed
deepshekhardas wants to merge 6 commits into
tailwindlabs:mainfrom
deepshekhardas:fix/upgrade-node-modules
Closed

fix: prevent @tailwindcss/upgrade from rewriting node_modules when run from subdirectory#20341
deepshekhardas wants to merge 6 commits into
tailwindlabs:mainfrom
deepshekhardas:fix/upgrade-node-modules

Conversation

@deepshekhardas

Copy link
Copy Markdown

Cherry-pick of PR #20329

benface and others added 6 commits July 14, 2026 18:20
Notes by Robin Malfait:

Split the commit in 2, because I want to be able to see the test fail
_before_ we apply the fix.
@greptile-apps

greptile-apps Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Confidence Score: 3/5

The CSS analysis path is correctly fixed, but the template migration path in index.ts uses the same unfixed pattern and could rewrite files inside ignored directories when the tool is run from a subdirectory.

The fix addresses the reported scenario but leaves an identical isGitIgnored call in index.ts at line 46 unfixed, which guards template file migration with the same potentially broken predicate when run from a subdirectory. The new integration test uses source(none) so this gap is not caught.

packages/@tailwindcss-upgrade/src/index.ts — the isGitIgnored call at line 46 needs the same gitRoot treatment applied in analyze.ts.

Reviews (1): Last reviewed commit: "update CHANGELOG" | Re-trigger Greptile

@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

The upgrade flow now passes its base directory into stylesheet analysis. Analysis resolves the Git repository root with git rev-parse --show-toplevel and uses it when checking ignored files, falling back to the base directory outside a repository. A regression test covers running the upgrade from a nested workspace directory with a root .gitignore, and the changelog documents the fix.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main fix: avoiding node_modules rewrites when running from a subdirectory.
Description check ✅ Passed The description is related to the change set because it notes this is a cherry-pick of the same fix.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
⚔️ Resolve merge conflicts
  • Resolve merge conflict in branch fix/upgrade-node-modules

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
packages/@tailwindcss-upgrade/src/index.ts (2)

44-46: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Respect the repo-root .gitignore for template files.

The PR successfully updates analyze.ts to use gitRoot(base) so that the repository root's .gitignore rules are applied. However, isIgnored in this file is still initialized with { cwd: base }.

This means that when upgrading from a subpackage, template files that should be ignored by the root .gitignore (e.g., build outputs in a dist/ folder) will still be scanned and incorrectly migrated.

Update the initialization to match analyze.ts (and remember to add import { gitRoot } from './utils/git' to your imports):

🐛 Proposed fix
 async function run() {
   let base = process.cwd()
-  let isIgnored = await isGitIgnored({ cwd: base })
+  let isIgnored = await isGitIgnored({ cwd: gitRoot(base) ?? base })

105-106: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Filter discovered CSS files to respect repo-root ignores.

The globby call above uses gitignore: true, which resolves .gitignore files starting from cwd (base). When base is a subpackage, globby will not see the repository root's .gitignore.

Because analyze.ts seeds these initial stylesheets directly into its processing map without verifying them against isIgnored, any git-ignored CSS files (like dist/out.css) discovered here will be incorrectly mutated.

Filter the discovered files using the properly initialized isIgnored helper. It's best to apply this filter inside the if (files.length === 0) block to ensure that files explicitly passed as CLI arguments are still upgraded.

🐛 Proposed fix
         // gitignore: true will first search for all .gitignore including node_modules folders, this makes the initial search much faster
         ignore: ['**/node_modules/**'],
       })
+
+      files = files.filter((file) => {
+        try {
+          return !isIgnored(file)
+        } catch {
+          return false
+        }
+      })
     }
🧹 Nitpick comments (1)
integrations/upgrade/index.test.ts (1)

3405-3410: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add coverage for non-node_modules ignored files.

This test successfully verifies that @imported files inside node_modules are ignored. However, because node_modules is already hardcoded in the globby ignore list in index.ts (ignore: ['**/node_modules/**']), this test setup doesn't catch cases where other git-ignored files (like a dist/ folder containing generated CSS or HTML templates) are incorrectly discovered and processed when upgrading from a nested directory.

To ensure comprehensive coverage of the root .gitignore logic across both CSS discovery and template scanning, consider adding a dummy file in a dist/ directory, ignoring dist/ in this .gitignore, and asserting that the dist/ file remains unchanged.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 7c5d8ca8-d57a-443e-9993-c4886d7f58bf

📥 Commits

Reviewing files that changed from the base of the PR and between bdcd708 and eb97c9a.

📒 Files selected for processing (5)
  • CHANGELOG.md
  • integrations/upgrade/index.test.ts
  • packages/@tailwindcss-upgrade/src/codemods/css/analyze.ts
  • packages/@tailwindcss-upgrade/src/index.ts
  • packages/@tailwindcss-upgrade/src/utils/git.ts

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