mirror of
https://github.com/kennethreitz/pipenv.git
synced 2026-06-05 22:50:18 +00:00
Merge pull request #1769 from dvf/dvf/parse-environment-variables
Allow values in Pipfile to consume Environment Variables
This commit is contained in:
@@ -302,6 +302,27 @@ To prevent pipenv from loading the ``.env`` file, set the ``PIPENV_DONT_LOAD_ENV
|
||||
|
||||
$ PIPENV_DONT_LOAD_ENV=1 pipenv shell
|
||||
|
||||
☤ Support for Environment Variables
|
||||
-----------------------------------
|
||||
|
||||
``pipenv`` supports the usage of environment variables in values. For example:
|
||||
|
||||
[[source]]
|
||||
url = "https://${PYPI_USERNAME}:${PYPI_PASSWORD}@my_private_repo.example.com/simple"
|
||||
verify_ssl = true
|
||||
name = "pypi"
|
||||
|
||||
[dev-packages]
|
||||
|
||||
[packages]
|
||||
requests = {version="*", index="home"}
|
||||
maya = {version="*", index="pypi"}
|
||||
records = "*"
|
||||
|
||||
Environment variables may be specified as ``${MY_ENVAR}`` or ``$MY_ENVAR``.
|
||||
On Windows, ``%MY_ENVAR%`` is supported in addition to ``${MY_ENVAR}`` or ``$MY_ENVAR``.
|
||||
|
||||
|
||||
☤ Configuration With Environment Variables
|
||||
------------------------------------------
|
||||
|
||||
|
||||
Vendored
+22
-1
@@ -62,6 +62,24 @@ class PipfileParser(object):
|
||||
def __repr__(self):
|
||||
return '<PipfileParser path={0!r}'.format(self.filename)
|
||||
|
||||
def inject_environment_variables(self, d):
|
||||
"""
|
||||
Recursively injects environment variables into TOML values
|
||||
"""
|
||||
|
||||
if not d:
|
||||
return d
|
||||
|
||||
for k, v in d.items():
|
||||
if isinstance(v, str):
|
||||
d[k] = os.path.expandvars(v)
|
||||
elif isinstance(v, dict):
|
||||
d[k] = self.inject_environment_variables(v)
|
||||
elif isinstance(v, list):
|
||||
d[k] = [self.inject_environment_variables(e) for e in v]
|
||||
|
||||
return d
|
||||
|
||||
def parse(self):
|
||||
# Open the Pipfile.
|
||||
with open(self.filename) as f:
|
||||
@@ -78,8 +96,11 @@ class PipfileParser(object):
|
||||
config = {}
|
||||
config.update(default_config)
|
||||
|
||||
# Deserialize the TOML, and parse for Environment Variables
|
||||
parsed_toml = self.inject_environment_variables(toml.loads(content))
|
||||
|
||||
# Load the Pipfile's configuration.
|
||||
config.update(toml.loads(content))
|
||||
config.update(parsed_toml)
|
||||
|
||||
# Structure the data for output.
|
||||
data = {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# Make sure we use the patched packages.
|
||||
import pipenv # noqa
|
||||
import os
|
||||
|
||||
from prettytoml import lexer
|
||||
from prettytoml.elements.atomic import AtomicElement
|
||||
@@ -7,6 +8,7 @@ from prettytoml.elements.metadata import (
|
||||
WhitespaceElement, PunctuationElement, CommentElement
|
||||
)
|
||||
from prettytoml.elements.table import TableElement
|
||||
from pipenv.vendor.pipfile.api import PipfileParser
|
||||
|
||||
|
||||
def test_table():
|
||||
@@ -27,3 +29,36 @@ def test_table():
|
||||
assert set(table.items()) == {('id', 42), ('age', 14)}
|
||||
del table['id']
|
||||
assert set(table.items()) == {('age', 14)}
|
||||
|
||||
|
||||
class TestPipfileParser:
|
||||
|
||||
def test_inject_environment_variables(self):
|
||||
os.environ['PYTEST_PIPFILE_TEST'] = "XYZ"
|
||||
p = PipfileParser()
|
||||
|
||||
parsed_dict = p.inject_environment_variables({
|
||||
"a_string": "https://$PYTEST_PIPFILE_TEST@something.com",
|
||||
"another_string": "https://${PYTEST_PIPFILE_TEST}@something.com",
|
||||
"nested": {
|
||||
"a_string": "https://$PYTEST_PIPFILE_TEST@something.com",
|
||||
"another_string": "${PYTEST_PIPFILE_TEST}",
|
||||
},
|
||||
"list": [
|
||||
{
|
||||
"a_string": "https://$PYTEST_PIPFILE_TEST@something.com",
|
||||
"another_string": "${PYTEST_PIPFILE_TEST}"
|
||||
},
|
||||
{},
|
||||
],
|
||||
"bool": True,
|
||||
"none": None,
|
||||
})
|
||||
|
||||
assert parsed_dict["a_string"] == "https://XYZ@something.com"
|
||||
assert parsed_dict["another_string"] == "https://XYZ@something.com"
|
||||
assert parsed_dict["nested"]["another_string"] == "XYZ"
|
||||
assert parsed_dict["list"][0]["a_string"] == "https://XYZ@something.com"
|
||||
assert parsed_dict["list"][1] == {}
|
||||
assert parsed_dict["bool"] is True
|
||||
assert parsed_dict["none"] is None
|
||||
|
||||
Reference in New Issue
Block a user