65 Commits

Author SHA1 Message Date
caca34168e Merge pull request '2021.4' (#19) from 2021.4 into master
Reviewed-on: sh-edraft.de/sh_common_py_lib#19
2021-04-01 10:13:32 +02:00
18b8ac589d Publish 2021.4.0 2021-04-01 10:04:13 +02:00
d85e628784 Improved readme 2021-03-31 15:51:14 +02:00
1e150cf10c Improved readme 2021-03-31 15:49:52 +02:00
9b0f0b7559 Improved readme 2021-03-31 15:49:00 +02:00
cc118b5030 Merge pull request '2021.04.03 - Readme' (#18) from 2021.04.03 into 2021.4
Reviewed-on: sh-edraft.de/sh_common_py_lib#18
2021-03-31 15:42:40 +02:00
3e7ff78861 Merge branch '2021.4' into 2021.04.03 2021-03-31 15:40:18 +02:00
448d538d21 Updated reame 2021-03-31 15:38:26 +02:00
d368161eb3 Publish 2021.4.0rc7 2021-03-31 12:11:55 +02:00
eef8488ca2 Bugfixes for new lib 2021-03-31 12:11:19 +02:00
b22d04b145 Publish 2021.4.0rc6 2021-03-31 12:03:15 +02:00
6579e54c2b Improved windows support 2021-03-31 12:02:51 +02:00
88c0153ca2 Improved windows support for publisher 2021-03-31 11:55:46 +02:00
f28c6ab309 Removed prints 2021-03-31 11:51:20 +02:00
976041f812 Publish 2021.4.0rc5 2021-03-31 11:48:26 +02:00
7693dd462f Bugfixes for publisher windows support 2021-03-31 11:47:47 +02:00
df5e61cf98 Bugfixes for publisher windows support 2021-03-31 11:47:28 +02:00
df87d08be3 Bugfix for live server windows support 2021-03-31 11:41:16 +02:00
33cb35e26f Publish 2021.4.0rc4.post1 2021-03-31 11:25:07 +02:00
18b2cd8f2f Publish 2021.4.0rc4 2021-03-31 11:01:08 +02:00
7ab2a881e8 Bugfixes 2021-03-31 10:47:14 +02:00
960de880ee Bugfixes 2021-03-31 10:44:54 +02:00
c0d8904782 Bugfixes for the command new 2021-03-31 10:19:54 +02:00
b6d508526a Bugfixes for the command new 2021-03-31 09:46:41 +02:00
31307485f0 Bugfixes in new command template 2021-03-31 09:13:04 +02:00
612c3583f1 Removed ununsed files 2021-03-30 21:02:36 +02:00
6cdd3376f1 Publish 2021.4.0rc3 2021-03-30 21:01:10 +02:00
b947789779 Bugfixes 2021-03-30 20:59:09 +02:00
0da83935fc Bugfixes 2021-03-30 12:44:31 +02:00
3428c70b69 Bugfixes 2021-03-30 11:54:44 +02:00
3d511ff727 Bugfixes 2021-03-30 11:53:07 +02:00
cf2f293290 Publish 2021.4.0rc2 2021-03-30 11:03:16 +02:00
c39601a35d Improved publisher 2021-03-30 11:02:58 +02:00
5f36e0a43e Improved publisher 2021-03-30 10:43:39 +02:00
31fe1c5cd7 Improved service collection 2021-03-30 10:29:50 +02:00
0cdecd893a Improved database context 2021-03-30 10:06:07 +02:00
260fe06be8 Improved new command 2021-03-30 09:54:04 +02:00
8ddfd35a82 Improved generate command 2021-03-30 09:47:47 +02:00
099bae3d7c Removed usage of ServiceABC 2021-03-30 09:27:45 +02:00
9758e1fae2 Improved update command 2021-03-29 16:16:27 +02:00
211143d6ab Package update 2021-03-29 16:06:54 +02:00
70b49a098a Publish 2021.4.0rc1 2021-03-29 15:59:05 +02:00
e2544f90fe Merge pull request '2021.4.2' (#12) from 2021.4.2 into 2021.4
Reviewed-on: sh-edraft.de/sh_common_py_lib#12
2021-03-29 15:48:58 +02:00
c223524d1b Removed direct import 2021-03-29 15:47:41 +02:00
1789e2671a Publish 2021.4.2 2021-03-29 15:26:45 +02:00
d0812bcf5c Added database table test 2021-03-29 14:29:17 +02:00
4d5368e5fc Bugfixes & improved database context handling 2021-03-29 14:18:58 +02:00
f3be927440 Removed service abc 2021-03-29 13:29:26 +02:00
d0e3e1792f Added db context handling 2021-03-29 13:25:25 +02:00
31793fb290 Added db context handling 2021-03-29 13:25:15 +02:00
41ddc86961 Bugfixes 2021-03-29 12:16:12 +02:00
30ef74dd18 Added generated simple di test app 2021-03-29 11:48:25 +02:00
bc69476bb2 Improved new project templates & publish 2021.4.2.dev1 2021-03-29 11:47:49 +02:00
05b9fd801b Bugfixes 2021-03-29 09:21:58 +02:00
7af7f866c1 Removed application runtime | Code refactoring p.2 2021-03-29 08:56:18 +02:00
069e44bee6 Code refactoring p.1 2021-03-27 08:41:33 +01:00
3c0dd00a99 Bugfixes 2021-03-26 13:16:40 +01:00
afb91c8f1f Improved service provider 2021-03-23 21:42:08 +01:00
ca51f88d2b Improved service provider 2021-03-23 21:39:29 +01:00
a683b70c5f [WIP] Improved service collection 2021-03-23 20:23:30 +01:00
c650e87443 [WIP] Added first changes for the DI 2021-03-23 20:21:24 +01:00
36dfedf918 Bugfixes cpl cli output 2021-03-23 17:31:24 +01:00
252f2b55fe Bugfixes in templates 2021-03-23 17:29:13 +01:00
99091a2540 Publish for 2021.4.2 2021-03-21 20:22:04 +01:00
c3fdb7a049 Changed version 2021-03-21 20:05:51 +01:00
143 changed files with 2319 additions and 643 deletions

101
README.md
View File

@@ -1,2 +1,101 @@
# sh_common_py_lib <h1 align="center">CPL - Common python library</h1>
<!-- Summary -->
<p align="center">
<!-- <img src="" alt="cpl-logo" width="120px" height="120px"/> -->
<br>
<i>
CPL is a development platform for python server applications
<br>using Python.</i>
<br>
</p>
## Table of Contents
<!-- TABLE OF CONTENTS -->
<ol>
<li>
<a href="#getting-started">Getting Started</a>
<ul>
<li><a href="#prerequisites">Prerequisites</a></li>
<li><a href="#installation">Installation</a></li>
</ul>
</li>
<li><a href="#roadmap">Roadmap</a></li>
<li><a href="#contributing">Contributing</a></li>
<li><a href="#license">License</a></li>
<li><a href="#contact">Contact</a></li>
</ol>
<!-- GETTING STARTED -->
## Getting Started
[Get started with CPL][quickstart].
### Prerequisites
- Install [python] which includes [Pip installs packages][pip]
### Installation
Install the cpl package
```sh
pip install sh_cpl --extra-index-url https://pip.sh-edraft.de
```
Create workspace:
```sh
cpl new <console|library> <PROJECT NAME>
```
Run the application:
```sh
cd <PROJECT NAME>
cpl start
```
<!-- ROADMAP -->
## Roadmap
See the [open issues](https://git.sh-edraft.de/sh-edraft.de/sh_common_py_lib/issues) for a list of proposed features (and known issues).
<!-- CONTRIBUTING -->
## Contributing
### Contributing Guidelines
Read through our [contributing guidelines][contributing] to learn about our submission process, coding rules and more.
### Want to Help?
Want to file a bug, contribute some code, or improve documentation? Excellent! Read up on our guidelines for [contributing][contributing].
<!-- LICENSE -->
## License
Distributed under the MIT License. See [LICENSE] for more information.
<!-- CONTACT -->
## Contact
Sven Heidemann - sven.heidemann@sh-edraft.de
Project link: [https://git.sh-edraft.de/sh-edraft.de/sh_common_py_lib](https://git.sh-edraft.de/sh-edraft.de/sh_common_py_lib)
<!-- External LINKS -->
[pip_url]: https://pip.sh-edraft.de
[python]: https://www.python.org/
[pip]: https://pypi.org/project/pip/
<!-- Internal LINKS -->
[project]: https://git.sh-edraft.de/sh-edraft.de/sh_common_py_lib
[quickstart]: https://git.sh-edraft.de/sh-edraft.de/sh_common_py_lib/wiki/quickstart
[contributing]: https://git.sh-edraft.de/sh-edraft.de/sh_common_py_lib/wiki/contributing
[license]: LICENSE

View File

@@ -4,7 +4,7 @@
"Version": { "Version": {
"Major": "2021", "Major": "2021",
"Minor": "04", "Minor": "04",
"Micro": "01-15" "Micro": "0"
}, },
"Author": "Sven Heidemann", "Author": "Sven Heidemann",
"AuthorEmail": "sven.heidemann@sh-edraft.de", "AuthorEmail": "sven.heidemann@sh-edraft.de",
@@ -22,8 +22,8 @@
"packaging==20.9", "packaging==20.9",
"pyfiglet==0.8.post1", "pyfiglet==0.8.post1",
"pynput==1.7.3", "pynput==1.7.3",
"SQLAlchemy==1.4.0", "SQLAlchemy==1.4.3",
"setuptools==54.1.2", "setuptools==54.2.0",
"tabulate==0.8.9", "tabulate==0.8.9",
"termcolor==1.1.0", "termcolor==1.1.0",
"watchdog==2.0.2", "watchdog==2.0.2",
@@ -34,6 +34,7 @@
"Classifiers": [] "Classifiers": []
}, },
"BuildSettings": { "BuildSettings": {
"ProjectType": "library",
"SourcePath": "src", "SourcePath": "src",
"OutputPath": "dist", "OutputPath": "dist",
"Main": "cpl_cli.main", "Main": "cpl_cli.main",

View File

@@ -15,11 +15,11 @@ __title__ = 'sh_cpl.cpl'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.0'
from collections import namedtuple from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl.application'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.0'
from collections import namedtuple from collections import namedtuple
@@ -23,9 +23,7 @@ from collections import namedtuple
from .application_abc import ApplicationABC from .application_abc import ApplicationABC
from .application_builder import ApplicationBuilder from .application_builder import ApplicationBuilder
from .application_builder_abc import ApplicationBuilderABC from .application_builder_abc import ApplicationBuilderABC
from .application_runtime import ApplicationRuntime
from .application_runtime_abc import ApplicationRuntimeABC
from .startup_abc import StartupABC from .startup_abc import StartupABC
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='0')

View File

@@ -1,21 +1,21 @@
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from typing import Optional from typing import Optional
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.configuration.configuration_abc import ConfigurationABC from cpl.configuration.configuration_abc import ConfigurationABC
from cpl.console.console import Console from cpl.console.console import Console
from cpl.dependency_injection.service_provider_abc import ServiceProviderABC from cpl.dependency_injection.service_provider_abc import ServiceProviderABC
from cpl.environment import ApplicationEnvironmentABC
class ApplicationABC(ABC): class ApplicationABC(ABC):
@abstractmethod @abstractmethod
def __init__(self, config: ConfigurationABC, runtime: ApplicationRuntimeABC, services: ServiceProviderABC): def __init__(self, config: ConfigurationABC, services: ServiceProviderABC):
""" """
ABC of application ABC of application
""" """
self._configuration: Optional[ConfigurationABC] = config self._configuration: Optional[ConfigurationABC] = config
self._runtime: Optional[ApplicationRuntimeABC] = runtime self._environment: Optional[ApplicationEnvironmentABC] = self._configuration.environment
self._services: Optional[ServiceProviderABC] = services self._services: Optional[ServiceProviderABC] = services
def run(self): def run(self):

View File

@@ -2,10 +2,9 @@ from typing import Type, Optional
from cpl.application.application_abc import ApplicationABC from cpl.application.application_abc import ApplicationABC
from cpl.application.application_builder_abc import ApplicationBuilderABC from cpl.application.application_builder_abc import ApplicationBuilderABC
from cpl.application.application_runtime import ApplicationRuntime
from cpl.application.startup_abc import StartupABC from cpl.application.startup_abc import StartupABC
from cpl.configuration import Configuration from cpl.configuration.configuration import Configuration
from cpl.dependency_injection import ServiceProvider from cpl.dependency_injection.service_collection import ServiceCollection
class ApplicationBuilder(ApplicationBuilderABC): class ApplicationBuilder(ApplicationBuilderABC):
@@ -19,8 +18,8 @@ class ApplicationBuilder(ApplicationBuilderABC):
self._startup: Optional[StartupABC] = None self._startup: Optional[StartupABC] = None
self._configuration = Configuration() self._configuration = Configuration()
self._runtime = ApplicationRuntime() self._environment = self._configuration.environment
self._services = ServiceProvider(self._configuration, self._runtime) self._services = ServiceCollection(self._configuration)
def use_startup(self, startup: Type[StartupABC]): def use_startup(self, startup: Type[StartupABC]):
""" """
@@ -28,7 +27,7 @@ class ApplicationBuilder(ApplicationBuilderABC):
:param startup: :param startup:
:return: :return:
""" """
self._startup = startup(self._configuration, self._runtime, self._services) self._startup = startup(self._configuration, self._services)
def build(self) -> ApplicationABC: def build(self) -> ApplicationABC:
""" """
@@ -39,4 +38,4 @@ class ApplicationBuilder(ApplicationBuilderABC):
self._startup.configure_configuration() self._startup.configure_configuration()
self._startup.configure_services() self._startup.configure_services()
return self._app(self._configuration, self._runtime, self._services) return self._app(self._configuration, self._services.build_service_provider())

View File

@@ -1,52 +0,0 @@
import pathlib
from datetime import datetime
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
class ApplicationRuntime(ApplicationRuntimeABC):
def __init__(self):
"""
Representation of the application runtime
"""
ApplicationRuntimeABC.__init__(self)
self._start_time: datetime = datetime.now()
self._end_time: datetime = datetime.now()
self._working_directory = pathlib.Path().absolute()
self._runtime_directory = pathlib.Path(__file__).parent.absolute()
@property
def start_time(self) -> datetime:
return self._start_time
@property
def end_time(self) -> datetime:
return self._end_time
@end_time.setter
def end_time(self, end_time: datetime):
self._end_time = end_time
@property
def date_time_now(self) -> datetime:
return datetime.now()
@property
def working_directory(self) -> str:
return self._working_directory
def set_working_directory(self, path: str = ''):
if path != '':
self._working_directory = path
return
self._working_directory = pathlib.Path().absolute()
@property
def runtime_directory(self) -> str:
return self._runtime_directory
def set_runtime_directory(self, file: str):
self._runtime_directory = pathlib.Path(file).parent.absolute()

View File

@@ -1,49 +0,0 @@
from abc import ABC, abstractmethod
from datetime import datetime
class ApplicationRuntimeABC(ABC):
@abstractmethod
def __init__(self):
"""
ABC for application runtime
"""
pass
@property
@abstractmethod
def start_time(self) -> datetime: pass
@start_time.setter
@abstractmethod
def start_time(self, start_time: datetime): pass
@property
@abstractmethod
def end_time(self): pass
@end_time.setter
@abstractmethod
def end_time(self, end_time: datetime): pass
@property
@abstractmethod
def date_time_now(self) -> datetime: pass
@property
@abstractmethod
def working_directory(self) -> str: pass
@property
@abstractmethod
def runtime_directory(self) -> str: pass
@abstractmethod
def set_runtime_directory(self, runtime_directory: str):
"""
Sets the current runtime directory
:param runtime_directory:
:return:
"""
pass

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl.configuration'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.0'
from collections import namedtuple from collections import namedtuple
@@ -27,4 +27,4 @@ from .configuration_variable_name_enum import ConfigurationVariableNameEnum
from .console_argument import ConsoleArgument from .console_argument import ConsoleArgument
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='0')

View File

@@ -11,7 +11,7 @@ from cpl.configuration.console_argument import ConsoleArgument
from cpl.console.console import Console from cpl.console.console import Console
from cpl.console.foreground_color_enum import ForegroundColorEnum from cpl.console.foreground_color_enum import ForegroundColorEnum
from cpl.environment.application_environment import ApplicationEnvironment from cpl.environment.application_environment import ApplicationEnvironment
from cpl.environment.environment_abc import ApplicationEnvironmentABC from cpl.environment.application_environment_abc import ApplicationEnvironmentABC
from cpl.environment.environment_name_enum import EnvironmentNameEnum from cpl.environment.environment_name_enum import EnvironmentNameEnum

View File

@@ -4,7 +4,7 @@ from typing import Type, Union, Optional
from cpl.configuration.console_argument import ConsoleArgument from cpl.configuration.console_argument import ConsoleArgument
from cpl.configuration.configuration_model_abc import ConfigurationModelABC from cpl.configuration.configuration_model_abc import ConfigurationModelABC
from cpl.environment.environment_abc import ApplicationEnvironmentABC from cpl.environment.application_environment_abc import ApplicationEnvironmentABC
class ConfigurationABC(ABC): class ConfigurationABC(ABC):
@@ -82,8 +82,7 @@ class ConfigurationABC(ABC):
pass pass
@abstractmethod @abstractmethod
def get_configuration(self, search_type: Union[str, Type[ConfigurationModelABC]]) -> Union[ def get_configuration(self, search_type: Union[str, Type[ConfigurationModelABC]]) -> Union[str, Callable[ConfigurationModelABC]]:
str, Callable[ConfigurationModelABC]]:
""" """
Returns value in configuration by given type Returns value in configuration by given type
:param search_type: :param search_type:

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl.console'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.0'
from collections import namedtuple from collections import namedtuple
@@ -27,4 +27,4 @@ from .foreground_color_enum import ForegroundColorEnum
from .spinner_thread import SpinnerThread from .spinner_thread import SpinnerThread
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl.database'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.0'
from collections import namedtuple from collections import namedtuple
@@ -25,4 +25,4 @@ from .database_settings import DatabaseSettings
from .database_settings_name_enum import DatabaseSettingsNameEnum from .database_settings_name_enum import DatabaseSettingsNameEnum
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl.database.connection'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.0'
from collections import namedtuple from collections import namedtuple
@@ -24,4 +24,4 @@ from .database_connection import DatabaseConnection
from .database_connection_abc import DatabaseConnectionABC from .database_connection_abc import DatabaseConnectionABC
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl.database.context'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.0'
from collections import namedtuple from collections import namedtuple
@@ -24,4 +24,4 @@ from .database_context import DatabaseContext
from .database_context_abc import DatabaseContextABC from .database_context_abc import DatabaseContextABC
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='0')

View File

@@ -30,6 +30,9 @@ class DatabaseContext(DatabaseContextABC):
self._db.connect(connection_string) self._db.connect(connection_string)
self._create_tables() self._create_tables()
def save_changes(self):
self._db.session.commit()
def _create_tables(self): def _create_tables(self):
try: try:
for subclass in DatabaseModel.__subclasses__(): for subclass in DatabaseModel.__subclasses__():

View File

@@ -6,6 +6,10 @@ from sqlalchemy.orm import Session
class DatabaseContextABC(ABC): class DatabaseContextABC(ABC):
@abstractmethod
def __init__(self, *args):
pass
@property @property
@abstractmethod @abstractmethod
def engine(self) -> engine: pass def engine(self) -> engine: pass
@@ -23,6 +27,12 @@ class DatabaseContextABC(ABC):
""" """
pass pass
def save_changes(self):
"""
Saves changes of the database
"""
pass
@abstractmethod @abstractmethod
def _create_tables(self): def _create_tables(self):
""" """

View File

@@ -15,14 +15,17 @@ __title__ = 'cpl.dependency_injection'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.0'
from collections import namedtuple from collections import namedtuple
# imports: # imports:
from .service_abc import ServiceABC from .service_collection import ServiceCollection
from .service_collection_abc import ServiceCollectionABC
from .service_descriptor import ServiceDescriptor
from .service_lifetime_enum import ServiceLifetimeEnum
from .service_provider import ServiceProvider from .service_provider import ServiceProvider
from .service_provider_abc import ServiceProviderABC from .service_provider_abc import ServiceProviderABC
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='0')

View File

@@ -1,11 +0,0 @@
from abc import ABC, abstractmethod
class ServiceABC(ABC):
@abstractmethod
def __init__(self):
"""
ABC to represent a service
"""
pass

View File

@@ -0,0 +1,70 @@
from typing import Union, Type, Callable, Optional
from cpl.configuration.configuration_abc import ConfigurationABC
from cpl.database.database_settings import DatabaseSettings
from cpl.database.context.database_context_abc import DatabaseContextABC
from cpl.dependency_injection.service_provider_abc import ServiceProviderABC
from cpl.dependency_injection.service_collection_abc import ServiceCollectionABC
from cpl.dependency_injection.service_descriptor import ServiceDescriptor
from cpl.dependency_injection.service_lifetime_enum import ServiceLifetimeEnum
from cpl.dependency_injection.service_provider import ServiceProvider
from cpl.logging.logger_service import Logger
from cpl.logging.logger_abc import LoggerABC
from cpl.utils.credential_manager import CredentialManager
class ServiceCollection(ServiceCollectionABC):
def __init__(self, config: ConfigurationABC):
ServiceCollectionABC.__init__(self)
self._configuration: ConfigurationABC = config
self._database_context: Optional[DatabaseContextABC] = None
self._service_descriptors: list[ServiceDescriptor] = []
def _add_descriptor(self, service: Union[type, object], lifetime: ServiceLifetimeEnum):
found = False
for descriptor in self._service_descriptors:
if isinstance(service, descriptor.service_type):
found = True
if found:
service_type = service
if not isinstance(service, type):
service_type = type(service)
raise Exception(f'Service of type {service_type} already exists')
self._service_descriptors.append(ServiceDescriptor(service, lifetime))
def add_db_context(self, db_context_type: Type[DatabaseContextABC], db_settings: DatabaseSettings):
self._database_context = db_context_type(db_settings)
self._database_context.connect(CredentialManager.build_string(db_settings.connection_string, db_settings.credentials))
def add_logging(self):
self.add_singleton(LoggerABC, Logger)
def add_singleton(self, service_type: Union[type, object], service: Union[type, object] = None):
impl = None
if service is not None:
if isinstance(service, type):
impl = self.build_service_provider().build_service(service)
self._add_descriptor(impl, ServiceLifetimeEnum.singleton)
else:
if isinstance(service_type, type):
impl = self.build_service_provider().build_service(service_type)
self._add_descriptor(impl, ServiceLifetimeEnum.singleton)
def add_scoped(self, service_type: Type, service: Callable = None):
raise Exception('Not implemented')
def add_transient(self, service_type: Union[type], service: Union[type] = None):
if service is not None:
self._add_descriptor(service, ServiceLifetimeEnum.transient)
else:
self._add_descriptor(service_type, ServiceLifetimeEnum.transient)
def build_service_provider(self) -> ServiceProviderABC:
return ServiceProvider(self._service_descriptors, self._configuration, self._database_context)

View File

@@ -0,0 +1,71 @@
from abc import abstractmethod, ABC
from collections import Callable
from typing import Type
from cpl.database.database_settings import DatabaseSettings
from cpl.database.context.database_context_abc import DatabaseContextABC
from cpl.dependency_injection.service_provider_abc import ServiceProviderABC
class ServiceCollectionABC(ABC):
@abstractmethod
def __init__(self):
"""
ABC for service providing
"""
pass
@abstractmethod
def add_db_context(self, db_context: Type[DatabaseContextABC], db_settings: DatabaseSettings):
"""
Adds database context
:param db_context:
:param db_settings:
:return:
"""
pass
@abstractmethod
def add_logging(self):
"""
Adds the CPL internal logger
"""
pass
@abstractmethod
def add_transient(self, service_type: Type, service: Callable = None):
"""
Adds a service with transient lifetime
:param service_type:
:param service:
:return:
"""
pass
@abstractmethod
def add_scoped(self, service_type: Type, service: Callable = None):
"""
Adds a service with scoped lifetime
:param service_type:
:param service:
:return:
"""
pass
@abstractmethod
def add_singleton(self, service_type: Type, service: Callable = None):
"""
Adds a service with singleton lifetime
:param service_type:
:param service:
:return:
"""
pass
@abstractmethod
def build_service_provider(self) -> ServiceProviderABC:
"""
Creates instance of the service provider
"""
pass

View File

@@ -0,0 +1,33 @@
from typing import Union, Optional
from cpl.dependency_injection.service_lifetime_enum import ServiceLifetimeEnum
class ServiceDescriptor:
def __init__(self, implementation: Union[type, Optional[object]], lifetime: ServiceLifetimeEnum):
self._service_type = implementation
self._implementation = implementation
self._lifetime = lifetime
if not isinstance(implementation, type):
self._service_type = type(implementation)
else:
self._implementation = None
@property
def service_type(self) -> type:
return self._service_type
@property
def implementation(self) -> Union[type, Optional[object]]:
return self._implementation
@implementation.setter
def implementation(self, implementation: Union[type, Optional[object]]):
self._implementation = implementation
@property
def lifetime(self) -> ServiceLifetimeEnum:
return self._lifetime

View File

@@ -0,0 +1,8 @@
from enum import Enum
class ServiceLifetimeEnum(Enum):
singleton = 0
scoped = 1 # not supported yet
transient = 2

View File

@@ -1,45 +1,61 @@
from collections import Callable from collections import Callable
from inspect import signature, Parameter from inspect import signature, Parameter
from typing import Type, Optional, Union from typing import Optional
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.configuration.configuration_abc import ConfigurationABC from cpl.configuration.configuration_abc import ConfigurationABC
from cpl.configuration.configuration_model_abc import ConfigurationModelABC from cpl.configuration.configuration_model_abc import ConfigurationModelABC
from cpl.database.context.database_context_abc import DatabaseContextABC from cpl.database.context.database_context_abc import DatabaseContextABC
from cpl.dependency_injection.service_abc import ServiceABC
from cpl.dependency_injection.service_provider_abc import ServiceProviderABC from cpl.dependency_injection.service_provider_abc import ServiceProviderABC
from cpl.environment.environment_abc import ApplicationEnvironmentABC from cpl.dependency_injection.service_descriptor import ServiceDescriptor
from cpl.dependency_injection.service_lifetime_enum import ServiceLifetimeEnum
from cpl.environment.application_environment_abc import ApplicationEnvironmentABC
class ServiceProvider(ServiceProviderABC): class ServiceProvider(ServiceProviderABC):
def __init__(self, config: ConfigurationABC, runtime: ApplicationRuntimeABC): def __init__(self, service_descriptors: list[ServiceDescriptor], config: ConfigurationABC, db_context: Optional[DatabaseContextABC]):
"""
Service for service providing
:param runtime:
"""
ServiceProviderABC.__init__(self) ServiceProviderABC.__init__(self)
self._service_descriptors: list[ServiceDescriptor] = service_descriptors
self._configuration: ConfigurationABC = config self._configuration: ConfigurationABC = config
self._runtime: ApplicationRuntimeABC = runtime self._database_context = db_context
self._database_context: Optional[DatabaseContextABC] = None
self._transient_services: dict[Type[ServiceABC], Callable[ServiceABC]] = {} def _find_service(self, service_type: type) -> [ServiceDescriptor]:
self._scoped_services: dict[Type[ServiceABC], Callable[ServiceABC]] = {} for descriptor in self._service_descriptors:
self._singleton_services: dict[Type[ServiceABC], Callable[ServiceABC], ServiceABC] = {} if descriptor.service_type == service_type or issubclass(descriptor.service_type, service_type):
return descriptor
def _create_instance(self, service: Union[Callable[ServiceABC], ServiceABC]) -> Callable[ServiceABC]: return None
"""
Creates an instance of given type def _get_service(self, parameter: Parameter) -> object:
:param service: for descriptor in self._service_descriptors:
:return: if descriptor.service_type == parameter.annotation or issubclass(descriptor.service_type, parameter.annotation):
""" if descriptor.implementation is not None:
sig = signature(service.__init__) return descriptor.implementation
implementation = self.build_service(descriptor.service_type)
if descriptor.lifetime == ServiceLifetimeEnum.singleton:
descriptor.implementation = implementation
return implementation
def build_service(self, service_type: type) -> object:
for descriptor in self._service_descriptors:
if descriptor.service_type == service_type or issubclass(descriptor.service_type, service_type):
if descriptor.implementation is not None:
service_type = type(descriptor.implementation)
else:
service_type = descriptor.service_type
break
sig = signature(service_type.__init__)
params = [] params = []
for param in sig.parameters.items(): for param in sig.parameters.items():
parameter = param[1] parameter = param[1]
if parameter.name != 'self' and parameter.annotation != Parameter.empty: if parameter.name != 'self' and parameter.annotation != Parameter.empty:
if issubclass(parameter.annotation, ApplicationRuntimeABC): if issubclass(parameter.annotation, ServiceProviderABC):
params.append(self._runtime) params.append(self)
elif issubclass(parameter.annotation, ApplicationEnvironmentABC): elif issubclass(parameter.annotation, ApplicationEnvironmentABC):
params.append(self._configuration.environment) params.append(self._configuration.environment)
@@ -53,70 +69,22 @@ class ServiceProvider(ServiceProviderABC):
elif issubclass(parameter.annotation, ConfigurationABC): elif issubclass(parameter.annotation, ConfigurationABC):
params.append(self._configuration) params.append(self._configuration)
elif issubclass(parameter.annotation, ServiceProviderABC):
params.append(self)
else: else:
params.append(self.get_service(parameter.annotation)) params.append(self._get_service(parameter))
return service(*params) return service_type(*params)
def add_db_context(self, db_context: Type[DatabaseContextABC]): def get_service(self, service_type: type) -> Optional[Callable[object]]:
self._database_context = self._create_instance(db_context) result = self._find_service(service_type)
def get_db_context(self) -> Callable[DatabaseContextABC]: if result is None:
return self._database_context return None
def add_transient(self, service_type: Type[ServiceABC], service: Callable[ServiceABC] = None): if result.implementation is not None:
if service is None: return result.implementation
self._transient_services[service_type] = service_type
else:
self._transient_services[service_type] = service
def add_scoped(self, service_type: Type[ServiceABC], service: Callable[ServiceABC] = None): implementation = self.build_service(service_type)
if service is None: if result.lifetime == ServiceLifetimeEnum.singleton:
self._scoped_services[service_type] = service_type result.implementation = implementation
else:
self._scoped_services[service_type] = service
def add_singleton(self, service_type: Type[ServiceABC], service: Callable[ServiceABC] = None): return implementation
for known_service in self._singleton_services:
if type(known_service) == service_type:
raise Exception(f'Service with type {service_type} already exists')
if service is None:
self._singleton_services[service_type] = self._create_instance(service_type)
else:
self._singleton_services[service_type] = self._create_instance(service)
def get_service(self, instance_type: Type) -> Callable[ServiceABC]:
if issubclass(instance_type, ServiceProviderABC):
return self
for service in self._transient_services:
if service == instance_type and isinstance(self._transient_services[service], type(instance_type)):
return self._create_instance(self._transient_services[service])
for service in self._scoped_services:
if service == instance_type and isinstance(self._scoped_services[service], type(instance_type)):
return self._create_instance(self._scoped_services[service])
for service in self._singleton_services:
if service == instance_type and isinstance(self._singleton_services[service], instance_type):
return self._singleton_services[service]
def remove_service(self, instance_type: Type[ServiceABC]):
for service in self._transient_services:
if service == instance_type and isinstance(self._transient_services[service], type(instance_type)):
del self._transient_services[service]
return
for service in self._scoped_services:
if service == instance_type and isinstance(self._scoped_services[service], type(instance_type)):
del self._scoped_services[service]
return
for service in self._singleton_services:
if service == instance_type and isinstance(self._singleton_services[service], instance_type):
del self._singleton_services[service]
return

View File

@@ -1,9 +1,6 @@
from abc import abstractmethod, ABC from abc import abstractmethod, ABC
from collections import Callable from collections import Callable
from typing import Type from typing import Type, Optional
from cpl.database.context.database_context_abc import DatabaseContextABC
from cpl.dependency_injection.service_abc import ServiceABC
class ServiceProviderABC(ABC): class ServiceProviderABC(ABC):
@@ -16,66 +13,19 @@ class ServiceProviderABC(ABC):
pass pass
@abstractmethod @abstractmethod
def add_db_context(self, db_context: Type[DatabaseContextABC]): def build_service(self, service_type: type) -> object:
""" """
Adds database context Creates instance of given type
:param db_context:
:return:
"""
pass
@abstractmethod
def get_db_context(self) -> Callable[DatabaseContextABC]:
""""
Returns database context
:return Callable[DatabaseContextABC]:
"""
pass
@abstractmethod
def add_transient(self, service_type: Type, service: Callable = None):
"""
Adds a service with transient lifetime
:param service_type: :param service_type:
:param service:
:return: :return:
""" """
pass pass
@abstractmethod @abstractmethod
def add_scoped(self, service_type: Type, service: Callable = None): def get_service(self, instance_type: Type) -> Optional[Callable[object]]:
"""
Adds a service with scoped lifetime
:param service_type:
:param service:
:return:
"""
pass
@abstractmethod
def add_singleton(self, service_type: Type, service: Callable = None):
"""
Adds a service with singleton lifetime
:param service_type:
:param service:
:return:
"""
pass
@abstractmethod
def get_service(self, instance_type: Type) -> Callable[ServiceABC]:
""" """
Returns instance of given type Returns instance of given type
:param instance_type: :param instance_type:
:return: :return:
""" """
pass pass
@abstractmethod
def remove_service(self, instance_type: type):
"""
Removes service
:param instance_type:
:return:
"""
pass

View File

@@ -15,14 +15,14 @@ __title__ = 'cpl.environment'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.0'
from collections import namedtuple from collections import namedtuple
# imports: # imports:
from .environment_abc import ApplicationEnvironmentABC from .application_environment_abc import ApplicationEnvironmentABC
from .environment_name_enum import EnvironmentNameEnum from .environment_name_enum import EnvironmentNameEnum
from .application_environment import ApplicationEnvironment from .application_environment import ApplicationEnvironment
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='0')

