Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,21 @@ Get a value from a .env.example file:
dotenv <key> --file .env.example
```

### JSON

By default multiple keys are returned as a JSON object. To return a single key as a JSON object, use the `--json` flag.
To not return a JSON object, use the `--no-json` flag.

Return a .env file as JSON:

```shell
dotenv --json
dotenv
```

Wildcard search:

```shell
dotenv "DB_*"
```

### Multiline Values
Expand Down
2 changes: 2 additions & 0 deletions Taskfile.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ tasks:
- task --list --sort alphanumeric

tests:
aliases:
- test
desc: Run tests
deps:
- build
Expand Down
35 changes: 28 additions & 7 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ async function app() {
.argument('[key...]', 'Environment variable key')
.option('-f, --file <filename>', 'Specify the .env file (default: .env)')
.option('-j, --json', 'Output as JSON')
.option('--no-json', 'Output as plain text')
.option('-m, --multiline', 'Allow multiline values')
.option('-s, --set <value>', 'Update the environment variable in the .env file')
.option('-q, --quote', 'Quote the value when --set regardless of need')
Expand All @@ -48,12 +49,6 @@ async function app() {
const keys: string[] = program.args;
const set: string = cliOptions.set;

// Multiple keys or no keys assume --json
if (keys.length > 1 || !keys.length) {
log.debug('Key count (0 or >1) defaulting to JSON');
cliOptions.json = true;
}

// Determine if we are setting a value, and if so, what's the value
let setValue: string = '';
if (stdin && set) {
Expand All @@ -76,7 +71,8 @@ async function app() {
let options: Options = {
fullEnvPath: fullEnvPath,
envObject: new EnvObject(),
json: (cliOptions.json !== undefined),
json: (process.argv.includes('--json')), // commander.js sets json instead of no-json
noJson: (process.argv.includes('--no-json')), // commander.js fails to parse this
multiline: (cliOptions.multiline !== undefined),
quote: (cliOptions.quote !== undefined),
action: {
Expand All @@ -88,12 +84,37 @@ async function app() {
targetKeys: keys,
setValue: escapeAndQuote(setValue, (cliOptions.quote !== undefined)),
};

// Multiple keys or no keys assume --json
if ((keys.length > 1 || !keys.length) && !options['noJson']) {
log.debug('Key count (0 or >1) defaulting to JSON');
options.json = true;
}
log.debug('Options:', options);

qualifyingRules(options);

options.envObject = parseEnvFile(envFilePath);

if (keys.length === 1 && !options['noJson']) {
log.debug('Single key, and not --no-json, checking for wildcard');

if (options.targetKeys[0].includes('*')) {
log.debug('Wildcard found')
const target: string = options.targetKeys[0].replace('*', '.*');
const regex: RegExp = new RegExp('^' + target + '$');
let i: number = 0;
for (const key in options.envObject) {
if (key.match(regex)) {
log.debug(`Adding "${key}" to targetKeys`);
options.targetKeys[i] = key;
i++;
}
}
options.json = true;
}
}

if (options.json && options.returnAllKeys) {
log.debug('Outputting entire .env file as JSON');
log.info(options.envObject.toJsonString(options.multiline));
Expand Down
1 change: 1 addition & 0 deletions src/components/qualifyingRules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export interface Options {
fullEnvPath: string;
envObject: EnvObject;
json: boolean;
noJson: boolean;
multiline: boolean;
quote: boolean;
action: {
Expand Down
4 changes: 4 additions & 0 deletions src/services/handlers/getValue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import {Options} from "../../components/qualifyingRules.js";
export default function getValue(options: Options) {
let result: string = '';

if (options.targetKeys.length === 0) {
options.targetKeys = Object.keys(options.envObject);
}

for (const key of options.targetKeys) {
log.debug(`Getting "${key}"`);

Expand Down