mirror of
https://github.com/hanzoai/cross-env.git
synced 2026-09-24 16:58:15 +00:00
feat: Convert list delimiters for PATH-style env variables (#93)
* feat: Convert list delimiters for PATH-style env variables In Windows, env variables that represent a list (such as PATH or NODE_PATH) separate their elements using a semicolon(;), but in UNIX they're separated using a colon (:). This commit adds a conversion layer, so regardless of how the delimiter is written when calling cross-env, it will be converted to the correct platform delimiter at runtime. To interpret a colon/semicolon literally instead, preced it with a backslash, like this: "cross-env VAR=semi\\;colon\\:" BREAKING CHANGE: If an env variable has : or ; in its value, it will be converted to : on UNIX systems or ; on Windows systems. To keep the old functionality, you will need to escape those characters with a backslash. #80 * chore: Add myself (DanReyLop) to the contributors list * Simplified logic. Now only : (UNIX-style) are converted to ; (Windows-style), not the other way around BREAKING CHANGE: You now must escape `:` to use it in a value of you don't want it to be swapped with `;` on Windows
This commit is contained in:
committed by
Kent C. Dodds
parent
ea80021304
commit
ea0ac4bd04
@@ -92,6 +92,16 @@
|
||||
"code",
|
||||
"test"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "DanReyLop",
|
||||
"name": "Daniel Rey López",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/1715800?v=3",
|
||||
"profile": "https://daniel.blog",
|
||||
"contributions": [
|
||||
"code",
|
||||
"test"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ Run scripts that set and use environment variables across platforms
|
||||
[![downloads][downloads-badge]][npm-stat]
|
||||
|
||||
[![MIT License][license-badge]][LICENSE]
|
||||
[](#contributors)
|
||||
[](#contributors)
|
||||
[![PRs Welcome][prs-badge]][prs]
|
||||
[![Donate][donate-badge]][donate]
|
||||
[![Code of Conduct][coc-badge]][coc]
|
||||
@@ -114,7 +114,7 @@ Thanks goes to these people ([emoji key][emojis]):
|
||||
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
|
||||
| [<img src="https://avatars.githubusercontent.com/u/1500684?v=3" width="100px;"/><br /><sub>Kent C. Dodds</sub>](https://kentcdodds.com)<br />[💻](https://github.com/kentcdodds/cross-env/commits?author=kentcdodds) [📖](https://github.com/kentcdodds/cross-env/commits?author=kentcdodds) 🚇 [⚠️](https://github.com/kentcdodds/cross-env/commits?author=kentcdodds) | [<img src="https://avatars1.githubusercontent.com/u/499038?v=3" width="100px;"/><br /><sub>Ya Zhuang </sub>](https://zhuangya.me)<br />🔌 [📖](https://github.com/kentcdodds/cross-env/commits?author=zhuangya) | [<img src="https://avatars3.githubusercontent.com/u/3440094?v=3" width="100px;"/><br /><sub>James Harris</sub>](https://wopian.me)<br />[📖](https://github.com/kentcdodds/cross-env/commits?author=wopian) | [<img src="https://avatars1.githubusercontent.com/u/8941730?v=3" width="100px;"/><br /><sub>compumike08</sub>](https://github.com/compumike08)<br />[🐛](https://github.com/kentcdodds/cross-env/issues?q=author%3Acompumike08) [📖](https://github.com/kentcdodds/cross-env/commits?author=compumike08) [⚠️](https://github.com/kentcdodds/cross-env/commits?author=compumike08) | [<img src="https://avatars1.githubusercontent.com/u/2270425?v=3" width="100px;"/><br /><sub>Daniel Rodríguez Rivero</sub>](https://github.com/danielo515)<br />[🐛](https://github.com/kentcdodds/cross-env/issues?q=author%3Adanielo515) [💻](https://github.com/kentcdodds/cross-env/commits?author=danielo515) [📖](https://github.com/kentcdodds/cross-env/commits?author=danielo515) | [<img src="https://avatars2.githubusercontent.com/u/1508477?v=3" width="100px;"/><br /><sub>Jonas Keinholz</sub>](https://github.com/inyono)<br />[🐛](https://github.com/kentcdodds/cross-env/issues?q=author%3Ainyono) [💻](https://github.com/kentcdodds/cross-env/commits?author=inyono) [⚠️](https://github.com/kentcdodds/cross-env/commits?author=inyono) | [<img src="https://avatars3.githubusercontent.com/u/1656170?v=3" width="100px;"/><br /><sub>Hugo Wood</sub>](https://github.com/hgwood)<br />[🐛](https://github.com/kentcdodds/cross-env/issues?q=author%3Ahgwood) [💻](https://github.com/kentcdodds/cross-env/commits?author=hgwood) [⚠️](https://github.com/kentcdodds/cross-env/commits?author=hgwood) |
|
||||
| :---: | :---: | :---: | :---: | :---: | :---: | :---: |
|
||||
| [<img src="https://avatars0.githubusercontent.com/u/3715715?v=3" width="100px;"/><br /><sub>Thiebaud Thomas</sub>](https://github.com/thomasthiebaud)<br /> |
|
||||
| [<img src="https://avatars0.githubusercontent.com/u/3715715?v=3" width="100px;"/><br /><sub>Thiebaud Thomas</sub>](https://github.com/thomasthiebaud)<br />[🐛](https://github.com/kentcdodds/cross-env/issues?q=author%3Athomasthiebaud) [💻](https://github.com/kentcdodds/cross-env/commits?author=thomasthiebaud) [⚠️](https://github.com/kentcdodds/cross-env/commits?author=thomasthiebaud) | [<img src="https://avatars1.githubusercontent.com/u/1715800?v=3" width="100px;"/><br /><sub>Daniel Rey López</sub>](https://daniel.blog)<br />[💻](https://github.com/kentcdodds/cross-env/commits?author=DanReyLop) [⚠️](https://github.com/kentcdodds/cross-env/commits?author=DanReyLop) |
|
||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||
|
||||
This project follows the [all-contributors][all-contributors] specification. Contributions of any kind welcome!
|
||||
|
||||
+2
-1
@@ -1,5 +1,6 @@
|
||||
import {spawn} from 'cross-spawn'
|
||||
import commandConvert from './command'
|
||||
import varValueConvert from './variable'
|
||||
|
||||
module.exports = crossEnv
|
||||
|
||||
@@ -35,7 +36,7 @@ function getCommand(commandArgs, envVars) {
|
||||
const shifted = commandArgs.shift()
|
||||
const match = envSetterRegex.exec(shifted)
|
||||
if (match) {
|
||||
envVars[match[1]] = match[3] || match[4] || match[5]
|
||||
envVars[match[1]] = varValueConvert(match[3] || match[4] || match[5])
|
||||
} else {
|
||||
return shifted
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import isWindows from 'is-windows'
|
||||
|
||||
/**
|
||||
* Converts an environment variable value to be appropriate for the current OS.
|
||||
* It will transform UNIX-style list values to Windows-style.
|
||||
* For example, the value of the $PATH variable "/usr/bin:/usr/local/bin:."
|
||||
* will become "/usr/bin;/usr/local/bin;." on Windows.
|
||||
* @param {String} originalValue Original value of the env variable
|
||||
* @returns {String} Converted value
|
||||
*/
|
||||
export default function varValueConvert(originalValue) {
|
||||
const targetSeparator = isWindows() ? ';' : ':'
|
||||
return originalValue.replace(/(\\*):/g, (match, backslashes) => {
|
||||
if (backslashes.length % 2) {
|
||||
// Odd number of backslashes preceding it means it's escaped,
|
||||
// remove 1 backslash and return the rest as-is
|
||||
return match.substr(1)
|
||||
}
|
||||
return backslashes + targetSeparator
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
import isWindowsMock from 'is-windows'
|
||||
import varValueConvert from './variable'
|
||||
|
||||
beforeEach(() => {
|
||||
isWindowsMock.__mock.reset()
|
||||
})
|
||||
|
||||
test(`doesn't affect simple variable values`, () => {
|
||||
isWindowsMock.__mock.returnValue = true
|
||||
expect(varValueConvert('foo')).toBe('foo')
|
||||
})
|
||||
|
||||
test(`doesn't convert a ; into a : on UNIX`, () => {
|
||||
isWindowsMock.__mock.returnValue = false
|
||||
expect(varValueConvert('foo;bar')).toBe('foo;bar')
|
||||
})
|
||||
|
||||
test(`converts a : into a ; on Windows`, () => {
|
||||
isWindowsMock.__mock.returnValue = true
|
||||
expect(varValueConvert('foo:bar')).toBe('foo;bar')
|
||||
})
|
||||
|
||||
test(`doesn't convert already valid separators`, () => {
|
||||
isWindowsMock.__mock.returnValue = false
|
||||
expect(varValueConvert('foo:bar')).toBe('foo:bar')
|
||||
})
|
||||
|
||||
test(`doesn't convert escaped separators on Windows`, () => {
|
||||
isWindowsMock.__mock.returnValue = true
|
||||
expect(varValueConvert('foo\\:bar')).toBe('foo:bar')
|
||||
})
|
||||
|
||||
test(`doesn't convert escaped separators on UNIX`, () => {
|
||||
isWindowsMock.__mock.returnValue = false
|
||||
expect(varValueConvert('foo\\:bar')).toBe('foo:bar')
|
||||
})
|
||||
|
||||
test(`converts a separator even if preceded by an escaped backslash`, () => {
|
||||
isWindowsMock.__mock.returnValue = true
|
||||
expect(varValueConvert('foo\\\\:bar')).toBe('foo\\\\;bar')
|
||||
})
|
||||
|
||||
test(`converts multiple separators`, () => {
|
||||
isWindowsMock.__mock.returnValue = true
|
||||
expect(varValueConvert('foo:bar:baz')).toBe('foo;bar;baz')
|
||||
})
|
||||
Reference in New Issue
Block a user