Skip to content

Commit

Permalink
Fixing issues with test, container and py27 vs py36
Browse files Browse the repository at this point in the history
  • Loading branch information
Suszyński Krzysztof committed Jul 28, 2017
1 parent 87d96e6 commit 24049ea
Show file tree
Hide file tree
Showing 19 changed files with 236 additions and 216 deletions.
198 changes: 113 additions & 85 deletions puppeter/container.py
Expand Up @@ -28,13 +28,10 @@ def original_cls():
pass


NamedClass = Union[Type[T], Callable[[Any, Any], T], NamedBean]


def Named(bean_name):
def named_decorator(cls):

class __NamedBean(NamedBean, cls):
class NamedBeanImpl(NamedBean, cls):
def __init__(self, *args, **kwargs):
self.wrapped = cls(*args, **kwargs)

Expand All @@ -51,93 +48,17 @@ def __repr__(self):

def __getattr__(self, name):
return getattr(self.wrapped, name)
return __NamedBean
return NamedBeanImpl
return named_decorator


def bind(cls, impl_cls):
# type: (Type[T], Type[T]) -> None
beans = __get_all_beans(cls)
beans.append(__Bean(cls, impl_cls=impl_cls))


def bind_to_instance(cls, impl):
# type: (Type[T], T) -> None
beans = __get_all_beans(cls)
beans.append(__Bean(cls, impl=impl))


def get_all(cls, *args, **kwargs):
# type: (Type[T], Any, Any) -> Sequence[T]
beans = __get_all_beans(cls)
try:
return __instantinate_beans(beans, *args, **kwargs)
except Exception:
return tuple()


def get(cls, *args, **kwargs):
# type: (Type[T], Any, Any) -> T
beans = __get_all_beans(cls)
if len(beans) == 1:
return beans[0].impl(*args, **kwargs)
else:
impls = list(map(lambda bean: str(bean.impl_cls()), beans))
raise ValueError('Zero or more then one implementation found for class %s. '
'Found those implementations: %s. '
'Use @Named beans and get_named() function!' % (cls, impls))


def get_named(cls, bean_name, *args, **kwargs):
# type: (Type[T], str, Any, Any) -> T
for bean in __get_all_beans(cls):
if bean.name() == bean_name:
return bean.impl(*args, **kwargs)
raise ValueError('Bean named %s has not been found for class %s' % (bean_name, cls))


def get_all_with_name_starting_with(cls, name_prefix, *args, **kwargs):
# type: (Type[T], str, Any, Any) -> Sequence[T]
beans = []
for bean in __get_all_beans(cls):
name = bean.name()
if name is not None and name.startswith(name_prefix):
beans.append(bean)
return __instantinate_beans(beans, *args, **kwargs)


def get_bean(cls):
# type: (Type[T]) -> __Bean[T]
return __get_all_beans(cls)[0]


__ROOT_DIR = dirname(dirname(__file__))
__beans = {} # type: Dict[Type, MutableSequence[__Bean]]


def __instantinate_beans(beans, *args, **kwargs):
# type: (Sequence[__Bean[T]], Any, Any) -> Sequence[T]
impls = tuple(map(lambda bean: bean.impl(*args, **kwargs), beans)) # type: Sequence[T]
return impls


def __get_all_beans(cls):
# type: (Type[T]) -> MutableSequence[__Bean[T]]
try:
return __beans[cls]
except KeyError:
lst = [] # type: MutableSequence[__Bean[T]]
__beans[cls] = lst
return lst


class __Bean(Generic[T]):
class Bean(Generic[T]):
def __init__(self, cls, impl=None, impl_cls=None):
if impl is None and impl_cls is None:
raise Exception('20170707:164636')
self.__cls = cls # type: Type[T]
self.__impl = impl # type: T
self.__impl_cls = impl_cls # type: NamedClass[T]
self.__impl_cls = impl_cls # type: Union[Type[T], Callable[[Any, Any], T], NamedBean]

def __repr__(self):
name = self.name()
Expand All @@ -147,7 +68,7 @@ def __repr__(self):
return 'Bean of %s' % repr(self.impl_cls())

