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] 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 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 return result
def test_click_invocation(mocker): prompt = mocker.patch("click.prompt") prompt.return_value = DEFAULT assert read_user_variable(VARIABLE, DEFAULT) == DEFAULT click.prompt.assert_called_once_with(VARIABLE, default=DEFAULT)
def _fetch_config_from_user_prompts( prompts: Dict[str, Any], cookiecutter_context: OrderedDict) -> Dict[str, str]: """Interactively obtains information from user prompts. Args: prompts: Prompts from prompts.yml. cookiecutter_context: Cookiecutter context generated from cookiecutter.json. Returns: Configuration for starting a new project. This is passed as ``extra_context`` to cookiecutter and will overwrite the cookiecutter.json defaults. """ # pylint: disable=import-outside-toplevel from cookiecutter.environment import StrictEnvironment from cookiecutter.prompt import read_user_variable, render_variable config: Dict[str, str] = dict() for variable_name, prompt_dict in prompts.items(): prompt = _Prompt(**prompt_dict) # render the variable on the command line cookiecutter_variable = render_variable( env=StrictEnvironment(context=cookiecutter_context), raw=cookiecutter_context[variable_name], cookiecutter_dict=config, ) # read the user's input for the variable user_input = read_user_variable(str(prompt), cookiecutter_variable) if user_input: prompt.validate(user_input) config[variable_name] = user_input return config
def test_click_invocation(mocker): prompt = mocker.patch('click.prompt') prompt.return_value = DEFAULT assert read_user_variable(VARIABLE, DEFAULT) == DEFAULT click.prompt.assert_called_once_with(VARIABLE, default=DEFAULT)
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 iteritems(context[u'cookiecutter']): 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 iteritems(context[u'cookiecutter']): 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 prompt_config(): project_name = prompt.read_user_variable( "Project Name", DEFAULT_CONFIGURATION["project_name"]) ci_cd = prompt_dict("Continuous Delivery", DEFAULT_CONFIGURATION["ci_cd"]) endpoint = prompt.read_user_variable("Jupyterhub Endpoint") authentication = prompt_dict("Authentication", DEFAULT_CONFIGURATION["authentication"]) provider = prompt_dict("Cloud Provider", DEFAULT_CONFIGURATION["providers"]) config = { "project_name": project_name, "provider": provider, "ci_cd": ci_cd, "endpoint": endpoint, } auth_config = { "auth": { "admin": { "access": True, "users": [] }, "whitelist": [] } } if authentication == "github": prompt_github_auth_config(auth_config) elif authentication == "auth0": prompt_auth0_config(auth_config) config["authentication"] = yaml.dumps(auth_config) if provider == "do": prompt_do_config(config) elif provider == "gcp": prompt_gcp_config(config) elif provider == "aws": prompt_aws_config(config) return config
def prompt_user(): # Prompt user for input for key, value in defaults.items(): if not key.startswith("_"): if isinstance(value, list): defaults[key] = prompt.read_user_choice(key, value) elif isinstance(value, str): defaults[key] = prompt.read_user_variable(key, value) # adjust defaults based on special conditions if key.endswith("import_type"): defaults["import"] = defaults["installed"][defaults[key]] elif key.endswith("import"): defaults["project_name"] = defaults[key] defaults["repository_name"] = ( defaults[key].replace(" ", "_") + "_Rainmeter_Skin" ) # promt user to pick skin to load if importing an installed skin if ( defaults["import_type"] == "Skin" and defaults["import"] != "Create a new skin" ): # now ask the user which skin to load on-install skin_configs = [] for dirpath, _, filenames in os.walk( defaults["_skins_path"] + os.sep + defaults[key] ): for f in filenames: if f.endswith(".ini"): skin_configs.append( dirpath.replace( defaults["_skins_path"] + os.sep, "", ) + os.sep + f ) defaults["_load_skin"] = prompt.read_user_choice( "skin to load", skin_configs ) elif key.endswith("project_name"): defaults["repository_name"] = ( defaults[key].replace(" ", "_") + "_Rainmeter_Skin" ) elif key.endswith("req_windows_version"): defaults["req_windows_version"] = defaults["_windows_version_alias"][defaults[key]] elif key.endswith("req_rainmeter_version"): # restrict windows version based on rainmeter version if float(defaults[key][:3]) >= 4.0: defaults["req_windows_version"].remove("Windows XP") defaults["req_windows_version"].remove("Windows Vista") if vcs.is_vcs_installed("git"): print("git is installed") init_commit = prompt.read_user_yes_no("Create initial commit? (y/n)", "y") if isinstance(init_commit, str): init_commit = True if init_commit == "y" else False defaults["_init_commit"] = init_commit
def test_click_invocation(mocker): """Test click function called correctly by cookiecutter. Test for string type invocation. """ prompt = mocker.patch('click.prompt') prompt.return_value = DEFAULT assert read_user_variable(VARIABLE, DEFAULT) == DEFAULT click.prompt.assert_called_once_with(VARIABLE, default=DEFAULT)
def _prompt_user_for_config( # pylint: disable=too-many-locals template_path: Path, checkout: str = None, directory: str = None) -> Dict[str, str]: """Prompt user in the CLI to provide configuration values for cookiecutter variables in a starter, such as project_name, package_name, etc. """ # pylint: disable=import-outside-toplevel from cookiecutter.prompt import read_user_variable, render_variable from cookiecutter.repository import determine_repo_dir # for performance reasons with tempfile.TemporaryDirectory() as tmpdir: temp_dir_path = Path(tmpdir).resolve() cookiecutter_repo, _ = determine_repo_dir( template=str(template_path), abbreviations=dict(), clone_to_dir=temp_dir_path, checkout=checkout, no_input=True, directory=directory, ) cookiecutter_dir = temp_dir_path / cookiecutter_repo prompts_yml = cookiecutter_dir / "prompts.yml" # If there is no prompts.yml, no need to ask user for input. if not prompts_yml.is_file(): return {} with open(prompts_yml) as config_file: prompts_dict = yaml.safe_load(config_file) cookiecutter_env = _prepare_cookiecutter_env(cookiecutter_dir) config: Dict[str, str] = dict() config["output_dir"] = str(Path.cwd().resolve()) for variable_name, prompt_dict in prompts_dict.items(): prompt = _Prompt(**prompt_dict) # render the variable on the command line cookiecutter_variable = render_variable( env=cookiecutter_env.env, raw=cookiecutter_env.context[variable_name], cookiecutter_dict=config, ) # read the user's input for the variable user_input = read_user_variable(str(prompt), cookiecutter_variable) if user_input: prompt.validate(user_input) config[variable_name] = user_input return config
def _run_prompts_for_user_input(prompts: Dict[str, Dict[str, str]], cookiecutter_dir: Path) -> Dict[str, str]: # pylint: disable=import-outside-toplevel from cookiecutter.prompt import read_user_variable, render_variable cookiecutter_env = _prepare_cookiecutter_env(cookiecutter_dir) config: Dict[str, str] = dict() for variable_name, prompt_dict in prompts.items(): prompt = _Prompt(**prompt_dict) # render the variable on the command line cookiecutter_variable = render_variable( env=cookiecutter_env.env, raw=cookiecutter_env.context[variable_name], cookiecutter_dict=config, ) # read the user's input for the variable user_input = read_user_variable(str(prompt), cookiecutter_variable) if user_input: prompt.validate(user_input) config[variable_name] = user_input return config
if __name__ == '__main__': from cookiecutter.prompt import read_user_variable, read_user_choice, read_repo_password from cookiecutter.main import cookiecutter context = {} context['project_name'] = read_user_variable('project_name', 'my_project_name') context['django_template'] = read_user_choice('django_template', ['django']) context['db_backend'] = read_user_choice('db_backend', ['mysql', 'postgresql']) context['db_password'] = read_repo_password('db_password') context['docker_compose_file_version'] = read_user_variable('docker_compose_file_version', '3.8') if context['db_backend'] == 'mysql': context['db_user'] = '******' elif context['db_backend'] == 'postgresql': context['db_user'] = '******' repo = 'https://github.com/otto-torino/webapp-boilerplate/' template = 'templates/base' output_dir = '.' cookiecutter(repo, no_input=True, extra_context=context, directory=template, output_dir=output_dir) template = f'templates/{context['django_template']}' output_dir = f'{output_dir}/{context['project_name']}' cookiecutter(repo, no_input=True, extra_context=context, directory=template, output_dir=output_dir)