mirror of
https://github.com/wassname/cookiecutter-data-science.git
synced 2026-06-27 21:21:44 +08:00
1fe968d24e
* 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>
123 lines
4.3 KiB
Python
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
|