#!/usr/bin/env python3 """ Silique (https://www.silique.fr) Copyright (C) 2024 distribued with GPL-2 or later license This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA """ from .helper import get_rougail_environment_var, get_rougail_environment_dict from rougail.object_model import CONVERT_OPTION from rougail.config import RougailConfig from tiramisu.error import ValueOptionError class RougailUserDataEnvironment: def __init__(self, config: 'Config', *, rougailconfig: RougailConfig=None, ): self.config = config if rougailconfig is None: rougailconfig = RougailConfig user_data = rougailconfig['step.user_data'] if 'environment' not in user_data: user_data.append('environment') rougailconfig['step.user_data'] = user_data user_data = rougailconfig['step.user_data'] if 'environment' not in user_data: raise Exception('environment is not set in step.user_data') self.rougailconfig = rougailconfig self.errors = [] self.warnings = [] def run(self): self.config.property.read_write() if self.rougailconfig['environment.mandatory']: current_titles = [] while True: mandatories = self.config.value.mandatory() if not mandatories: break mandatory = mandatories[0] path = mandatory.path() if '.' in path: current_config = self.config for idx, p in enumerate(path.split('.')[0:-1]): current_config = current_config.option(p) if idx < len(current_titles): if current_titles[idx] == p: continue current_titles = current_titles[0:idx] current_titles.append(p) self.print(current_config.description(), idx) self.display_environment(mandatory) else: self.parse(self.config) self.config.property.read_only() def parse(self, config, title_level=0): for option in config: if option.isoptiondescription(): self.print(option.description(), title_level) self.parse(option, title_level + 1) else: self.display_environment(option) def print(self, title, title_level): print(' ' * title_level + '📂 ' + title, 'bold') def display_environment(self, option): kwargs = {} option_type = option.information.get('type') isdefault = option.owner.isdefault() default = option.value.get() ismulti = option.ismulti() type_obj = None # here we retrieve the conversion func of the considered type # carefull, it could be None -> in this case, do nothing type_obj = CONVERT_OPTION.get(option_type, {}).get("func") # rougail_environment_var = get_rougail_environment_var() option_name = option.path() if option_name in rougail_environment_var: if ismulti: option_bash_value = get_rougail_environment_dict()[option_name] # here we expect the bash option value of a multi to be coma separated: option_value = option_bash_value.split(",") if type_obj is not None: option_value_typed = [type_obj(opt) for opt in option_value] option.value.set(option_value_typed) else: option.value.set(option_value) else: option_bash_value = get_rougail_environment_dict()[option_name] if type_obj is not None: option.value.set(type_obj(option_bash_value)) else: option.value.set(option_bash_value) #RougailValidator.option = option #RougailValidator.option_type = {'type': option_type, # 'func': type_obj, # } #RougailValidator.ismulti = ismulti #if option_type == 'choice': # question_funtion = select # #RougailValidator.default = default # kwargs['choices'] = option.value.list() #elif option_type == 'boolean': # question_funtion = confirm #else: # question_funtion = text # kwargs['validate'] = RougailValidator #args = ['📓 ' + option.description()] #if ismulti: # kwargs['multiline'] = True # if default: # kwargs['default'] = "\n".join(default) #elif default is not None: # kwargs['default'] = default #value = RougailValidator().convert_value(question_funtion(*args, **kwargs).ask(), False) #if isdefault and value == default: # option.value.reset() #else: # option.value.set(value) #class RougailValidator(Validator): # def validate(self, document): # return self.convert_value(document.text) # # def convert_value(self, # document, # validate=True, # ): # if not self.ismulti: # value = self._convert_a_value(document, document, validate) # else: # value = [] # if document is not None: # for val in document.strip().split('\n'): # val = self._convert_a_value(val, document, validate) # if val is not None: # value.append(val) # if validate: # try: # self.option.value.set(value) # except ValueOptionError as err: # err.prefix = '' # raise ValidationError( # message=str(err), # cursor_position=len(document), # ) # return value # # def _convert_a_value(self, value, document, validate): # if value is None: # if self.option_type['type'] == 'choice': # return self.default # return # if isinstance(value, str): # value = value.strip() # if value == '': # if validate and "mandatory" in self.option.property.get(): # raise ValidationError( # message=f"Value must not be empty", # cursor_position=len(document), # ) # return # if self.option_type['func']: # try: # return self.option_type['func'](value) # except: # raise ValidationError( # message=f"Not a valid {self.option_type['type']}", # cursor_position=len(document), # ) # return value