Ignore the standalone CLI (#20139)
This PR fixes an issue where if you use the standalone CLI, and you move the standalone CLI into the current project, then we would scan that standalone CLI as-if it contains Tailwind CSS classes. Since the CLI contains actual Tailwind CSS classes, and is in fact readable text, this binary would've been used as a source. There are a few ways of fixing this, we could hardcode all the known names, but that would result in an issue if you rename the CLI. We could check whether it's a binary format and look for magic numbers at the top. We could also check for a shebang at the top of the file and skip it that way. While some of these solutions might still be useful for the future. For now I fixed it by essentially always ignoring `process.execPath`. That way we never ever scan the actual executable regardless of whether you renamed it or not. Fixes: #20134 ## Test plan - Added an integration tests - Works on every OS [ci-all]
This commit is contained in:
parent
44818a6cf6
commit
0c5f8bfd88
3 changed files with 48 additions and 1 deletions
|
|
@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- Canonicalization: don't suggest invalid `calc(…)` expressions (e.g. `px-[calc(1rem+0px)]` → `px-[calc(1rem+0)]`) ([#20127](https://github.com/tailwindlabs/tailwindcss/pull/20127))
|
||||
- Canonicalization: avoid suggesting large spacing-scale values for arbitrary lengths (e.g. `left-[99999px]` → `left-[99999px]`, not `left-24999.75`) ([#20130](https://github.com/tailwindlabs/tailwindcss/pull/20130))
|
||||
- Ensure `@tailwindcss/cli` in `--watch` mode recovers when a tracked dependency is deleted and restored ([#20137](https://github.com/tailwindlabs/tailwindcss/pull/20137))
|
||||
- Ensure standalone `@tailwindcss/cli` binaries are ignored when scanning for class candidates ([#20139](https://github.com/tailwindlabs/tailwindcss/pull/20139))
|
||||
|
||||
## [4.3.0] - 2026-05-08
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import nodeFs from 'node:fs/promises'
|
||||
import os from 'node:os'
|
||||
import path from 'node:path'
|
||||
import { candidate, css, html, js, json, test, ts } from '../utils'
|
||||
import { candidate, css, html, IS_WINDOWS, js, json, test, ts } from '../utils'
|
||||
|
||||
const STANDALONE_BINARY = (() => {
|
||||
switch (os.platform()) {
|
||||
|
|
@ -15,6 +16,41 @@ const STANDALONE_BINARY = (() => {
|
|||
}
|
||||
})()
|
||||
|
||||
test(
|
||||
'does not scan itself for candidates',
|
||||
{
|
||||
fs: {
|
||||
'package.json': json`
|
||||
{
|
||||
"dependencies": {}
|
||||
}
|
||||
`,
|
||||
'src/index.css': css` @import 'tailwindcss'; `,
|
||||
},
|
||||
},
|
||||
async ({ root, fs, exec }) => {
|
||||
let sourceBinary = path.resolve(
|
||||
__dirname,
|
||||
`../../packages/@tailwindcss-standalone/dist/${STANDALONE_BINARY}`,
|
||||
)
|
||||
let binary = IS_WINDOWS ? 'tailwindcss.exe' : 'tailwindcss'
|
||||
let localBinary = path.join(root, binary)
|
||||
await nodeFs.copyFile(sourceBinary, localBinary)
|
||||
|
||||
if (!IS_WINDOWS) {
|
||||
await nodeFs.chmod(localBinary, 0o755)
|
||||
}
|
||||
|
||||
await exec(`${IS_WINDOWS ? binary : `./${binary}`} --input src/index.css --output dist/out.css`)
|
||||
|
||||
await fs.expectFileNotToContain('dist/out.css', [
|
||||
candidate`flex`,
|
||||
candidate`grid`,
|
||||
candidate`underline`,
|
||||
])
|
||||
},
|
||||
)
|
||||
|
||||
test(
|
||||
'includes first-party plugins',
|
||||
{
|
||||
|
|
|
|||
|
|
@ -250,6 +250,16 @@ export async function handle(args: Result<ReturnType<typeof options>>) {
|
|||
return [{ ...compiler.root, negated: false }]
|
||||
})().concat(compiler.sources)
|
||||
|
||||
// Do not scan the current executable. Otherwise when using the standalone
|
||||
// CLI, if the CLI lives in the current repo we would be scanning that file.
|
||||
//
|
||||
// This is also immune against renames of the executable file.
|
||||
sources.push({
|
||||
base: path.dirname(process.execPath),
|
||||
pattern: path.basename(process.execPath),
|
||||
negated: true,
|
||||
})
|
||||
|
||||
let scanner = new Scanner({ sources })
|
||||
DEBUG && I.end('Setup compiler')
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue