def replace_placeholders(match: Match) -> str: """Regex file path match replacer.""" # Remove enclosing curly brackets specified_path = match.group(0)[1:-1] absolute_path = expand_path( path=Path(specified_path), config_directory=self.directory, ) if absolute_path in performed_compilations: # TODO: Is joining the right thing to do here? return ' '.join( [ str(path) for path in performed_compilations[absolute_path] ], ) else: logger.error( 'String placeholder {' + specified_path + '} ' f'could not be replaced. "{specified_path}" ' 'has not been compiled.', ) # Return the placeholder left alone return '{' + specified_path + '}'
def test_expand_path_method(test_config_directory): absolute_path = Path('/tmp/ast') tilde_path = Path('~/dir') relative_path = Path('test') assert expand_path( path=absolute_path, config_directory=Path('/what/ever'), ) == absolute_path assert expand_path( path=tilde_path, config_directory=Path('/what/ever'), ) == Path.home() / 'dir' assert expand_path( path=relative_path, config_directory=test_config_directory, ) == test_config_directory / 'test'
def _absolute_path(self, of: str) -> Path: """ Return absolute path from relative string path. :param of: Relative path. :return: Absolute path anchored to `self.directory`. """ return config.expand_path( path=Path(of), config_directory=self.directory, )
def __init__( self, name: str, module_config: ModuleConfigDict, module_directory: Path, replacer: Callable[[str], str] = lambda string: string, context_store: Context = Context(), global_modules_config: Optional[GlobalModulesConfig] = None, dry_run: bool = False, ) -> None: """ Initialize Module object with a section from a config dictionary. Section name must be [module/*], where * is the module name. In addition, the enabled option must be set to "true", or not set at all. module_config example: {'name': 'enabled': True, 'event_listener': {'type': 'weekday'}, 'on_startup': {'run': ['echo weekday is {event}']}, } """ self.name = name # The source directory for the module, determining how to interpret # relative paths in the module config self.directory = module_directory # All user string options should be processed by the replacer self.replace = replacer # Use static event_listener if no event_listener is specified self.event_listener: EventListener = \ event_listener_factory( module_config.get( 'event_listener', {'type': 'static'}, ), ) self.context_store = context_store # Move root actions to 'on_startup' block module_config = self.prepare_on_startup_block( module_name=self.name, module_config=module_config, ) # Create action block object for each available action block type action_blocks: ModuleActionBlocks = {'on_modified': {}} # type: ignore params = { 'module_name': self.name, 'directory': self.directory, 'replacer': self.interpolate_string, 'context_store': self.context_store, 'global_modules_config': global_modules_config, } # Create special case setup action block, it removes any action already # performed. action_blocks['on_setup'] = SetupActionBlock( action_block=module_config.get('on_setup', {}), **params, ) # Create normal action blocks for block_name in ('on_startup', 'on_event', 'on_exit'): action_blocks[block_name] = ActionBlock( # type: ignore action_block=module_config.get( # type: ignore block_name, {}, ), **params, ) for path_string, action_block_dict in module_config.get( 'on_modified', {}, ).items(): modified_path = expand_path( path=Path(path_string), config_directory=self.directory, ) action_blocks['on_modified'][modified_path] = \ ActionBlock( action_block=action_block_dict, **params, ) self.action_blocks = action_blocks requirements = cast_to_list(module_config.get('requires', [])) self.depends_on = tuple( # type: ignore requirement['module'] for requirement in requirements if 'module' in requirement )
def __init__( self, module_config: ModuleConfig, module_directory: Path, replacer: Callable[[str], str] = lambda string: string, context_store: compiler.Context = {}, ) -> None: """ Initialize Module object with a section from a config dictionary. Section name must be [module/*], where * is the module name. In addition, the enabled option must be set to "true", or not set at all. module_config example: {'module/name': 'enabled': True, 'event_listener': {'type': 'weekday'}, 'on_startup': {'run': ['echo weekday is {event}']}, } """ # Can only initialize one module at a time assert len(module_config) == 1 section: str = next(iter(module_config.keys())) self.name: str = section[7:] # The source directory for the module, determining how to interpret # relative paths in the module config self.directory = module_directory # All user string options should be processed by the replacer self.replace = replacer # Extract configuration content module_config_content: ModuleConfigDict = module_config[section] # Use static event_listener if no event_listener is specified self.event_listener: EventListener = \ event_listener_factory( module_config_content.get( 'event_listener', {'type': 'static'}, ), ) self.context_store = context_store # Create action block object for each available action block type action_blocks: ModuleActionBlocks = {'on_modified': {}} # type: ignore for block_name in ('on_startup', 'on_event', 'on_exit'): action_blocks[block_name] = ActionBlock( # type: ignore action_block=module_config_content.get( # type: ignore block_name, {}, ), directory=self.directory, replacer=self.interpolate_string, context_store=self.context_store, ) for path_string, action_block_dict \ in module_config_content.get('on_modified', {}).items(): modified_path = expand_path( path=Path(path_string), config_directory=self.directory, ) action_blocks['on_modified'][modified_path] = \ ActionBlock( action_block=action_block_dict, directory=self.directory, replacer=self.interpolate_string, context_store=self.context_store, ) self.action_blocks = action_blocks