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 devDependencies `ts-standard`, `sinon`
|
||||
- **Feature**: support both `$var` and `${var}` when expanding vars
|
||||
- **Feature**: Added support for nested env variables with the `--recursive` flag
|
||||
|
||||
## 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
|
||||
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) {
|
||||
command = expandEnvs(command, 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) {
|
||||
expandEnvs = true;
|
||||
}
|
||||
let recursive = false;
|
||||
if (program.recursive === true) {
|
||||
recursive = true;
|
||||
}
|
||||
let verbose = false;
|
||||
if (parsedCmdOptions.verbose === true) {
|
||||
verbose = true;
|
||||
@ -65,6 +69,7 @@ export function parseArgs(args) {
|
||||
rc,
|
||||
options: {
|
||||
expandEnvs,
|
||||
recursive,
|
||||
noOverride,
|
||||
silent,
|
||||
useShell,
|
||||
@ -83,16 +88,18 @@ export function parseArgsUsingCommander(args) {
|
||||
.usage('[options] -- <command> [...args]')
|
||||
.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('-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('--no-override', 'Do not override existing environment variables')
|
||||
.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('--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
|
||||
.addOption(new Option('-r, --rc-file [path]', 'Deprecated Option')
|
||||
.hideHelp()
|
||||
.argParser(() => { throw new CommanderError(1, 'deprecated-option', 'The -r flag has been deprecated, use the -f flag instead.'); }))
|
||||
// ENDTODO
|
||||
.allowUnknownOption(true)
|
||||
.allowExcessArguments(true)
|
||||
.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[];
|
||||
options?: {
|
||||
expandEnvs?: boolean;
|
||||
recursive?: boolean;
|
||||
noOverride?: boolean;
|
||||
silent?: boolean;
|
||||
useShell?: boolean;
|
||||
|
||||
@ -40,6 +40,12 @@ export async function EnvCmd(
|
||||
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) {
|
||||
command = expandEnvs(command, env)
|
||||
commandArgs = commandArgs.map(arg => expandEnvs(arg, env))
|
||||
|
||||
@ -33,6 +33,10 @@ export function parseArgs(args: string[]): EnvCmdOptions {
|
||||
if (parsedCmdOptions.expandEnvs === true) {
|
||||
expandEnvs = true
|
||||
}
|
||||
let recursive = false
|
||||
if (program.recursive === true) {
|
||||
recursive = true
|
||||
}
|
||||
let verbose = false
|
||||
if (parsedCmdOptions.verbose === true) {
|
||||
verbose = true
|
||||
@ -75,6 +79,7 @@ export function parseArgs(args: string[]): EnvCmdOptions {
|
||||
rc,
|
||||
options: {
|
||||
expandEnvs,
|
||||
recursive,
|
||||
noOverride,
|
||||
silent,
|
||||
useShell,
|
||||
@ -96,6 +101,7 @@ export function parseArgsUsingCommander(args: string[]): CommanderOptions {
|
||||
.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('-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('--no-override', 'Do not override existing environment variables')
|
||||
.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[]
|
||||
options?: {
|
||||
expandEnvs?: boolean
|
||||
recursive?: boolean
|
||||
noOverride?: boolean
|
||||
silent?: 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',
|
||||
async (): Promise<void> => {
|
||||
delete process.env.BOB
|
||||
|
||||
@ -98,6 +98,12 @@ describe('parseArgs', (): void => {
|
||||
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 => {
|
||||
const res = parseArgs(['-f', envFilePath, '--silent', '--', command, ...commandArgs])
|
||||
assert.exists(res.envFile)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user