View File

@@ -1,7 +1,9 @@
import pathlib
from datetime import datetime
from socket import gethostname from socket import gethostname
from typing import Optional from typing import Optional
from cpl.environment.environment_abc import ApplicationEnvironmentABC from cpl.environment.application_environment_abc import ApplicationEnvironmentABC
from cpl.environment.environment_name_enum import EnvironmentNameEnum from cpl.environment.environment_name_enum import EnvironmentNameEnum
@@ -20,6 +22,11 @@ class ApplicationEnvironment(ApplicationEnvironmentABC):
self._customer: Optional[str] = None self._customer: Optional[str] = None
self._content_root_path: Optional[str] = crp self._content_root_path: Optional[str] = crp
self._start_time: datetime = datetime.now()
self._end_time: datetime = datetime.now()
self._working_directory = pathlib.Path().absolute()
self._runtime_directory = pathlib.Path(__file__).parent.absolute()
@property @property
def environment_name(self) -> str: def environment_name(self) -> str:
return str(self._environment_name.value) return str(self._environment_name.value)
@@ -55,3 +62,37 @@ class ApplicationEnvironment(ApplicationEnvironmentABC):
@property @property
def host_name(self): def host_name(self):
return gethostname() return gethostname()
@property
def start_time(self) -> datetime:
return self._start_time
@property
def end_time(self) -> datetime:
return self._end_time
@end_time.setter
def end_time(self, end_time: datetime):
self._end_time = end_time
@property
def date_time_now(self) -> datetime:
return datetime.now()
@property
def working_directory(self) -> str:
return self._working_directory
def set_working_directory(self, path: str = ''):
if path != '':
self._working_directory = path
return
self._working_directory = pathlib.Path().absolute()
@property
def runtime_directory(self) -> str:
return self._runtime_directory
def set_runtime_directory(self, file: str):
self._runtime_directory = pathlib.Path(file).parent.absolute()

