diff --git a/news/2754.trivial b/news/2754.trivial new file mode 100644 index 00000000..64ce2f5d --- /dev/null +++ b/news/2754.trivial @@ -0,0 +1 @@ +Added a warning message if the ``PIPENV_DOTENV_LOCATION`` environment variable is set but the specified file does not exist. diff --git a/pipenv/core.py b/pipenv/core.py index 8e56adb1..bab12f93 100644 --- a/pipenv/core.py +++ b/pipenv/core.py @@ -50,12 +50,10 @@ from .environments import ( PIPENV_SKIP_VALIDATION, PIPENV_HIDE_EMOJIS, PIPENV_YES, - PIPENV_DONT_LOAD_ENV, PIPENV_DEFAULT_PYTHON_VERSION, PIPENV_MAX_SUBPROCESS, PIPENV_DONT_USE_PYENV, SESSION_IS_INTERACTIVE, - PIPENV_DOTENV_LOCATION, PIPENV_CACHE_DIR, ) @@ -148,17 +146,30 @@ def do_clear(): def load_dot_env(): """Loads .env file into sys.environ.""" - if not PIPENV_DONT_LOAD_ENV: + if not environments.PIPENV_DONT_LOAD_ENV: # If the project doesn't exist yet, check current directory for a .env file project_directory = project.project_directory or "." - denv = PIPENV_DOTENV_LOCATION or os.sep.join([project_directory, ".env"]) + dotenv_file = environments.PIPENV_DOTENV_LOCATION or os.sep.join( + [project_directory, ".env"] + ) - if os.path.isfile(denv): + if os.path.isfile(dotenv_file): click.echo( crayons.normal("Loading .env environment variables…", bold=True), err=True, ) - dotenv.load_dotenv(denv, override=True) + else: + if environments.PIPENV_DOTENV_LOCATION: + click.echo( + "{0}: file {1}={2} does not exist!!\n{3}".format( + crayons.red("Warning", bold=True), + crayons.normal("PIPENV_DOTENV_LOCATION", bold=True), + crayons.normal(environments.PIPENV_DOTENV_LOCATION, bold=True), + crayons.red("Not loading environment variables.", bold=True), + ), + err=True, + ) + dotenv.load_dotenv(dotenv_file, override=True) def add_to_path(p): diff --git a/tests/unit/test_core.py b/tests/unit/test_core.py index e737a59e..394e1120 100644 --- a/tests/unit/test_core.py +++ b/tests/unit/test_core.py @@ -1,7 +1,11 @@ +import os + import pytest import mock -from pipenv.core import warn_in_virtualenv +from pipenv._compat import TemporaryDirectory +from pipenv.core import warn_in_virtualenv, load_dot_env +from pipenv.utils import temp_environ @mock.patch('pipenv.environments.PIPENV_VIRTUALENV', 'totallyrealenv') @@ -13,3 +17,43 @@ def test_suppress_nested_venv_warning(capsys): warn_in_virtualenv() output, err = capsys.readouterr() assert 'Courtesy Notice' not in err + + +@pytest.mark.core +def test_load_dot_env_from_environment_variable_location(capsys): + with temp_environ(), TemporaryDirectory(prefix='pipenv-', suffix='') as tempdir: + dotenv_path = os.path.join(tempdir.name, 'test.env') + key, val = 'SOME_KEY', 'some_value' + with open(dotenv_path, 'w') as f: + f.write('{}={}'.format(key, val)) + + with mock.patch('pipenv.environments.PIPENV_DOTENV_LOCATION', dotenv_path): + load_dot_env() + assert os.environ[key] == val + + +@pytest.mark.core +def test_doesnt_load_dot_env_if_disabled(capsys): + with temp_environ(), TemporaryDirectory(prefix='pipenv-', suffix='') as tempdir: + dotenv_path = os.path.join(tempdir.name, 'test.env') + key, val = 'SOME_KEY', 'some_value' + with open(dotenv_path, 'w') as f: + f.write('{}={}'.format(key, val)) + + with mock.patch('pipenv.environments.PIPENV_DOTENV_LOCATION', dotenv_path): + with mock.patch('pipenv.environments.PIPENV_DONT_LOAD_ENV', '1'): + load_dot_env() + assert key not in os.environ + + load_dot_env() + assert key in os.environ + + +@pytest.mark.core +def test_load_dot_env_warns_if_file_doesnt_exist(capsys): + with temp_environ(), TemporaryDirectory(prefix='pipenv-', suffix='') as tempdir: + dotenv_path = os.path.join(tempdir.name, 'does-not-exist.env') + with mock.patch('pipenv.environments.PIPENV_DOTENV_LOCATION', dotenv_path): + load_dot_env() + output, err = capsys.readouterr() + assert 'Warning' in err