def impl_cls(self):
# type: () -> NamedClass[T]
# type: () -> Union[Type[T], Callable[[Any, Any], T], NamedBean]
if self.__impl is None and self.__impl_cls is not None:
return self.__impl_cls
else:
Expand All @@ -169,11 +90,118 @@ def impl(self, *args, **kwargs):
return self.__impl


class Container:

def __init__(self):
self.__beans = {} # type: Dict[Type, MutableSequence[Bean]]

def bind(self, cls, impl_cls):
# type: (Type[T], Type[T]) -> None
beans = self.__get_all_beans(cls)
beans.append(Bean(cls, impl_cls=impl_cls))

def bind_to_instance(self, cls, impl):
# type: (Type[T], T) -> None
beans = self.__get_all_beans(cls)
beans.append(Bean(cls, impl=impl))

def get_all(self, cls, *args, **kwargs):
# type: (Type[T], Any, Any) -> Sequence[T]
beans = self.__get_all_beans(cls)
try:
return self.__instantinate_beans(beans, *args, **kwargs)
except Exception:
return tuple()

def get(self, cls, *args, **kwargs):
# type: (Type[T], Any, Any) -> T
beans = self.__get_all_beans(cls)
if len(beans) == 1:
return beans[0].impl(*args, **kwargs)
else:
impls = list(map(lambda bean: str(bean.impl_cls()), beans))
raise ValueError('Zero or more then one implementation found for class %s. '
'Found those implementations: %s. '
'Use @Named beans and get_named() function!' % (cls, impls))

def get_named(self, cls, bean_name, *args, **kwargs):
# type: (Type[T], str, Any, Any) -> T
for bean in self.__get_all_beans(cls):
if bean.name() == bean_name:
return bean.impl(*args, **kwargs)
raise ValueError('Bean named %s has not been found for class %s' % (bean_name, cls))

def get_all_with_name_starting_with(self, cls, name_prefix, *args, **kwargs):
# type: (Type[T], str, Any, Any) -> Sequence[T]
beans = []
for bean in self.__get_all_beans(cls):
name = bean.name()
if name is not None and name.startswith(name_prefix):
beans.append(bean)
return self.__instantinate_beans(beans, *args, **kwargs)

def get_bean(self, cls):
# type: (Type[T]) -> Bean[T]
return self.__get_all_beans(cls)[0]

def __instantinate_beans(self, beans, *args, **kwargs):
# type: (Sequence[Bean[T]], Any, Any) -> Sequence[T]
impls = tuple(map(lambda bean: bean.impl(*args, **kwargs), beans)) # type: Sequence[T]
return impls

def __get_all_beans(self, cls):
# type: (Type[T]) -> MutableSequence[Bean[T]]
try:
return self.__beans[cls]
except KeyError:
lst = [] # type: MutableSequence[Bean[T]]
self.__beans[cls] = lst
return lst


app_container = Container()


def bind(cls, impl_cls):
# type: (Type[T], Type[T]) -> None
app_container.bind(cls, impl_cls)


def bind_to_instance(cls, impl):
# type: (Type[T], T) -> None
app_container.bind_to_instance(cls, impl)


def get_all(cls, *args, **kwargs):
# type: (Type[T], Any, Any) -> Sequence[T]
return app_container.get_all(cls, *args, **kwargs)


def get(cls, *args, **kwargs):
# type: (Type[T], Any, Any) -> T
return app_container.get(cls, *args, **kwargs)


def get_named(cls, bean_name, *args, **kwargs):
# type: (Type[T], str, Any, Any) -> T
return app_container.get_named(cls, bean_name, *args, **kwargs)


def get_all_with_name_starting_with(cls, name_prefix, *args, **kwargs):
# type: (Type[T], str, Any, Any) -> Sequence[T]
return app_container.get_all_with_name_starting_with(cls, name_prefix, *args, **kwargs)


def get_bean(cls):
return app_container.get_bean(cls)


def __load_modules(module_name):
import os
from os.path import join, abspath, isdir, exists
rootdir = dirname(dirname(__file__))

search = join(abspath(__ROOT_DIR), module_name.replace('.', os.sep))
search = join(abspath(rootdir), module_name.replace('.', os.sep))
lst = os.listdir(search)
modules = []
for d in lst:
Expand Down
5 changes: 4 additions & 1 deletion puppeter/domain/model/installer.py
Expand Up @@ -55,6 +55,9 @@ def is_after_4x(self):