View File

@@ -1,4 +1,5 @@
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from datetime import datetime
class ApplicationEnvironmentABC(ABC): class ApplicationEnvironmentABC(ABC):
@@ -45,3 +46,40 @@ class ApplicationEnvironmentABC(ABC):
@property @property
@abstractmethod @abstractmethod
def host_name(self) -> str: pass def host_name(self) -> str: pass
@property
@abstractmethod
def start_time(self) -> datetime: pass
@start_time.setter
@abstractmethod
def start_time(self, start_time: datetime): pass
@property
@abstractmethod
def end_time(self): pass
@end_time.setter
@abstractmethod
def end_time(self, end_time: datetime): pass
@property
@abstractmethod
def date_time_now(self) -> datetime: pass
@property
@abstractmethod
def working_directory(self) -> str: pass
@property
@abstractmethod
def runtime_directory(self) -> str: pass
@abstractmethod
def set_runtime_directory(self, runtime_directory: str):
"""
Sets the current runtime directory
:param runtime_directory:
:return:
"""
pass

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl.logging'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.0'
from collections import namedtuple from collections import namedtuple
@@ -27,4 +27,4 @@ from .logging_settings import LoggingSettings
from .logging_settings_name_enum import LoggingSettingsNameEnum from .logging_settings_name_enum import LoggingSettingsNameEnum
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='0')

View File

@@ -1,16 +1,14 @@
from abc import abstractmethod from abc import abstractmethod, ABC
from cpl.dependency_injection.service_abc import ServiceABC
class LoggerABC(ServiceABC): class LoggerABC(ABC):
@abstractmethod @abstractmethod
def __init__(self): def __init__(self):
""" """
ABC for logging ABC for logging
""" """
ServiceABC.__init__(self) ABC.__init__(self)
@abstractmethod @abstractmethod
def header(self, string: str): def header(self, string: str):

View File

@@ -3,9 +3,9 @@ import os
import traceback import traceback
from string import Template from string import Template
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.console.console import Console from cpl.console.console import Console
from cpl.console.foreground_color_enum import ForegroundColorEnum from cpl.console.foreground_color_enum import ForegroundColorEnum
from cpl.environment.application_environment_abc import ApplicationEnvironmentABC
from cpl.logging.logger_abc import LoggerABC from cpl.logging.logger_abc import LoggerABC
from cpl.logging.logging_level_enum import LoggingLevelEnum from cpl.logging.logging_level_enum import LoggingLevelEnum
from cpl.logging.logging_settings import LoggingSettings from cpl.logging.logging_settings import LoggingSettings
@@ -14,7 +14,7 @@ from cpl.time.time_format_settings import TimeFormatSettings
class Logger(LoggerABC): class Logger(LoggerABC):
def __init__(self, logging_settings: LoggingSettings, time_format: TimeFormatSettings, app_runtime: ApplicationRuntimeABC): def __init__(self, logging_settings: LoggingSettings, time_format: TimeFormatSettings, env: ApplicationEnvironmentABC):
""" """
Service for logging Service for logging
:param logging_settings: :param logging_settings:
@@ -23,13 +23,13 @@ class Logger(LoggerABC):
""" """
LoggerABC.__init__(self) LoggerABC.__init__(self)
self._app_runtime = app_runtime self._env = env
self._log_settings: LoggingSettings = logging_settings self._log_settings: LoggingSettings = logging_settings
self._time_format_settings: TimeFormatSettings = time_format self._time_format_settings: TimeFormatSettings = time_format
self._log = Template(self._log_settings.filename).substitute( self._log = Template(self._log_settings.filename).substitute(
date_time_now=self._app_runtime.date_time_now.strftime(self._time_format_settings.date_time_format), date_time_now=self._env.date_time_now.strftime(self._time_format_settings.date_time_format),
start_time=self._app_runtime.start_time.strftime(self._time_format_settings.date_time_log_format) start_time=self._env.start_time.strftime(self._time_format_settings.date_time_log_format)
) )
self._path = self._log_settings.path self._path = self._log_settings.path
self._level = self._log_settings.level self._level = self._log_settings.level

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl.mailing'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.0'
from collections import namedtuple from collections import namedtuple
@@ -27,4 +27,4 @@ from .email_client_settings import EMailClientSettings
from .email_client_settings_name_enum import EMailClientSettingsNameEnum from .email_client_settings_name_enum import EMailClientSettingsNameEnum
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='0')

View File

@@ -1,17 +1,16 @@
from abc import abstractmethod from abc import abstractmethod, ABC
from cpl.dependency_injection.service_abc import ServiceABC
from cpl.mailing.email import EMail from cpl.mailing.email import EMail
class EMailClientABC(ServiceABC): class EMailClientABC(ABC):
@abstractmethod @abstractmethod
def __init__(self): def __init__(self):
""" """
ABC to send emails ABC to send emails
""" """
ServiceABC.__init__(self) ABC.__init__(self)
@abstractmethod @abstractmethod
def connect(self): def connect(self):

View File

@@ -2,7 +2,7 @@ import ssl
from smtplib import SMTP from smtplib import SMTP
from typing import Optional from typing import Optional
from cpl.environment.environment_abc import ApplicationEnvironmentABC from cpl.environment.application_environment_abc import ApplicationEnvironmentABC
from cpl.logging.logger_abc import LoggerABC from cpl.logging.logger_abc import LoggerABC
from cpl.mailing.email import EMail from cpl.mailing.email import EMail
from cpl.mailing.email_client_abc import EMailClientABC from cpl.mailing.email_client_abc import EMailClientABC

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl.time'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.0'
from collections import namedtuple from collections import namedtuple
@@ -24,4 +24,4 @@ from .time_format_settings import TimeFormatSettings
from .time_format_settings_names_enum import TimeFormatSettingsNamesEnum from .time_format_settings_names_enum import TimeFormatSettingsNamesEnum
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl.utils'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.0'
from collections import namedtuple from collections import namedtuple
@@ -25,4 +25,4 @@ from .string import String
from .pip import Pip from .pip import Pip
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'sh_cpl.cpl_cli'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.0'
from collections import namedtuple from collections import namedtuple
@@ -29,4 +29,4 @@ from .main import main
from .startup import Startup from .startup import Startup
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='0')

View File

@@ -1,5 +1,5 @@
{ {
"CLI": { "CLI": {
"PipPath": "https://pip-dev.sh-edraft.de" "PipPath": "https://pip.sh-edraft.de"
} }
} }

View File

@@ -1,7 +1,6 @@
from typing import Optional from typing import Optional
from cpl.application.application_abc import ApplicationABC from cpl.application.application_abc import ApplicationABC
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.configuration.configuration_abc import ConfigurationABC from cpl.configuration.configuration_abc import ConfigurationABC
from cpl.console.console import Console from cpl.console.console import Console
from cpl.dependency_injection import ServiceProviderABC from cpl.dependency_injection import ServiceProviderABC
@@ -22,11 +21,11 @@ from cpl_cli.command.version_service import VersionService
class CLI(ApplicationABC): class CLI(ApplicationABC):
def __init__(self, config: ConfigurationABC, runtime: ApplicationRuntimeABC, services: ServiceProviderABC): def __init__(self, config: ConfigurationABC, services: ServiceProviderABC):
""" """
CPL CLI CPL CLI
""" """
ApplicationABC.__init__(self, config, runtime, services) ApplicationABC.__init__(self, config, services)
self._command_handler: Optional[CommandHandler] = None self._command_handler: Optional[CommandHandler] = None

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_cli.command'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.0'
from collections import namedtuple from collections import namedtuple
@@ -28,4 +28,4 @@ from .publish_service import PublishService
from .version_service import VersionService from .version_service import VersionService
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='0')

View File

@@ -1,4 +1,3 @@
from cpl.console.console import Console
from cpl_cli.command_abc import CommandABC from cpl_cli.command_abc import CommandABC
from cpl_cli.publish.publisher_abc import PublisherABC from cpl_cli.publish.publisher_abc import PublisherABC
@@ -21,4 +20,3 @@ class BuildService(CommandABC):
:return: :return:
""" """
self._publisher.build() self._publisher.build()
Console.write('\n')

View File

