diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ef8ce8..aac0efe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,14 +1,14 @@ # Changelog -## 10.1.0 - Pending +## 10.1.0 -- **Feature**: Added a new `--verbose` flag that prints additional debugging info to `console.info` - **Feature**: Added support for expanding vars using the `-x` flag. -Note: only supports for `$var` syntax +Note: only supports `$var` syntax - **Feature**: Added support for `--silent` flag that ignores env-cmd errors and missing files and only terminates on caught signals -- **Upgrade**: Updated `commander` dependency to `v4` -- **Upgrade**: Updated `sinon`, `nyc`, `ts-standard` dev dependencies +- **Feature**: Added a new `--verbose` flag that prints additional debugging info to `console.info` +- **Upgrade**: Updated dependency `commander` to `v4` +- **Upgrade**: Updated devDependencies `sinon`, `nyc`, and `ts-standard` - **Fix**: Handle case where the termination signal is the termination code ## 10.0.1 diff --git a/README.md b/README.md index 21ebfb7..4d6b04f 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,11 @@ A simple node program for executing commands using an environment from an env file. -## Install +## 💾 Install `npm install env-cmd` or `npm install -g env-cmd` -## Basic Usage +## ⌨️ Basic Usage **Environment file `./.env`** @@ -41,7 +41,7 @@ ENV3=THE FISH ./node_modules/.bin/env-cmd node index.js ``` -## Using custom env file path +### Using custom env file path To use a custom env filename or path, pass the `-f` flag. This is a major breaking change from prior versions < 9.0.0 @@ -58,14 +58,15 @@ Usage: _ [options] [...args] Options: -v, --version output the version number - -f, --file [path] Custom env file path (default path: ./.env) - -r, --rc-file [path] Custom rc file path (default path: ./.env-cmdrc(|.js|.json) -e, --environments [env1,env2,...] The rc file environment(s) to use - -x, --expand-envs Replace $var in args and command with environment variables + -f, --file [path] Custom env file path (default path: ./.env) --fallback Fallback to default env file path, if custom env file path not found --no-override Do not override existing environment variables + -r, --rc-file [path] Custom rc file path (default path: ./.env-cmdrc(|.js|.json) + --silent Ignore any env-cmd errors and only fail on executed program failure. --use-shell Execute the command in a new shell with the given environment --verbose Print helpful debugging information + -x, --expand-envs Replace $var in args and command with environment variables -h, --help output usage information ``` @@ -128,24 +129,45 @@ commands together that share the same environment variables. ``` ### Asynchronous env file support + + EnvCmd supports reading from asynchronous `.env` files. Instead of using a `.env` file, pass in a `.js` + file that exports either an object or a `Promise` resolving to an object (`{ ENV_VAR_NAME: value, ... }`). Asynchronous `.rc` + files are also supported using `.js` file extension and resolving to an object with top level environment + names (`{ production: { ENV_VAR_NAME: value, ... } }`). + + **Terminal** + + ```sh + ./node_modules/.bin/env-cmd -f ./async-file.js node index.js + ``` -EnvCmd supports reading from asynchronous `.env` files. Instead of using a `.env` file, pass in a `.js` -file that exports either an object or a `Promise` resolving to an object (`{ ENV_VAR_NAME: value, ... }`). Asynchronous `.rc` -files are also supported using `.js` file extension and resolving to an object with top level environment -names (`{ production: { ENV_VAR_NAME: value, ... } }`). +### `-x` expands vars in arguments + +EnvCmd supports expanding `$var` values passed in as arguments to the command. The allows a user +to provide arguments to a command that are based on environment variable values at runtime. **Terminal** ```sh -./node_modules/.bin/env-cmd -f ./async-file.js node index.js +# $USER will be expanded into the env value it contains at runtime +./node_modules/.bin/env-cmd -x node index.js --user=$USER ``` -## Examples +### `--silent` suppresses env-cmd errors + +EnvCmd supports the `--silent` flag the suppresses all errors generated by `env-cmd` +while leaving errors generated by the child process and cli signals still usable. This +flag is primarily used to allow `env-cmd` to run in environments where the `.env` +file might not be present, but still execute the child process without failing +due to a missing file. + + +## 💿 Examples You can find examples of how to use the various options above by visiting the examples repo [env-cmd-examples](https://github.com/toddbluhm/env-cmd-examples). -## Environment File Formats +## 💽️ Environment File Formats These are the currently accepted environment file formats. If any other formats are desired please create an issue. @@ -155,7 +177,7 @@ These are the currently accepted environment file formats. If any other formats - `.env-cmdrc` as valid json or `.env-cmdrc.json` in execution directory with at least one environment `{ "dev": { "key1": "val1" } }` - `.env-cmdrc.js` JavaScript file exporting an `object` or a `Promise` that resolves to an `object` that contains at least one environment -## Path Rules +## 🗂 Path Rules This lib attempts to follow standard `bash` path rules. The rules are as followed: @@ -170,7 +192,7 @@ Working Directory = `/Users/test/Development/app` | Relative | `./some/relative/path.env` or `some/relative/path.env` | `/Users/test/Development/app/some/relative/path.env` | | Relative with parent dir | `../some/relative/path.env` | `/Users/test/Development/some/relative/path.env` | -## ⚒ API Usage +## 🛠 API Usage ### `EnvCmd` @@ -186,7 +208,9 @@ A function that executes a given command in a new child process with the given e - **`environments`** { `string[]` }: List of environment to read from the `.rc` file - **`filePath`** { `string` }: Custom path to the `.rc` file (defaults to: `./.env-cmdrc(|.js|.json)`) - **`options`** { `object` } + - **`expandEnvs`** { `boolean` }: Expand `$var` values passed to `commandArgs` (default: `false`) - **`noOverride`** { `boolean` }: Prevent `.env` file vars from overriding existing `process.env` vars (default: `false`) + - **`silent`** { `boolean` }: Ignore any errors thrown by env-cmd, used to ignore missing file errors (default: `false`) - **`useShell`** { `boolean` }: Runs command inside a new shell instance (default: `false`) - **`verbose`** { `boolean` }: Prints extra debug logs to `console.info` (default: `false`) - **Returns** { `Promise` }: key is env var name and value is the env var value @@ -205,14 +229,14 @@ A function that parses environment variables from a `.env` or a `.rc` file - **`verbose`** { `boolean` }: Prints extra debug logs to `console.info` (default: `false`) - **Returns** { `Promise` }: key is env var name and value is the env var value -## Why +## 🧙 Why Because sometimes it is just too cumbersome passing a lot of environment variables to scripts. It is usually just easier to have a file with all the vars in them, especially for development and testing. 🚨**Do not commit sensitive environment data to a public git repo!** 🚨 -## Related Projects +## 🧬 Related Projects [`cross-env`](https://github.com/kentcdodds/cross-env) - Cross platform setting of environment scripts @@ -221,13 +245,6 @@ usually just easier to have a file with all the vars in them, especially for dev Special thanks to [`cross-env`](https://github.com/kentcdodds/cross-env) for inspiration (uses the same `cross-spawn` lib underneath too). -## 🎉 Contributors - -- Eric Lanehart -- Jon Scheiding -- Alexander Praetorius -- Anton Versal - ## 📋 Contributing Guide I welcome all pull requests. Please make sure you add appropriate test cases for any features diff --git a/dist/parse-args.js b/dist/parse-args.js index f8df729..34ed8ba 100644 --- a/dist/parse-args.js +++ b/dist/parse-args.js @@ -43,7 +43,7 @@ function parseArgs(args) { noOverride, silent, useShell, - verbose, + verbose } }; if (verbose === true) { diff --git a/dist/types.d.ts b/dist/types.d.ts index 1a02098..a037458 100644 --- a/dist/types.d.ts +++ b/dist/types.d.ts @@ -9,7 +9,7 @@ export interface GetEnvVarOptions { }; verbose?: boolean; } -export interface EnvCmdOptions extends GetEnvVarOptions { +export interface EnvCmdOptions extends Pick { command: string; commandArgs: string[]; options?: { diff --git a/src/env-cmd.ts b/src/env-cmd.ts index 4478508..659698a 100644 --- a/src/env-cmd.ts +++ b/src/env-cmd.ts @@ -33,13 +33,18 @@ export async function CLI (args: string[]): Promise<{ [key: string]: any }> { * @returns {Promise<{ [key: string]: any }>} Returns an object containing [environment variable name]: value */ export async function EnvCmd ( - { command, commandArgs, envFile, rc, options = {} }: EnvCmdOptions + { + command, + commandArgs, + envFile, + rc, + options = {} + }: EnvCmdOptions ): Promise<{ [key: string]: any }> { let env: { [name: string]: string } = {} try { env = await getEnvVars({ envFile, rc, verbose: options.verbose }) - } - catch (e) { + } catch (e) { if (!(options.silent ?? false)) { throw e } diff --git a/src/parse-args.ts b/src/parse-args.ts index 90a567f..54b3ad1 100644 --- a/src/parse-args.ts +++ b/src/parse-args.ts @@ -48,7 +48,7 @@ export function parseArgs (args: string[]): EnvCmdOptions { noOverride, silent, useShell, - verbose, + verbose } } if (verbose === true) { diff --git a/src/types.ts b/src/types.ts index ee16aac..a1c1486 100644 --- a/src/types.ts +++ b/src/types.ts @@ -10,7 +10,7 @@ export interface GetEnvVarOptions { verbose?: boolean } -export interface EnvCmdOptions extends GetEnvVarOptions { +export interface EnvCmdOptions extends Pick { command: string commandArgs: string[] options?: { diff --git a/test/env-cmd.spec.ts b/test/env-cmd.spec.ts index e6ca73f..1e7b284 100644 --- a/test/env-cmd.spec.ts +++ b/test/env-cmd.spec.ts @@ -195,8 +195,8 @@ describe('EnvCmd', (): void => { it('should ignore errors if silent flag provided', async (): Promise => { - delete process.env.BOB; - getEnvVarsStub.throws('MissingFile'); + delete process.env.BOB + getEnvVarsStub.throws('MissingFile') await envCmdLib.EnvCmd({ command: 'node', commandArgs: ['-v'], @@ -215,7 +215,7 @@ describe('EnvCmd', (): void => { it('should allow errors if silent flag not provided', async (): Promise => { - getEnvVarsStub.throws('MissingFile'); + getEnvVarsStub.throws('MissingFile') try { await envCmdLib.EnvCmd({ command: 'node', @@ -224,10 +224,9 @@ describe('EnvCmd', (): void => { filePath: './.env' } }) - } - catch (e) { + } catch (e) { assert.equal(e.name, 'MissingFile') - return; + return } assert.fail('Should not get here.') }