Skip to content

Commit

Permalink
Allow piping data into the CLI (#6876)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
RobinMalfait committed Jan 4, 2022
1 parent 058a925 commit 657bf5f
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 13 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Expand Up @@ -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
Expand Down
13 changes: 9 additions & 4 deletions integrations/execute.js
Expand Up @@ -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 = []
Expand Down Expand Up @@ -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,
Expand Down
17 changes: 17 additions & 0 deletions integrations/tailwindcss-cli/tests/integration.test.js
Expand Up @@ -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(
Expand Down
53 changes: 44 additions & 9 deletions src/cli.js
Expand Up @@ -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

Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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)
)
})
Expand All @@ -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)
}

Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 657bf5f

Please sign in to comment.