@@ -1,12 +1,12 @@
import os import os
from collections import Callable from collections import Callable
from cpl.application.application_abc import ApplicationRuntimeABC
from cpl.configuration.configuration_abc import ConfigurationABC from cpl.configuration.configuration_abc import ConfigurationABC
from cpl.console.foreground_color_enum import ForegroundColorEnum from cpl.console.foreground_color_enum import ForegroundColorEnum
from cpl.console.console import Console from cpl.console.console import Console
from cpl.utils.string import String from cpl.utils.string import String
from cpl_cli.command_abc import CommandABC from cpl_cli.command_abc import CommandABC
from cpl_cli.templates.generate.init_template import InitTemplate
from cpl_cli.templates.generate.abc_template import ABCTemplate from cpl_cli.templates.generate.abc_template import ABCTemplate
from cpl_cli.templates.generate.class_template import ClassTemplate from cpl_cli.templates.generate.class_template import ClassTemplate
from cpl_cli.templates.generate.configmodel_template import ConfigModelTemplate from cpl_cli.templates.generate.configmodel_template import ConfigModelTemplate
@@ -18,11 +18,10 @@ from cpl_cli.templates.template_file_abc import TemplateFileABC
class GenerateService(CommandABC): class GenerateService(CommandABC):
def __init__(self, configuration: ConfigurationABC, runtime: ApplicationRuntimeABC): def __init__(self, configuration: ConfigurationABC):
""" """
Service for the CLI command generate Service for the CLI command generate
:param configuration: :param configuration:
:param runtime:
""" """
CommandABC.__init__(self) CommandABC.__init__(self)
@@ -54,7 +53,7 @@ class GenerateService(CommandABC):
} }
self._config = configuration self._config = configuration
self._runtime = runtime self._env = self._config.environment
@staticmethod @staticmethod
def _help(message: str): def _help(message: str):
@@ -105,17 +104,30 @@ class GenerateService(CommandABC):
template = template(class_name, schematic, self._schematics[schematic]["Upper"], rel_path) template = template(class_name, schematic, self._schematics[schematic]["Upper"], rel_path)
file_path = os.path.join(self._runtime.working_directory, template.path, template.name) file_path = os.path.join(self._env.working_directory, template.path, template.name)
if not os.path.isdir(os.path.dirname(file_path)): if not os.path.isdir(os.path.dirname(file_path)):
os.makedirs(os.path.dirname(file_path)) os.makedirs(os.path.dirname(file_path))
directory = ''
for subdir in template.path.split('/'):
directory = os.path.join(directory, subdir)
if subdir != 'src':
file = InitTemplate(class_name, schematic, self._schematics[schematic]["Upper"], rel_path)
Console.spinner(
f'Creating {os.path.abspath(directory)}/{file.name}',
self._create_file,
os.path.join(os.path.abspath(directory), file.name),
file.value,
text_foreground_color=ForegroundColorEnum.green,
spinner_foreground_color=ForegroundColorEnum.cyan
)
if os.path.isfile(file_path): if os.path.isfile(file_path):
Console.error(f'{String.first_to_upper(schematic)} already exists!') Console.error(f'{String.first_to_upper(schematic)} already exists!')
exit() exit()
message = f'Creating {self._runtime.working_directory}/{template.path}/{template.name}' message = f'Creating {self._env.working_directory}/{template.path}/{template.name}'
if template.path == '': if template.path == '':
message = f'Creating {self._runtime.working_directory}/{template.name}' message = f'Creating {self._env.working_directory}/{template.name}'
Console.spinner( Console.spinner(
message, message,
@@ -148,5 +160,3 @@ class GenerateService(CommandABC):
else: else:
self._help('Usage: cpl generate <schematic> [options]') self._help('Usage: cpl generate <schematic> [options]')
exit() exit()
Console.write('\n')

View File

@@ -24,7 +24,7 @@ class HelpService(CommandABC):
['help (h|H)', 'Lists available command and their short descriptions.'], ['help (h|H)', 'Lists available command and their short descriptions.'],
['install (i|I)', 'With argument installs packages to project, without argument installs project dependencies.'], ['install (i|I)', 'With argument installs packages to project, without argument installs project dependencies.'],
['new (n|N)', 'Creates new CPL project.'], ['new (n|N)', 'Creates new CPL project.'],
['publish (p|P)', 'Prepares files for publish into an output directory named dist/ at the given output path and executes setup_template.py. Must be executed from within a workspace directory.'], ['publish (p|P)', 'Prepares files for publish into an output directory named dist/ at the given output path and executes setup.py. Must be executed from within a library workspace directory.'],
['start (s|S)', 'Starts CPL project, restarting on file changes'], ['start (s|S)', 'Starts CPL project, restarting on file changes'],
['uninstall (ui|UI)', 'Uninstalls packages from project.'], ['uninstall (ui|UI)', 'Uninstalls packages from project.'],
['update (u|u)', 'Update CPL and project dependencies.'], ['update (u|u)', 'Update CPL and project dependencies.'],
@@ -35,5 +35,3 @@ class HelpService(CommandABC):
Console.write(f'\n\t{name} ') Console.write(f'\n\t{name} ')
Console.set_foreground_color(ForegroundColorEnum.default) Console.set_foreground_color(ForegroundColorEnum.default)
Console.write(f'{description}') Console.write(f'{description}')
Console.write('\n')

View File

@@ -4,9 +4,9 @@ import subprocess
from packaging import version from packaging import version
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.console.console import Console from cpl.console.console import Console
from cpl.console.foreground_color_enum import ForegroundColorEnum from cpl.console.foreground_color_enum import ForegroundColorEnum
from cpl.environment.application_environment_abc import ApplicationEnvironmentABC
from cpl.utils.pip import Pip from cpl.utils.pip import Pip
from cpl_cli.cli_settings import CLISettings from cpl_cli.cli_settings import CLISettings
from cpl_cli.command_abc import CommandABC from cpl_cli.command_abc import CommandABC
@@ -18,18 +18,18 @@ from cpl_cli.error import Error
class InstallService(CommandABC): class InstallService(CommandABC):
def __init__(self, runtime: ApplicationRuntimeABC, build_settings: BuildSettings, project_settings: ProjectSettings, def __init__(self, env: ApplicationEnvironmentABC, build_settings: BuildSettings, project_settings: ProjectSettings,
cli_settings: CLISettings): cli_settings: CLISettings):
""" """
Service for the CLI command install Service for the CLI command install
:param runtime: :param env:
:param build_settings: :param build_settings:
:param project_settings: :param project_settings:
:param cli_settings: :param cli_settings:
""" """
CommandABC.__init__(self) CommandABC.__init__(self)
self._runtime = runtime self._env = env
self._build_settings = build_settings self._build_settings = build_settings
self._project_settings = project_settings self._project_settings = project_settings
self._cli_settings = cli_settings self._cli_settings = cli_settings
@@ -147,7 +147,7 @@ class InstallService(CommandABC):
BuildSettings.__name__: SettingsHelper.get_build_settings_dict(self._build_settings) BuildSettings.__name__: SettingsHelper.get_build_settings_dict(self._build_settings)
} }
with open(os.path.join(self._runtime.working_directory, 'cpl.json'), 'w') as project_file: with open(os.path.join(self._env.working_directory, 'cpl.json'), 'w') as project_file:
project_file.write(json.dumps(config, indent=2)) project_file.write(json.dumps(config, indent=2))
project_file.close() project_file.close()
@@ -163,5 +163,3 @@ class InstallService(CommandABC):
self._install_project() self._install_project()
else: else:
self._install_package(args[0]) self._install_package(args[0])
Console.write('\n')

View File

@@ -7,37 +7,32 @@ from packaging import version
import cpl import cpl
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.configuration.configuration_abc import ConfigurationABC from cpl.configuration.configuration_abc import ConfigurationABC
from cpl.console.foreground_color_enum import ForegroundColorEnum from cpl.console.foreground_color_enum import ForegroundColorEnum
from cpl.console.console import Console from cpl.console.console import Console
from cpl.utils.string import String
from cpl_cli.command_abc import CommandABC from cpl_cli.command_abc import CommandABC
from cpl_cli.configuration.build_settings import BuildSettings from cpl_cli.configuration.build_settings import BuildSettings
from cpl_cli.configuration.build_settings_name_enum import BuildSettingsNameEnum from cpl_cli.configuration.build_settings_name_enum import BuildSettingsNameEnum
from cpl_cli.configuration.project_settings import ProjectSettings from cpl_cli.configuration.project_settings import ProjectSettings
from cpl_cli.configuration.project_settings_name_enum import ProjectSettingsNameEnum from cpl_cli.configuration.project_settings_name_enum import ProjectSettingsNameEnum
from cpl_cli.configuration.project_type_enum import ProjectTypeEnum
from cpl_cli.configuration.version_settings_name_enum import VersionSettingsNameEnum from cpl_cli.configuration.version_settings_name_enum import VersionSettingsNameEnum
from cpl_cli.templates.new.console.license import LicenseTemplate from cpl_cli.source_creator.console_builder import ConsoleBuilder
from cpl_cli.templates.new.console.readme_py import ReadmeTemplate from cpl_cli.source_creator.library_builder import LibraryBuilder
from cpl_cli.templates.new.console.src.application import ApplicationTemplate
from cpl_cli.templates.new.console.src.main import MainWithApplicationHostAndStartupTemplate, MainWithoutApplicationHostTemplate, MainWithApplicationHostTemplate
from cpl_cli.templates.new.console.src.startup import StartupTemplate
from cpl_cli.templates.new.console.src.tests.init import TestsInitTemplate
from cpl_cli.templates.template_file_abc import TemplateFileABC
class NewService(CommandABC): class NewService(CommandABC):
def __init__(self, configuration: ConfigurationABC, runtime: ApplicationRuntimeABC): def __init__(self, configuration: ConfigurationABC):
""" """
Service for the CLI command new Service for the CLI command new
:param configuration: :param configuration:
:param runtime:
""" """
CommandABC.__init__(self) CommandABC.__init__(self)
self._config = configuration self._config = configuration
self._runtime = runtime self._env = self._config.environment
self._project: ProjectSettings = ProjectSettings() self._project: ProjectSettings = ProjectSettings()
self._project_dict = {} self._project_dict = {}
@@ -96,10 +91,15 @@ class NewService(CommandABC):
self._project.from_dict(self._project_dict) self._project.from_dict(self._project_dict)
def _create_build_settings(self): def _create_build_settings(self):
main = f'{String.convert_to_snake_case(self._project.name)}.main'
if self._command == ProjectTypeEnum.library.value:
main = f'{String.convert_to_snake_case(self._project.name)}_cli.main'
self._build_dict = { self._build_dict = {
BuildSettingsNameEnum.project_type.value: self._command,
BuildSettingsNameEnum.source_path.value: 'src', BuildSettingsNameEnum.source_path.value: 'src',
BuildSettingsNameEnum.output_path.value: 'dist', BuildSettingsNameEnum.output_path.value: 'dist',
BuildSettingsNameEnum.main.value: 'main', BuildSettingsNameEnum.main.value: main,
BuildSettingsNameEnum.entry_point.value: self._project.name, BuildSettingsNameEnum.entry_point.value: self._project.name,
BuildSettingsNameEnum.include_package_data.value: False, BuildSettingsNameEnum.include_package_data.value: False,
BuildSettingsNameEnum.included.value: [], BuildSettingsNameEnum.included.value: [],
@@ -127,90 +127,32 @@ class NewService(CommandABC):
Gets project path Gets project path
:return: :return:
""" """
project_path = os.path.join(self._runtime.working_directory, self._project.name) project_path = os.path.join(self._env.working_directory, self._project.name)
if os.path.isdir(project_path) and len(os.listdir(project_path)) > 0: if os.path.isdir(project_path) and len(os.listdir(project_path)) > 0:
Console.error('Project path is not empty\n') Console.error('Project path is not empty\n')
return None return None
return project_path return project_path
def _get_project_informations(self): def _get_project_information(self):
""" """
Gets project informations from user Gets project information's from user
:return: :return:
""" """
result = Console.read('Do you want to use application host? (y/n) ') result = Console.read('Do you want to use application base? (y/n) ')
if result.lower() == 'y': if result.lower() == 'y':
self._use_application_api = True self._use_application_api = True
if self._use_application_api:
result = Console.read('Do you want to use startup? (y/n) ') result = Console.read('Do you want to use startup? (y/n) ')
if result.lower() == 'y': if result.lower() == 'y':
self._use_startup = True self._use_startup = True
else:
result = Console.read('Do you want to use service providing? (y/n) ')
if result.lower() == 'y':
self._use_service_providing = True
Console.set_foreground_color(ForegroundColorEnum.default) Console.set_foreground_color(ForegroundColorEnum.default)
# else:
# result = Console.read('Do you want to use service providing? (y/n) ')
# if result.lower() == 'y':
# self._use_service_providing = True
def _build_project_dir(self, project_path: str):
"""
Builds the project files
:param project_path:
:return:
"""
if not os.path.isdir(project_path):
os.makedirs(project_path)
with open(os.path.join(project_path, 'cpl.json'), 'w') as project_json:
project_json.write(json.dumps(self._project_json, indent=2))
project_json.close()
templates: list[TemplateFileABC] = [
LicenseTemplate(),
ReadmeTemplate(),
TestsInitTemplate()
]
if self._use_application_api:
templates.append(ApplicationTemplate())
if self._use_startup:
templates.append(StartupTemplate())
templates.append(MainWithApplicationHostAndStartupTemplate())
else:
templates.append(MainWithApplicationHostTemplate())
else:
templates.append(MainWithoutApplicationHostTemplate())
for template in templates:
Console.spinner(
f'Creating {self._project.name}/{template.path}{template.name}',
self._create_template,
project_path,
template,
text_foreground_color=ForegroundColorEnum.green,
spinner_foreground_color=ForegroundColorEnum.cyan
)
@staticmethod
def _create_template(project_path: str, template: TemplateFileABC):
"""
Creates template
:param project_path:
:param template:
:return:
"""
file_path = os.path.join(project_path, template.path, template.name)
file_rel_path = os.path.join(project_path, template.path)
if not os.path.isdir(file_rel_path):
os.makedirs(file_rel_path)
with open(file_path, 'w') as license_file:
license_file.write(template.value)
license_file.close()
def _console(self, args: list[str]): def _console(self, args: list[str]):
""" """
Generates new console project Generates new console project
@@ -226,9 +168,44 @@ class NewService(CommandABC):
if path is None: if path is None:
return return
self._get_project_informations() self._get_project_information()
try: try:
self._build_project_dir(path) ConsoleBuilder.build(
path,
self._use_application_api,
self._use_startup,
self._use_service_providing,
self._project.name,
self._project_json
)
except Exception as e:
Console.error('Could not create project', str(e))
def _library(self, args: list[str]):
"""
Generates new library project
:param args:
:return:
"""
name = self._config.get_configuration(self._command)
self._create_project_settings(name)
self._create_build_settings()
self._create_project_json()
path = self._get_project_path()
if path is None:
return
self._get_project_information()
try:
LibraryBuilder.build(
path,
self._use_application_api,
self._use_startup,
self._use_service_providing,
self._project.name,
self._project_json
)
except Exception as e: except Exception as e:
Console.error('Could not create project', str(e)) Console.error('Could not create project', str(e))
@@ -240,14 +217,15 @@ class NewService(CommandABC):
""" """
if len(args) == 0: if len(args) == 0:
self._help('Usage: cpl new <schematic> [options]') self._help('Usage: cpl new <schematic> [options]')
exit() return
self._command = args[0] self._command = str(args[0]).lower()
if self._command == 'console': if self._command == ProjectTypeEnum.console.value:
self._console(args) self._console(args)
elif self._command == ProjectTypeEnum.library.value:
self._library(args)
else: else:
self._help('Usage: cpl new <schematic> [options]') self._help('Usage: cpl new <schematic> [options]')
exit() return
Console.write('\n')

View File

@@ -21,4 +21,3 @@ class PublishService(CommandABC):
:return: :return:
""" """
self._publisher.publish() self._publisher.publish()
Console.write('\n')

View File

@@ -2,9 +2,9 @@ import json
import os import os
import subprocess import subprocess
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.console.console import Console from cpl.console.console import Console
from cpl.console.foreground_color_enum import ForegroundColorEnum from cpl.console.foreground_color_enum import ForegroundColorEnum
from cpl.environment.application_environment_abc import ApplicationEnvironmentABC
from cpl.utils.pip import Pip from cpl.utils.pip import Pip
from cpl_cli.command_abc import CommandABC from cpl_cli.command_abc import CommandABC
from cpl_cli.configuration.build_settings import BuildSettings from cpl_cli.configuration.build_settings import BuildSettings
@@ -14,17 +14,17 @@ from cpl_cli.configuration.settings_helper import SettingsHelper
class UninstallService(CommandABC): class UninstallService(CommandABC):
def __init__(self, runtime: ApplicationRuntimeABC, build_settings: BuildSettings, def __init__(self, env: ApplicationEnvironmentABC, build_settings: BuildSettings,
project_settings: ProjectSettings): project_settings: ProjectSettings):
""" """
Service for the CLI command uninstall Service for the CLI command uninstall
:param runtime: :param env:
:param build_settings: :param build_settings:
:param project_settings: :param project_settings:
""" """
CommandABC.__init__(self) CommandABC.__init__(self)
self._runtime = runtime self._env = env
self._build_settings = build_settings self._build_settings = build_settings
self._project_settings = project_settings self._project_settings = project_settings
@@ -74,7 +74,7 @@ class UninstallService(CommandABC):
ProjectSettings.__name__: SettingsHelper.get_project_settings_dict(self._project_settings), ProjectSettings.__name__: SettingsHelper.get_project_settings_dict(self._project_settings),
BuildSettings.__name__: SettingsHelper.get_build_settings_dict(self._build_settings) BuildSettings.__name__: SettingsHelper.get_build_settings_dict(self._build_settings)
} }
with open(os.path.join(self._runtime.working_directory, 'cpl.json'), 'w') as project_file: with open(os.path.join(self._env.working_directory, 'cpl.json'), 'w') as project_file:
project_file.write(json.dumps(config, indent=2)) project_file.write(json.dumps(config, indent=2))
project_file.close() project_file.close()

