Support Environment Variables in config file

Environment variables can be assigned as values in the configuration
file using the !ENV tag. Resolves #1954.

The behavior is defined in the third-party package pyyaml_env_tag:
https://github.com/waylan/pyyaml-env-tag
This commit is contained in:
Waylan Limberg
2020-12-23 11:12:56 -05:00
parent 30dc6a0ef7
commit f4de3c7387
7 changed files with 85 additions and 4 deletions

View File

@@ -25,6 +25,20 @@ The current and past members of the MkDocs team.
### Major Additions to Version 1.2
#### Support added for Environment Variables in the configuration file (#1954)
Environments variables may now be specified in the configuration file with the
`!ENV` tag. The value of the variable will be parsed by the YAML parser and
converted to the appropriate type.
```yaml
somekey: !ENV VAR_NAME
otherkey: !ENV [VAR_NAME, FALLBACK_VAR, 'default value']
```
See [Environment Variables](../user-guide/configuration.md#environment-variables)
in the Configuration documentation for details.
#### A `--wait` flag has been added to the `serve` command (#2061)
To delay a rebuild of the site when using the livereload server, use the
@@ -34,7 +48,7 @@ To delay a rebuild of the site when using the livereload server, use the
mkdocs serve --wait 60
```
#### Update `gh-deloy` command (#2170)
#### Update `gh-deploy` command (#2170)
The vendored (and modified) copy of ghp_import has been replaced with a
dependency on the upstream library. As of version 1.0.0, [ghp_import] includes a

View File

@@ -12,6 +12,43 @@ project directory named `mkdocs.yml`.
As a minimum, this configuration file must contain the `site_name` setting. All
other settings are optional.
### Environment Variables
In most cases, the value of a configuration option is set directly in the
configuration file. However, as an option, the value of a configuration option
may be set to the value of an environment variable using the `!ENV` tag. For
example, to set the value of the `site_name` option to the value of the
variable `SITE_NAME` the YAML file may contain the following:
```yaml
site_name: !ENV SITE_NAME
```
If the environment variable is not defined, then the configuration setting
would be assigned a `null` (or `None` in Python) value. A default value can be
defined as the last value in a list. Like this:
```yaml
site_name: !ENV [SITE_NAME, 'My default site name']
```
Multiple fallback variables can be used as well. Note that the last value is
not an environment variable, but must be a value to use as a default if none
of the specified environment variables are defined.
```yaml
site_name: !ENV [SITE_NAME, OTHER_NAME, 'My default site name']
```
Simple types defined within an environment variable such as string, bool,
integer, float, datestamp and null are parsed as if they were defined directly
in the YAML file, which means that the value will be converted to the
appropriate type. However, complex types such as lists and key/value pairs
cannot be defined within a single environment variable.
For more details, see the [pyyaml_env_tag](https://github.com/waylan/pyyaml-env-tag)
project.
## Project information
### site_name

View File

@@ -305,6 +305,28 @@ class UtilsTests(unittest.TestCase):
self.assertTrue(isinstance(config['key'], str))
self.assertTrue(isinstance(config['key2'][0], str))
@mock.patch.dict(os.environ, {'VARNAME': 'Hello, World!', 'BOOLVAR': 'false'})
def test_env_var_in_yaml(self):
yaml_src = dedent(
'''
key1: !ENV VARNAME
key2: !ENV UNDEFINED
key3: !ENV [UNDEFINED, default]
key4: !ENV [UNDEFINED, VARNAME, default]
key5: !ENV BOOLVAR
'''
)
config = utils.yaml_load(yaml_src)
self.assertIsInstance(config['key1'], str)
self.assertEqual(config['key1'], 'Hello, World!')
self.assertIsNone(config['key2'])
self.assertIsInstance(config['key3'], str)
self.assertEqual(config['key3'], 'default')
self.assertIsInstance(config['key4'], str)
self.assertEqual(config['key4'], 'Hello, World!')
self.assertIs(config['key5'], False)
def test_copy_files(self):
src_paths = [
'foo.txt',

View File

@@ -17,6 +17,7 @@ import posixpath
import functools
from datetime import datetime, timezone
from urllib.parse import urlparse
from yaml_env_tag import construct_env_tag
from mkdocs import exceptions
@@ -56,6 +57,10 @@ def yaml_load(source, loader=yaml.Loader):
# will be unicode on translation.
Loader.add_constructor('tag:yaml.org,2002:str', construct_yaml_str)
# Attach Environment Variable constructor.
# See https://github.com/waylan/pyyaml-env-tag
Loader.add_constructor('!ENV', construct_env_tag)
try:
return yaml.load(source, Loader)
finally:

View File

@@ -5,4 +5,5 @@ Markdown==3.2.1
PyYAML==5.1
tornado==4.1
mdx_gh_links==0.2
ghp-import==1.0
ghp-import==1.0
pyyaml_env_tag==0.1

View File

@@ -5,4 +5,5 @@ Markdown>=3.2.1
PyYAML>=5.2
tornado>=5.1.1
mdx_gh_links>=0.2
ghp-import>=1.0
ghp-import>=1.0
pyyaml_env_tag>=0.1

View File

@@ -61,7 +61,8 @@ setup(
'Markdown>=3.2.1',
'PyYAML>=3.10',
'tornado>=5.0',
'ghp-import>=1.0'
'ghp-import>=1.0',
'pyyaml_env_tag>=0.1'
],
python_requires='>=3.6',
entry_points={