def _install_into_directory(os_services: OsServices, src_file_path: pathlib.Path, dst_file_name: str, dst_container_path: pathlib.Path): target = dst_container_path / dst_file_name if target.exists(): raise HardErrorException( failure_details.FailureDetailsRenderer( failure_details.FailureDetails.new_message( text_docs.single_line( str_constructor.FormatMap( '{dst} already exists: {target}', { 'dst': instruction_arguments.DESTINATION_PATH_ARGUMENT.name, 'target': target, })) ) ) ) src = str(src_file_path) dst = str(target) if src_file_path.is_dir(): os_services.copy_tree__preserve_as_much_as_possible(src, dst) else: os_services.copy_file__preserve_as_much_as_possible(src, dst)
def _err_msg(path: str, header_tmpl: str) -> TextRenderer: header = str_constructor.FormatMap(header_tmpl, _FORMAT_MAP) return rend_comb.SingletonSequenceR( header_blocks.w_details( header, text_docs.minor_blocks_of_string_lines([path]) ) )
def os_exception_error_message(ex: OSError) -> TextRenderer: return blocks.MajorBlocksOfSingleLineObject( line_objects.PreFormattedString( str_constructor.FormatMap( _OS_EXCEPTION_ERROR_MESSAGE, { 'msg': ex.strerror, 'errno': ex.errno, 'filename': ex.filename, 'filename2': ex.filename2, })))
def _raise_he__single_line( format_str: str, format_map: Mapping[str, ToStringObject], ex: Exception, ): raise HardErrorException( failure_details.FailureDetailsRenderer( FailureDetails.new_message( text_docs.single_line( str_constructor.FormatMap(format_str, format_map)), ex)))
def _str_constructor_w_format_map( self, template: str, extra_format_map: Dict[str, Any] = None, ) -> StringConstructor: format_map = self.error_message_format_map if extra_format_map: format_map = dict( list(self.error_message_format_map.items()) + list(extra_format_map.items())) return str_constructor.FormatMap(template, format_map)
def _actor_info_block(actor_name: str) -> Renderer[MinorBlock]: return blocks.MinorBlockOfSingleLineObject( line_objects.StringLineObject( str_constructor.FormatMap( '{actor:/u} "{actor_name}"', { 'actor': concepts.ACTOR_CONCEPT_INFO.name, 'actor_name': actor_name, } ) ) )
def validate_pre_sds_if_applicable(self, hds: HomeDs) -> Optional[TextRenderer]: if self.path_str == '': return text_docs.single_line(_EMPTY_FILE_NAME) path = PurePosixPath(self.path_str) if path.is_absolute(): return text_docs.single_line( str_constructor.FormatMap( 'A {FILE_NAME} must not be absolute: {path}', { 'FILE_NAME': syntax.FILE_NAME.name, 'path': str(path), })) return None
def _get_exit_code(self) -> int: sds = self._sds try: f = sds.result.exitcode_file.open() except IOError: rel_path = sds.relative_to_sds_root(sds.result.exitcode_file) err_msg = text_docs.single_line( str_constructor.FormatMap( 'Cannot read {exit_code} from file {file}', { 'exit_code': texts.ATTRIBUTE__EXIT_CODE, 'file': rel_path, })) raise HardErrorException(err_msg) try: contents = f.read() except IOError: raise HardErrorException( text_docs.single_line( str_constructor.Concatenate([ _FAILED_TO_READ_CONTENTS_FROM, sds.result.exitcode_file, ]))) finally: f.close() try: return int(contents) except ValueError: msg = text_docs.single_line( str_constructor.FormatMap( 'The contents of the file for {exit_code} ("{file}") is not an integer: "{contents}"', { 'exit_code': texts.ATTRIBUTE__EXIT_CODE, 'file': sds.result.exitcode_file, 'contents': contents, })) raise HardErrorException(msg)
def _file_exists_but_must_also_satisfy_file_matcher( self) -> pfh.PassOrFailOrHardError: matching_result = self._matches_file_matcher_for_expectation_type() if matching_result.value: return pfh.new_pfh_pass() else: err_msg = rend_comb.SequenceR([ path_err_msgs.line_header_block__primitive( str_constructor.FormatMap( 'Existing {PATH} does not satisfy {FILE_MATCHER}', _EXISTING_PATH_FAILURE_FORMAT_MAP), self.described_path.describer, ), rendering__node_bool.BoolTraceRenderer(matching_result.trace), ]) return pfh.new_pfh_fail(err_msg)
AccumulatedComponents.empty(), ) class _ParseAsCommand(ParserFromTokenParserBase[CommandSdv]): def __init__(self): super().__init__(consume_last_line_if_is_at_eol_after_parse=False) self._arguments_parser = parse_arguments.parser() def parse_from_token_parser(self, parser: TokenParser) -> CommandSdv: program_name = parse_string.parse_string_from_token_parser( parser, _PARSE_NAME_CONF) arguments = self._arguments_parser.parse_from_token_parser(parser) return CommandSdv(CommandDriverSdvForSystemProgram(program_name), arguments) _PROGRAM_NAME_STRING_REFERENCES_RESTRICTION = is_string__all_indirect_refs_are_strings( text_docs.single_pre_formatted_line_object( str_constructor.FormatMap( 'A program name must be defined in terms of {string_type}.', { 'string_type': define_symbol.TYPE_W_STR_RENDERING_INFO_DICT[ WithStrRenderingType.STRING].identifier }, ))) _PARSE_NAME_CONF = parse_string.Configuration( 'NAME', _PROGRAM_NAME_STRING_REFERENCES_RESTRICTION)
from exactly_lib.type_val_prims.files_source.files_source import FilesSource from exactly_lib.util.description_tree import details from exactly_lib.util.description_tree.renderer import DetailsRenderer from exactly_lib.util.description_tree.tree import Detail from exactly_lib.util.render import combinators as rend_comb from exactly_lib.util.str_ import str_constructor from exactly_lib.util.symbol_table import SymbolTable from .. import syntax from ..file_maker import FileMakerAdv, FileMakerDdv, FileMakerSdv, FileMaker FILE_NAME_STRING_REFERENCES_RESTRICTION = reference_restrictions.is_string__all_indirect_refs_are_strings( text_docs.single_pre_formatted_line_object( str_constructor.FormatMap( 'A {file_name} must be defined in terms of {string_type}.', { 'file_name': syntax.FILE_NAME.name, 'string_type': syntax_elements.STRING_SYNTAX_ELEMENT.singular_name }, ) ) ) class FileSpecification(WithDetailsDescription): def __init__(self, file_name: str, file_maker: FileMaker, ): self.name = file_name self.maker = file_maker
_ARGUMENTS__LINE_NUMS = [ a.Single(a.Multiplicity.MANDATORY, names.LINE_NUMBERS_FILTER_OPTION), a.Single(a.Multiplicity.ONE_OR_MORE, a.Named(names.RANGE_EXPR_SED_NAME)) ] _MATCHER_ARGUMENT = a.Named('MATCHER') _RANGE_LIMIT_SEPARATOR = ':' _RANGE_EXPR_REFERENCE_RESTRICTIONS = is_string__all_indirect_refs_are_strings( text_docs.single_pre_formatted_line_object( str_constructor.FormatMap( 'A {RANGE} must be made up of just {string_type} values.', { 'RANGE': names.RANGE_EXPR_SED_NAME, 'string_type': help_texts.ANY_TYPE_INFO_DICT[ValueType.STRING].identifier }))) class SyntaxDescription( grammar.PrimitiveDescriptionWithNameAsInitialSyntaxToken): def __init__(self): self._tp = TextParser({ 'MATCHER': _MATCHER_ARGUMENT.name, '_LINE_MATCHER_': syntax_elements.LINE_MATCHER_SYNTAX_ELEMENT.singular_name, 'FIRST_LINE_NUMBER': line_matcher_type.FIRST_LINE_NUMBER,
def parse(self, token_parser: TokenParser) -> IntegerSdv: string_sdv = self._string_parser.parse(token_parser) return integer_sdv.IntegerSdv(string_sdv, self._custom_integer_restriction) def validator_for_non_negative(actual: int) -> Optional[TextRenderer]: if actual < 0: return expected_found.unexpected_lines( _NON_NEGATIVE_INTEGER_ARGUMENT_DESCRIPTION, str(actual)) return None _NON_NEGATIVE_INTEGER_ARGUMENT_DESCRIPTION = 'An integer >= 0' _REFERENCE_RESTRICTIONS = is_string__all_indirect_refs_are_strings( text_docs.single_pre_formatted_line_object( str_constructor.FormatMap( 'The {INTEGER} argument must be made up of just {string_type} values.', { 'INTEGER': syntax_elements.INTEGER_SYNTAX_ELEMENT.argument.name, 'string_type': help_texts.ANY_TYPE_INFO_DICT[ValueType.STRING].identifier }))) _STRING_PARSER_CONFIGURATION = parse_string.Configuration( syntax_elements.INTEGER_SYNTAX_ELEMENT.singular_name, _REFERENCE_RESTRICTIONS, )
is_at_eol_or_end_of_set() return file_name, None ret_val = [] while not tokens.has_valid_head_matching(_TOKEN_IS_SET_END): ret_val.append(parse_element()) return ret_val _TOKEN_IS_SET_END = token_matchers.is_unquoted_and_equals(syntax.LITERAL_END) _FILE_NAME_STRING_REFERENCES_RESTRICTION = is_string__all_indirect_refs_are_strings( text_docs.single_pre_formatted_line_object( str_constructor.FormatMap( 'A file name must be defined in terms of {string_type}.', {'string_type': syntax_elements.STRING_SYNTAX_ELEMENT.singular_name}, ) ) ) _FILE_NAME_STRING_CONFIGURATION = parse_string.Configuration( syntax.FILE_NAME.name, _FILE_NAME_STRING_REFERENCES_RESTRICTION, ) _MESSAGE_FACTORY = MessageFactory({ 'FILES_CONDITION': syntax_elements.FILES_CONDITION_SYNTAX_ELEMENT.singular_name, }) _FILE_NAME_OR_SET_END = 'FILE-NAME or ' + syntax.END_BRACE__FOR_FORMAT_STRINGS _HEADER = """\
'FILE_NAME': syntax.FILE_NAME.name, 'path': str(path), })) return None def validate_post_sds_if_applicable( self, tcds: TestCaseDs) -> Optional[TextRenderer]: return None _FORMAT_MAP = { 'FILE_NAME': syntax.FILE_NAME.name, 'string': misc_texts.PLAIN_STRING, } _EMPTY_FILE_NAME = str_constructor.FormatMap( 'A {FILE_NAME} must not be the empty {string}.', _FORMAT_MAP, ) TSD = TypeVar('TSD', bound=WithNodeDescription) class _Describer(Generic[TSD], DetailsRenderer): def __init__(self, files: Mapping[PurePosixPath, Optional[TSD]]): self._files = files def render(self) -> Sequence[Detail]: return self._renderer().render() def _entries(self) -> Sequence[Tuple[Renderer[str], Optional[TSD]]]: files = self._files return [(string_rendering.of_to_string_object(fn), files[fn])
self._string_source = string_source self._tcds = tcds def validate(self) -> Optional[TextRenderer]: mb_str_src_err_msg_renderer = self._string_source.validator.validate_post_sds_if_applicable( self._tcds) return (None if mb_str_src_err_msg_renderer is None else rend_comb.ConcatenationR([ text_docs.single_line(_STDIN_VALIDATION_ERROR_HEADER), rend_comb.Indented(mb_str_src_err_msg_renderer), ])) def resolve(self, environment: ApplicationEnvironment) -> StringSource: return self._string_source.value_of_any_dependency( self._tcds).primitive(environment) _STDIN_VALIDATION_ERROR_HEADER = str_constructor.FormatMap( '{stdin} set in {phase_setup}:', { 'stdin': misc_texts.STDIN.capitalize(), 'phase_setup': phase_infos.SETUP.name.syntax, }) _NOTES = """\ If the {atc} is a {PROGRAM} that itself defines {stdin}, then the {stdin} set here is appended to the {stdin} defined by the {PROGRAM}. (This requires that the {actor} is {run_program_actor}.) """