@Named('gem')
class RubygemsInstaller(Installer):
def is_after_4x(self):
return True

def __init__(self):
Installer.__init__(self)
self.__version = None
Expand Down Expand Up @@ -202,7 +205,7 @@ def raw_options(self):
def read_raw_options(self, options):
try:
new_args = options['jvm_args']
self.__args.clear()
del self.__args[:]
self.__args.extend(new_args)
except KeyError:
pass
Expand Down
1 change: 1 addition & 0 deletions puppeter/persistence/service/commandscollector.py
@@ -1,3 +1,4 @@
from __future__ import absolute_import
import os
import re
import pkg_resources
Expand Down
1 change: 1 addition & 0 deletions puppeter/persistence/service/java.py
@@ -1,3 +1,4 @@
from __future__ import absolute_import
import re
import subprocess

Expand Down
7 changes: 3 additions & 4 deletions puppeter/persistence/service/os.py
@@ -1,10 +1,9 @@
from __future__ import absolute_import
import os
import distro
import platform
from typing import Sequence, Callable

import distro
from os.path import isfile

import puppeter.settings
from puppeter.domain.facter import Facter
from puppeter.domain.model.osfacts import OsFamily, OperatingSystem, \
Expand Down Expand Up @@ -71,7 +70,7 @@ def __calculate_docker_bool():


def __is_readable(file):
return isfile(file) and os.access(file, os.R_OK)
return os.path.isfile(file) and os.access(file, os.R_OK)


def __any(seq, predicate):
Expand Down
5 changes: 5 additions & 0 deletions puppeter/presentation/__init__.py
@@ -1,5 +1,10 @@
from puppeter import container
from puppeter.domain.gateway.answers import AnswersProcessor
from puppeter.presentation.answersprocessor import AnswersProcessorImpl
from puppeter.presentation.app import App
from puppeter.presentation.interactiveapp import InteractiveApp
from puppeter.presentation.unattendedapp import UnattendedApp

container.bind(AnswersProcessor, AnswersProcessorImpl)
container.bind(App, InteractiveApp)
container.bind(App, UnattendedApp)
7 changes: 5 additions & 2 deletions puppeter/presentation/answersprocessor.py
@@ -1,6 +1,8 @@
from argparse import Namespace
from typing import Sequence, List

from pip._vendor.packaging.markers import Op

import puppeter
from puppeter import container
from puppeter.domain.facter import Facter
Expand All @@ -9,20 +11,21 @@
from puppeter.domain.model import osfacts
from puppeter.domain.model.answers import Answers
from puppeter.domain.model.configurer import Configurer
from puppeter.presentation.app import Options


class AnswersProcessorImpl(AnswersProcessor):

def __init__(self, options):
self.options = options # type: Namespace
self.options = options # type: Options
self.__log = puppeter.get_logger(AnswersProcessorImpl)

def process(self, answers):
configurers = []
configurers.extend(self.__perform_installation(answers))
commands = self.__collect_commands(configurers)
for line in commands:
if self.options.execute:
if self.options.execute():
self.__log.warning('EXECUTING: %s', line)
else:
print(line)
Expand Down
21 changes: 20 additions & 1 deletion puppeter/presentation/app.py
Expand Up @@ -4,6 +4,7 @@
from abc import abstractmethod, ABCMeta
from logging import StreamHandler
from logging.handlers import SysLogHandler
from typing import IO, Any

from six import with_metaclass

Expand All @@ -13,7 +14,25 @@
from puppeter.domain.gateway.answers import AnswersProcessor
from puppeter.domain.model.answers import Answers
from puppeter.domain.model.osfacts import OsFamily
from puppeter.presentation.cmdparser import Options


class Options:
def __init__(self, namespace):
self.__answers = namespace.answers # type: IO[Any]
self.__verbose = namespace.verbose # type: int
self.__execute = namespace.execute # type: bool

def answers(self):
# type: () -> IO[Any]
return self.__answers

def verbose(self):
# type: () -> int
return self.__verbose

def execute(self):
# type: () -> bool
return self.__execute


class App(with_metaclass(ABCMeta, object)):
Expand Down
14 changes: 0 additions & 14 deletions puppeter/presentation/appfactory.py

This file was deleted.

0 comments on commit 24049ea

Please sign in to comment.