Repository: cookiecutter/cookiecutter

Issue:
Expand Environment Variables in Cookiecutter Configuration File
I set my cookiecutterrc file via an environment variable, like this:

```
export COOKIECUTTER_CONFIG="$XDG_CONFIG_HOME/cookiecutter/cookiecutterrc"
```

In my cookiecutterrc, I'd like to use those same environment variables to set paths, however they don't currently expand:

```
default_context:
    full_name: "Nathan Farrar"
    email: "nathan.farrar@gmail.com"
    github_username: "nfarrar"
cookiecutters_dir: "$XDG_CACHE_HOME/cookiecutter/template"
replay_dir: "$XDG_CACHE_HOME/cookiecutter/replay"
abbreviations:
    pp: https://github.com/audreyr/cookiecutter-pypackage.git
    gh: https://github.com/{0}.git
    bb: https://bitbucket.org/{0}
```

For example:

```
$ cookiecutter pp
$ ls ~/
...
drwxr-xr-x   3 nfarrar staff  102 Feb 28 07:37 '$XDG_CACHE_HOME'
...
```



Discussion:

Resolving patch:
diff --git a/cookiecutter/config.py b/cookiecutter/config.py
--- a/cookiecutter/config.py
+++ b/cookiecutter/config.py
@@ -31,6 +31,13 @@
 }
 
 
+def _expand_path(path):
+    """Expand both environment variables and user home in the given path."""
+    path = os.path.expandvars(path)
+    path = os.path.expanduser(path)
+    return path
+
+
 def get_config(config_path):
     """
     Retrieve the config from the specified path, returning it as a config dict.
@@ -52,6 +59,12 @@ def get_config(config_path):
     config_dict = copy.copy(DEFAULT_CONFIG)
     config_dict.update(yaml_dict)
 
+    raw_replay_dir = config_dict['replay_dir']
+    config_dict['replay_dir'] = _expand_path(raw_replay_dir)
+
+    raw_cookies_dir = config_dict['cookiecutters_dir']
+    config_dict['cookiecutters_dir'] = _expand_path(raw_cookies_dir)
+
     return config_dict
 
 


Test patch:
diff --git a/tests/test-config/config-expand-user.yaml b/tests/test-config/config-expand-user.yaml
new file mode 100644
--- /dev/null
+++ b/tests/test-config/config-expand-user.yaml
@@ -0,0 +1,2 @@
+cookiecutters_dir: "~/templates"
+replay_dir: "~/replay-files"
diff --git a/tests/test-config/config-expand-vars.yaml b/tests/test-config/config-expand-vars.yaml
new file mode 100644
--- /dev/null
+++ b/tests/test-config/config-expand-vars.yaml
@@ -0,0 +1,2 @@
+cookiecutters_dir: "$COOKIES/templates"
+replay_dir: "$COOKIES/replay-files"
diff --git a/tests/test_get_user_config.py b/tests/test_get_user_config.py
--- a/tests/test_get_user_config.py
+++ b/tests/test_get_user_config.py
@@ -141,3 +141,25 @@ def test_force_default_config(mocker):
 
     assert user_config == config.DEFAULT_CONFIG
     assert not spy_get_config.called
+
+
+def test_expand_user_for_directories_in_config(monkeypatch):
+    def _expanduser(path):
+        return path.replace('~', 'Users/bob')
+    monkeypatch.setattr('os.path.expanduser', _expanduser)
+
+    config_file = 'tests/test-config/config-expand-user.yaml'
+
+    user_config = config.get_user_config(config_file)
+    assert user_config['replay_dir'] == 'Users/bob/replay-files'
+    assert user_config['cookiecutters_dir'] == 'Users/bob/templates'
+
+
+def test_expand_vars_for_directories_in_config(monkeypatch):
+    monkeypatch.setenv('COOKIES', 'Users/bob/cookies')
+
+    config_file = 'tests/test-config/config-expand-vars.yaml'
+
+    user_config = config.get_user_config(config_file)
+    assert user_config['replay_dir'] == 'Users/bob/cookies/replay-files'
+    assert user_config['cookiecutters_dir'] == 'Users/bob/cookies/templates'