Skip to content
This repository was archived by the owner on Nov 19, 2025. It is now read-only.

Commit c8679f4

Browse files
hgwoodKent C. Dodds
authored andcommitted
feat(spawn): add support for quoted scripts
* feat(spawn): add support for quoted scripts Use the shell option of spawn introduced in Node.js 4.8 (see nodejs/node#4598) to pass the command to the OS shell. Supersedes #77. * docs(readme): add gotchas Add Gotchas paragraph about passing variables to multiple scripts. * docs(readme): add required node version badge Replace the Prerequisite paragraph by a badge showing the require version of Node.js required to run cross-env. * test(spawn): add test for quoted scripts See #89 (review). BREAKING CHANGE: Changes the behavior when passed quoted scripts or special characters interpreted by the shell.
1 parent 5a6e3b8 commit c8679f4

4 files changed

Lines changed: 36 additions & 6 deletions

File tree

README.md

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Run scripts that set and use environment variables across platforms
77
[![Code Coverage][coverage-badge]][coverage]
88
[![Dependencies][dependencyci-badge]][dependencyci]
99
[![version][version-badge]][package]
10+
[![node-version][node-version-badge]][node]
1011
[![downloads][downloads-badge]][npm-stat]
1112

1213
[![MIT License][license-badge]][LICENSE]
@@ -36,10 +37,6 @@ setting or using the environment variable properly for the platform. Just set it
3637
like you would if it's running on a POSIX system, and `cross-env` will take care
3738
of setting it properly.
3839

39-
## Prerequisites
40-
41-
- [NodeJS][node] version 4.0 or greater.
42-
4340
## Installation
4441

4542
This module is distributed via [npm][npm] which is bundled with [node][node] and
@@ -87,6 +84,19 @@ the parent. This is quite useful for launching the same command with different
8784
env variables or when the environment variables are too long to have everything
8885
in one line.
8986

87+
## Gotchas
88+
89+
If you want to have the environment variable apply to several commands in series
90+
then you will need to wrap those in quotes in your script. For example:
91+
92+
```json
93+
{
94+
"scripts": {
95+
"greet": "cross-env GREETING=Hi NAME=Joe \"echo $GREETING && echo $NAME\""
96+
}
97+
}
98+
```
99+
90100
## Inspiration
91101

92102
I originally created this to solve a problem I was having with my npm scripts in
@@ -129,6 +139,7 @@ MIT
129139
[dependencyci]: https://dependencyci.com/github/kentcdodds/cross-env
130140
[version-badge]: https://img.shields.io/npm/v/cross-env.svg?style=flat-square
131141
[package]: https://www.npmjs.com/package/cross-env
142+
[node-version-badge]: https://img.shields.io/badge/node-%3E%3D%204.8-orange.svg?style=flat-square
132143
[downloads-badge]: https://img.shields.io/npm/dm/cross-env.svg?style=flat-square
133144
[npm-stat]: http://npm-stat.com/charts.html?package=cross-env&from=2016-04-01
134145
[license-badge]: https://img.shields.io/npm/l/cross-env.svg?style=flat-square

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"cross-env": "dist/bin/cross-env.js"
88
},
99
"engines": {
10-
"node": ">=4.0"
10+
"node": ">=4.8"
1111
},
1212
"scripts": {
1313
"start": "nps",

src/index.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@ const envSetterRegex = /(\w+)=('(.+)'|"(.+)"|(.+))/
88
function crossEnv(args) {
99
const [command, commandArgs, env] = getCommandArgsAndEnvVars(args)
1010
if (command) {
11-
const proc = spawn(command, commandArgs, {stdio: 'inherit', env})
11+
const proc = spawn(command, commandArgs, {
12+
stdio: 'inherit',
13+
shell: true,
14+
env,
15+
})
1216
process.on('SIGTERM', () => proc.kill('SIGTERM'))
1317
process.on('SIGINT', () => proc.kill('SIGINT'))
1418
process.on('SIGBREAK', () => proc.kill('SIGBREAK'))

src/index.test.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,20 @@ it(`should handle equality signs in quoted strings`, () => {
4343
testEnvSetting({FOO_ENV: 'foo=bar'}, 'FOO_ENV="foo=bar"')
4444
})
4545

46+
it(`should handle quoted scripts`, () => {
47+
crossEnv(['GREETING=Hi', 'NAME=Joe', 'echo $GREETING && echo $NAME'])
48+
expect(
49+
crossSpawnMock.spawn,
50+
).toHaveBeenCalledWith('echo $GREETING && echo $NAME', [], {
51+
stdio: 'inherit',
52+
shell: true,
53+
env: Object.assign({}, process.env, {
54+
GREETING: 'Hi',
55+
NAME: 'Joe',
56+
}),
57+
})
58+
})
59+
4660
it(`should do nothing given no command`, () => {
4761
crossEnv([])
4862
expect(crossSpawnMock.spawn).toHaveBeenCalledTimes(0)
@@ -80,6 +94,7 @@ function testEnvSetting(expected, ...envSettings) {
8094
expect(crossSpawnMock.spawn).toHaveBeenCalledTimes(1)
8195
expect(crossSpawnMock.spawn).toHaveBeenCalledWith('echo', ['hello world'], {
8296
stdio: 'inherit',
97+
shell: true,
8398
env: Object.assign({}, process.env, env),
8499
})
85100

0 commit comments

Comments
 (0)