Source code for cookiecutter.prompt

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
cookiecutter.prompt
---------------------

Functions for prompting the user for project info.
"""

from collections import OrderedDict

import click
from past.builtins import basestring

from future.utils import iteritems
from jinja2.environment import Environment


[docs]def read_user_variable(var_name, default_value): """Prompt the user for the given variable and return the entered value or the given default. :param str var_name: Variable of the context to query the user :param default_value: Value that will be returned if no input happens """ # Please see http://click.pocoo.org/4/api/#click.prompt return click.prompt(var_name, default=default_value)
[docs]def read_user_yes_no(question, default_value): """Prompt the user to reply with 'yes' or 'no' (or equivalent values). Note: Possible choices are 'true', '1', 'yes', 'y' or 'false', '0', 'no', 'n' :param str question: Question to the user :param default_value: Value that will be returned if no input happens """ # Please see http://click.pocoo.org/4/api/#click.prompt return click.prompt( question, default=default_value, type=click.BOOL )
[docs]def read_user_choice(var_name, options): """Prompt the user to choose from several options for the given variable. The first item will be returned if no input happens. :param str var_name: Variable as specified in the context :param list options: Sequence of options that are available to select from :return: Exactly one item of ``options`` that has been chosen by the user """ # Please see http://click.pocoo.org/4/api/#click.prompt if not isinstance(options, list): raise TypeError if not options: raise ValueError choice_map = OrderedDict( (u'{}'.format(i), value) for i, value in enumerate(options, 1) ) choices = choice_map.keys() default = u'1' choice_lines = [u'{} - {}'.format(*c) for c in choice_map.items()] prompt = u'\n'.join(( u'Select {}:'.format(var_name), u'\n'.join(choice_lines), u'Choose from {}'.format(u', '.join(choices)) )) user_choice = click.prompt( prompt, type=click.Choice(choices), default=default ) return choice_map[user_choice]
[docs]def render_variable(env, raw, cookiecutter_dict): if not isinstance(raw, basestring): raw = str(raw) template = env.from_string(raw) rendered_template = template.render(cookiecutter=cookiecutter_dict) return rendered_template
[docs]def prompt_choice_for_config(cookiecutter_dict, env, key, options, no_input): """Prompt the user which option to choose from the given. Each of the possible choices is rendered beforehand. """ rendered_options = [ render_variable(env, raw, cookiecutter_dict) for raw in options ] if no_input: return rendered_options[0] return read_user_choice(key, rendered_options)
[docs]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 = {} env = Environment() for key, raw in iteritems(context[u'cookiecutter']): if key.startswith(u'_'): cookiecutter_dict[key] = raw continue if isinstance(raw, list): # We are dealing with a choice variable val = prompt_choice_for_config( cookiecutter_dict, env, key, raw, no_input ) else: # 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 return cookiecutter_dict