mirror of
https://github.com/toddbluhm/env-cmd.git
synced 2025-12-08 18:23:33 +00:00
feat: recursive embedding of env vars in env vars
This commit is contained in:
parent
e5d3a27a54
commit
53f4549001
@ -5,6 +5,7 @@
|
|||||||
- **Upgrade**: Upgraded dependency `commander` to `5.x`
|
- **Upgrade**: Upgraded dependency `commander` to `5.x`
|
||||||
- **Upgrade**: Upgraded devDependencies `ts-standard`, `sinon`
|
- **Upgrade**: Upgraded devDependencies `ts-standard`, `sinon`
|
||||||
- **Feature**: support both `$var` and `${var}` when expanding vars
|
- **Feature**: support both `$var` and `${var}` when expanding vars
|
||||||
|
- **Feature**: Added support for nested env variables with the `--recursive` flag
|
||||||
|
|
||||||
## 10.1.0
|
## 10.1.0
|
||||||
|
|
||||||
|
|||||||
5
dist/env-cmd.js
vendored
5
dist/env-cmd.js
vendored
@ -29,6 +29,11 @@ export async function EnvCmd({ command, commandArgs, envFile, rc, options = {},
|
|||||||
// Add in the system environment variables to our environment list
|
// Add in the system environment variables to our environment list
|
||||||
env = Object.assign({}, processLib.env, env);
|
env = Object.assign({}, processLib.env, env);
|
||||||
}
|
}
|
||||||
|
if (options.recursive === true) {
|
||||||
|
for (const key of Object.keys(env)) {
|
||||||
|
env[key] = expand_envs_1.expandEnvs(env[key], env);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (options.expandEnvs === true) {
|
if (options.expandEnvs === true) {
|
||||||
command = expandEnvs(command, env);
|
command = expandEnvs(command, env);
|
||||||
commandArgs = commandArgs.map(arg => expandEnvs(arg, env));
|
commandArgs = commandArgs.map(arg => expandEnvs(arg, env));
|
||||||
|
|||||||
9
dist/parse-args.js
vendored
9
dist/parse-args.js
vendored
@ -28,6 +28,10 @@ export function parseArgs(args) {
|
|||||||
if (parsedCmdOptions.expandEnvs === true) {
|
if (parsedCmdOptions.expandEnvs === true) {
|
||||||
expandEnvs = true;
|
expandEnvs = true;
|
||||||
}
|
}
|
||||||
|
let recursive = false;
|
||||||
|
if (program.recursive === true) {
|
||||||
|
recursive = true;
|
||||||
|
}
|
||||||
let verbose = false;
|
let verbose = false;
|
||||||
if (parsedCmdOptions.verbose === true) {
|
if (parsedCmdOptions.verbose === true) {
|
||||||
verbose = true;
|
verbose = true;
|
||||||
@ -65,6 +69,7 @@ export function parseArgs(args) {
|
|||||||
rc,
|
rc,
|
||||||
options: {
|
options: {
|
||||||
expandEnvs,
|
expandEnvs,
|
||||||
|
recursive,
|
||||||
noOverride,
|
noOverride,
|
||||||
silent,
|
silent,
|
||||||
useShell,
|
useShell,
|
||||||
@ -83,16 +88,18 @@ export function parseArgsUsingCommander(args) {
|
|||||||
.usage('[options] -- <command> [...args]')
|
.usage('[options] -- <command> [...args]')
|
||||||
.option('-e, --environments [envs...]', 'The rc file environment(s) to use', parseArgList)
|
.option('-e, --environments [envs...]', 'The rc file environment(s) to use', parseArgList)
|
||||||
.option('-f, --file [path]', 'Custom env file path or .rc file path if \'-e\' used (default path: ./.env or ./.env-cmdrc.(js|cjs|mjs|json))')
|
.option('-f, --file [path]', 'Custom env file path or .rc file path if \'-e\' used (default path: ./.env or ./.env-cmdrc.(js|cjs|mjs|json))')
|
||||||
.option('-x, --expand-envs', 'Replace $var in args and command with environment variables')
|
.option('-x, --expand-envs', 'Replace $var and $\\{var\\} in args and command with environment variables')
|
||||||
.option('--fallback', 'Fallback to default env file path, if custom env file path not found')
|
.option('--fallback', 'Fallback to default env file path, if custom env file path not found')
|
||||||
.option('--no-override', 'Do not override existing environment variables')
|
.option('--no-override', 'Do not override existing environment variables')
|
||||||
.option('--silent', 'Ignore any env-cmd errors and only fail on executed program failure.')
|
.option('--silent', 'Ignore any env-cmd errors and only fail on executed program failure.')
|
||||||
.option('--use-shell', 'Execute the command in a new shell with the given environment')
|
.option('--use-shell', 'Execute the command in a new shell with the given environment')
|
||||||
.option('--verbose', 'Print helpful debugging information')
|
.option('--verbose', 'Print helpful debugging information')
|
||||||
|
.option('--recursive', 'Replace $var and $\\{var\\} in env file with the referenced environment variable')
|
||||||
// TODO: Remove -r deprecation error on version >= v12
|
// TODO: Remove -r deprecation error on version >= v12
|
||||||
.addOption(new Option('-r, --rc-file [path]', 'Deprecated Option')
|
.addOption(new Option('-r, --rc-file [path]', 'Deprecated Option')
|
||||||
.hideHelp()
|
.hideHelp()
|
||||||
.argParser(() => { throw new CommanderError(1, 'deprecated-option', 'The -r flag has been deprecated, use the -f flag instead.'); }))
|
.argParser(() => { throw new CommanderError(1, 'deprecated-option', 'The -r flag has been deprecated, use the -f flag instead.'); }))
|
||||||
|
// ENDTODO
|
||||||
.allowUnknownOption(true)
|
.allowUnknownOption(true)
|
||||||
.allowExcessArguments(true)
|
.allowExcessArguments(true)
|
||||||
.parse(['_', '_', ...args], { from: 'node' });
|
.parse(['_', '_', ...args], { from: 'node' });
|
||||||
|
|||||||
1
dist/types.d.ts
vendored
1
dist/types.d.ts
vendored
@ -29,6 +29,7 @@ export interface EnvCmdOptions extends GetEnvVarOptions {
|
|||||||
commandArgs: string[];
|
commandArgs: string[];
|
||||||
options?: {
|
options?: {
|
||||||
expandEnvs?: boolean;
|
expandEnvs?: boolean;
|
||||||
|
recursive?: boolean;
|
||||||
noOverride?: boolean;
|
noOverride?: boolean;
|
||||||
silent?: boolean;
|
silent?: boolean;
|
||||||
useShell?: boolean;
|
useShell?: boolean;
|
||||||
|
|||||||
@ -40,6 +40,12 @@ export async function EnvCmd(
|
|||||||
env = Object.assign({}, processLib.env, env)
|
env = Object.assign({}, processLib.env, env)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options.recursive === true) {
|
||||||
|
for (const key of Object.keys(env)) {
|
||||||
|
env[key] = expandEnvs(env[key], env)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (options.expandEnvs === true) {
|
if (options.expandEnvs === true) {
|
||||||
command = expandEnvs(command, env)
|
command = expandEnvs(command, env)
|
||||||
commandArgs = commandArgs.map(arg => expandEnvs(arg, env))
|
commandArgs = commandArgs.map(arg => expandEnvs(arg, env))
|
||||||
|
|||||||
@ -33,6 +33,10 @@ export function parseArgs(args: string[]): EnvCmdOptions {
|
|||||||
if (parsedCmdOptions.expandEnvs === true) {
|
if (parsedCmdOptions.expandEnvs === true) {
|
||||||
expandEnvs = true
|
expandEnvs = true
|
||||||
}
|
}
|
||||||
|
let recursive = false
|
||||||
|
if (program.recursive === true) {
|
||||||
|
recursive = true
|
||||||
|
}
|
||||||
let verbose = false
|
let verbose = false
|
||||||
if (parsedCmdOptions.verbose === true) {
|
if (parsedCmdOptions.verbose === true) {
|
||||||
verbose = true
|
verbose = true
|
||||||
@ -75,6 +79,7 @@ export function parseArgs(args: string[]): EnvCmdOptions {
|
|||||||
rc,
|
rc,
|
||||||
options: {
|
options: {
|
||||||
expandEnvs,
|
expandEnvs,
|
||||||
|
recursive,
|
||||||
noOverride,
|
noOverride,
|
||||||
silent,
|
silent,
|
||||||
useShell,
|
useShell,
|
||||||
@ -96,6 +101,7 @@ export function parseArgsUsingCommander(args: string[]): CommanderOptions {
|
|||||||
.option('-e, --environments [envs...]', 'The rc file environment(s) to use', parseArgList)
|
.option('-e, --environments [envs...]', 'The rc file environment(s) to use', parseArgList)
|
||||||
.option('-f, --file [path]', 'Custom env file path or .rc file path if \'-e\' used (default path: ./.env or ./.env-cmdrc.(js|cjs|mjs|json))')
|
.option('-f, --file [path]', 'Custom env file path or .rc file path if \'-e\' used (default path: ./.env or ./.env-cmdrc.(js|cjs|mjs|json))')
|
||||||
.option('-x, --expand-envs', 'Replace $var in args and command with environment variables')
|
.option('-x, --expand-envs', 'Replace $var in args and command with environment variables')
|
||||||
|
.option('--recursive', 'Replace $var and $\\{var\\} in env file with the referenced environment variable')
|
||||||
.option('--fallback', 'Fallback to default env file path, if custom env file path not found')
|
.option('--fallback', 'Fallback to default env file path, if custom env file path not found')
|
||||||
.option('--no-override', 'Do not override existing environment variables')
|
.option('--no-override', 'Do not override existing environment variables')
|
||||||
.option('--silent', 'Ignore any env-cmd errors and only fail on executed program failure.')
|
.option('--silent', 'Ignore any env-cmd errors and only fail on executed program failure.')
|
||||||
|
|||||||
@ -37,6 +37,7 @@ export interface EnvCmdOptions extends GetEnvVarOptions {
|
|||||||
commandArgs: string[]
|
commandArgs: string[]
|
||||||
options?: {
|
options?: {
|
||||||
expandEnvs?: boolean
|
expandEnvs?: boolean
|
||||||
|
recursive?: boolean
|
||||||
noOverride?: boolean
|
noOverride?: boolean
|
||||||
silent?: boolean
|
silent?: boolean
|
||||||
useShell?: boolean
|
useShell?: boolean
|
||||||
|
|||||||
@ -169,6 +169,35 @@ describe('EnvCmd', (): void => {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
it('should spawn process with args expanded if recursive option is true',
|
||||||
|
async (): Promise<void> => {
|
||||||
|
getEnvVarsStub.returns({ PING: 'PONG', recursive: 'PING ${PING}' }) /* eslint-disable-line */
|
||||||
|
await envCmdLib.EnvCmd({
|
||||||
|
command: 'node',
|
||||||
|
commandArgs: [],
|
||||||
|
envFile: {
|
||||||
|
filePath: './.env',
|
||||||
|
fallback: true
|
||||||
|
},
|
||||||
|
rc: {
|
||||||
|
environments: ['dev'],
|
||||||
|
filePath: './.rc'
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
recursive: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const spawnArgs = spawnStub.args[0]
|
||||||
|
|
||||||
|
assert.equal(getEnvVarsStub.callCount, 1, 'getEnvVars must be called once')
|
||||||
|
assert.equal(spawnStub.callCount, 1)
|
||||||
|
assert.isAtLeast(expandEnvsSpy.callCount, 3, 'total number of env args')
|
||||||
|
assert.equal(spawnArgs[0], 'node')
|
||||||
|
assert.equal(spawnArgs[2].env.recursive, 'PING PONG')
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
it('should ignore errors if silent flag provided',
|
it('should ignore errors if silent flag provided',
|
||||||
async (): Promise<void> => {
|
async (): Promise<void> => {
|
||||||
delete process.env.BOB
|
delete process.env.BOB
|
||||||
|
|||||||
@ -98,6 +98,12 @@ describe('parseArgs', (): void => {
|
|||||||
assert.isTrue(res.options!.expandEnvs)
|
assert.isTrue(res.options!.expandEnvs)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should parse recursive option', (): void => {
|
||||||
|
const res = parseArgs(['-f', envFilePath, '--recursive', command, ...commandArgs])
|
||||||
|
assert.exists(res.envFile)
|
||||||
|
assert.isTrue(res.options!.recursive)
|
||||||
|
})
|
||||||
|
|
||||||
it('should parse silent option', (): void => {
|
it('should parse silent option', (): void => {
|
||||||
const res = parseArgs(['-f', envFilePath, '--silent', '--', command, ...commandArgs])
|
const res = parseArgs(['-f', envFilePath, '--silent', '--', command, ...commandArgs])
|
||||||
assert.exists(res.envFile)
|
assert.exists(res.envFile)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user