Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,11 @@ $ dotenv set EMAIL [email protected]
$ dotenv list
USER=foo
[email protected]
$ dotenv list --format=json
{
"USER": "foo",
"EMAIL": "[email protected]"
}
$ dotenv run -- python foo.py
```

Expand Down
20 changes: 17 additions & 3 deletions src/dotenv/cli.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import json
import os
import shlex
import sys
from subprocess import Popen
from typing import Any, Dict, List
Expand Down Expand Up @@ -36,7 +38,11 @@ def cli(ctx: click.Context, file: Any, quote: Any, export: Any) -> None:

@cli.command()
@click.pass_context
def list(ctx: click.Context) -> None:
@click.option('--format', default='simple',
type=click.Choice(['simple', 'json', 'shell', 'export']),
help="The format in which to display the list. Default format is simple, "
"which displays name=value without quotes.")
def list(ctx: click.Context, format: bool) -> None:
'''Display all the stored key/value.'''
file = ctx.obj['FILE']
if not os.path.isfile(file):
Expand All @@ -45,8 +51,16 @@ def list(ctx: click.Context) -> None:
ctx=ctx
)
dotenv_as_dict = dotenv_values(file)
for k, v in dotenv_as_dict.items():
click.echo('%s=%s' % (k, v))
if format == 'json':
click.echo(json.dumps(dotenv_as_dict, indent=2, sort_keys=True))
else:
prefix = 'export ' if format == 'export' else ''
for k in sorted(dotenv_as_dict):
v = dotenv_as_dict[k]
if v is not None:
if format in ('export', 'shell'):
v = shlex.quote(v)
click.echo('%s%s=%s' % (prefix, k, v))


@cli.command()
Expand Down
24 changes: 19 additions & 5 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,33 @@

import pytest
import sh

from typing import Optional
import dotenv
from dotenv.cli import cli as dotenv_cli
from dotenv.version import __version__


def test_list(cli, dotenv_file):
@pytest.mark.parametrize(
"format,content,expected",
(
(None, "x='a b c'", '''x=a b c\n'''),
("simple", "x='a b c'", '''x=a b c\n'''),
("json", "x='a b c'", '''{\n "x": "a b c"\n}\n'''),
("shell", "x='a b c'", '''x='a b c'\n'''),
("export", "x='a b c'", '''export x='a b c'\n'''),
)
)
def test_list(cli, dotenv_file, format: Optional[str], content: str, expected: str):
with open(dotenv_file, "w") as f:
f.write("a=b")
f.write(content + '\n')

args = ['--file', dotenv_file, 'list']
if format is not None:
args.extend(['--format', format])

result = cli.invoke(dotenv_cli, ['--file', dotenv_file, 'list'])
result = cli.invoke(dotenv_cli, args)

assert (result.exit_code, result.output) == (0, result.output)
assert (result.exit_code, result.output) == (0, expected)


def test_list_non_existent_file(cli):
Expand Down