Source code for cookiecutter.operators.checkbox

# -*- coding: utf-8 -*-

"""Operator plugin that inherits a base class and is made available through `type`."""
from __future__ import unicode_literals
from __future__ import print_function

import logging
from PyInquirer import prompt

from cookiecutter.operators import BaseOperator

logger = logging.getLogger(__name__)


[docs]class InquirerCheckboxOperator(BaseOperator): """ Operator for PyInquirer type prompts. Takes in three forms of `choices` inputs. 1. list of string 2. list of maps with all keys = `name` 3. list of maps with the key as the output, the value as displayed question :param message: String message to show when prompting. :param choices: A list of strings or list of k/v pairs per above description :param name: A key to insert the output value to. If not provided defaults to inserting into parent key :param qmark: A marker to select with like 😃 :return: List of answers """ type = 'checkbox' def __init__(self, *args, **kwargs): # noqa super(InquirerCheckboxOperator, self).__init__(*args, **kwargs) def _execute(self): # Fix the input choices if they don't have the pattern {'name': 'thing'} # and are just a list of strings if self.no_input: output = ( self.operator_dict['default'] if 'default' in self.operator_dict else [] ) return output if 'index' not in self.operator_dict: self.operator_dict['index'] = False choices_type = None for i, v in enumerate(self.operator_dict['choices']): if i != 0 and type(v) != choices_type: raise ValueError("All items need to be of the same type") choices_type = type(v) if choices_type == str: self.operator_dict['choices'] = [ {'name': x} if isinstance(x, str) else x for x in self.operator_dict['choices'] ] answer = self._run_prompt() if self.operator_dict['index']: return self.operator_dict['choices'].index(answer) else: return answer elif choices_type == dict: # This is the normal input to the operator ie # choices = ['name': 'stuff', 'name': 'things'] keys = list(list(i.keys())[0] for i in self.operator_dict['choices']) num_keys = list(dict.fromkeys(keys)) if len(num_keys) == 1 and keys[0] == 'name': return self._run_prompt() # Otherwise we expect to reindex the key as the output per this: # choices = ['stuff': 'How much stuff?', 'things': 'How many things?'] choices = [] for i in self.operator_dict['choices']: choices.append(i[list(i.keys())[0]]) # Fixing to the expected input choices {'name': 'stuff', 'name': ...} choices_dict = self.operator_dict['choices'] self.operator_dict['choices'] = [ {'name': x} if isinstance(x, str) else x for x in choices ] answer = self._run_prompt() # This is for reindexing the output output = [] for i, v in enumerate(choices_dict): val = list(v.keys())[0] if v[val] in answer: if self.operator_dict['index']: output.append(i) else: output.append(val) return output def _run_prompt(self): if 'name' not in self.operator_dict: self.operator_dict.update({'name': 'tmp'}) return prompt([self.operator_dict])['tmp'] else: return prompt([self.operator_dict])