Esempio n. 1
0
        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 + '}'
Esempio n. 2
0
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'
Esempio n. 3
0
    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,
        )
Esempio n. 4
0
    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
        )
Esempio n. 5
0
    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