mirror of
https://github.com/tailwindlabs/tailwindcss.git
synced 2025-12-08 21:36:08 +00:00
Allow piping data into the CLI (#6876)
* use outputFile instead of direct writeFile This is an improvement we introduced earlier but forgot this part. * allow to pipe in data to the CLI * add integration tests to validate piping to the CLI * update changelog
This commit is contained in:
parent
058a9256ae
commit
657bf5f8c9
@ -12,6 +12,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Fix `@apply` in files without `@tailwind` directives ([#6580](https://github.com/tailwindlabs/tailwindcss/pull/6580), [#6875](https://github.com/tailwindlabs/tailwindcss/pull/6875))
|
||||
- CLI: avoid unnecessary writes to output files ([#6550](https://github.com/tailwindlabs/tailwindcss/pull/6550))
|
||||
|
||||
### Added
|
||||
|
||||
- Allow piping data into the CLI ([#6876](https://github.com/tailwindlabs/tailwindcss/pull/6876))
|
||||
|
||||
## [3.0.9] - 2022-01-03
|
||||
|
||||
### Fixed
|
||||
|
||||
@ -21,9 +21,14 @@ module.exports = function $(command, options = {}) {
|
||||
let abortController = new AbortController()
|
||||
let cwd = resolveToolRoot()
|
||||
|
||||
let args = command.split(' ')
|
||||
command = args.shift()
|
||||
command = command === 'node' ? command : path.resolve(cwd, 'node_modules', '.bin', command)
|
||||
let args = options.shell
|
||||
? [command]
|
||||
: (() => {
|
||||
let args = command.split(' ')
|
||||
command = args.shift()
|
||||
command = command === 'node' ? command : path.resolve(cwd, 'node_modules', '.bin', command)
|
||||
return [command, args]
|
||||
})()
|
||||
|
||||
let stdoutMessages = []
|
||||
let stderrMessages = []
|
||||
@ -55,7 +60,7 @@ module.exports = function $(command, options = {}) {
|
||||
}, 200)
|
||||
|
||||
let runningProcess = new Promise((resolve, reject) => {
|
||||
let child = spawn(command, args, {
|
||||
let child = spawn(...args, {
|
||||
...options,
|
||||
env: {
|
||||
...process.env,
|
||||
|
||||
@ -27,6 +27,23 @@ describe('static build', () => {
|
||||
)
|
||||
})
|
||||
|
||||
it('should be possible to pipe in data', async () => {
|
||||
await writeInputFile('index.html', html`<div class="font-bold"></div>`)
|
||||
|
||||
await $('cat ./src/index.css | node ../../lib/cli.js -i - -o ./dist/main.css', {
|
||||
shell: true,
|
||||
env: { NODE_ENV: 'production' },
|
||||
})
|
||||
|
||||
expect(await readOutputFile('main.css')).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
`
|
||||
)
|
||||
})
|
||||
|
||||
it('should safelist a list of classes to always include', async () => {
|
||||
await writeInputFile('index.html', html`<div class="font-bold"></div>`)
|
||||
await writeInputFile(
|
||||
|
||||
53
src/cli.js
53
src/cli.js
@ -50,6 +50,17 @@ async function outputFile(file, contents) {
|
||||
await fs.promises.writeFile(file, contents, 'utf8')
|
||||
}
|
||||
|
||||
function drainStdin() {
|
||||
return new Promise((resolve, reject) => {
|
||||
let result = ''
|
||||
process.stdin.on('data', (chunk) => {
|
||||
result += chunk
|
||||
})
|
||||
process.stdin.on('end', () => resolve(result))
|
||||
process.stdin.on('error', (err) => reject(err))
|
||||
})
|
||||
}
|
||||
|
||||
function help({ message, usage, commands, options }) {
|
||||
let indent = 2
|
||||
|
||||
@ -364,7 +375,7 @@ async function build() {
|
||||
input = args['--input'] = args['_'][1]
|
||||
}
|
||||
|
||||
if (input && !fs.existsSync((input = path.resolve(input)))) {
|
||||
if (input && input !== '-' && !fs.existsSync((input = path.resolve(input)))) {
|
||||
console.error(`Specified input file ${args['--input']} does not exist.`)
|
||||
process.exit(9)
|
||||
}
|
||||
@ -546,8 +557,8 @@ async function build() {
|
||||
|
||||
return Promise.all(
|
||||
[
|
||||
fs.promises.writeFile(output, result.css, () => true),
|
||||
result.map && fs.writeFile(output + '.map', result.map.toString(), () => true),
|
||||
outputFile(output, result.css),
|
||||
result.map && outputFile(output + '.map', result.map.toString()),
|
||||
].filter(Boolean)
|
||||
)
|
||||
})
|
||||
@ -558,9 +569,21 @@ async function build() {
|
||||
})
|
||||
}
|
||||
|
||||
let css = input
|
||||
? fs.readFileSync(path.resolve(input), 'utf8')
|
||||
: '@tailwind base; @tailwind components; @tailwind utilities'
|
||||
let css = await (() => {
|
||||
// Piping in data, let's drain the stdin
|
||||
if (input === '-') {
|
||||
return drainStdin()
|
||||
}
|
||||
|
||||
// Input file has been provided
|
||||
if (input) {
|
||||
return fs.readFileSync(path.resolve(input), 'utf8')
|
||||
}
|
||||
|
||||
// No input file provided, fallback to default atrules
|
||||
return '@tailwind base; @tailwind components; @tailwind utilities'
|
||||
})()
|
||||
|
||||
return processCSS(css)
|
||||
}
|
||||
|
||||
@ -694,9 +717,21 @@ async function build() {
|
||||
})
|
||||
}
|
||||
|
||||
let css = input
|
||||
? fs.readFileSync(path.resolve(input), 'utf8')
|
||||
: '@tailwind base; @tailwind components; @tailwind utilities'
|
||||
let css = await (() => {
|
||||
// Piping in data, let's drain the stdin
|
||||
if (input === '-') {
|
||||
return drainStdin()
|
||||
}
|
||||
|
||||
// Input file has been provided
|
||||
if (input) {
|
||||
return fs.readFileSync(path.resolve(input), 'utf8')
|
||||
}
|
||||
|
||||
// No input file provided, fallback to default atrules
|
||||
return '@tailwind base; @tailwind components; @tailwind utilities'
|
||||
})()
|
||||
|
||||
let result = await processCSS(css)
|
||||
env.DEBUG && console.timeEnd('Finished in')
|
||||
return result
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user