Skip to content
This repository has been archived by the owner on Jan 6, 2021. It is now read-only.

Commit

Permalink
feat(bin): two bins (shell, non-shell) (#104)
Browse files Browse the repository at this point in the history
Revert the default bin (cross-env) to its v3 behavior (not using the shell option). Add a new
(cross-env-shell)  which uses the shell option.

BREAKING CHANGE: Scripts using quotes or escape sequences will see a difference in behavior.
Switching to the second bin should resolve any issue.

Closes #99.
  • Loading branch information
hgwood authored and Kent C. Dodds committed May 11, 2017
1 parent 3881423 commit d7b48d5
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 9 deletions.
25 changes: 20 additions & 5 deletions README.md
Expand Up @@ -58,7 +58,8 @@ I use this in my npm scripts:
}
```

Ultimately, the command that is executed (using `cross-spawn`) is:
Ultimately, the command that is executed (using [`cross-spawn`][cross-spawn])
is:

```
webpack --config build/webpack.config.js
Expand All @@ -84,19 +85,32 @@ the parent. This is quite useful for launching the same command with different
env variables or when the environment variables are too long to have everything
in one line.

## Gotchas
## `cross-env` vs `cross-env-shell`

If you want to have the environment variable apply to several commands in series
then you will need to wrap those in quotes in your script. For example:
The `cross-env` module exposes two bins: `cross-env` and `cross-env-shell`. The
first one executes commands using [`cross-spawn`][cross-spawn], while the
second one uses the `shell` option from Node's `spawn`.

The main use case for `cross-env-shell` is when your need an environment
variable to be set across an entire inline shell script, rather than just one
command.

For example, if you want to have the environment variable apply to several
commands in series then you will need to wrap those in quotes and use
`cross-env-shell` instead of `cross-env`.

```json
{
"scripts": {
"greet": "cross-env GREETING=Hi NAME=Joe \"echo $GREETING && echo $NAME\""
"greet": "cross-env-shell GREETING=Hi NAME=Joe \"echo $GREETING && echo $NAME\""
}
}
```

The rule of thumb is: if you want to pass to `cross-env` a command that
contains special shell characters *that you want interpreted*, then use
`cross-env-shell`. Otherwise stick to `cross-env`.

## Inspiration

I originally created this to solve a problem I was having with my npm scripts in
Expand Down Expand Up @@ -164,3 +178,4 @@ MIT
[all-contributors]: https://github.com/kentcdodds/all-contributors
[win-bash]: https://msdn.microsoft.com/en-us/commandline/wsl/about
[angular-formly]: https://github.com/formly-js/angular-formly
[cross-spawn]: https://www.npmjs.com/package/cross-spawn
5 changes: 5 additions & 0 deletions src/bin/cross-env-shell.js
@@ -0,0 +1,5 @@
#!/usr/bin/env node

const crossEnv = require('..')

crossEnv(process.argv.slice(2), {shell: true})
4 changes: 2 additions & 2 deletions src/index.js
Expand Up @@ -6,15 +6,15 @@ module.exports = crossEnv

const envSetterRegex = /(\w+)=('(.+)'|"(.+)"|(.+))/

function crossEnv(args) {
function crossEnv(args, options = {}) {
const [envSetters, command, commandArgs] = parseCommand(args)
if (command) {
const proc = spawn(
commandConvert(command),
commandArgs.map(commandConvert),
{
stdio: 'inherit',
shell: true,
shell: options.shell,
env: getEnvVars(envSetters),
},
)
Expand Down
6 changes: 4 additions & 2 deletions src/index.test.js
Expand Up @@ -44,7 +44,9 @@ it(`should handle equality signs in quoted strings`, () => {
})

it(`should handle quoted scripts`, () => {
crossEnv(['GREETING=Hi', 'NAME=Joe', 'echo $GREETING && echo $NAME'])
crossEnv(['GREETING=Hi', 'NAME=Joe', 'echo $GREETING && echo $NAME'], {
shell: true,
})
expect(
crossSpawnMock.spawn,
).toHaveBeenCalledWith('echo $GREETING && echo $NAME', [], {
Expand Down Expand Up @@ -94,7 +96,7 @@ function testEnvSetting(expected, ...envSettings) {
expect(crossSpawnMock.spawn).toHaveBeenCalledTimes(1)
expect(crossSpawnMock.spawn).toHaveBeenCalledWith('echo', ['hello world'], {
stdio: 'inherit',
shell: true,
shell: undefined,
env: Object.assign({}, process.env, env),
})

Expand Down

0 comments on commit d7b48d5

Please sign in to comment.