View File

@@ -2,9 +2,9 @@ import json
import os import os
import subprocess import subprocess
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.console.console import Console from cpl.console.console import Console
from cpl.console.foreground_color_enum import ForegroundColorEnum from cpl.console.foreground_color_enum import ForegroundColorEnum
from cpl.environment.application_environment_abc import ApplicationEnvironmentABC
from cpl.utils.pip import Pip from cpl.utils.pip import Pip
from cpl_cli.cli_settings import CLISettings from cpl_cli.cli_settings import CLISettings
from cpl_cli.command_abc import CommandABC from cpl_cli.command_abc import CommandABC
@@ -16,34 +16,45 @@ from cpl_cli.configuration.settings_helper import SettingsHelper
class UpdateService(CommandABC): class UpdateService(CommandABC):
def __init__(self, def __init__(self,
runtime: ApplicationRuntimeABC, env: ApplicationEnvironmentABC,
build_settings: BuildSettings, build_settings: BuildSettings,
project_settings: ProjectSettings, project_settings: ProjectSettings,
cli_settings: CLISettings): cli_settings: CLISettings):
""" """
Service for the CLI command update Service for the CLI command update
:param runtime: :param env:
:param build_settings: :param build_settings:
:param project_settings: :param project_settings:
:param cli_settings: :param cli_settings:
""" """
CommandABC.__init__(self) CommandABC.__init__(self)
self._runtime = runtime self._env = env
self._build_settings = build_settings self._build_settings = build_settings
self._project_settings = project_settings self._project_settings = project_settings
self._cli_settings = cli_settings self._cli_settings = cli_settings
def _update_project_dependencies(self): def _collect_project_dependencies(self) -> list[tuple]:
""" """
Updates project dependencies Collects project dependencies
:return: :return:
""" """
dependencies = []
for package in self._project_settings.dependencies: for package in self._project_settings.dependencies:
name = package name = package
if '==' in package: if '==' in package:
name = package.split('==')[0] name = package.split('==')[0]
dependencies.append((package, name))
return dependencies
def _update_project_dependencies(self, dependencies):
"""
Updates project dependencies
:return:
"""
for package, name in dependencies:
Pip.install( Pip.install(
name, name,
'--upgrade', '--upgrade',
@@ -66,11 +77,18 @@ class UpdateService(CommandABC):
Checks project dependencies for updates Checks project dependencies for updates
:return: :return:
""" """
Console.spinner( dependencies = Console.spinner(
'Collecting installed dependencies', self._update_project_dependencies, 'Collecting installed dependencies', self._collect_project_dependencies,
text_foreground_color=ForegroundColorEnum.green, text_foreground_color=ForegroundColorEnum.green,
spinner_foreground_color=ForegroundColorEnum.cyan spinner_foreground_color=ForegroundColorEnum.cyan
) )
Console.spinner(
'Updating installed dependencies', self._update_project_dependencies, dependencies,
text_foreground_color=ForegroundColorEnum.green,
spinner_foreground_color=ForegroundColorEnum.cyan
)
Console.write_line(f'Found {len(self._project_settings.dependencies)} dependencies.') Console.write_line(f'Found {len(self._project_settings.dependencies)} dependencies.')
@staticmethod @staticmethod
@@ -117,7 +135,7 @@ class UpdateService(CommandABC):
BuildSettings.__name__: SettingsHelper.get_build_settings_dict(self._build_settings) BuildSettings.__name__: SettingsHelper.get_build_settings_dict(self._build_settings)
} }
with open(os.path.join(self._runtime.working_directory, 'cpl.json'), 'w') as project: with open(os.path.join(self._env.working_directory, 'cpl.json'), 'w') as project:
project.write(json.dumps(config, indent=2)) project.write(json.dumps(config, indent=2))
project.close() project.close()
@@ -131,5 +149,3 @@ class UpdateService(CommandABC):
self._check_project_dependencies() self._check_project_dependencies()
self._check_outdated() self._check_outdated()
Pip.reset_executable() Pip.reset_executable()
Console.write('\n')

View File

@@ -1,13 +1,11 @@
from abc import abstractmethod from abc import abstractmethod, ABC
from cpl.dependency_injection.service_abc import ServiceABC
class CommandABC(ServiceABC): class CommandABC(ABC):
@abstractmethod @abstractmethod
def __init__(self): def __init__(self):
ServiceABC.__init__(self) ABC.__init__(self)
@abstractmethod @abstractmethod
def run(self, args: list[str]): pass def run(self, args: list[str]): pass

View File

@@ -1,25 +1,25 @@
import os import os
from abc import ABC
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.configuration.configuration_abc import ConfigurationABC from cpl.configuration.configuration_abc import ConfigurationABC
from cpl.dependency_injection.service_abc import ServiceABC from cpl.console.console import Console
from cpl.dependency_injection.service_provider_abc import ServiceProviderABC from cpl.dependency_injection.service_provider_abc import ServiceProviderABC
from cpl_cli.error import Error from cpl_cli.error import Error
from cpl_cli.command_model import CommandModel from cpl_cli.command_model import CommandModel
class CommandHandler(ServiceABC): class CommandHandler(ABC):
def __init__(self, runtime: ApplicationRuntimeABC, config: ConfigurationABC, services: ServiceProviderABC): def __init__(self, config: ConfigurationABC, services: ServiceProviderABC):
""" """
Service to handle incoming commands and args Service to handle incoming commands and args
:param runtime: :param config:
:param services: :param services:
""" """
ServiceABC.__init__(self) ABC.__init__(self)
self._runtime = runtime
self._config = config self._config = config
self._env = self._config.environment
self._services = services self._services = services
self._commands: list[CommandModel] = [] self._commands: list[CommandModel] = []
@@ -43,7 +43,7 @@ class CommandHandler(ServiceABC):
""" """
for command in self._commands: for command in self._commands:
if cmd == command.name or cmd in command.aliases: if cmd == command.name or cmd in command.aliases:
if command.is_project_needed and not os.path.isfile(os.path.join(self._runtime.working_directory, 'cpl.json')): if command.is_project_needed and not os.path.isfile(os.path.join(self._env.working_directory, 'cpl.json')):
Error.error('The command requires to be run in an CPL project, but a project could not be found.') Error.error('The command requires to be run in an CPL project, but a project could not be found.')
return return
@@ -51,3 +51,4 @@ class CommandHandler(ServiceABC):
self._config.add_json_file('cpl.json', optional=True, output=False) self._config.add_json_file('cpl.json', optional=True, output=False)
self._services.get_service(command.command).run(args) self._services.get_service(command.command).run(args)
Console.write('\n')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_cli.configuration'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.0'
from collections import namedtuple from collections import namedtuple
@@ -28,4 +28,4 @@ from .version_settings import VersionSettings
from .version_settings_name_enum import VersionSettingsNameEnum from .version_settings_name_enum import VersionSettingsNameEnum
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='0')

View File

