Skip to content

Commit

Permalink
feat(cli) add --format= option to list command (#407)
Browse files Browse the repository at this point in the history
Allows dumping of all variables in various formats.

Currently defined formats:
   simple:  Each variable is output as <name>=<value> with no
            quoting or escaping. The output is not parseable. This
            is the default format for backwards compatibility.
   shell:   Each variable is output as <name>=<value>, where
            <value> is quoted/escaped with shell-compatible rules,
            the result may be imported into a shell script with
              eval "$(dotenv list --format=shell)"
   export:  Similar to "shell" but prefixes each line with "export "
            so that when imported into a shell script, the variables
            are exported.
   json:    The entire set of variables is output as a JSON-serialized
            object

Co-authored-by: Saurabh Kumar <theskumar@users.noreply.github.com>
  • Loading branch information
sammck and theskumar committed Jul 23, 2022
1 parent 2f36c08 commit 914c68e
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 8 deletions.
5 changes: 5 additions & 0 deletions README.md
Expand Up @@ -146,6 +146,11 @@ $ dotenv set EMAIL foo@example.org
$ dotenv list
USER=foo
EMAIL=foo@example.org
$ dotenv list --format=json
{
"USER": "foo",
"EMAIL": "foo@example.org"
}
$ dotenv run -- python foo.py
```

Expand Down
20 changes: 17 additions & 3 deletions src/dotenv/cli.py
@@ -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
29 changes: 24 additions & 5 deletions tests/test_cli.py
Expand Up @@ -2,19 +2,38 @@

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'''),
("simple", """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"),
("shell", """x='"a b c"'""", '''x='"a b c"'\n'''),
("shell", '''x="'a b c'"''', '''x=''"'"'a b c'"'"''\n'''),
("shell", "x='a\nb\nc'", "x='a\nb\nc'\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

0 comments on commit 914c68e

Please sign in to comment.