# Path: makeapp/appconfig.py
# class Config(metaclass=ConfigMeta):
#     """Base for application template configuration."""
# 
#     parent_template: List[str] = None
#     """Parent template names."""
# 
#     cleanup: List[str] = None
#     """Paths to cleanup after rollout."""
# 
#     def __init__(self, app_template: 'AppTemplate'):
#         """
# 
#         :param app_template:
# 
#         """
#         self.app_template = app_template
#         self.logger = app_template.maker.logger
# 
#         settings = {}
# 
#         for key, val in self.__class__.__dict__.items():
# 
#             if isinstance(val, ConfigSetting):
#                 settings[f'{app_template.name}_{key}'] = val
# 
#         self.settings = settings
# 
#     def hook_configure(self):
#         """Executed on rollout configuration."""
# 
#         settings_conf = self.settings
# 
#         if not settings_conf:
#             return
# 
#         app_template = self.app_template
#         settings_current = app_template.maker.settings
#         settings_gathered = {}
#         advertise_template = True
# 
#         for setting_name, settings_obj in settings_conf.items():
# 
#             current_value = settings_current.get(setting_name)
# 
#             if current_value is None:
# 
#                 if advertise_template:
#                     click.secho(
#                         f"Gathering settings for '{app_template.name}' application template ...",
#                         fg='blue'
#                     )
#                     advertise_template = False
# 
#                 current_value = click.prompt(
#                     f'{settings_obj.title} ({setting_name})',
#                     default=settings_obj.default,
#                     type=settings_obj.type,
#                 )
# 
#                 settings_gathered[setting_name] = current_value
# 
#         app_template.maker.update_settings(settings_gathered)
# 
#     def print_banner(self, text: str):
#         """Prints out a banner with the given text.
# 
#         :param text:
# 
#         """
#         max_line_len = max(map(len, text.splitlines()))
#         text = text + '\n' + '=' * max_line_len + '\n'
# 
#         self.logger.warning(text)
#         sleep(1)
# 
#     def hook_rollout_init(self):
#         """Executed on skeleton rollout initialization."""
# 
#     def hook_rollout_pre(self):
#         """Executed before application skeleton rollout."""
# 
#     def hook_rollout_post(self):
#         """Executed after application skeleton rollout."""
#         cleanup = self.cleanup or []
# 
#         for path in cleanup:
#             path = Path(path).absolute()
#             self.logger.info(f'Cleanup {path} ...')
#             rmtree(path, ignore_errors=True)
# 
# Path: makeapp/exceptions.py
# class AppMakerException(MakeappException):
#     """Basic AppMaker related exception."""


import importlib.util
import os
from typing import Type, Dict, Tuple
from .appconfig import Config
from .exceptions import AppMakerException
    from .appmaker import AppMaker
        )

        app_template = AppTemplate(
            maker=maker,
            name=name,
            path=path,
            parent=parent,
        )

        maker.app_templates.append(app_template)

        if app_template.is_default:
            maker.app_template_default = app_template

        return app_template

    @classmethod
    def _find(cls, name_or_path: str, search_paths: Tuple[str, ...]) -> Tuple[str, str]:
        """Searches a template by it's name or in path.
        Returns a tuple (template_name, template_path)

        :param name_or_path:
        :param search_paths:

        """
        for supposed_path in search_paths:
            if '/' in supposed_path and os.path.exists(supposed_path):
                path = str(os.path.abspath(supposed_path))
                return path.split('/')[-1], path


# Path: makeapp/appconfig.py
# class Config(metaclass=ConfigMeta):
#     """Base for application template configuration."""
# 
#     parent_template: List[str] = None
#     """Parent template names."""
# 
#     cleanup: List[str] = None
#     """Paths to cleanup after rollout."""
# 
#     def __init__(self, app_template: 'AppTemplate'):
#         """
# 
#         :param app_template:
# 
#         """
#         self.app_template = app_template
#         self.logger = app_template.maker.logger
# 
#         settings = {}
# 
#         for key, val in self.__class__.__dict__.items():
# 
#             if isinstance(val, ConfigSetting):
#                 settings[f'{app_template.name}_{key}'] = val
# 
#         self.settings = settings
# 
#     def hook_configure(self):
#         """Executed on rollout configuration."""
# 
#         settings_conf = self.settings
# 
#         if not settings_conf:
#             return
# 
#         app_template = self.app_template
#         settings_current = app_template.maker.settings
#         settings_gathered = {}
#         advertise_template = True
# 
#         for setting_name, settings_obj in settings_conf.items():
# 
#             current_value = settings_current.get(setting_name)
# 
#             if current_value is None:
# 
#                 if advertise_template:
#                     click.secho(
#                         f"Gathering settings for '{app_template.name}' application template ...",
#                         fg='blue'
#                     )
#                     advertise_template = False
# 
#                 current_value = click.prompt(
#                     f'{settings_obj.title} ({setting_name})',
#                     default=settings_obj.default,
#                     type=settings_obj.type,
#                 )
# 
#                 settings_gathered[setting_name] = current_value
# 
#         app_template.maker.update_settings(settings_gathered)
# 
#     def print_banner(self, text: str):
#         """Prints out a banner with the given text.
# 
#         :param text:
# 
#         """
#         max_line_len = max(map(len, text.splitlines()))
#         text = text + '\n' + '=' * max_line_len + '\n'
# 
#         self.logger.warning(text)
#         sleep(1)
# 
#     def hook_rollout_init(self):
#         """Executed on skeleton rollout initialization."""
# 
#     def hook_rollout_pre(self):
#         """Executed before application skeleton rollout."""
# 
#     def hook_rollout_post(self):
#         """Executed after application skeleton rollout."""
#         cleanup = self.cleanup or []
# 
#         for path in cleanup:
#             path = Path(path).absolute()
#             self.logger.info(f'Cleanup {path} ...')
#             rmtree(path, ignore_errors=True)
# 
# Path: makeapp/exceptions.py
# class AppMakerException(MakeappException):
#     """Basic AppMaker related exception."""


# Path: makeapp/apptemplate.py
import importlib.util
import os
from typing import Type, Dict, Tuple
from .appconfig import Config
from .exceptions import AppMakerException
    from .appmaker import AppMaker

        )

        app_template = AppTemplate(
            maker=maker,
            name=name,
            path=path,
            parent=parent,
        )

        maker.app_templates.append(app_template)

        if app_template.is_default:
            maker.app_template_default = app_template

        return app_template

    @classmethod
    def _find(cls, name_or_path: str, search_paths: Tuple[str, ...]) -> Tuple[str, str]:
        """Searches a template by it's name or in path.
        Returns a tuple (template_name, template_path)

        :param name_or_path:
        :param search_paths:

        """
        for supposed_path in search_paths:
            if '/' in supposed_path and os.path.exists(supposed_path):
                path = str(os.path.abspath(supposed_path))
                return path.split('/')[-1], path


        raise AppMakerException(