pax_global_header00006660000000000000000000000064137470346130014522gustar00rootroot0000000000000052 comment=20d7f2d5bc0bf3a0009fa39b3888e975e9e4f442 .github/000077500000000000000000000000001374703461300124265ustar00rootroot00000000000000.github/workflows/000077500000000000000000000000001374703461300144635ustar00rootroot00000000000000.github/workflows/python-package.yaml000066400000000000000000000015421374703461300202630ustar00rootroot00000000000000name: CI/CD Pipeline on: - push - pull_request jobs: test: name: Test Python ${{ matrix.python-version }} on ${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: - ubuntu-latest - macos-latest - windows-latest python-version: - 3.6 - 3.7 - 3.8 - 3.9 - pypy3 steps: - uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | python -m pip install --upgrade pip setuptools wheel pip install -e .['dev'] - name: Run linter run: | make lint - name: Run tests run: | make test .gitignore000066400000000000000000000000761374703461300130610ustar00rootroot00000000000000__pycache__/ *.pyc *.egg-info/ build/ dist/ .coverage venv/ CHANGELOG.md000066400000000000000000000025331374703461300127020ustar00rootroot00000000000000# Changelog ## [2.2.0] - 2020-10-30 * Allow for missing .env file -- in this case the command will be executed without setting any environment variables. The previous behaviour was to fail with a FileNotFoundError * Migrated from TravisCI to github actions. We test now on Linux, Mac and Windows x all supported Python versions! * Fixed tests under windows, where NamedTemporaryFile cannot be opened twice. * refactored __main__.py into cli.py and wrapped argparsing into dedicated function * bumped minimal Python version to 3.6 * Added 3.8, 3.9 to travis tests * Cleaned up Makefile * Added twine to dev-dependencies ## [2.1.0] - 2020-10-27 * make sure child process terminates when dotenv terminates * measure coverage for tests as well * skip coverage report for files w/ complete coverage * use twine for uploading to pypi ## [2.0.1] - 2019-09-07 * Version bump for Debian source-only upload ## [2.0.0] - 2019-08-03 * Differentiate single vs double quotes ## [1.3.0] - 2019-05-11 * Support for lines starting with `export` * Support for empty values ## [1.2.0] - 2019-05-10 * Fixed newlines * Added more tests ## [1.1.0] - 2019-04-28 * Added Bash completion and provide it via sdist and Debian package ## [1.0.2] - 2019-04-14 * Debian package * Fixed Travis-CI pipeline and added tests for py37 ## [1.0.0] - 2018-10-14 * Initial Release LICENSE000066400000000000000000000020601374703461300120710ustar00rootroot00000000000000MIT License Copyright (c) 2018 Bastian Venthur Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. MANIFEST.in000066400000000000000000000000371374703461300126240ustar00rootroot00000000000000recursive-include completion * Makefile000066400000000000000000000007221374703461300125270ustar00rootroot00000000000000VERSION = $(shell python3 setup.py --version) all: lint test test: pytest .PHONY: test lint: flake8 .PHONY: lint docs: $(MAKE) -C docs html .PHONY: docs release: python3 setup.py sdist bdist_wheel twine upload --repository-url https://upload.pypi.org/legacy/ dist/* .PHONY: release tarball: git archive --output=../dotenv-cli_$(VERSION).orig.tar.gz HEAD clean: find . -type f -name *.pyc -delete find . -type d -name __pycache__ -delete .PHONY: clean README.md000066400000000000000000000044531374703461300123530ustar00rootroot00000000000000# dotenv CLI Dotenv-CLI is a simple package that provides the `dotenv` command. It reads the `.env` file from the current directory puts the contents in the environment and executes the given command. `dotenv` supports alternative `.env` files like `.env.development` via the `-e` or `--dotenv` parametes. `dotenv` provides bash completion, so you can use `dotenv` like this: ```bash $ dotenv make all clean docs lint release test ``` ## Install ### Using PyPi dotenv-cli is [available on PyPi][pypi], you can install it via: [pypi]: https://pypi.org/project/dotenv-cli/ ```bash $ pip install dotenv-cli ``` ### On Debian and Ubuntu Alternatively, you can install dotenv-cli on Debian based distributions via: ```bash # apt-get install python3-dotenv-cli ``` ## Usage Create an `.env` file in the root of your project and populate it with some values like so: ```sh SOME_SECRET=donttrythisathome SOME_CONFIG=foo ``` Just prepend the command you want to run with the extra environment variables from the `.env` file with `dotenv`: ```bash $ dotenv some-command ``` and those variables will be available in your environment variables. ## Rules The parser understands the following: * Basic unquoted values (`BASIC=basic basic`) * Lines starting with `export` (`export EXPORT=foo`), so you can `source` the file in bash * Lines starting with `#` are ignored (`# Comment`) * Empty values (`EMPTY=`) become empty strings * Inner quotes are maintained in basic values: `INNER_QUOTES=this 'is' a test` or `INNER_QUOTES2=this "is" a test` * White spaces are trimmed from unquoted values: `TRIM_WHITESPACE= foo ` and maintained in quoted values: `KEEP_WHITESPACE=" foo "` * Interpret escapes (e.g. `\n`) in double quoted values, keep them as-is in single quoted values. Example `.env` file: ```sh BASIC=basic basic export EXPORT=foo EMPTY= INNER_QUOTES=this 'is' a test INNER_QUOTES2=this "is" a test TRIM_WHITESPACE= foo KEEP_WHITESPACE=" foo " MULTILINE_DQ="multi\nline" MULTILINE_SQ='multi\nline' MULTILINE_NQ=multi\nline # # some comment ``` becomes: ```sh $ dotenv env BASIC=basic basic EXPORT=foo EMPTY= INNER_QUOTES=this 'is' a test INNER_QUOTES2=this "is" a test TRIM_WHITESPACE=foo KEEP_WHITESPACE= foo MULTILINE_DQ=multi line MULTILINE_SQ=multi\nline MULTILINE_NQ=multi\nline ``` completion/000077500000000000000000000000001374703461300132375ustar00rootroot00000000000000completion/bash/000077500000000000000000000000001374703461300141545ustar00rootroot00000000000000completion/bash/dotenv000066400000000000000000000015451374703461300154030ustar00rootroot00000000000000_dotenv() { local cur prev words cword _init_completion || return # find completion(s) for command executed with dotenv local i for (( i=1; i <= COMP_CWORD; i++ )); do if [[ ${COMP_WORDS[i]} != -* ]]; then _command_offset $i return fi # if current option requires a parameter, ignore the next one case "${COMP_WORDS[i]}" in -e|--dotenv) ((i++)) ;; esac done # completion for dotenv files case "$prev" in -e|--dotenv) COMPREPLY=( $( compgen -f -- "$cur" ) ) return ;; esac # check dotenv's options if [[ $cur == -* ]]; then COMPREPLY=( $( compgen -W '$( _parse_help "$1" )' -- "$cur" ) ) return fi } && complete -F _dotenv dotenv # vim: filetype=sh debian/000077500000000000000000000000001374703461300123105ustar00rootroot00000000000000debian/changelog000066400000000000000000000043171374703461300141670ustar00rootroot00000000000000dotenv-cli (2.2.0-1) unstable; urgency=medium * Allow for missing .env file -- in this case the command will be executed without setting any environment variables. The previous behaviour was to fail with a FileNotFoundError * Migrated from TravisCI to github actions. We test now on Linux, Mac and Windows x all supported Python versions! * Fixed tests under windows, where NamedTemporaryFile cannot be opened twice. * refactored __main__.py into cli.py and wrapped argparsing into dedicated function * bumped minimal Python version to 3.6 * Added 3.8, 3.9 to travis tests * Cleaned up Makefile * Added twine to dev-dependencies -- Bastian Venthur Fri, 30 Oct 2020 16:48:44 +0100 dotenv-cli (2.1.0-1) unstable; urgency=medium * make sure child process terminates when dotenv terminates * measure coverage for tests as well * skip coverage report for files w/ complete coverage * use twine for uploading to pypi -- Bastian Venthur Tue, 27 Oct 2020 22:21:31 +0100 dotenv-cli (2.0.1-1) unstable; urgency=medium * Source only upload * Minor version bump -- Bastian Venthur Sat, 07 Sep 2019 13:30:25 +0200 dotenv-cli (2.0.0-1) unstable; urgency=medium * Interpret escapes only in double quoted values, keep them as is in single quoted -- Bastian Venthur Sat, 03 Aug 2019 14:38:36 +0200 dotenv-cli (1.3.0-1) unstable; urgency=medium * Added support for export-lines * Added support for empty values -- Bastian Venthur Sat, 11 May 2019 14:34:47 +0200 dotenv-cli (1.2.0-1) unstable; urgency=medium * Fixed newlines -- Bastian Venthur Fri, 10 May 2019 19:47:57 +0200 dotenv-cli (1.1.0-1) unstable; urgency=medium * Added bash completion -- Bastian Venthur Sun, 28 Apr 2019 12:56:49 +0200 dotenv-cli (1.0.2-1) unstable; urgency=medium * Conflict with ruby-dotenv (Closes: #926916) -- Bastian Venthur Sun, 14 Apr 2019 17:42:29 +0200 dotenv-cli (1.0.0-1) unstable; urgency=medium * Initial release (Closes: #923856) -- Bastian Venthur Wed, 06 Mar 2019 09:55:47 +0100 debian/compat000066400000000000000000000000031374703461300135070ustar00rootroot0000000000000011 debian/control000066400000000000000000000015011374703461300137100ustar00rootroot00000000000000Source: dotenv-cli Section: python Priority: optional Maintainer: Bastian Venthur Build-Depends: debhelper (>= 11), dh-python, python3-all, python3-setuptools, bash-completion Standards-Version: 4.3.0 Homepage: https://github.com/venthur/dotenv-cli Vcs-Browser: https://github.com/venthur/dotenv-cli Vcs-Git: https://github.com/venthur/dotenv-cli.git Testsuite: autopkgtest-pkg-python Package: python3-dotenv-cli Architecture: all Depends: ${python3:Depends}, ${misc:Depends} Conflicts: ruby-dotenv Description: CLI that loads .env configuration This package provides the dotenv command. It reads the .env file from the current directory puts the contents in the environment and executes the given command. . dotenv supports alternative .env files like .env.development via the -e or --dotenv parameters. debian/copyright000066400000000000000000000025241374703461300142460ustar00rootroot00000000000000Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: dotenv-cli Source: https://github.com/venthur/dotenv-cli Files: * Copyright: 2018 Bastian Venthur License: MIT Files: debian/* Copyright: 2019 Bastian Venthur License: MIT License: MIT Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: . The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. . THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. debian/python3-dotenv-cli.bash-completion000066400000000000000000000000271374703461300207630ustar00rootroot00000000000000completion/bash/dotenv debian/rules000077500000000000000000000011421374703461300133660ustar00rootroot00000000000000#!/usr/bin/make -f # See debhelper(7) (uncomment to enable) # output every command that modifies files on the build system. #export DH_VERBOSE = 1 export PYBUILD_DISABLE=test export PYBUILD_NAME=dotenv-cli %: dh $@ --with python3,bash-completion --buildsystem=pybuild # If you need to rebuild the Sphinx documentation # Add spinxdoc to the dh --with line #override_dh_auto_build: # dh_auto_build # PYTHONPATH=. http_proxy='127.0.0.1:9' sphinx-build -N -bhtml docs/ build/html # HTML generator # PYTHONPATH=. http_proxy='127.0.0.1:9' sphinx-build -N -bman docs/ build/man # Manpage generator debian/source/000077500000000000000000000000001374703461300136105ustar00rootroot00000000000000debian/source/format000066400000000000000000000000141374703461300150160ustar00rootroot000000000000003.0 (quilt) debian/source/options000066400000000000000000000004271374703461300152310ustar00rootroot00000000000000extend-diff-ignore = "^[^/]*[.]egg-info/" # below are my exceptions, probably best to try to mirror the .gitignore extend-diff-ignore = "^build/" extend-diff-ignore = "^dist/" extend-diff-ignore = "^.pytest_cache/" extend-diff-ignore = "^.coverage" extend-diff-ignore = "^venv/" debian/watch000066400000000000000000000004171374703461300133430ustar00rootroot00000000000000# You can run the "uscan" command to check for upstream updates and more. # See uscan(1) for format # Compulsory line, this is a version 4 file version=4 # Direct Git # opts="mode=git" https://github.com/venthur/dotenv-cli.git \ # refs/tags/v([\d\.]+) debian uupdate dotenv_cli/000077500000000000000000000000001374703461300132145ustar00rootroot00000000000000dotenv_cli/__init__.py000066400000000000000000000000631374703461300153240ustar00rootroot00000000000000from dotenv_cli.version import __VERSION__ # noqa dotenv_cli/cli.py000066400000000000000000000020241374703461300143330ustar00rootroot00000000000000import argparse import logging from dotenv_cli.core import run_dotenv from dotenv_cli import __VERSION__ logger = logging.getLogger(__name__) def parse_args(args=None): """Parse arguments. Paramters --------- args : list[str] This if for debugging only. Returns ------- argparse.Namespace """ parser = argparse.ArgumentParser() parser.add_argument( '-e', '--dotenv', help='Alternative .env file', default='.env', ) parser.add_argument( 'command', help='Shell command to execute', nargs=argparse.REMAINDER, ) parser.add_argument( '--version', action='version', version=__VERSION__, ) return parser.parse_args(args) def main(): """Run dotenv. This function parses sys.argv and runs dotenv. Returns ------- int the return value """ args = parse_args() if not args.command: return return run_dotenv(args.dotenv, args.command) dotenv_cli/core.py000066400000000000000000000051311374703461300145160ustar00rootroot00000000000000import atexit import logging import os from subprocess import Popen # , PIPE, STDOUT logger = logging.getLogger(__name__) def read_dotenv(filename): """Read dotenv file. Parameters ---------- filename : str path to the filename Returns ------- dict """ try: with open(filename, 'r') as fh: data = fh.read() except FileNotFoundError: logger.warning(f"{filename} does not exist, continuing without " "setting environment variables.") data = "" res = {} for line in data.splitlines(): logger.debug(line) line = line.strip() # ignore comments if line.startswith('#'): continue # ignore empty lines or lines w/o '=' if '=' not in line: continue key, value = line.split('=', 1) # allow export if key.startswith('export '): key = key.split(' ', 1)[-1] key = key.strip() value = value.strip() # remove quotes (not sure if this is standard behaviour) if len(value) >= 2 and value[0] == value[-1] == '"': value = value[1:-1] # escape escape characters value = bytes(value, 'utf-8').decode('unicode-escape') elif len(value) >= 2 and value[0] == value[-1] == "'": value = value[1:-1] res[key] = value logger.debug(res) return res def run_dotenv(filename, command): """Run dotenv. This function executes the commands with the environment variables parsed from filename. Parameters ---------- filename : str path to the .env file command : list[str] command to execute Returns ------- int the return value """ # read dotenv dotenv = read_dotenv(filename) # update env env = os.environ.copy() env.update(dotenv) # execute proc = Popen( command, # stdin=PIPE, # stdout=PIPE, # stderr=STDOUT, universal_newlines=True, bufsize=0, shell=False, env=env, ) def terminate_proc(): """Kill child process. All signals should be forwarded to the child processes automatically, however child processes are also free to ignore some of them. With this we make sure the child processes get killed once dotenv exits. """ proc.kill() # register atexit.register(terminate_proc) _, _ = proc.communicate() # unregister atexit.unregister(terminate_proc) return proc.returncode dotenv_cli/version.py000066400000000000000000000000261374703461300152510ustar00rootroot00000000000000__VERSION__ = '2.2.0' setup.cfg000066400000000000000000000002301374703461300127020ustar00rootroot00000000000000[tool:pytest] addopts = --cov=dotenv_cli --cov=tests --cov-branch --cov-report=term-missing:skip-covered [flake8] exclude = venv,build setup.py000066400000000000000000000020641374703461300126020ustar00rootroot00000000000000#!/usr/bin/env python from setuptools import setup meta = {} exec(open('./dotenv_cli/version.py').read(), meta) meta['long_description'] = open('./README.md').read() setup( name='dotenv-cli', version=meta['__VERSION__'], description='Simple dotenv CLI.', long_description=meta['long_description'], long_description_content_type='text/markdown', keywords='dotenv cli .env', author='Bastian Venthur', author_email='mail@venthur.de', url='https://github.com/venthur/dotenv-cli', python_requires='>=3.6', extras_require={ 'dev': [ 'pytest', 'pytest-cov', 'flake8', 'wheel', 'twine', ] }, packages=['dotenv_cli'], entry_points={ 'console_scripts': [ 'dotenv = dotenv_cli.cli:main' ] }, license='MIT', classifiers=[ 'Development Status :: 5 - Production/Stable', 'Intended Audience :: Developers', 'License :: OSI Approved :: MIT License', 'Programming Language :: Python :: 3', ], ) tests/000077500000000000000000000000001374703461300122305ustar00rootroot00000000000000tests/__init__.py000066400000000000000000000000001374703461300143270ustar00rootroot00000000000000tests/test_cli.py000066400000000000000000000026431374703461300144150ustar00rootroot00000000000000from subprocess import run, PIPE from pathlib import Path import tempfile import pytest DOTENV_FILE = """ # comment=foo TEST=foo TWOLINES='foo\nbar' TEST_COMMENT=foo # bar LINE_WITH_EQUAL='foo=bar' """ @pytest.fixture def dotenvfile(): _file = Path.cwd() / '.env' with _file.open('w') as fh: fh.write(DOTENV_FILE) yield _file _file.unlink() def test_stdout(dotenvfile): proc = run(['dotenv', 'echo', 'test'], stdout=PIPE) assert b'test' in proc.stdout def test_stderr(dotenvfile): proc = run(['dotenv', 'python', '-c', 'import os; os.write(2, b"test")'], stderr=PIPE) assert b'test' in proc.stderr def test_returncode(dotenvfile): proc = run(['dotenv', 'false']) assert proc.returncode == 1 proc = run(['dotenv', 'true']) assert proc.returncode == 0 def test_alternative_dotenv(): with tempfile.NamedTemporaryFile('w', delete=False) as f: f.write('foo=bar') proc = run(['dotenv', '-e', f.name, 'env'], stdout=PIPE) assert b'foo=bar' in proc.stdout proc = run(['dotenv', '--dotenv', f.name, 'env'], stdout=PIPE) assert b'foo=bar' in proc.stdout def test_nonexisting_dotenv(): proc = run(['dotenv', '-e', '/tmp/i.dont.exist', 'true'], stderr=PIPE) assert proc.returncode == 0 assert b'does not exist' in proc.stderr def test_no_command(): proc = run(['dotenv']) assert proc.returncode == 0 tests/test_core.py000066400000000000000000000074041374703461300145760ustar00rootroot00000000000000import tempfile import pytest from dotenv_cli import core def test_full(): TEST = r""" BASIC=basic basic export EXPORT=foo EMPTY= INNER_QUOTES=this 'is' a test INNER_QUOTES2=this "is" a test TRIM_WHITESPACE= foo KEEP_WHITESPACE=" foo " MULTILINE_DQ="multi\nline" MULTILINE_SQ='multi\nline' MULTILINE_NQ=multi\nline # some comment should be ignored """ with tempfile.NamedTemporaryFile('w', delete=False) as f: f.write(TEST) env = core.read_dotenv(f.name) assert env['BASIC'] == 'basic basic' assert env['EXPORT'] == 'foo' assert env['EMPTY'] == '' assert env['INNER_QUOTES'] == "this 'is' a test" assert env['INNER_QUOTES2'] == 'this "is" a test' assert env['TRIM_WHITESPACE'] == "foo" assert env['KEEP_WHITESPACE'] == " foo " assert env['MULTILINE_DQ'] == "multi\nline" assert env['MULTILINE_SQ'] == "multi\\nline" assert env['MULTILINE_NQ'] == "multi\\nline" assert len(env) == 10 def test_basic(): """Basic unquoted strings""" TEST = "FOO=BAR" with tempfile.NamedTemporaryFile('w', delete=False) as f: f.write(TEST) env = core.read_dotenv(f.name) assert env['FOO'] == 'BAR' def test_empty(): """Empty values become empty strings.""" TEST = "FOO=" with tempfile.NamedTemporaryFile('w', delete=False) as f: f.write(TEST) env = core.read_dotenv(f.name) assert env['FOO'] == '' def test_inner_quotes(): """Inner quotes are mainained.""" TEST = "\n".join(["FOO1=this 'is' a test", 'FOO2=this "is" a test']) with tempfile.NamedTemporaryFile('w', delete=False) as f: f.write(TEST) env = core.read_dotenv(f.name) assert env['FOO1'] == "this 'is' a test" assert env['FOO2'] == 'this "is" a test' def test_trim_whitespaces(): """Whitespaces are stripped from unquoted values.""" TEST = "FOO= test " with tempfile.NamedTemporaryFile('w', delete=False) as f: f.write(TEST) env = core.read_dotenv(f.name) assert env['FOO'] == "test" def test_keep_whitespaces(): """Whitespaces are mainteined from quoted values.""" TEST = "FOO=' test '" with tempfile.NamedTemporaryFile('w', delete=False) as f: f.write(TEST) env = core.read_dotenv(f.name) assert env['FOO'] == " test " def test_multiline(): """Quoted values can contain newlines.""" TEST = r'FOO="This is\nbar"' with tempfile.NamedTemporaryFile('w', delete=False) as f: f.write(TEST) env = core.read_dotenv(f.name) assert env['FOO'] == 'This is\nbar' @pytest.mark.parametrize('input_, expected', [ ('FOO="Test"', 'Test'), ("FOO='Test'", 'Test'), ("FOO='\"Test\"'", '"Test"'), ('FOO="\'Test\'"', "'Test'"), ]) def test_quotes(input_, expected): with tempfile.NamedTemporaryFile('w', delete=False) as f: f.write(input_) env = core.read_dotenv(f.name) assert env['FOO'] == expected def test_comments(): """Lines starting with # are ignored.""" TEST = """ FOO=BAR # comment BAR=BAZ """ with tempfile.NamedTemporaryFile('w', delete=False) as f: f.write(TEST) env = core.read_dotenv(f.name) assert len(env) == 2 assert env['FOO'] == 'BAR' assert env['BAR'] == 'BAZ' def test_emtpy_lines(): """Empty lines are skipped.""" TEST = """ FOO=BAR BAR=BAZ """ with tempfile.NamedTemporaryFile('w', delete=False) as f: f.write(TEST) env = core.read_dotenv(f.name) assert len(env) == 2 assert env['FOO'] == 'BAR' assert env['BAR'] == 'BAZ' def test_export(): """Exports are allowed.""" TEST = "export FOO=BAR" with tempfile.NamedTemporaryFile('w', delete=False) as f: f.write(TEST) env = core.read_dotenv(f.name) assert env['FOO'] == 'BAR' tests/test_version.py000066400000000000000000000001431374703461300153240ustar00rootroot00000000000000def test_version(): from dotenv_cli import __VERSION__ assert isinstance(__VERSION__, str)