Skip to content

Commit e88ce39

Browse files
author
Hugo Chinchilla Carbonell
committed
Support for configurable quoting mode, references theskumar#15
1 parent 5094182 commit e88ce39

File tree

4 files changed

+34
-15
lines changed

4 files changed

+34
-15
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.PHONY: clean-pyc clean-build
1+
.PHONY: clean-pyc clean-build test
22

33
clean: clean-build clean-pyc
44

dotenv/cli.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,15 @@
99
@click.option('-f', '--file', default=os.path.join(os.getcwd(), '.env'),
1010
type=click.Path(exists=True),
1111
help="Location of the .env file, defaults to .env file in current working directory.")
12+
@click.option('-q', '--quote', default='always',
13+
type=click.Choice(['always', 'never', 'auto']),
14+
help="Whether to quote or not the variable values. Default mode is always.")
1215
@click.pass_context
13-
def cli(ctx, file):
16+
def cli(ctx, file, quote):
1417
'''This script is used to set, get or unset values from a .env file.'''
1518
ctx.obj = {}
1619
ctx.obj['FILE'] = file
20+
ctx.obj['QUOTE'] = quote
1721

1822
# Need to investigate if this can actually work or if the scope of the new environ variables
1923
# Expires when python exits
@@ -43,7 +47,8 @@ def list(ctx):
4347
def set(ctx, key, value):
4448
'''Store the given key/value.'''
4549
file = ctx.obj['FILE']
46-
success, key, value = set_key(file, key, value)
50+
quote = ctx.obj['QUOTE']
51+
success, key, value = set_key(file, key, value, quote)
4752
if success:
4853
click.echo('%s="%s"' % (key, value))
4954
else:
@@ -69,7 +74,8 @@ def get(ctx, key):
6974
def unset(ctx, key):
7075
'''Removes the given key.'''
7176
file = ctx.obj['FILE']
72-
success, key = unset_key(file, key)
77+
quote = ctx.obj['QUOTE']
78+
success, key = unset_key(file, key, quote)
7379
if success:
7480
click.echo("Successfully removed %s" % key)
7581
else:

dotenv/main.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def get_key(dotenv_path, key_to_get):
3636
return None
3737

3838

39-
def set_key(dotenv_path, key_to_set, value_to_set):
39+
def set_key(dotenv_path, key_to_set, value_to_set, quote_mode="always"):
4040
"""
4141
Adds or Updates a key/value to the given .env
4242
@@ -50,11 +50,11 @@ def set_key(dotenv_path, key_to_set, value_to_set):
5050
return None, key_to_set, value_to_set
5151
dotenv_as_dict = OrderedDict(parse_dotenv(dotenv_path))
5252
dotenv_as_dict[key_to_set] = value_to_set
53-
success = flatten_and_write(dotenv_path, dotenv_as_dict)
53+
success = flatten_and_write(dotenv_path, dotenv_as_dict, quote_mode)
5454
return success, key_to_set, value_to_set
5555

5656

57-
def unset_key(dotenv_path, key_to_unset):
57+
def unset_key(dotenv_path, key_to_unset, quote_mode="always"):
5858
"""
5959
Removes a given key from the given .env
6060
@@ -71,7 +71,7 @@ def unset_key(dotenv_path, key_to_unset):
7171
else:
7272
warnings.warn("key %s not removed from %s - key doesn't exist." % (key_to_unset, dotenv_path))
7373
return None, key_to_unset
74-
success = flatten_and_write(dotenv_path, dotenv_as_dict)
74+
success = flatten_and_write(dotenv_path, dotenv_as_dict, quote_mode)
7575
return success, key_to_unset
7676

7777

@@ -86,8 +86,12 @@ def parse_dotenv(dotenv_path):
8686
yield k, v
8787

8888

89-
def flatten_and_write(dotenv_path, dotenv_as_dict):
89+
def flatten_and_write(dotenv_path, dotenv_as_dict, quote_mode="always"):
9090
with open(dotenv_path, "w") as f:
9191
for k, v in dotenv_as_dict.items():
92-
f.write('%s="%s"\n' % (k, v))
92+
_mode = quote_mode
93+
if _mode == "auto" and " " in v:
94+
_mode = "always"
95+
str_format = '%s="%s"\n' if _mode == "always" else '%s=%s\n'
96+
f.write(str_format % (k, v))
9397
return True

tests/test_cli.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,21 @@ def test_unset():
3535

3636

3737
def test_console_script(cli):
38+
TEST_COMBINATIONS = (
39+
# quote_mode, var_name, var_value, expected_result
40+
("always", "HELLO", "WORLD", 'HELLO="WORLD"\n'),
41+
("never", "HELLO", "WORLD", 'HELLO=WORLD\n'),
42+
("auto", "HELLO", "WORLD", 'HELLO=WORLD\n'),
43+
("auto", "HELLO", "HELLO WORLD", 'HELLO="HELLO WORLD"\n'),
44+
)
3845
with cli.isolated_filesystem():
39-
sh.touch(dotenv_path)
40-
sh.dotenv('-f', dotenv_path, 'set', 'HELLO', 'WORLD')
41-
output = sh.dotenv('-f', dotenv_path, 'get', 'HELLO', )
42-
assert output == 'HELLO="WORLD"\n'
43-
sh.rm(dotenv_path)
46+
for quote_mode,variable,value,expected_result in TEST_COMBINATIONS:
47+
sh.touch(dotenv_path)
48+
sh.dotenv('-f', dotenv_path, '-q', quote_mode, 'set', variable, value)
49+
output = sh.cat(dotenv_path)
50+
assert output == expected_result
51+
sh.rm(dotenv_path)
52+
4453

4554
# should fail for not existing file
4655
result = cli.invoke(dotenv.cli.set, ['my_key', 'my_value'])

0 commit comments

Comments
 (0)