@@ -1,3 +1,4 @@
import sys
import traceback import traceback
from typing import Optional from typing import Optional
@@ -5,6 +6,7 @@ from cpl.configuration.configuration_model_abc import ConfigurationModelABC
from cpl.console.console import Console from cpl.console.console import Console
from cpl.console.foreground_color_enum import ForegroundColorEnum from cpl.console.foreground_color_enum import ForegroundColorEnum
from cpl_cli.configuration.build_settings_name_enum import BuildSettingsNameEnum from cpl_cli.configuration.build_settings_name_enum import BuildSettingsNameEnum
from cpl_cli.configuration.project_type_enum import ProjectTypeEnum
class BuildSettings(ConfigurationModelABC): class BuildSettings(ConfigurationModelABC):
@@ -12,6 +14,7 @@ class BuildSettings(ConfigurationModelABC):
def __init__(self): def __init__(self):
ConfigurationModelABC.__init__(self) ConfigurationModelABC.__init__(self)
self._project_type: Optional[ProjectTypeEnum] = None
self._source_path: Optional[str] = None self._source_path: Optional[str] = None
self._output_path: Optional[str] = None self._output_path: Optional[str] = None
self._main: Optional[str] = None self._main: Optional[str] = None
@@ -21,6 +24,10 @@ class BuildSettings(ConfigurationModelABC):
self._excluded: Optional[list[str]] = None self._excluded: Optional[list[str]] = None
self._package_data: Optional[dict[str, list[str]]] = None self._package_data: Optional[dict[str, list[str]]] = None
@property
def project_type(self):
return self._project_type
@property @property
def source_path(self) -> str: def source_path(self) -> str:
return self._source_path return self._source_path
@@ -55,6 +62,7 @@ class BuildSettings(ConfigurationModelABC):
def from_dict(self, settings: dict): def from_dict(self, settings: dict):
try: try:
self._project_type = settings[BuildSettingsNameEnum.project_type.value]
self._source_path = settings[BuildSettingsNameEnum.source_path.value] self._source_path = settings[BuildSettingsNameEnum.source_path.value]
self._output_path = settings[BuildSettingsNameEnum.output_path.value] self._output_path = settings[BuildSettingsNameEnum.output_path.value]
self._include_package_data = bool(settings[BuildSettingsNameEnum.include_package_data.value]) self._include_package_data = bool(settings[BuildSettingsNameEnum.include_package_data.value])
@@ -63,6 +71,25 @@ class BuildSettings(ConfigurationModelABC):
self._included = settings[BuildSettingsNameEnum.included.value] self._included = settings[BuildSettingsNameEnum.included.value]
self._excluded = settings[BuildSettingsNameEnum.excluded.value] self._excluded = settings[BuildSettingsNameEnum.excluded.value]
self._package_data = settings[BuildSettingsNameEnum.package_data.value] self._package_data = settings[BuildSettingsNameEnum.package_data.value]
if sys.platform == 'win32':
self._source_path = str(self._source_path).replace('/', '\\')
self._output_path = str(self._output_path).replace('/', '\\')
# windows paths for excluded files
excluded = []
for ex in self._excluded:
excluded.append(str(ex).replace('/', '\\'))
self._excluded = excluded
# windows paths for included files
included = []
for inc in self._included:
included.append(str(inc).replace('/', '\\'))
self._included = included
except Exception as e: except Exception as e:
Console.set_foreground_color(ForegroundColorEnum.red) Console.set_foreground_color(ForegroundColorEnum.red)
Console.write_line( Console.write_line(

View File

@@ -3,6 +3,7 @@ from enum import Enum
class BuildSettingsNameEnum(Enum): class BuildSettingsNameEnum(Enum):
project_type = 'ProjectType'
source_path = 'SourcePath' source_path = 'SourcePath'
output_path = 'OutputPath' output_path = 'OutputPath'
main = 'Main' main = 'Main'

View File

@@ -0,0 +1,7 @@
from enum import Enum
class ProjectTypeEnum(Enum):
console = 'console'
library = 'library'

View File

@@ -34,6 +34,7 @@ class SettingsHelper:
@staticmethod @staticmethod
def get_build_settings_dict(build: BuildSettings) -> dict: def get_build_settings_dict(build: BuildSettings) -> dict:
return { return {
BuildSettingsNameEnum.project_type.value: build.project_type,
BuildSettingsNameEnum.source_path.value: build.source_path, BuildSettingsNameEnum.source_path.value: build.source_path,
BuildSettingsNameEnum.output_path.value: build.output_path, BuildSettingsNameEnum.output_path.value: build.output_path,
BuildSettingsNameEnum.main.value: build.main, BuildSettingsNameEnum.main.value: build.main,

View File

@@ -15,11 +15,11 @@ __title__ = 'cpl_cli.live_server'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.0'
from collections import namedtuple from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='0')

View File

@@ -6,28 +6,26 @@ import psutil as psutil
from watchdog.events import FileSystemEventHandler from watchdog.events import FileSystemEventHandler
from watchdog.observers import Observer from watchdog.observers import Observer
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.console.console import Console from cpl.console.console import Console
from cpl.dependency_injection.service_abc import ServiceABC from cpl.environment.application_environment_abc import ApplicationEnvironmentABC
from cpl_cli.configuration.build_settings import BuildSettings from cpl_cli.configuration.build_settings import BuildSettings
from cpl_cli.live_server.live_server_thread import LiveServerThread from cpl_cli.live_server.live_server_thread import LiveServerThread
class LiveServerService(ServiceABC, FileSystemEventHandler): class LiveServerService(FileSystemEventHandler):
def __init__(self, runtime: ApplicationRuntimeABC, build_settings: BuildSettings): def __init__(self, env: ApplicationEnvironmentABC, build_settings: BuildSettings):
""" """
Service for the live development server Service for the live development server
:param runtime: :param env:
:param build_settings: :param build_settings:
""" """
ServiceABC.__init__(self)
FileSystemEventHandler.__init__(self) FileSystemEventHandler.__init__(self)
self._runtime = runtime self._env = env
self._build_settings = build_settings self._build_settings = build_settings
self._src_dir = os.path.join(self._runtime.working_directory, self._build_settings.source_path) self._src_dir = os.path.join(self._env.working_directory, self._build_settings.source_path)
self._ls_thread = None self._ls_thread = None
self._observer = None self._observer = None
@@ -72,7 +70,7 @@ class LiveServerService(ServiceABC, FileSystemEventHandler):
def _start(self): def _start(self):
self._start_observer() self._start_observer()
self._ls_thread = LiveServerThread(self._src_dir) self._ls_thread = LiveServerThread(self._src_dir, self._build_settings)
self._ls_thread.start() self._ls_thread.start()
self._ls_thread.join() self._ls_thread.join()
Console.close() Console.close()

View File

@@ -6,11 +6,12 @@ from datetime import datetime
from cpl.console.console import Console from cpl.console.console import Console
from cpl.console.foreground_color_enum import ForegroundColorEnum from cpl.console.foreground_color_enum import ForegroundColorEnum
from cpl_cli.configuration import BuildSettings
class LiveServerThread(threading.Thread): class LiveServerThread(threading.Thread):
def __init__(self, path: str): def __init__(self, path: str, build_settings: BuildSettings):
""" """
Thread to start the CPL project for the live development server Thread to start the CPL project for the live development server
:param path: :param path:
@@ -18,13 +19,15 @@ class LiveServerThread(threading.Thread):
threading.Thread.__init__(self) threading.Thread.__init__(self)
self._path = path self._path = path
self._build_settings = build_settings
self._main = '' self._main = ''
self._command = [] self._command = []
@property @property
def command(self) -> list[str]: def command(self) -> list[str]:
return self._command return self._command
@property @property
def main(self) -> str: def main(self) -> str:
return self._main return self._main
@@ -34,7 +37,8 @@ class LiveServerThread(threading.Thread):
Starts the CPL project Starts the CPL project
:return: :return:
""" """
self._main = os.path.join(self._path, 'main.py') main = self._build_settings.main.replace('.', '/')
self._main = os.path.join(self._path, f'{main}.py')
if not os.path.isfile(self._main): if not os.path.isfile(self._main):
Console.error('Entry point main.py not found') Console.error('Entry point main.py not found')
return return
@@ -46,5 +50,13 @@ class LiveServerThread(threading.Thread):
Console.write_line(f'Started at {now.strftime("%Y-%m-%d %H:%M:%S")}\n\n') Console.write_line(f'Started at {now.strftime("%Y-%m-%d %H:%M:%S")}\n\n')
Console.set_foreground_color(ForegroundColorEnum.default) Console.set_foreground_color(ForegroundColorEnum.default)
env_vars = os.environ
if sys.platform == 'win32':
env_vars['PYTHONPATH'] = f'{os.path.dirname(self._path)};' \
f'{os.path.join(os.path.dirname(self._path), self._build_settings.source_path)}'
else:
env_vars['PYTHONPATH'] = f'{os.path.dirname(self._path)}:' \
f'{os.path.join(os.path.dirname(self._path), self._build_settings.source_path)}'
self._command = [sys.executable, self._main, ''.join(sys.argv[2:])] self._command = [sys.executable, self._main, ''.join(sys.argv[2:])]
subprocess.run(self._command) subprocess.run(self._command, env=env_vars)

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_cli.publish'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.0'
from collections import namedtuple from collections import namedtuple
@@ -24,4 +24,4 @@ from .publisher_abc import PublisherABC
from .publisher_service import PublisherService from .publisher_service import PublisherService
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='0')

View File

@@ -1,13 +1,11 @@
from abc import abstractmethod from abc import abstractmethod, ABC
from cpl.dependency_injection.service_abc import ServiceABC
class PublisherABC(ServiceABC): class PublisherABC(ABC):
@abstractmethod @abstractmethod
def __init__(self): def __init__(self):
ServiceABC.__init__(self) ABC.__init__(self)
@property @property
@abstractmethod @abstractmethod

View File

@@ -1,15 +1,15 @@
import importlib
import os import os
import shutil import shutil
import sys
from string import Template as stringTemplate from string import Template as stringTemplate
import setuptools import setuptools
from packaging import version from packaging import version
from setuptools import sandbox from setuptools import sandbox
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.console.foreground_color_enum import ForegroundColorEnum from cpl.console.foreground_color_enum import ForegroundColorEnum
from cpl.console.console import Console from cpl.console.console import Console
from cpl.environment.application_environment_abc import ApplicationEnvironmentABC
from cpl_cli.configuration.build_settings import BuildSettings from cpl_cli.configuration.build_settings import BuildSettings
from cpl_cli.configuration.project_settings import ProjectSettings from cpl_cli.configuration.project_settings import ProjectSettings
from cpl_cli.publish.publisher_abc import PublisherABC from cpl_cli.publish.publisher_abc import PublisherABC
@@ -19,45 +19,50 @@ from cpl_cli.templates.publish.setup_template import SetupTemplate
class PublisherService(PublisherABC): class PublisherService(PublisherABC):
def __init__(self, runtime: ApplicationRuntimeABC, project: ProjectSettings, build: BuildSettings): def __init__(self, env: ApplicationEnvironmentABC, project: ProjectSettings, build: BuildSettings):
""" """
Service to build or publish files for distribution Service to build or publish files for distribution
:param runtime: :param env:
:param project: :param project:
:param build: :param build:
""" """
PublisherABC.__init__(self) PublisherABC.__init__(self)
self._runtime = runtime self._env = env
self._project_settings = project self._project_settings = project
self._build_settings = build self._build_settings = build
self._source_path = os.path.join(self._runtime.working_directory, self._build_settings.source_path) self._source_path = os.path.join(self._env.working_directory, self._build_settings.source_path)
self._output_path = os.path.join(self._runtime.working_directory, self._build_settings.output_path) self._output_path = os.path.join(self._env.working_directory, self._build_settings.output_path)
self._included_files: list[str] = [] self._included_files: list[str] = []
self._included_dirs: list[str] = [] self._included_dirs: list[str] = []
self._distributed_files: list[str] = [] self._distributed_files: list[str] = []
self._path_mark = '/'
if sys.platform == 'win32':
self._path_mark = '\\'
self._src_path_part = f'src{self._path_mark}'
@property @property
def source_path(self) -> str: def source_path(self) -> str:
return '' return self._source_path
@property @property
def dist_path(self) -> str: def dist_path(self) -> str:
return '' return self._output_path
@staticmethod def _get_module_name_from_dirs(self, file: str) -> str:
def _get_module_name_from_dirs(file: str) -> str:
""" """
Extracts module name from directories Extracts module name from directories
:param file: :param file:
:return: :return:
""" """
if 'src/' in file: if self._src_path_part in file:
file = file.replace('src/', '', 1) file = file.replace(self._src_path_part, '', 1)
dirs = os.path.dirname(file).split('/') dirs = os.path.dirname(file).split(self._path_mark)
for d in dirs: for d in dirs:
if d.__contains__('.'): if d.__contains__('.'):
dirs.remove(d) dirs.remove(d)
@@ -138,11 +143,9 @@ class PublisherService(PublisherABC):
relative_path = os.path.relpath(r) relative_path = os.path.relpath(r)
file_path = os.path.join(relative_path, os.path.relpath(sub_file)) file_path = os.path.join(relative_path, os.path.relpath(sub_file))
print(file_path)
self._included_files.append(os.path.relpath(file_path)) self._included_files.append(os.path.relpath(file_path))
elif os.path.isfile(rel_path): elif os.path.isfile(rel_path):
print(rel_path)
self._included_files.append(rel_path) self._included_files.append(rel_path)
for r, d, f in os.walk(self._build_settings.source_path): for r, d, f in os.walk(self._build_settings.source_path):
@@ -230,8 +233,8 @@ class PublisherService(PublisherABC):
for file in self._included_files: for file in self._included_files:
dist_file = file dist_file = file
if 'src/' in dist_file: if self._src_path_part in dist_file:
dist_file = dist_file.replace('src/', '', 1) dist_file = dist_file.replace(self._src_path_part, '', 1)
output_path = os.path.join(build_path, os.path.dirname(dist_file)) output_path = os.path.join(build_path, os.path.dirname(dist_file))
output_file = os.path.join(build_path, dist_file) output_file = os.path.join(build_path, dist_file)
@@ -252,8 +255,8 @@ class PublisherService(PublisherABC):
for empty_dir in self._included_dirs: for empty_dir in self._included_dirs:
dist_dir = empty_dir dist_dir = empty_dir
if 'src/' in dist_dir: if self._src_path_part in dist_dir:
dist_dir = dist_dir.replace('src/', '', 1) dist_dir = dist_dir.replace(self._src_path_part, '', 1)
output_path = os.path.join(build_path, dist_dir) output_path = os.path.join(build_path, dist_dir)
if not os.path.isdir(output_path): if not os.path.isdir(output_path):
@@ -272,7 +275,7 @@ class PublisherService(PublisherABC):
os.remove(file) os.remove(file)
for path in paths: for path in paths:
if os.path.isdir(path): if path != self._output_path and os.path.isdir(path):
shutil.rmtree(path) shutil.rmtree(path)
def _create_setup(self): def _create_setup(self):
@@ -288,14 +291,30 @@ class PublisherService(PublisherABC):
main = None main = None
try: try:
main = importlib.import_module(self._build_settings.main) main_name = self._build_settings.main
if '.' in self._build_settings.main:
length = len(self._build_settings.main.split('.'))
main_name = self._build_settings.main.split('.')[length - 1]
sys.path.insert(0, self._source_path)
main_mod = __import__(self._build_settings.main)
main = getattr(main_mod, main_name)
except Exception as e: except Exception as e:
Console.error('Could not find entry point', str(e)) Console.error('Could not find entry point', str(e))
return
if main is None or not hasattr(main, 'main'): if main is None or not callable(main) and not hasattr(main, 'main'):
Console.error('Could not find entry point') Console.error('Could not find entry point')
return return
if callable(main):
mod_name = main.__module__
func_name = main.__name__
else:
mod_name = main.__name__
func_name = main.main.__name__
with open(setup_file, 'w+') as setup_py: with open(setup_file, 'w+') as setup_py:
setup_string = stringTemplate(SetupTemplate.get_setup_py()).substitute( setup_string = stringTemplate(SetupTemplate.get_setup_py()).substitute(
Name=self._project_settings.name, Name=self._project_settings.name,
@@ -311,7 +330,7 @@ class PublisherService(PublisherABC):
Dependencies=self._project_settings.dependencies, Dependencies=self._project_settings.dependencies,
EntryPoints={ EntryPoints={
'console_scripts': [ 'console_scripts': [
f'{self._build_settings.entry_point} = {main.__name__}:{main.main.__name__}' f'{self._build_settings.entry_point} = {mod_name}:{func_name}'
] ]
}, },
PackageData=self._build_settings.package_data PackageData=self._build_settings.package_data
@@ -368,9 +387,13 @@ class PublisherService(PublisherABC):
""" """
self._output_path = os.path.join(self._output_path, 'build') self._output_path = os.path.join(self._output_path, 'build')
Console.spinner('Reading source files:', self._read_sources, text_foreground_color=ForegroundColorEnum.green, spinner_foreground_color=ForegroundColorEnum.blue) Console.spinner('Reading source files:', self._read_sources, text_foreground_color=ForegroundColorEnum.green,
Console.spinner('Creating internal packages:', self._create_packages, text_foreground_color=ForegroundColorEnum.green, spinner_foreground_color=ForegroundColorEnum.blue) spinner_foreground_color=ForegroundColorEnum.blue)
Console.spinner('Building application:', self._dist_files, text_foreground_color=ForegroundColorEnum.green, spinner_foreground_color=ForegroundColorEnum.blue) Console.spinner('Creating internal packages:', self._create_packages,
text_foreground_color=ForegroundColorEnum.green,
spinner_foreground_color=ForegroundColorEnum.blue)
Console.spinner('Building application:', self._dist_files, text_foreground_color=ForegroundColorEnum.green,
spinner_foreground_color=ForegroundColorEnum.blue)
def publish(self): def publish(self):
""" """
@@ -385,12 +408,40 @@ class PublisherService(PublisherABC):
self._output_path = os.path.join(self._output_path, 'publish') self._output_path = os.path.join(self._output_path, 'publish')
Console.write_line('Build:') Console.write_line('Build:')
Console.spinner('Reading source files:', self._read_sources, text_foreground_color=ForegroundColorEnum.green, spinner_foreground_color=ForegroundColorEnum.blue) Console.spinner(
Console.spinner('Creating internal packages:', self._create_packages, text_foreground_color=ForegroundColorEnum.green, spinner_foreground_color=ForegroundColorEnum.blue) 'Reading source files:',
Console.spinner('Building application:', self._dist_files, text_foreground_color=ForegroundColorEnum.green, spinner_foreground_color=ForegroundColorEnum.blue) self._read_sources,
text_foreground_color=ForegroundColorEnum.green,
spinner_foreground_color=ForegroundColorEnum.blue
)
Console.spinner(
'Creating internal packages:',
self._create_packages,
text_foreground_color=ForegroundColorEnum.green,
spinner_foreground_color=ForegroundColorEnum.blue
)
Console.spinner(
'Building application:',
self._dist_files,
text_foreground_color=ForegroundColorEnum.green,
spinner_foreground_color=ForegroundColorEnum.blue
)
Console.write_line('\nPublish:') Console.write_line('\nPublish:')
Console.spinner('Generating setup.py:', self._create_setup, text_foreground_color=ForegroundColorEnum.green, spinner_foreground_color=ForegroundColorEnum.blue) Console.spinner(
'Generating setup.py:',
self._create_setup,
text_foreground_color=ForegroundColorEnum.green,
spinner_foreground_color=ForegroundColorEnum.blue
)
Console.write_line('Running setup.py:\n') Console.write_line('Running setup.py:\n')
self._run_setup() self._run_setup()
Console.spinner('Cleaning dist path:', self._clean_dist_files, text_foreground_color=ForegroundColorEnum.green, spinner_foreground_color=ForegroundColorEnum.blue) Console.spinner(
'Cleaning dist path:',
self._clean_dist_files,
text_foreground_color=ForegroundColorEnum.green,
spinner_foreground_color=ForegroundColorEnum.blue
)

View File

@@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
"""
sh_cpl sh-edraft Common Python library
~~~~~~~~~~~~~~~~~~~
sh-edraft Common Python library
:copyright: (c) 2020 - 2021 sh-edraft.de
:license: MIT, see LICENSE for more details.
"""
__title__ = 'cpl_cli.source_creator'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.0'
from collections import namedtuple
# imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='0')

View File

@@ -0,0 +1,73 @@
import json
import os
from cpl.console.foreground_color_enum import ForegroundColorEnum
from cpl.console.console import Console
from cpl_cli.source_creator.template_builder import TemplateBuilder
from cpl_cli.templates.new.console.appsettings_json import AppsettingsTemplate
from cpl_cli.templates.new.console.license import LicenseTemplate
from cpl_cli.templates.new.console.readme_py import ReadmeTemplate
from cpl_cli.templates.new.console.src.name.application import ApplicationTemplate
from cpl_cli.templates.new.console.src.name.init import MainInitTemplate
from cpl_cli.templates.new.console.src.name.main import MainWithApplicationHostAndStartupTemplate, \
MainWithoutApplicationBaseTemplate, MainWithApplicationBaseTemplate, MainWithDependencyInjection
from cpl_cli.templates.new.console.src.name.startup import StartupTemplate
from cpl_cli.templates.new.console.src.tests.init import TestsInitTemplate
from cpl_cli.templates.template_file_abc import TemplateFileABC
class ConsoleBuilder:
def __init__(self):
pass
@staticmethod
def build(project_path: str, use_application_api: bool, use_startup: bool, use_service_providing: bool,
project_name: str, project_settings: dict):
"""
Builds the console project files
:param project_path:
:param use_application_api:
:param use_startup:
:param use_service_providing:
:param project_name:
:param project_settings:
:return:
"""
if not os.path.isdir(project_path):
os.makedirs(project_path)
with open(os.path.join(project_path, 'cpl.json'), 'w') as project_json:
project_json.write(json.dumps(project_settings, indent=2))
project_json.close()
templates: list[TemplateFileABC] = [
LicenseTemplate(),
ReadmeTemplate(),
TestsInitTemplate(),
AppsettingsTemplate(),
MainInitTemplate(project_name)
]
if use_application_api:
templates.append(ApplicationTemplate(project_name))
if use_startup:
templates.append(StartupTemplate(project_name))
templates.append(MainWithApplicationHostAndStartupTemplate(project_name))
else:
templates.append(MainWithApplicationBaseTemplate(project_name))
else:
if use_service_providing:
templates.append(MainWithDependencyInjection(project_name))
else:
templates.append(MainWithoutApplicationBaseTemplate(project_name))
for template in templates:
Console.spinner(
f'Creating {project_name}/{template.path}{template.name}',
TemplateBuilder.build,
project_path,
template,
text_foreground_color=ForegroundColorEnum.green,
spinner_foreground_color=ForegroundColorEnum.cyan
)

View File

@@ -0,0 +1,73 @@
import json
import os
from cpl.console.foreground_color_enum import ForegroundColorEnum
from cpl.console.console import Console
from cpl_cli.source_creator.template_builder import TemplateBuilder
from cpl_cli.templates.new.library.appsettings_json import AppsettingsTemplate
from cpl_cli.templates.new.library.license import LicenseTemplate
from cpl_cli.templates.new.library.readme_py import ReadmeTemplate
from cpl_cli.templates.new.library.src.cli.application import ApplicationTemplate
from cpl_cli.templates.new.library.src.cli.init import CLIInitTemplate
from cpl_cli.templates.new.library.src.cli.main import MainWithApplicationHostAndStartupTemplate, \
MainWithoutApplicationBaseTemplate, MainWithApplicationBaseTemplate, MainWithDependencyInjection
from cpl_cli.templates.new.library.src.cli.startup import StartupTemplate
from cpl_cli.templates.new.library.src.tests.init import TestsInitTemplate
from cpl_cli.templates.template_file_abc import TemplateFileABC
class LibraryBuilder:
def __init__(self):
pass
@staticmethod
def build(project_path: str, use_application_api: bool, use_startup: bool, use_service_providing: bool,
project_name: str, project_settings: dict):
"""
Builds the library project files
:param project_path:
:param use_application_api:
:param use_startup:
:param use_service_providing:
:param project_name:
:param project_settings:
:return:
"""
if not os.path.isdir(project_path):
os.makedirs(project_path)
with open(os.path.join(project_path, 'cpl.json'), 'w') as project_json:
project_json.write(json.dumps(project_settings, indent=2))
project_json.close()
templates: list[TemplateFileABC] = [
LicenseTemplate(),
ReadmeTemplate(),
TestsInitTemplate(),
CLIInitTemplate(project_name),
AppsettingsTemplate()
]
if use_application_api:
templates.append(ApplicationTemplate(project_name))
if use_startup:
templates.append(StartupTemplate(project_name))
templates.append(MainWithApplicationHostAndStartupTemplate(project_name))
else:
templates.append(MainWithApplicationBaseTemplate())
else:
if use_service_providing:
templates.append(MainWithDependencyInjection())
else:
templates.append(MainWithoutApplicationBaseTemplate())
for template in templates:
Console.spinner(
f'Creating {project_name}/{template.path}{template.name}',
TemplateBuilder.build,
project_path,
template,
text_foreground_color=ForegroundColorEnum.green,
spinner_foreground_color=ForegroundColorEnum.cyan
)

View File

@@ -0,0 +1,24 @@
import os
from cpl_cli.templates.template_file_abc import TemplateFileABC
class TemplateBuilder:
@staticmethod
def build(project_path: str, template: TemplateFileABC):
"""
Creates template
:param project_path:
:param template:
:return:
"""
file_path = os.path.join(project_path, template.path, template.name)
file_rel_path = os.path.join(project_path, template.path)
if not os.path.isdir(file_rel_path):
os.makedirs(file_rel_path)
with open(file_path, 'w') as license_file:
license_file.write(template.value)
license_file.close()

View File

@@ -1,7 +1,7 @@
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.application.startup_abc import StartupABC from cpl.application.startup_abc import StartupABC
from cpl.configuration.console_argument import ConsoleArgument from cpl.configuration.console_argument import ConsoleArgument
from cpl.configuration.configuration_abc import ConfigurationABC from cpl.configuration.configuration_abc import ConfigurationABC
from cpl.dependency_injection.service_collection_abc import ServiceCollectionABC
from cpl.dependency_injection.service_provider_abc import ServiceProviderABC from cpl.dependency_injection.service_provider_abc import ServiceProviderABC
from cpl_cli.command.build_service import BuildService from cpl_cli.command.build_service import BuildService
from cpl_cli.command.generate_service import GenerateService from cpl_cli.command.generate_service import GenerateService
@@ -22,21 +22,21 @@ from cpl_cli.publish.publisher_abc import PublisherABC
class Startup(StartupABC): class Startup(StartupABC):
def __init__(self, config: ConfigurationABC, runtime: ApplicationRuntimeABC, services: ServiceProviderABC): def __init__(self, config: ConfigurationABC, services: ServiceCollectionABC):
StartupABC.__init__(self) StartupABC.__init__(self)
self._configuration = config self._configuration = config
self._application_runtime = runtime self._env = self._configuration.environment
self._services = services self._services = services
self._application_runtime.set_runtime_directory(__file__) self._env.set_runtime_directory(__file__)
def configure_configuration(self) -> ConfigurationABC: def configure_configuration(self) -> ConfigurationABC:
self._configuration.argument_error_function = Error.error self._configuration.argument_error_function = Error.error
self._configuration.add_environment_variables('PYTHON_') self._configuration.add_environment_variables('PYTHON_')
self._configuration.add_environment_variables('CPL_') self._configuration.add_environment_variables('CPL_')
self._configuration.add_json_file('appsettings.json', path=self._application_runtime.runtime_directory, self._configuration.add_json_file('appsettings.json', path=self._env.runtime_directory,
optional=False, output=False) optional=False, output=False)
self._configuration.add_console_argument(ConsoleArgument('', 'build', ['b', 'B'], '')) self._configuration.add_console_argument(ConsoleArgument('', 'build', ['b', 'B'], ''))
self._configuration.add_console_argument(ConsoleArgument('', 'generate', ['g', 'G'], '', console_arguments=[ self._configuration.add_console_argument(ConsoleArgument('', 'generate', ['g', 'G'], '', console_arguments=[
@@ -52,7 +52,8 @@ class Startup(StartupABC):
ConsoleArgument('', 'install', ['i', 'I'], ' ', is_value_token_optional=True) ConsoleArgument('', 'install', ['i', 'I'], ' ', is_value_token_optional=True)
) )
self._configuration.add_console_argument(ConsoleArgument('', 'new', ['n', 'N'], '', console_arguments=[ self._configuration.add_console_argument(ConsoleArgument('', 'new', ['n', 'N'], '', console_arguments=[
ConsoleArgument('', 'console', ['c', 'C'], ' ') ConsoleArgument('', 'console', ['c', 'C'], ' '),
ConsoleArgument('', 'library', ['l', 'L'], ' ')
])) ]))
self._configuration.add_console_argument(ConsoleArgument('', 'publish', ['p', 'P'], '')) self._configuration.add_console_argument(ConsoleArgument('', 'publish', ['p', 'P'], ''))
self._configuration.add_console_argument(ConsoleArgument('', 'start', ['s', 'S'], '')) self._configuration.add_console_argument(ConsoleArgument('', 'start', ['s', 'S'], ''))
@@ -80,4 +81,4 @@ class Startup(StartupABC):
self._services.add_transient(UpdateService) self._services.add_transient(UpdateService)
self._services.add_transient(VersionService) self._services.add_transient(VersionService)
return self._services return self._services.build_service_provider()

View File

@@ -15,11 +15,11 @@ __title__ = 'cpl_cli.templates'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.0'
from collections import namedtuple from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='0')

View File

@@ -15,11 +15,11 @@ __title__ = 'cpl_cli.templates.build'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.0'
from collections import namedtuple from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='0')

View File

@@ -15,11 +15,11 @@ __title__ = 'cpl_cli.templates.generate'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.0'
from collections import namedtuple from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='0')

View File

@@ -0,0 +1,32 @@
import textwrap
from string import Template
from cpl.utils.string import String
from cpl_cli.templates.template_file_abc import TemplateFileABC
class InitTemplate(TemplateFileABC):
def __init__(self, name: str, schematic: str, schematic_upper: str, path: str):
TemplateFileABC.__init__(self)
self._name = f'__init__.py'
self._class_name = f'{String.first_to_upper(name)}{schematic_upper}'
self._path = path
self._value = textwrap.dedent("""\
# imports
""")
@property
def name(self) -> str:
return self._name
@property
def path(self) -> str:
return self._path
@property
def value(self) -> str:
return Template(self._value).substitute(
Name=self._class_name
)

View File

@@ -14,13 +14,10 @@ class ServiceTemplate(TemplateFileABC):
self._class_name = f'{String.first_to_upper(name)}{schematic_upper}' self._class_name = f'{String.first_to_upper(name)}{schematic_upper}'
self._path = path self._path = path
self._value = textwrap.dedent("""\ self._value = textwrap.dedent("""\
from cpl.dependency_injection import ServiceABC class $Name:
class $Name(ServiceABC):
def __init__(self): def __init__(self):
ServiceABC.__init__(self) pass
""") """)
@property @property

View File

@@ -15,11 +15,11 @@ __title__ = 'cpl_cli.templates.new'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.0'
from collections import namedtuple from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='0')

View File

@@ -15,11 +15,11 @@ __title__ = 'cpl_cli.templates.new.console'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.0'
from collections import namedtuple from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='0')

View File

@@ -0,0 +1,41 @@
import textwrap
from cpl_cli.templates.template_file_abc import TemplateFileABC
class AppsettingsTemplate(TemplateFileABC):
def __init__(self):
TemplateFileABC.__init__(self)
self._name = 'appsettings.json'
self._path = ''
self._value = textwrap.dedent("""\
{
"TimeFormatSettings": {
"DateFormat": "%Y-%m-%d",
"TimeFormat": "%H:%M:%S",
"DateTimeFormat": "%Y-%m-%d %H:%M:%S.%f",
"DateTimeLogFormat": "%Y-%m-%d_%H-%M-%S"
},
"LoggingSettings": {
"Path": "logs/",
"Filename": "log_$start_time.log",
"ConsoleLogLevel": "ERROR",
"FileLogLevel": "WARN"
}
}
""")
@property
def name(self) -> str:
return self._name
@property
def path(self) -> str:
return self._path
@property
def value(self) -> str:
return self._value

View File

@@ -15,11 +15,11 @@ __title__ = 'cpl_cli.templates.new.console.src'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.0'
from collections import namedtuple from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='0')

View File

@@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
"""
sh_cpl sh-edraft Common Python library
~~~~~~~~~~~~~~~~~~~
sh-edraft Common Python library
:copyright: (c) 2020 - 2021 sh-edraft.de
:license: MIT, see LICENSE for more details.
"""
__title__ = 'cpl_cli.templates.new.console.src.name'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.0'
from collections import namedtuple
# imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='0')

View File

@@ -1,27 +1,28 @@
import textwrap import textwrap
from cpl.utils.string import String
from cpl_cli.templates.template_file_abc import TemplateFileABC from cpl_cli.templates.template_file_abc import TemplateFileABC
class ApplicationTemplate(TemplateFileABC): class ApplicationTemplate(TemplateFileABC):
def __init__(self): def __init__(self, name: str):
TemplateFileABC.__init__(self) TemplateFileABC.__init__(self)
name = String.convert_to_snake_case(name)
self._name = 'application.py' self._name = 'application.py'
self._path = 'src/' self._path = f'src/{name}/'
self._value = textwrap.dedent("""\ self._value = textwrap.dedent("""\
from cpl.application.application_abc import ApplicationABC from cpl.application import ApplicationABC
from cpl.application.application_runtime_abc import ApplicationRuntimeABC from cpl.configuration import ConfigurationABC
from cpl.configuration.configuration_abc import ConfigurationABC from cpl.console import Console
from cpl.console.console import Console from cpl.dependency_injection import ServiceProviderABC
from cpl.dependency_injection.service_provider_abc import ServiceProviderABC
class Application(ApplicationABC): class Application(ApplicationABC):
def __init__(self, config: ConfigurationABC, runtime: ApplicationRuntimeABC, services: ServiceProviderABC): def __init__(self, config: ConfigurationABC, services: ServiceProviderABC):
ApplicationABC.__init__(self, config, runtime, services) ApplicationABC.__init__(self, config, services)
def configure(self): def configure(self):
pass pass

View File

@@ -0,0 +1,29 @@
import textwrap
from cpl.utils.string import String
from cpl_cli.templates.template_file_abc import TemplateFileABC
class MainInitTemplate(TemplateFileABC):
def __init__(self, name: str):
TemplateFileABC.__init__(self)
name = String.convert_to_snake_case(name)
self._name = '__init__.py'
self._path = f'src/{name}/'
self._value = textwrap.dedent("""\
# imports:
""")
@property
def name(self) -> str:
return self._name
@property
def path(self) -> str:
return self._path
@property
def value(self) -> str:
return self._value

View File

@@ -0,0 +1,158 @@
import textwrap
from cpl.utils.string import String
from cpl_cli.templates.template_file_abc import TemplateFileABC
class MainWithApplicationHostAndStartupTemplate(TemplateFileABC):
def __init__(self, name: str):
TemplateFileABC.__init__(self)
name = String.convert_to_snake_case(name)
self._name = 'main.py'
self._path = f'src/{name}/'
self._value = textwrap.dedent(f"""\
from cpl.application import ApplicationBuilder
from {name}.application import Application
from {name}.startup import Startup
def main():
app_builder = ApplicationBuilder(Application)
app_builder.use_startup(Startup)
app_builder.build().run()
if __name__ == '__main__':
main()
""")
@property
def name(self) -> str:
return self._name
@property
def path(self) -> str:
return self._path
@property
def value(self) -> str:
return self._value
class MainWithApplicationBaseTemplate(TemplateFileABC):
def __init__(self, name: str):
TemplateFileABC.__init__(self)
name = String.convert_to_snake_case(name)
self._name = 'main.py'
self._path = f'src/{name}'
self._value = textwrap.dedent(f"""\
from cpl.application import ApplicationBuilder
from {name}.application import Application
def main():
app_builder = ApplicationBuilder(Application)
app_builder.build().run()
if __name__ == '__main__':
main()
""")
@property
def name(self) -> str:
return self._name
@property
def path(self) -> str:
return self._path
@property
def value(self) -> str:
return self._value
class MainWithoutApplicationBaseTemplate(TemplateFileABC):
def __init__(self, name: str):
TemplateFileABC.__init__(self)
name = String.convert_to_snake_case(name)
self._name = 'main.py'
self._path = f'src/{name}'
self._value = textwrap.dedent("""\
from cpl.console import Console
def main():
Console.write_line('Hello World')
if __name__ == '__main__':
main()
""")
@property
def name(self) -> str:
return self._name
@property
def path(self) -> str:
return self._path
@property
def value(self) -> str:
return self._value
class MainWithDependencyInjection(TemplateFileABC):
def __init__(self, name: str):
TemplateFileABC.__init__(self)
name = String.convert_to_snake_case(name)
self._name = 'main.py'
self._path = f'src/{name}'
self._value = textwrap.dedent("""\
from cpl.configuration import Configuration, ConfigurationABC
from cpl.console import Console
from cpl.dependency_injection import ServiceCollection, ServiceProviderABC
def configure_configuration() -> ConfigurationABC:
config = Configuration()
return config
def configure_services(config: ConfigurationABC) -> ServiceProviderABC:
services = ServiceCollection(config)
return services.build_service_provider()
def main():
config = configure_configuration()
provider = configure_services(config)
Console.write_line('Hello World')
if __name__ == '__main__':
main()
""")
@property
def name(self) -> str:
return self._name
@property
def path(self) -> str:
return self._path
@property
def value(self) -> str:
return self._value

View File

@@ -1,37 +1,37 @@
import textwrap import textwrap
from cpl.utils.string import String
from cpl_cli.templates.template_file_abc import TemplateFileABC from cpl_cli.templates.template_file_abc import TemplateFileABC
class StartupTemplate(TemplateFileABC): class StartupTemplate(TemplateFileABC):
def __init__(self): def __init__(self, name: str):
TemplateFileABC.__init__(self) TemplateFileABC.__init__(self)
name = String.convert_to_snake_case(name)
self._name = 'startup.py' self._name = 'startup.py'
self._path = 'src/' self._path = f'src/{name}/'
self._value = textwrap.dedent("""\ self._value = textwrap.dedent("""\
from cpl.application.application_runtime_abc import ApplicationRuntimeABC from cpl.application import StartupABC
from cpl.application.startup_abc import StartupABC from cpl.configuration import ConfigurationABC
from cpl.configuration.configuration_abc import ConfigurationABC from cpl.dependency_injection import ServiceProviderABC, ServiceCollectionABC
from cpl.dependency_injection.service_provider_abc import ServiceProviderABC
class Startup(StartupABC): class Startup(StartupABC):
def __init__(self, config: ConfigurationABC, runtime: ApplicationRuntimeABC, services: ServiceProviderABC): def __init__(self, config: ConfigurationABC, services: ServiceCollectionABC):
StartupABC.__init__(self) StartupABC.__init__(self)
self._configuration = config self._configuration = config
self._application_runtime = runtime self._environment = self._configuration.environment
self._services = services self._services = services
def configure_configuration(self) -> ConfigurationABC: def configure_configuration(self) -> ConfigurationABC:
return self._configuration return self._configuration
def configure_services(self) -> ServiceProviderABC: def configure_services(self) -> ServiceProviderABC:
return self._services return self._services.build_service_provider()
""") """)
@property @property

View File

@@ -15,11 +15,11 @@ __title__ = 'cpl_cli.templates.new.console.src.tests'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.0'
from collections import namedtuple from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='0')

View File

@@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
"""
sh_cpl sh-edraft Common Python library
~~~~~~~~~~~~~~~~~~~
sh-edraft Common Python library
:copyright: (c) 2020 - 2021 sh-edraft.de
:license: MIT, see LICENSE for more details.
"""
__title__ = 'cpl_cli.templates.new.library'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.0'
from collections import namedtuple
# imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='0')

View File

@@ -0,0 +1,41 @@
import textwrap
from cpl_cli.templates.template_file_abc import TemplateFileABC
class AppsettingsTemplate(TemplateFileABC):
def __init__(self):
TemplateFileABC.__init__(self)
self._name = 'appsettings.json'
self._path = ''
self._value = textwrap.dedent("""\
{
"TimeFormatSettings": {
"DateFormat": "%Y-%m-%d",
"TimeFormat": "%H:%M:%S",
"DateTimeFormat": "%Y-%m-%d %H:%M:%S.%f",
"DateTimeLogFormat": "%Y-%m-%d_%H-%M-%S"
},
"LoggingSettings": {
"Path": "logs/",
"Filename": "log_$start_time.log",
"ConsoleLogLevel": "ERROR",
"FileLogLevel": "WARN"
}
}
""")
@property
def name(self) -> str:
return self._name
@property
def path(self) -> str:
return self._path
@property
def value(self) -> str:
return self._value

View File

@@ -0,0 +1,23 @@
from cpl_cli.templates.template_file_abc import TemplateFileABC
class LicenseTemplate(TemplateFileABC):
def __init__(self):
TemplateFileABC.__init__(self)
self._name = 'LICENSE'
self._path = ''
self._value = """"""
@property
def name(self) -> str:
return self._name
@property
def path(self) -> str:
return self._path
@property
def value(self) -> str:
return self._value

View File

@@ -0,0 +1,23 @@
from cpl_cli.templates.template_file_abc import TemplateFileABC
class ReadmeTemplate(TemplateFileABC):
def __init__(self):
TemplateFileABC.__init__(self)
self._name = 'README.md'
self._path = ''
self._value = """"""
@property
def name(self) -> str:
return self._name
@property
def path(self) -> str:
return self._path
@property
def value(self) -> str:
return self._value

View File

@@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
"""
sh_cpl sh-edraft Common Python library
~~~~~~~~~~~~~~~~~~~
sh-edraft Common Python library
:copyright: (c) 2020 - 2021 sh-edraft.de
:license: MIT, see LICENSE for more details.
"""
__title__ = 'cpl_cli.templates.new.library.src'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.0'
from collections import namedtuple
# imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='0')

View File

@@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
"""
sh_cpl sh-edraft Common Python library
~~~~~~~~~~~~~~~~~~~
sh-edraft Common Python library
:copyright: (c) 2020 - 2021 sh-edraft.de
:license: MIT, see LICENSE for more details.
"""
__title__ = 'cpl_cli.templates.new.library.src.cli'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.0'
from collections import namedtuple
# imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='0')

View File

@@ -0,0 +1,44 @@
import textwrap
from cpl.utils.string import String
from cpl_cli.templates.template_file_abc import TemplateFileABC
class ApplicationTemplate(TemplateFileABC):
def __init__(self, name: str):
TemplateFileABC.__init__(self)
name = String.convert_to_snake_case(name)
self._name = 'application.py'
self._path = f'src/{name}_cli/'
self._value = textwrap.dedent("""\
from cpl.application import ApplicationABC
from cpl.configuration import ConfigurationABC
from cpl.console import Console
from cpl.dependency_injection import ServiceProviderABC
class Application(ApplicationABC):
def __init__(self, config: ConfigurationABC, services: ServiceProviderABC):
ApplicationABC.__init__(self, config, services)
def configure(self):
pass
def main(self):
Console.write_line('Hello World')
""")
@property
def name(self) -> str:
return self._name
@property
def path(self) -> str:
return self._path
@property
def value(self) -> str:
return self._value

View File

@@ -0,0 +1,29 @@
import textwrap
from cpl.utils.string import String
from cpl_cli.templates.template_file_abc import TemplateFileABC
class CLIInitTemplate(TemplateFileABC):
def __init__(self, name: str):
TemplateFileABC.__init__(self)
name = String.convert_to_snake_case(name)
self._name = '__init__.py'
self._path = f'src/{name}_cli/'
self._value = textwrap.dedent("""\
# imports:
""")
@property
def name(self) -> str:
return self._name
@property
def path(self) -> str:
return self._path
@property
def value(self) -> str:
return self._value

View File

@@ -1,20 +1,22 @@
import textwrap import textwrap
from cpl.utils.string import String
from cpl_cli.templates.template_file_abc import TemplateFileABC from cpl_cli.templates.template_file_abc import TemplateFileABC
class MainWithApplicationHostAndStartupTemplate(TemplateFileABC): class MainWithApplicationHostAndStartupTemplate(TemplateFileABC):
def __init__(self): def __init__(self, name: str):
TemplateFileABC.__init__(self) TemplateFileABC.__init__(self)
name = String.convert_to_snake_case(name)
self._name = 'main.py' self._name = 'main.py'
self._path = 'src/' self._path = f'src/{name}_cli/'
self._value = textwrap.dedent("""\ self._value = textwrap.dedent(f"""\
from cpl.application.application_builder import ApplicationBuilder from cpl.application import ApplicationBuilder
from application import Application from {name}_cli.application import Application
from startup import Startup from {name}_cli.startup import Startup
def main(): def main():
@@ -40,17 +42,17 @@ class MainWithApplicationHostAndStartupTemplate(TemplateFileABC):
return self._value return self._value
class MainWithApplicationHostTemplate(TemplateFileABC): class MainWithApplicationBaseTemplate(TemplateFileABC):
def __init__(self): def __init__(self):
TemplateFileABC.__init__(self) TemplateFileABC.__init__(self)
self._name = 'main.py' self._name = 'main.py'
self._path = 'src/' self._path = 'src/'
self._value = textwrap.dedent("""\ self._value = textwrap.dedent(f"""\
from cpl.application.application_builder import ApplicationBuilder from cpl.application import ApplicationBuilder
from application import Application from {name}_cli.application import Application
def main(): def main():
@@ -75,7 +77,7 @@ class MainWithApplicationHostTemplate(TemplateFileABC):
return self._value return self._value
class MainWithoutApplicationHostTemplate(TemplateFileABC): class MainWithoutApplicationBaseTemplate(TemplateFileABC):
def __init__(self): def __init__(self):
TemplateFileABC.__init__(self) TemplateFileABC.__init__(self)
@@ -83,7 +85,7 @@ class MainWithoutApplicationHostTemplate(TemplateFileABC):
self._name = 'main.py' self._name = 'main.py'
self._path = 'src/' self._path = 'src/'
self._value = textwrap.dedent("""\ self._value = textwrap.dedent("""\
from cpl.console.console import Console from cpl.console import Console
def main(): def main():
@@ -105,3 +107,49 @@ class MainWithoutApplicationHostTemplate(TemplateFileABC):
@property @property
def value(self) -> str: def value(self) -> str:
return self._value return self._value
class MainWithDependencyInjection(TemplateFileABC):
def __init__(self):
TemplateFileABC.__init__(self)
self._name = 'main.py'
self._path = 'src/'
self._value = textwrap.dedent("""\
from cpl.configuration import Configuration, ConfigurationABC
from cpl.console import Console
from cpl.dependency_injection import ServiceCollection, ServiceProviderABC
def configure_configuration() -> ConfigurationABC:
config = Configuration()
return config
def configure_services(config: ConfigurationABC) -> ServiceProviderABC:
services = ServiceCollection(config)
return services.build_service_provider()
def main():
config = configure_configuration()
provider = configure_services(config)
Console.write_line('Hello World')
if __name__ == '__main__':
main()
""")
@property
def name(self) -> str:
return self._name
@property
def path(self) -> str:
return self._path
@property
def value(self) -> str:
return self._value

View File

@@ -0,0 +1,47 @@
import textwrap
from cpl.utils.string import String
from cpl_cli.templates.template_file_abc import TemplateFileABC
class StartupTemplate(TemplateFileABC):
def __init__(self, name: str):
TemplateFileABC.__init__(self)
name = String.convert_to_snake_case(name)
self._name = 'startup.py'
self._path = f'src/{name}_cli/'
self._value = textwrap.dedent("""\
from cpl.application import StartupABC
from cpl.configuration import ConfigurationABC
from cpl.dependency_injection import ServiceProviderABC, ServiceCollectionABC
class Startup(StartupABC):
def __init__(self, config: ConfigurationABC, services: ServiceCollectionABC):
StartupABC.__init__(self)
self._configuration = config
self._environment = self._configuration.environment
self._services = services
def configure_configuration(self) -> ConfigurationABC:
return self._configuration
def configure_services(self) -> ServiceProviderABC:
return self._services.build_service_provider()
""")
@property
def name(self) -> str:
return self._name
@property
def path(self) -> str:
return self._path
@property
def value(self) -> str:
return self._value

View File

@@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
"""
sh_cpl sh-edraft Common Python library
~~~~~~~~~~~~~~~~~~~
sh-edraft Common Python library
:copyright: (c) 2020 - 2021 sh-edraft.de
:license: MIT, see LICENSE for more details.
"""
__title__ = 'cpl_cli.templates.new.library.src.name'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.0'
from collections import namedtuple
# imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='0')

View File

@@ -0,0 +1,27 @@
import textwrap
from cpl_cli.templates.template_file_abc import TemplateFileABC
class TestsInitTemplate(TemplateFileABC):
def __init__(self, name: str):
TemplateFileABC.__init__(self)
self._name = '__init__.py'
self._path = f'src/{name}/'
self._value = textwrap.dedent("""\
# imports:
""")
@property
def name(self) -> str:
return self._name
@property
def path(self) -> str:
return self._path
@property
def value(self) -> str:
return self._value

View File

@@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
"""
sh_cpl sh-edraft Common Python library
~~~~~~~~~~~~~~~~~~~
sh-edraft Common Python library
:copyright: (c) 2020 - 2021 sh-edraft.de
:license: MIT, see LICENSE for more details.
"""
__title__ = 'cpl_cli.templates.new.library.src.tests'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.0'
from collections import namedtuple
# imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='0')

View File

@@ -0,0 +1,27 @@
import textwrap
from cpl_cli.templates.template_file_abc import TemplateFileABC
class TestsInitTemplate(TemplateFileABC):
def __init__(self):
TemplateFileABC.__init__(self)
self._name = '__init__.py'
self._path = 'src/tests/'
self._value = textwrap.dedent("""\
# imports:
""")
@property
def name(self) -> str:
return self._name
@property
def path(self) -> str:
return self._path
@property
def value(self) -> str:
return self._value

View File

@@ -15,11 +15,11 @@ __title__ = 'cpl_cli.templates.publish'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15' __version__ = '2021.4.0'
from collections import namedtuple from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15') version_info = VersionInfo(major='2021', minor='04', micro='0')

View File

@@ -6,6 +6,15 @@ def test_spinner():
time.sleep(2) time.sleep(2)
def test_console():
Console.write_line('Hello World')
Console.write('\nName: ')
Console.write_line(' Hello', Console.read_line())
Console.clear()
Console.write_at(5, 5, 'at 5, 5')
Console.write_at(10, 10, 'at 10, 10')
if __name__ == '__main__': if __name__ == '__main__':
Console.write_line('Hello World\n') Console.write_line('Hello World\n')
Console.spinner('Test:', test_spinner, spinner_foreground_color=ForegroundColorEnum.cyan, Console.spinner('Test:', test_spinner, spinner_foreground_color=ForegroundColorEnum.cyan,
@@ -25,5 +34,6 @@ if __name__ == '__main__':
# cursor_foreground_color=ForegroundColorEnum.red # cursor_foreground_color=ForegroundColorEnum.red
# ) # )
# Console.write_line(f'You selected: {selected}') # Console.write_line(f'You selected: {selected}')
# test_console()
Console.write_line() Console.write_line()

View File

@@ -1,13 +0,0 @@
from cpl.console.console import Console
from model.test_model import TestModel
def main():
Console.write_line('Hello World')
Console.write_line('Dies ist ein test')
test = TestModel()
if __name__ == '__main__':
main()

View File

@@ -1,22 +0,0 @@
import time
from cpl.console import Console
class TestModel:
def __init__(self):
Console.spinner('Waiting: ', self._wait, 10)
option = Console.select('->', 'Select option: ', [
'Option 1',
'Option 2',
'Option 3',
'Option 4',
'Option 5',
'Option 6'
])
Console.write_line('You selected', option)
@staticmethod
def _wait(count: int):
time.sleep(count)

Some files were not shown because too many files have changed in this diff Show More