Files
Peter Bull 1fe968d24e [WIP] New version with cleaner options (#162)
* WIP - New version with cleaner options

* Fix find-replace error (#177)

* Remove unnecessary .gitkeep

* Remove unused tox.ini

* Split reqs into dev/non-dev

* Add basic packages support

* Add tests for testing environment creation and requirements

* Set up CI with Azure Pipelines (#194)

* Change archived asciinema example (#163)

* Change archived asciinema example

* Update README.md

Fix Asciinema powerline error

* Update docs to show updated asciinema example

* Added source and destination to Make data target (#169)

* Fix broken Airflow link (#182)

* Fixed: Typo in Makefile (#184)

Fixed typo in Makefile, section "Set up python interpreter environment": intalled --> installed

* Set up CI with Azure Pipelines

[skip ci]

* Update azure-pipelines.yml for Azure Pipelines

* Update azure-pipelines.yml for Azure Pipelines

* Update azure-pipelines.yml for Azure Pipelines

* str paths for windows support

* handle multiple data providers (#199)

* Add missing env directory bin/activate path

* Remove version from PYTHON_INTERPRETER command

* Search for virtualenvwrapper.sh path if executable not found

* Try chardet for character encoding detection

* Specify python and virtualenv binaries for virtualenvwrapper

* Add shebang to virtualenvwrapper.sh

* Diagnostic

* Try virtualenvwrapper-win

* Set encoding if detected None

* Fixes to Mac and Windows tests on Azure pipelines (#217)

* Temporarily comment out py36

* Update azure-pipelines.yml

* Fix tests on Windows and Mac (#1)

* Temporarily remove py37

* Update virtualenv_harness.sh

* put py37 back in

* Set encoding to utf-8

* Comment out rmvirtualenv

* Update test_creation.py

* Update virtualenv_harness.sh

* Add --show-capture

* Update azure-pipelines.yml

* Update azure-pipelines.yml

* Update test_creation.py

* Update virtualenv_harness.sh

* Update virtualenv_harness.sh

* Update virtualenv_harness.sh

* Update virtualenv_harness.sh

* Update Makefile

* Update virtualenv_harness.sh

* Update cookiecutter.json

* Update cookiecutter.json

* Update virtualenv_harness.sh

* Update Makefile

* Update Makefile

* Update Makefile

* Update virtualenv_harness.sh

* Update virtualenv_harness.sh

* Update virtualenv_harness.sh

* Update virtualenv_harness.sh

* Update virtualenv_harness.sh

* Update virtualenv_harness.sh

* Update virtualenv_harness.sh

* Update virtualenv_harness.sh

* Update Makefile

* Update Makefile

* Update Makefile

* Update Makefile

* Update virtualenv_harness.sh

* Update virtualenv_harness.sh

* Update virtualenv_harness.sh

* Update Makefile

* Update Makefile

* Update virtualenv_harness.sh

* Update Makefile

* Update virtualenv_harness.sh

* Update virtualenv_harness.sh

* Update test_creation.py

* Update azure-pipelines.yml

* Update virtualenv_harness.sh

* Update virtualenv_harness.sh

* Update virtualenv_harness.sh

* Update virtualenv_harness.sh

* Update cookiecutter.json

* Update conda_harness.sh

* Update conda_harness.sh

* Update conda_harness.sh

Co-authored-by: Eric Jalbert <ericmjalbert@users.noreply.github.com>
Co-authored-by: Jonathan Raviotta <jraviotta@users.noreply.github.com>
Co-authored-by: Wes Roach <wesr000@gmail.com>
Co-authored-by: Christopher Geis <16896724+geisch@users.noreply.github.com>
Co-authored-by: Peter Bull <pjbull@gmail.com>
Co-authored-by: Ian Preston <17241371+ianepreston@users.noreply.github.com>
Co-authored-by: Jay Qi <jayqi@users.noreply.github.com>
Co-authored-by: inchiosa <4316698+inchiosa@users.noreply.github.com>

* More graceful deprecation

* Make tests pass locally

* test version match installed version

* Remove unused imports

* Unremove used import

* Move to GH Actions

* Fix typo

* Test non-windows

* Add netlify configs

* Update suggestion to keep using deprecated cookiecutter template (#231)

* Add mkdocs requirements file to docs directory

* Try setting python version in runtime txt for netlify

* Trigger build

* Python 3.8 netlify

* Python 3.6 netlify

* Do not specify python runtime for netlify

* Use 3.7

This reverts commit 898d7d3cf6008e47e89ed607167fad7aee1e065e.

Co-authored-by: James Myatt <james@jamesmyatt.co.uk>
Co-authored-by: drivendata <info@drivendata.org>
Co-authored-by: Eric Jalbert <ericmjalbert@users.noreply.github.com>
Co-authored-by: Jonathan Raviotta <jraviotta@users.noreply.github.com>
Co-authored-by: Wes Roach <wesr000@gmail.com>
Co-authored-by: Christopher Geis <16896724+geisch@users.noreply.github.com>
Co-authored-by: Ian Preston <17241371+ianepreston@users.noreply.github.com>
Co-authored-by: Jay Qi <jayqi@users.noreply.github.com>
Co-authored-by: inchiosa <4316698+inchiosa@users.noreply.github.com>
Co-authored-by: Robert Gibboni <robert@drivendata.org>
2021-03-19 22:38:18 -07:00

123 lines
4.3 KiB
Python

from collections import OrderedDict
from pathlib import Path
from cookiecutter.exceptions import UndefinedVariableInTemplate
from cookiecutter.environment import StrictEnvironment
from cookiecutter.generate import generate_context
from cookiecutter.prompt import (prompt_choice_for_config, render_variable, read_user_variable, read_user_choice)
from jinja2.exceptions import UndefinedError
def _prompt_choice_and_subitems(cookiecutter_dict, env, key, options, no_input):
result = {}
# first, get the selection
rendered_options = [
render_variable(env, list(raw.keys())[0], cookiecutter_dict) for raw in options
]
if no_input:
selected = rendered_options[0]
else:
selected = read_user_choice(key, rendered_options)
selected_item = [list(c.values())[0] for c in options if list(c.keys())[0] == selected][0]
result[selected] = {}
# then, fill in the sub values for that item
if isinstance(selected_item, dict):
for subkey, raw in selected_item.items():
# We are dealing with a regular variable
val = render_variable(env, raw, cookiecutter_dict)
if not no_input:
val = read_user_variable(subkey, val)
result[selected][subkey] = val
elif isinstance(selected_item, list):
val = prompt_choice_for_config(
cookiecutter_dict, env, selected, selected_item, no_input
)
result[selected] = val
elif isinstance(selected_item, str):
result[selected] = selected_item
return result
def prompt_for_config(context, no_input=False):
"""
Prompts the user to enter new config, using context as a source for the
field names and sample values.
:param no_input: Prompt the user at command line for manual configuration?
"""
cookiecutter_dict = OrderedDict([])
env = StrictEnvironment(context=context)
# First pass: Handle simple and raw variables, plus choices.
# These must be done first because the dictionaries keys and
# values might refer to them.
for key, raw in context[u'cookiecutter'].items():
if key.startswith(u'_'):
cookiecutter_dict[key] = raw
continue
try:
if isinstance(raw, list):
if isinstance(raw[0], dict):
val = _prompt_choice_and_subitems(
cookiecutter_dict, env, key, raw, no_input
)
cookiecutter_dict[key] = val
else:
# We are dealing with a choice variable
val = prompt_choice_for_config(
cookiecutter_dict, env, key, raw, no_input
)
cookiecutter_dict[key] = val
elif not isinstance(raw, dict):
# We are dealing with a regular variable
val = render_variable(env, raw, cookiecutter_dict)
if not no_input:
val = read_user_variable(key, val)
cookiecutter_dict[key] = val
except UndefinedError as err:
msg = "Unable to render variable '{}'".format(key)
raise UndefinedVariableInTemplate(msg, err, context)
# Second pass; handle the dictionaries.
for key, raw in context[u'cookiecutter'].items():
try:
if isinstance(raw, dict):
# We are dealing with a dict variable
val = render_variable(env, raw, cookiecutter_dict)
if not no_input:
val = read_user_dict(key, val)
cookiecutter_dict[key] = val
except UndefinedError as err:
msg = "Unable to render variable '{}'".format(key)
raise UndefinedVariableInTemplate(msg, err, context)
return cookiecutter_dict
def generate_context_wrapper(*args, **kwargs):
''' Hardcoded in cookiecutter, so we override:
https://github.com/cookiecutter/cookiecutter/blob/2bd62c67ec3e52b8e537d5346fd96ebd82803efe/cookiecutter/main.py#L85
'''
# replace full path to cookiecutter.json with full path to ccds.json
kwargs['context_file'] = str(Path(kwargs['context_file']).with_name('ccds.json'))
parsed_context = generate_context(*args, **kwargs)
# replace key
parsed_context['cookiecutter'] = parsed_context['ccds']
del parsed_context['ccds']
return parsed_context