def generate_sanitized_options(name: str) -> Set[str]: sanitized_name = sanitize_option_name(name) return { choice for choice in ( f'--{sanitized_name}', f'--{sanitized_name}'.lower(), ) if ' ' not in choice }
def __init__(self, project: Project, step: Step, commit: Optional[str], environment: Optional[str] = None, image: Optional[str] = None, title: Optional[str] = None, watch: bool = False, download_directory: Optional[str] = None, environment_variables: Optional[Dict[str, str]] = None, tags: Optional[Sequence[str]] = None): """ Initialize the dynamic run command. :param environment_variables: :param project: Project object :param step: YAML step object :param commit: Commit identifier :param environment: Environment identifier (slug or UUID) :param environment_variables: Mapping of environment variables :param tags: Tags to apply :param watch: Whether to chain to `exec watch` afterwards :param image: Image override :param download_directory: Where to (if somewhere) to download execution outputs (sync mode) """ assert isinstance(step, Step) self.project = project self.step = step self.commit = commit self.environment = environment self.image = image self.watch = bool(watch) self.download_directory = download_directory self.title = title self.environment_variables = dict(environment_variables or {}) self.tags = list(tags or []) super().__init__( name=sanitize_option_name(step.name.lower()), callback=self.execute, epilog= 'Multiple files per input: --my-input=myurl --my-input=myotherurl', add_help_option=True, ) self.params.append( click.Option( ['--parameter-file'], type=click.Path(exists=True, dir_okay=False), help='Read parameter values from JSON/YAML file', )) for parameter in step.parameters.values(): self.params.append(self.convert_param_to_option(parameter)) for input in step.inputs.values(): self.params.append(self.convert_input_to_option(input)) for name, value in step.environment_variables.items(): if name not in self.environment_variables: self.environment_variables[name] = value.default
def _process_parameters(self, parameters: Dict[str, Any], parameter_file: Optional[str]) -> None: if parameter_file: parameter_file_data = read_data_file(parameter_file) if not isinstance(parameter_file_data, dict): raise CLIException( 'Parameter file could not be parsed as a dictionary') for name, parameter in self.step.parameters.items(): # See if we can match the name or the sanitized name to an option for key in (name, sanitize_option_name(name)): if key not in parameter_file_data: continue value = parameter_file_data.pop(key) type = self.parameter_type_map.get(parameter.type, click.STRING) value = type.convert(value, param=None, ctx=None) parameters[name] = value if parameter_file_data: # Not everything was popped off unparsed_parameter_names = ', '.join( sorted(str(k) for k in parameter_file_data)) warn( f'Parameters ignored in parameter file: {unparsed_parameter_names}' ) missing_required_parameters = set() for name, parameter in self.step.parameters.items(): if name in parameters: # Clean out default-less flag parameters whose value would be None if parameter.type == 'flag' and parameters[name] is None: del parameters[name] else: required = (parameter.default is None and not parameter.optional) if required: missing_required_parameters.add(name) if missing_required_parameters: raise CLIException( f'Required parameters missing: {missing_required_parameters}')
def test_sanitize_option_name(): assert sanitize_option_name('Name With Space') == 'Name-With-Space' assert sanitize_option_name( 'Name With Spaces. And Dots.') == 'Name-With-Spaces-And-Dots' assert sanitize_option_name('äää') == 'aaa'