Skip to content

fix(node): handle character class globs in source() root check#19759

Open
siewcapital wants to merge 1 commit intotailwindlabs:mainfrom
siewcapital:fix/source-glob-character-class-root-check
Open

fix(node): handle character class globs in source() root check#19759
siewcapital wants to merge 1 commit intotailwindlabs:mainfrom
siewcapital:fix/source-glob-character-class-root-check

Conversation

@siewcapital
Copy link

Summary

Fixes a false-positive validation error when using source(...) with glob character classes such as [a-z].

@tailwindcss/node validates that the static prefix of the source(...) path exists before scanning. The previous implementation only treated * and { as glob markers, so patterns like ./src/[a-z]/**/*.html were interpreted as literal directories and failed with:

The source(...) does not exist or is not a directory.

This change updates the static-prefix detection to also stop at [ and ?, which are also valid glob metacharacters.

Changes

  • In ensureSourceDetectionRootExists, expand glob-symbol detection from /[*{]/ to /[*{[?]/.
  • Add compile.test.ts in @tailwindcss/node to cover source("./src/[a-z]/**/*.html") and verify compilation succeeds.

Test plan

  • pnpm vitest packages/@tailwindcss-node/src/compile.test.ts
  • pnpm vitest packages/@tailwindcss-node/src/*.test.ts

@siewcapital siewcapital requested a review from a team as a code owner March 6, 2026 04:15
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 6, 2026

Walkthrough

Updates the glob-detection heuristic in the compile function by expanding the regex pattern used to identify glob metacharacters from /[*{]/ to /[*{[?]/. This change includes character class brackets and question mark wildcards as recognized glob characters. A corresponding test file is added to validate the compile function's handling of glob patterns with character classes in source invocations.

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main fix: handling character class globs in the source() root validation check.
Description check ✅ Passed The description provides a comprehensive explanation of the problem, the solution, and test plan, directly aligned with the changeset modifications.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


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 and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
packages/@tailwindcss-node/src/compile.test.ts (1)

6-27: Please add a ? wildcard regression case too.

Line 73 expands the heuristic for both [ and ?, but this test only exercises the character-class path. Adding a source("./src/?/**/*.html") case would keep the new ? branch covered as well.

Possible follow-up test
 test('source() accepts glob patterns with character classes', async () => {
   let base = await fs.mkdtemp(path.join(process.cwd(), '.tmp-tailwind-source-glob-'))
@@
   }
 })
+
+test('source() accepts glob patterns with question-mark wildcards', async () => {
+  let base = await fs.mkdtemp(path.join(process.cwd(), '.tmp-tailwind-source-glob-'))
+
+  try {
+    await fs.mkdir(path.join(base, 'src'), { recursive: true })
+
+    let compiler = await compile('@import "tailwindcss" source("./src/?/**/*.html");', {
+      base,
+      onDependency() {},
+      customCssResolver(id) {
+        if (id === 'tailwindcss') {
+          return path.join(process.cwd(), 'packages/tailwindcss/index.css')
+        }
+      },
+    })
+
+    let css = compiler.build(['underline'])
+    expect(css).toContain('.underline')
+  } finally {
+    await fs.rm(base, { recursive: true, force: true })
+  }
+})
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/`@tailwindcss-node/src/compile.test.ts around lines 6 - 27, The test
"source() accepts glob patterns with character classes" only covers the
character-class path; add a second assertion or a new test that mirrors this one
but uses a question-mark wildcard glob (e.g., source("./src/?/**/*.html")) so
the compile(...) call and compiler.build(['underline']) exercise the `?`-branch;
update the test name or create "source() accepts glob patterns with ? wildcard"
and reuse the same setup (base temp dir, src subdir, customCssResolver) and
teardown to ensure the heuristic expansion for `?` is covered.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/`@tailwindcss-node/src/compile.test.ts:
- Around line 6-27: The test "source() accepts glob patterns with character
classes" only covers the character-class path; add a second assertion or a new
test that mirrors this one but uses a question-mark wildcard glob (e.g.,
source("./src/?/**/*.html")) so the compile(...) call and
compiler.build(['underline']) exercise the `?`-branch; update the test name or
create "source() accepts glob patterns with ? wildcard" and reuse the same setup
(base temp dir, src subdir, customCssResolver) and teardown to ensure the
heuristic expansion for `?` is covered.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 6cc48de8-2ff3-4068-bac2-3d4b44ceb9f6

📥 Commits

Reviewing files that changed from the base of the PR and between bf2e2fe and 6b6ba1f.

📒 Files selected for processing (2)
  • packages/@tailwindcss-node/src/compile.test.ts
  • packages/@tailwindcss-node/src/compile.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.

2 participants