From aa90adfd48c05a481ca45efa1e94f16947357c47 Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Tue, 15 Dec 2020 20:08:43 +0100 Subject: [PATCH 01/20] Publish improvements for pip install --- docs/cli.md | 6 ++++++ docs/install.md | 0 src/setup.py | 17 +++++++++++++++-- src/sh_edraft/cli/__init__.py | 25 +++++++++++++++++++++++++ src/sh_edraft/cli/cpl_cli.py | 8 ++++++++ src/tests_dev/publisher.py | 4 +++- 6 files changed, 57 insertions(+), 3 deletions(-) create mode 100644 docs/cli.md create mode 100644 docs/install.md create mode 100644 src/sh_edraft/cli/__init__.py create mode 100644 src/sh_edraft/cli/cpl_cli.py diff --git a/docs/cli.md b/docs/cli.md new file mode 100644 index 00000000..1ec439a0 --- /dev/null +++ b/docs/cli.md @@ -0,0 +1,6 @@ +prefix: cpl +commands: + new: + app + class + model \ No newline at end of file diff --git a/docs/install.md b/docs/install.md new file mode 100644 index 00000000..e69de29b diff --git a/src/setup.py b/src/setup.py index 4f86d310..b413a815 100644 --- a/src/setup.py +++ b/src/setup.py @@ -3,10 +3,23 @@ import setuptools setuptools.setup( name='sh_edraft', version='2020.0.1', - packages=setuptools.find_packages(), + packages=setuptools.find_packages(exclude=["tests*"]), url='https://www.sh-edraft.de', license='MIT', author='Sven Heidemann', author_email='edraft.sh@gmail.com', - description='sh-edraft python common lib' + description='sh-edraft python common lib', + python_requires='>=3.8', + install_requires=[ + 'discord.py', + 'flask', + 'mysql-connector', + 'SQLAlchemy', + 'termcolor' + ], + entry_points={ + 'console_scripts': [ + 'cpl = sh_edraft.cli.cpl_cli:main' + ] + } ) diff --git a/src/sh_edraft/cli/__init__.py b/src/sh_edraft/cli/__init__.py new file mode 100644 index 00000000..89b6ae33 --- /dev/null +++ b/src/sh_edraft/cli/__init__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- + +""" +sh_edraft.cli +~~~~~~~~~~~~~~~~~~~ + + + +:copyright: (c) 2020 sh-edraft.de +:license: MIT, see LICENSE for more details. + +""" + +__title__ = 'sh_edraft.cli' +__author__ = 'Sven Heidemann' +__license__ = 'MIT' +__copyright__ = 'Copyright (c) 2020 sh-edraft.de' +__version__ = '2020.12.9' + +from collections import namedtuple + +# imports: + +VersionInfo = namedtuple('VersionInfo', 'major minor micro') +version_info = VersionInfo(major=2020, minor=12, micro=9) diff --git a/src/sh_edraft/cli/cpl_cli.py b/src/sh_edraft/cli/cpl_cli.py new file mode 100644 index 00000000..7d8e25e4 --- /dev/null +++ b/src/sh_edraft/cli/cpl_cli.py @@ -0,0 +1,8 @@ +class CPLCli: + def main(self): + print('Hello world') + + +def main(): + cli = CPLCli() + cli.main() diff --git a/src/tests_dev/publisher.py b/src/tests_dev/publisher.py index f07de2f0..f9eea080 100644 --- a/src/tests_dev/publisher.py +++ b/src/tests_dev/publisher.py @@ -1,7 +1,6 @@ from typing import Optional from sh_edraft.configuration.base import ConfigurationBase -from sh_edraft.console import Console from sh_edraft.hosting import ApplicationHost from sh_edraft.hosting.base import ApplicationBase from sh_edraft.logging import Logger @@ -51,6 +50,9 @@ class Program(ApplicationBase): self._logger.debug(__name__, f'Customer: {self._configuration.environment.customer}') self._publisher.exclude('../tests') self._publisher.exclude('../tests_dev') + self._publisher.include('../../LICENSE') + self._publisher.include('../../README.MD') + self._publisher.include('../../requirements.txt') self._publisher.create() self._publisher.publish() From d76bf4564503a689aabf51150c03f755ec0bfeb9 Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Tue, 15 Dec 2020 20:11:41 +0100 Subject: [PATCH 02/20] Improved setup.py --- docs/install.md | 2 ++ src/setup.py | 2 +- src/sh_edraft/cli/cpl_cli.py | 9 +++------ 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/docs/install.md b/docs/install.md index e69de29b..1691ccfe 100644 --- a/docs/install.md +++ b/docs/install.md @@ -0,0 +1,2 @@ +python setup.py install # for install +python setup.py sdist bdist # for build \ No newline at end of file diff --git a/src/setup.py b/src/setup.py index b413a815..5f656653 100644 --- a/src/setup.py +++ b/src/setup.py @@ -19,7 +19,7 @@ setuptools.setup( ], entry_points={ 'console_scripts': [ - 'cpl = sh_edraft.cli.cpl_cli:main' + 'cpl = sh_edraft.cli.cpl_cli:CPLCli.main' ] } ) diff --git a/src/sh_edraft/cli/cpl_cli.py b/src/sh_edraft/cli/cpl_cli.py index 7d8e25e4..11bfe8e2 100644 --- a/src/sh_edraft/cli/cpl_cli.py +++ b/src/sh_edraft/cli/cpl_cli.py @@ -1,8 +1,5 @@ class CPLCli: - def main(self): + + @staticmethod + def main(): print('Hello world') - - -def main(): - cli = CPLCli() - cli.main() From 8c531ebd113331bed5bc4a75296736ad655fa31c Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Tue, 15 Dec 2020 22:16:24 +0100 Subject: [PATCH 03/20] Added first cli commands --- docs/cli.md | 5 +- src/setup.py | 2 +- src/sh_edraft/cli/cpl_cli.py | 5 -- src/sh_edraft/cli/cpl_cli/__init__.py | 0 src/sh_edraft/cli/cpl_cli/cli.py | 33 +++++++ src/sh_edraft/cli/cpl_cli/cli_commands.py | 87 +++++++++++++++++++ .../cli/cpl_cli/templates/app/__init__.txt | 1 + .../cli/cpl_cli/templates/app/main.txt | 8 ++ .../cli/cpl_cli/templates/app/program.txt | 43 +++++++++ .../cli/cpl_cli/templates/base/base.txt | 10 +++ .../cli/cpl_cli/templates/class/class.txt | 4 + .../cpl_cli/templates/configmodel/model.txt | 20 +++++ .../cli/cpl_cli/templates/enum/enum.txt | 6 ++ .../cli/cpl_cli/templates/module/__init__.py | 0 .../cli/cpl_cli/templates/service/service.txt | 6 ++ 15 files changed, 223 insertions(+), 7 deletions(-) delete mode 100644 src/sh_edraft/cli/cpl_cli.py create mode 100644 src/sh_edraft/cli/cpl_cli/__init__.py create mode 100644 src/sh_edraft/cli/cpl_cli/cli.py create mode 100644 src/sh_edraft/cli/cpl_cli/cli_commands.py create mode 100644 src/sh_edraft/cli/cpl_cli/templates/app/__init__.txt create mode 100644 src/sh_edraft/cli/cpl_cli/templates/app/main.txt create mode 100644 src/sh_edraft/cli/cpl_cli/templates/app/program.txt create mode 100644 src/sh_edraft/cli/cpl_cli/templates/base/base.txt create mode 100644 src/sh_edraft/cli/cpl_cli/templates/class/class.txt create mode 100644 src/sh_edraft/cli/cpl_cli/templates/configmodel/model.txt create mode 100644 src/sh_edraft/cli/cpl_cli/templates/enum/enum.txt create mode 100644 src/sh_edraft/cli/cpl_cli/templates/module/__init__.py create mode 100644 src/sh_edraft/cli/cpl_cli/templates/service/service.txt diff --git a/docs/cli.md b/docs/cli.md index 1ec439a0..f2f2291e 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -2,5 +2,8 @@ prefix: cpl commands: new: app + base class - model \ No newline at end of file + configmodel + enum + service \ No newline at end of file diff --git a/src/setup.py b/src/setup.py index 5f656653..b99cc603 100644 --- a/src/setup.py +++ b/src/setup.py @@ -19,7 +19,7 @@ setuptools.setup( ], entry_points={ 'console_scripts': [ - 'cpl = sh_edraft.cli.cpl_cli:CPLCli.main' + 'cpl = sh_edraft.cli.cpl_cli.cli:main' ] } ) diff --git a/src/sh_edraft/cli/cpl_cli.py b/src/sh_edraft/cli/cpl_cli.py deleted file mode 100644 index 11bfe8e2..00000000 --- a/src/sh_edraft/cli/cpl_cli.py +++ /dev/null @@ -1,5 +0,0 @@ -class CPLCli: - - @staticmethod - def main(): - print('Hello world') diff --git a/src/sh_edraft/cli/cpl_cli/__init__.py b/src/sh_edraft/cli/cpl_cli/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/sh_edraft/cli/cpl_cli/cli.py b/src/sh_edraft/cli/cpl_cli/cli.py new file mode 100644 index 00000000..49974db2 --- /dev/null +++ b/src/sh_edraft/cli/cpl_cli/cli.py @@ -0,0 +1,33 @@ +import sys + +from sh_edraft.cli.cpl_cli.cli_commands import CLICommands + + +class CLI: + + def __init__(self): + self._commands: dict = {} + + def setup(self): + self._commands[CLICommands.new.__name__] = CLICommands.new + + def main(self): + args = sys.argv[1:] + + try: + cmd = self._commands[args[0]] + cmd(args[1:]) + except KeyError: + CLICommands.unexpected_command(args[0]) + except Exception as e: + print(e) + + +def main(): + cli = CLI() + cli.setup() + cli.main() + + +if __name__ == '__main__': + main() diff --git a/src/sh_edraft/cli/cpl_cli/cli_commands.py b/src/sh_edraft/cli/cpl_cli/cli_commands.py new file mode 100644 index 00000000..53986d34 --- /dev/null +++ b/src/sh_edraft/cli/cpl_cli/cli_commands.py @@ -0,0 +1,87 @@ +import os + + +class CLICommands: + + @classmethod + def new(cls, args: list[str]): + if not os.path.isdir(f'./templates/{args[0]}'): + cls.unexpected_command(args[0]) + + sub_args = args[1:] + + if len(sub_args) != 1: + cls.unexpected_argument(sub_args[1]) + + full_path = sub_args[0] + name = os.path.basename(full_path) + path = os.path.dirname(full_path) + + if args[0] in ['base', 'class', 'configmodel', 'enum', 'service']: + if not os.path.isdir(path): + os.makedirs(path) + else: + if not os.path.isdir(full_path): + os.makedirs(full_path) + + for r, d, f in os.walk(f'./templates/{args[0]}'): + for file in f: + template_content = '' + with open(f'{r}/{file}') as template: + template_content = template.read() + template.close() + + file = file.replace('txt', 'py') + if args[0] in ['base', 'class', 'configmodel', 'enum', 'service']: + suffix = None + + if args[0] == 'base': + suffix = 'base' + + elif args[0] == 'configmodel': + suffix = 'settings' + + elif args[0] == 'service': + suffix = 'service' + + if suffix is not None: + file_path = f'{path}/{name}_{suffix}.py' + else: + file_path = f'{path}/{name}.py' + else: + file_path = f'{full_path}/{file}' + + with open(file_path, 'w+') as pyfile: + if name[0].islower(): + name = f'{name[0].upper()}{name[1:]}' + + if args[0] == 'configmodel': + template_content = template_content.replace('$Name', f'{name}Settings') + pyfile.write(template_content) + + elif args[0] == 'service': + template_content = template_content.replace('$Name', f'{name}Service') + template_content = template_content.replace('$Base', f'{name}Base') + pyfile.write(template_content) + + else: + template_content = template_content.replace('$Name', name) + pyfile.write(template_content) + + pyfile.close() + + @staticmethod + def help(): + print('Commands:') + + @classmethod + def unexpected_command(cls, command: str): + print(f'Unexpected command {command}') + cls.help() + exit() + + @classmethod + def unexpected_argument(cls, argument: str): + print(f'Unexpected argument {argument}') + cls.help() + exit() diff --git a/src/sh_edraft/cli/cpl_cli/templates/app/__init__.txt b/src/sh_edraft/cli/cpl_cli/templates/app/__init__.txt new file mode 100644 index 00000000..2e12875a --- /dev/null +++ b/src/sh_edraft/cli/cpl_cli/templates/app/__init__.txt @@ -0,0 +1 @@ +# imports: \ No newline at end of file diff --git a/src/sh_edraft/cli/cpl_cli/templates/app/main.txt b/src/sh_edraft/cli/cpl_cli/templates/app/main.txt new file mode 100644 index 00000000..081d79dd --- /dev/null +++ b/src/sh_edraft/cli/cpl_cli/templates/app/main.txt @@ -0,0 +1,8 @@ +from program import Program + +if __name__ == '__main__': + program = Program() + program.create_application_host() + program.create_configuration() + program.create_services() + program.main() diff --git a/src/sh_edraft/cli/cpl_cli/templates/app/program.txt b/src/sh_edraft/cli/cpl_cli/templates/app/program.txt new file mode 100644 index 00000000..890c6b73 --- /dev/null +++ b/src/sh_edraft/cli/cpl_cli/templates/app/program.txt @@ -0,0 +1,43 @@ +from typing import Optional + +from sh_edraft.configuration.base import ConfigurationBase +from sh_edraft.hosting import ApplicationHost +from sh_edraft.hosting.base import ApplicationBase +from sh_edraft.logging import Logger +from sh_edraft.logging.base import LoggerBase +from sh_edraft.service.providing.base import ServiceProviderBase + + +class Program(ApplicationBase): + + def __init__(self): + ApplicationBase.__init__(self) + + self._app_host: Optional[ApplicationHost] = None + self._services: Optional[ServiceProviderBase] = None + self._configuration: Optional[ConfigurationBase] = None + self._logger: Optional[LoggerBase] = None + + def create_application_host(self): + self._app_host = ApplicationHost() + self._configuration = self._app_host.configuration + self._services = self._app_host.services + + def create_configuration(self): + self._configuration.add_environment_variables('PYTHON_') + self._configuration.add_environment_variables('CPL_') + self._configuration.add_argument_variables() + self._configuration.add_json_file(f'appsettings.json') + self._configuration.add_json_file(f'appsettings.{self._configuration.environment.environment_name}.json', optional=True) + self._configuration.add_json_file(f'appsettings.{self._configuration.environment.host_name}.json', optional=True) + + def create_services(self): + # Add and create logger + self._services.add_singleton(LoggerBase, Logger) + self._logger = self._services.get_service(LoggerBase) + + def main(self): + self._logger.header(f'{self._configuration.environment.application_name}:') + self._logger.debug(__name__, f'Host: {self._configuration.environment.host_name}') + self._logger.debug(__name__, f'Environment: {self._configuration.environment.environment_name}') + self._logger.debug(__name__, f'Customer: {self._configuration.environment.customer}') diff --git a/src/sh_edraft/cli/cpl_cli/templates/base/base.txt b/src/sh_edraft/cli/cpl_cli/templates/base/base.txt new file mode 100644 index 00000000..1940e8ab --- /dev/null +++ b/src/sh_edraft/cli/cpl_cli/templates/base/base.txt @@ -0,0 +1,10 @@ +from abc import ABC, abstractmethod + + +class $Name(ABC): + + @abstractmethod + def __init__(self): pass + + @abstractmethod + def create(self): pass diff --git a/src/sh_edraft/cli/cpl_cli/templates/class/class.txt b/src/sh_edraft/cli/cpl_cli/templates/class/class.txt new file mode 100644 index 00000000..d22b7581 --- /dev/null +++ b/src/sh_edraft/cli/cpl_cli/templates/class/class.txt @@ -0,0 +1,4 @@ +class $Name: + + def __init__(self): + pass diff --git a/src/sh_edraft/cli/cpl_cli/templates/configmodel/model.txt b/src/sh_edraft/cli/cpl_cli/templates/configmodel/model.txt new file mode 100644 index 00000000..ca37a816 --- /dev/null +++ b/src/sh_edraft/cli/cpl_cli/templates/configmodel/model.txt @@ -0,0 +1,20 @@ +import traceback + +from sh_edraft.configuration.base import ConfigurationModelBase +from sh_edraft.console import Console +from sh_edraft.console.model import ForegroundColor + + +class $Name(ConfigurationModelBase): + + def __init__(self): + ConfigurationModelBase.__init__(self) + + def from_dict(self, settings: dict): + try: + pass + except Exception as e: + Console.set_foreground_color(ForegroundColor.red) + Console.write_line(f'[ ERROR ] [ {__name__} ]: Reading error in {self.__name__} settings') + Console.write_line(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}') + Console.set_foreground_color(ForegroundColor.default) diff --git a/src/sh_edraft/cli/cpl_cli/templates/enum/enum.txt b/src/sh_edraft/cli/cpl_cli/templates/enum/enum.txt new file mode 100644 index 00000000..a7aef900 --- /dev/null +++ b/src/sh_edraft/cli/cpl_cli/templates/enum/enum.txt @@ -0,0 +1,6 @@ +from enum import Enum + + +class $Name(Enum): + + pass diff --git a/src/sh_edraft/cli/cpl_cli/templates/module/__init__.py b/src/sh_edraft/cli/cpl_cli/templates/module/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/sh_edraft/cli/cpl_cli/templates/service/service.txt b/src/sh_edraft/cli/cpl_cli/templates/service/service.txt new file mode 100644 index 00000000..d2add199 --- /dev/null +++ b/src/sh_edraft/cli/cpl_cli/templates/service/service.txt @@ -0,0 +1,6 @@ +class $Name($Base): + + def __init__(self): + TestBase.__init__(self) + + self.create() From 97b4f516a88f323f998d634247b6058a5da2dd68 Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Tue, 15 Dec 2020 23:10:31 +0100 Subject: [PATCH 04/20] Bugfixes and improved setup logic --- docs/install.md | 4 ++-- requirements.txt | 26 +++++++++++++++++++++++ src/MANIFEST.in | 2 ++ src/setup.py | 1 + src/sh_edraft/cli/cpl_cli/cli.py | 1 + src/sh_edraft/cli/cpl_cli/cli_commands.py | 13 ++++++++---- 6 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 requirements.txt create mode 100644 src/MANIFEST.in diff --git a/docs/install.md b/docs/install.md index 1691ccfe..54c105b4 100644 --- a/docs/install.md +++ b/docs/install.md @@ -1,2 +1,2 @@ -python setup.py install # for install -python setup.py sdist bdist # for build \ No newline at end of file +python setup.py install # for install +python setup.py sdist bdist_wheel # for build \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..742e4085 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,26 @@ +aiohttp==3.6.3 +async-timeout==3.0.1 +attrs==20.3.0 +certifi==2020.11.8 +chardet==3.0.4 +click==7.1.2 +dateutils==0.6.12 +discord==1.0.1 +discord.py==1.5.1 +Flask==1.1.2 +idna==2.10 +itsdangerous==1.1.0 +Jinja2==2.11.2 +keyboard==0.13.5 +MarkupSafe==1.1.1 +multidict==4.7.6 +mysql-connector==2.2.9 +overloading==0.5.0 +python-dateutil==2.8.1 +pytz==2020.4 +six==1.15.0 +SQLAlchemy==1.3.20 +termcolor==1.1.0 +urllib3==1.26.2 +Werkzeug==1.0.1 +yarl==1.5.1 diff --git a/src/MANIFEST.in b/src/MANIFEST.in new file mode 100644 index 00000000..cb32f474 --- /dev/null +++ b/src/MANIFEST.in @@ -0,0 +1,2 @@ +include ../ README +recursive-include sh_edraft *.txt \ No newline at end of file diff --git a/src/setup.py b/src/setup.py index b99cc603..71cc0e2b 100644 --- a/src/setup.py +++ b/src/setup.py @@ -8,6 +8,7 @@ setuptools.setup( license='MIT', author='Sven Heidemann', author_email='edraft.sh@gmail.com', + include_package_data=True, description='sh-edraft python common lib', python_requires='>=3.8', install_requires=[ diff --git a/src/sh_edraft/cli/cpl_cli/cli.py b/src/sh_edraft/cli/cpl_cli/cli.py index 49974db2..a8ff912b 100644 --- a/src/sh_edraft/cli/cpl_cli/cli.py +++ b/src/sh_edraft/cli/cpl_cli/cli.py @@ -10,6 +10,7 @@ class CLI: def setup(self): self._commands[CLICommands.new.__name__] = CLICommands.new + self._commands[CLICommands.help.__name__] = CLICommands.help def main(self): args = sys.argv[1:] diff --git a/src/sh_edraft/cli/cpl_cli/cli_commands.py b/src/sh_edraft/cli/cpl_cli/cli_commands.py index 53986d34..cd0b6c21 100644 --- a/src/sh_edraft/cli/cpl_cli/cli_commands.py +++ b/src/sh_edraft/cli/cpl_cli/cli_commands.py @@ -5,7 +5,8 @@ class CLICommands: @classmethod def new(cls, args: list[str]): - if not os.path.isdir(f'./templates/{args[0]}'): + rel_path = os.path.dirname(__file__) + if not os.path.isdir(f'{rel_path}/templates/{args[0]}'): cls.unexpected_command(args[0]) sub_args = args[1:] @@ -13,7 +14,11 @@ class CLICommands: if len(sub_args) != 1: cls.unexpected_argument(sub_args[1]) - full_path = sub_args[0] + if not (sub_args[0].startswith('.') or sub_args[0].startswith('/')): + full_path = f'./{sub_args[0]}' + else: + full_path = sub_args[0] + name = os.path.basename(full_path) path = os.path.dirname(full_path) @@ -24,7 +29,7 @@ class CLICommands: if not os.path.isdir(full_path): os.makedirs(full_path) - for r, d, f in os.walk(f'./templates/{args[0]}'): + for r, d, f in os.walk(f'{rel_path}/templates/{args[0]}'): for file in f: template_content = '' with open(f'{r}/{file}') as template: @@ -71,7 +76,7 @@ class CLICommands: pyfile.close() @staticmethod - def help(): + def help(*args): print('Commands:') @classmethod From 88362006ef5ce18aada110c1892098cb7eaf8191 Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Wed, 16 Dec 2020 13:38:08 +0100 Subject: [PATCH 05/20] Improved cli --- src/sh_edraft/cli/command/__init__.py | 0 src/sh_edraft/cli/command/base/__init__.py | 0 .../cli/command/base/command_base.py | 10 +++ src/sh_edraft/cli/cpl_cli/cli.py | 19 ++--- src/sh_edraft/cli/cpl_cli/cli_commands.py | 6 +- .../cli/cpl_cli/commands/__init__.py | 0 src/sh_edraft/cli/cpl_cli/commands/help.py | 10 +++ src/sh_edraft/cli/cpl_cli/commands/new.py | 84 +++++++++++++++++++ src/sh_edraft/cli/interpreter/__init__.py | 0 src/sh_edraft/cli/interpreter/interpreter.py | 28 +++++++ 10 files changed, 146 insertions(+), 11 deletions(-) create mode 100644 src/sh_edraft/cli/command/__init__.py create mode 100644 src/sh_edraft/cli/command/base/__init__.py create mode 100644 src/sh_edraft/cli/command/base/command_base.py create mode 100644 src/sh_edraft/cli/cpl_cli/commands/__init__.py create mode 100644 src/sh_edraft/cli/cpl_cli/commands/help.py create mode 100644 src/sh_edraft/cli/cpl_cli/commands/new.py create mode 100644 src/sh_edraft/cli/interpreter/__init__.py create mode 100644 src/sh_edraft/cli/interpreter/interpreter.py diff --git a/src/sh_edraft/cli/command/__init__.py b/src/sh_edraft/cli/command/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/sh_edraft/cli/command/base/__init__.py b/src/sh_edraft/cli/command/base/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/sh_edraft/cli/command/base/command_base.py b/src/sh_edraft/cli/command/base/command_base.py new file mode 100644 index 00000000..bc63204b --- /dev/null +++ b/src/sh_edraft/cli/command/base/command_base.py @@ -0,0 +1,10 @@ +from abc import ABC, abstractmethod + + +class CommandBase(ABC): + + @abstractmethod + def __init__(self): pass + + @abstractmethod + def run(self, args: list[str]): pass diff --git a/src/sh_edraft/cli/cpl_cli/cli.py b/src/sh_edraft/cli/cpl_cli/cli.py index a8ff912b..b5d24415 100644 --- a/src/sh_edraft/cli/cpl_cli/cli.py +++ b/src/sh_edraft/cli/cpl_cli/cli.py @@ -1,25 +1,24 @@ import sys -from sh_edraft.cli.cpl_cli.cli_commands import CLICommands +from sh_edraft.cli.cpl_cli.commands.help import Help +from sh_edraft.cli.cpl_cli.commands.new import New +from sh_edraft.cli.interpreter.interpreter import Interpreter class CLI: def __init__(self): - self._commands: dict = {} + self._interpreter = Interpreter() def setup(self): - self._commands[CLICommands.new.__name__] = CLICommands.new - self._commands[CLICommands.help.__name__] = CLICommands.help + self._interpreter.add_command(New()) + self._interpreter.add_command(Help()) def main(self): - args = sys.argv[1:] - + print('CPL CLI:') + string = ' '.join(sys.argv[1:]) try: - cmd = self._commands[args[0]] - cmd(args[1:]) - except KeyError: - CLICommands.unexpected_command(args[0]) + self._interpreter.interpret(string) except Exception as e: print(e) diff --git a/src/sh_edraft/cli/cpl_cli/cli_commands.py b/src/sh_edraft/cli/cpl_cli/cli_commands.py index cd0b6c21..1d8d6765 100644 --- a/src/sh_edraft/cli/cpl_cli/cli_commands.py +++ b/src/sh_edraft/cli/cpl_cli/cli_commands.py @@ -60,7 +60,11 @@ class CLICommands: if name[0].islower(): name = f'{name[0].upper()}{name[1:]}' - if args[0] == 'configmodel': + if args[0] == 'base': + template_content = template_content.replace('$Name', f'{name}Base') + pyfile.write(template_content) + + elif args[0] == 'configmodel': template_content = template_content.replace('$Name', f'{name}Settings') pyfile.write(template_content) diff --git a/src/sh_edraft/cli/cpl_cli/commands/__init__.py b/src/sh_edraft/cli/cpl_cli/commands/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/sh_edraft/cli/cpl_cli/commands/help.py b/src/sh_edraft/cli/cpl_cli/commands/help.py new file mode 100644 index 00000000..3a723f14 --- /dev/null +++ b/src/sh_edraft/cli/cpl_cli/commands/help.py @@ -0,0 +1,10 @@ +from sh_edraft.cli.command.base.command_base import CommandBase + + +class Help(CommandBase): + + def __init__(self): + CommandBase.__init__(self) + + def run(self, args: list[str]): + print('Commands:') diff --git a/src/sh_edraft/cli/cpl_cli/commands/new.py b/src/sh_edraft/cli/cpl_cli/commands/new.py new file mode 100644 index 00000000..697d43c9 --- /dev/null +++ b/src/sh_edraft/cli/cpl_cli/commands/new.py @@ -0,0 +1,84 @@ +import os + +from sh_edraft.cli.command.base.command_base import CommandBase + + +class New(CommandBase): + + def __init__(self): + CommandBase.__init__(self) + + def run(self, args: list[str]): + rel_path = f'{os.path.dirname(__file__)}/../' + if not os.path.isdir(f'{rel_path}/templates/{args[0]}'): + print(f'Unexpected argument {args[0]}') + + sub_args = args[1:] + + if len(sub_args) != 1: + print(f'Unexpected argument {sub_args[1]}') + + if not (sub_args[0].startswith('.') or sub_args[0].startswith('/')): + full_path = f'./{sub_args[0]}' + else: + full_path = sub_args[0] + + name = os.path.basename(full_path) + path = os.path.dirname(full_path) + + if args[0] in ['base', 'class', 'configmodel', 'enum', 'service']: + if not os.path.isdir(path): + os.makedirs(path) + else: + if not os.path.isdir(full_path): + os.makedirs(full_path) + + for r, d, f in os.walk(f'{rel_path}/templates/{args[0]}'): + for file in f: + template_content = '' + with open(f'{r}/{file}') as template: + template_content = template.read() + template.close() + + file = file.replace('txt', 'py') + if args[0] in ['base', 'class', 'configmodel', 'enum', 'service']: + suffix = None + + if args[0] == 'base': + suffix = 'base' + + elif args[0] == 'configmodel': + suffix = 'settings' + + elif args[0] == 'service': + suffix = 'service' + + if suffix is not None: + file_path = f'{path}/{name}_{suffix}.py' + else: + file_path = f'{path}/{name}.py' + else: + file_path = f'{full_path}/{file}' + + with open(file_path, 'w+') as pyfile: + if name[0].islower(): + name = f'{name[0].upper()}{name[1:]}' + + if args[0] == 'base': + template_content = template_content.replace('$Name', f'{name}Base') + pyfile.write(template_content) + + elif args[0] == 'configmodel': + template_content = template_content.replace('$Name', f'{name}Settings') + pyfile.write(template_content) + + elif args[0] == 'service': + template_content = template_content.replace('$Name', f'{name}Service') + template_content = template_content.replace('$Base', f'{name}Base') + pyfile.write(template_content) + + else: + template_content = template_content.replace('$Name', name) + pyfile.write(template_content) + + pyfile.close() diff --git a/src/sh_edraft/cli/interpreter/__init__.py b/src/sh_edraft/cli/interpreter/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/sh_edraft/cli/interpreter/interpreter.py b/src/sh_edraft/cli/interpreter/interpreter.py new file mode 100644 index 00000000..7ee549ed --- /dev/null +++ b/src/sh_edraft/cli/interpreter/interpreter.py @@ -0,0 +1,28 @@ +from sh_edraft.cli.command.base.command_base import CommandBase + + +class Interpreter: + + def __init__(self): + self._commands: list[CommandBase] = [] + + def add_command(self, command: CommandBase): + self._commands.append(command) + + def remove_command(self, command: CommandBase): + self._commands.remove(command) + + def interpret(self, input_string: str): + input_list = input_string.split(' ') + commands = [type(cmd).__name__.lower() for cmd in self._commands] + command = input_list[0] + args = input_list[1:] + print(command) + if command in commands: + cmd = next((cmd for cmd in self._commands if type(cmd).__name__.lower() == command), None) + if cmd is not None: + cmd.run(args) + else: + print(f'Unexpected command {command}') + else: + print(f'Unexpected command {command}') From 5fb20035d8f079a4f87dba4741c7feeaa9119f2b Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Wed, 16 Dec 2020 14:35:43 +0100 Subject: [PATCH 06/20] Added version command to cli --- .../cli/command/base/command_base.py | 2 ++ src/sh_edraft/cli/cpl_cli/cli.py | 8 +++-- src/sh_edraft/cli/cpl_cli/commands/help.py | 3 +- src/sh_edraft/cli/cpl_cli/commands/new.py | 13 +++++-- src/sh_edraft/cli/cpl_cli/commands/version.py | 30 ++++++++++++++++ src/sh_edraft/cli/interpreter/interpreter.py | 8 ++--- src/sh_edraft/console/console.py | 34 +++++++++++++++++-- 7 files changed, 87 insertions(+), 11 deletions(-) create mode 100644 src/sh_edraft/cli/cpl_cli/commands/version.py diff --git a/src/sh_edraft/cli/command/base/command_base.py b/src/sh_edraft/cli/command/base/command_base.py index bc63204b..89bb476a 100644 --- a/src/sh_edraft/cli/command/base/command_base.py +++ b/src/sh_edraft/cli/command/base/command_base.py @@ -1,5 +1,7 @@ from abc import ABC, abstractmethod +from sh_edraft.console.console import Console + class CommandBase(ABC): diff --git a/src/sh_edraft/cli/cpl_cli/cli.py b/src/sh_edraft/cli/cpl_cli/cli.py index b5d24415..d74f807b 100644 --- a/src/sh_edraft/cli/cpl_cli/cli.py +++ b/src/sh_edraft/cli/cpl_cli/cli.py @@ -1,8 +1,11 @@ import sys +import traceback from sh_edraft.cli.cpl_cli.commands.help import Help from sh_edraft.cli.cpl_cli.commands.new import New +from sh_edraft.cli.cpl_cli.commands.version import Version from sh_edraft.cli.interpreter.interpreter import Interpreter +from sh_edraft.console.console import Console class CLI: @@ -13,14 +16,15 @@ class CLI: def setup(self): self._interpreter.add_command(New()) self._interpreter.add_command(Help()) + self._interpreter.add_command(Version()) def main(self): - print('CPL CLI:') string = ' '.join(sys.argv[1:]) try: self._interpreter.interpret(string) except Exception as e: - print(e) + tb = traceback.format_exc() + Console.error(str(e), tb) def main(): diff --git a/src/sh_edraft/cli/cpl_cli/commands/help.py b/src/sh_edraft/cli/cpl_cli/commands/help.py index 3a723f14..21885eb1 100644 --- a/src/sh_edraft/cli/cpl_cli/commands/help.py +++ b/src/sh_edraft/cli/cpl_cli/commands/help.py @@ -1,4 +1,5 @@ from sh_edraft.cli.command.base.command_base import CommandBase +from sh_edraft.console.console import Console class Help(CommandBase): @@ -7,4 +8,4 @@ class Help(CommandBase): CommandBase.__init__(self) def run(self, args: list[str]): - print('Commands:') + Console.write_line('Available Commands:') diff --git a/src/sh_edraft/cli/cpl_cli/commands/new.py b/src/sh_edraft/cli/cpl_cli/commands/new.py index 697d43c9..c9d63353 100644 --- a/src/sh_edraft/cli/cpl_cli/commands/new.py +++ b/src/sh_edraft/cli/cpl_cli/commands/new.py @@ -1,6 +1,7 @@ import os from sh_edraft.cli.command.base.command_base import CommandBase +from sh_edraft.console.console import Console class New(CommandBase): @@ -10,13 +11,21 @@ class New(CommandBase): def run(self, args: list[str]): rel_path = f'{os.path.dirname(__file__)}/../' + if len(args) == 0: + Console.error(f'Expected arguments {args}') + return + + elif len(args) != 2: + Console.error(f'Invalid arguments {args}') + return + if not os.path.isdir(f'{rel_path}/templates/{args[0]}'): - print(f'Unexpected argument {args[0]}') + Console.error(f'Unexpected argument {args[0]}') sub_args = args[1:] if len(sub_args) != 1: - print(f'Unexpected argument {sub_args[1]}') + Console.error(f'Unexpected argument {sub_args[1]}') if not (sub_args[0].startswith('.') or sub_args[0].startswith('/')): full_path = f'./{sub_args[0]}' diff --git a/src/sh_edraft/cli/cpl_cli/commands/version.py b/src/sh_edraft/cli/cpl_cli/commands/version.py new file mode 100644 index 00000000..0f7a4a47 --- /dev/null +++ b/src/sh_edraft/cli/cpl_cli/commands/version.py @@ -0,0 +1,30 @@ +import pkgutil +import sys +import platform + +import sh_edraft +from sh_edraft import cli +from sh_edraft.cli.command.base.command_base import CommandBase +from sh_edraft.console.console import Console + + +class Version(CommandBase): + + def __init__(self): + CommandBase.__init__(self) + + def run(self, args: list[str]): + Console.set_foreground_color('yellow') + Console.banner('CPL CLI') + Console.set_foreground_color('default') + Console.write_line(f'Common Python Library CLI: {cli.__version__}') + Console.write_line(f'Python: {sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}') + Console.write_line(f'OS: {platform.system()} {platform.processor()}') + + Console.write_line('\nCPL:') + packages = [] + for importer, modname, is_pkg in pkgutil.iter_modules(sh_edraft.__path__): + module = importer.find_module(modname).load_module(modname) + packages.append([f'{modname}:', module.__version__]) + + Console.table(['Name', 'Version'], packages) diff --git a/src/sh_edraft/cli/interpreter/interpreter.py b/src/sh_edraft/cli/interpreter/interpreter.py index 7ee549ed..5a7f38d8 100644 --- a/src/sh_edraft/cli/interpreter/interpreter.py +++ b/src/sh_edraft/cli/interpreter/interpreter.py @@ -1,4 +1,5 @@ from sh_edraft.cli.command.base.command_base import CommandBase +from sh_edraft.console.console import Console class Interpreter: @@ -16,13 +17,12 @@ class Interpreter: input_list = input_string.split(' ') commands = [type(cmd).__name__.lower() for cmd in self._commands] command = input_list[0] - args = input_list[1:] - print(command) + args = input_list[1:] if len(input_list) > 2 else [] if command in commands: cmd = next((cmd for cmd in self._commands if type(cmd).__name__.lower() == command), None) if cmd is not None: cmd.run(args) else: - print(f'Unexpected command {command}') + Console.error(f'Unexpected command {command}') else: - print(f'Unexpected command {command}') + Console.error(f'Unexpected command {command}') diff --git a/src/sh_edraft/console/console.py b/src/sh_edraft/console/console.py index 2418cf8a..b2b722da 100644 --- a/src/sh_edraft/console/console.py +++ b/src/sh_edraft/console/console.py @@ -1,5 +1,8 @@ import os from typing import Union, Optional + +import pyfiglet +from tabulate import tabulate from termcolor import colored from sh_edraft.console.model.background_color import BackgroundColor @@ -7,6 +10,8 @@ from sh_edraft.console.model.foreground_color import ForegroundColor class Console: + _is_first_write = True + _background_color: BackgroundColor = BackgroundColor.default _foreground_color: ForegroundColor = ForegroundColor.default _x: Optional[int] = None @@ -64,6 +69,9 @@ class Console: if cls._disabled: return + if cls._is_first_write: + cls._is_first_write = False + args = [] colored_args = [] @@ -88,6 +96,11 @@ class Console: Useful public methods """ + @classmethod + def banner(cls, string: str): + ascii_banner = pyfiglet.figlet_format(string) + cls.write_line(ascii_banner) + @staticmethod def clear(): os.system('cls' if os.name == 'nt' else 'clear') @@ -103,6 +116,15 @@ class Console: def disable(cls): cls._disabled = True + @classmethod + def error(cls, string: str, tb: str = None): + cls.set_foreground_color('red') + if tb is not None: + cls.write_line(f'{string} -> {tb}') + else: + cls.write_line(string) + cls.set_foreground_color('default') + @classmethod def enable(cls): cls._disabled = False @@ -126,6 +148,12 @@ class Console: cls._background_color = BackgroundColor.default cls._foreground_color = ForegroundColor.default + @classmethod + def table(cls, header: list[str], values: list[list[str]]): + table = tabulate(values, headers=header) + + Console.write_line(table) + @classmethod def write(cls, *args): string = ' '.join(map(str, args)) @@ -139,11 +167,13 @@ class Console: @classmethod def write_line(cls, *args): string = ' '.join(map(str, args)) - cls._output('') + if not cls._is_first_write: + cls._output('') cls._output(string, end='') @classmethod def write_line_at(cls, x: int, y: int, *args): string = ' '.join(map(str, args)) - cls._output('', end='') + if not cls._is_first_write: + cls._output('', end='') cls._output(string, x, y, end='') From acfe158470661db43375c87cde5f2096cc3a1d0c Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Wed, 16 Dec 2020 15:09:12 +0100 Subject: [PATCH 07/20] Improved version command & improved help command --- src/sh_edraft/cli/cpl_cli/commands/help.py | 10 ++++++++++ src/sh_edraft/cli/cpl_cli/commands/version.py | 12 +++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/sh_edraft/cli/cpl_cli/commands/help.py b/src/sh_edraft/cli/cpl_cli/commands/help.py index 21885eb1..7999bdb0 100644 --- a/src/sh_edraft/cli/cpl_cli/commands/help.py +++ b/src/sh_edraft/cli/cpl_cli/commands/help.py @@ -9,3 +9,13 @@ class Help(CommandBase): def run(self, args: list[str]): Console.write_line('Available Commands:') + commands = [ + ['help', 'Lists available commands and their short descriptions.'], + ['new', 'Creates a new file or package.'], + ['version', 'Outputs CPL CLI version.'] + ] + for name, description in commands: + Console.set_foreground_color('blue') + Console.write(f'\n\t{name} ') + Console.set_foreground_color('default') + Console.write(f'{description}') diff --git a/src/sh_edraft/cli/cpl_cli/commands/version.py b/src/sh_edraft/cli/cpl_cli/commands/version.py index 0f7a4a47..e514101f 100644 --- a/src/sh_edraft/cli/cpl_cli/commands/version.py +++ b/src/sh_edraft/cli/cpl_cli/commands/version.py @@ -2,6 +2,8 @@ import pkgutil import sys import platform +import pkg_resources + import sh_edraft from sh_edraft import cli from sh_edraft.cli.command.base.command_base import CommandBase @@ -25,6 +27,14 @@ class Version(CommandBase): packages = [] for importer, modname, is_pkg in pkgutil.iter_modules(sh_edraft.__path__): module = importer.find_module(modname).load_module(modname) - packages.append([f'{modname}:', module.__version__]) + packages.append([f'{modname}', module.__version__]) + + Console.table(['Name', 'Version'], packages) + + Console.write_line('\nPython Packages:') + packages = [] + deps = dict(tuple(str(ws).split()) for ws in pkg_resources.working_set) + for p in deps: + packages.append([p, deps[p]]) Console.table(['Name', 'Version'], packages) From bbd0a0f4c4d61f732091d0431f378b82e0476985 Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Wed, 16 Dec 2020 15:13:18 +0100 Subject: [PATCH 08/20] Improved cli error handling --- src/sh_edraft/cli/cpl_cli/cli.py | 1 + src/sh_edraft/cli/cpl_cli/commands/new.py | 4 ++++ src/sh_edraft/cli/interpreter/interpreter.py | 2 ++ 3 files changed, 7 insertions(+) diff --git a/src/sh_edraft/cli/cpl_cli/cli.py b/src/sh_edraft/cli/cpl_cli/cli.py index d74f807b..ae63de86 100644 --- a/src/sh_edraft/cli/cpl_cli/cli.py +++ b/src/sh_edraft/cli/cpl_cli/cli.py @@ -25,6 +25,7 @@ class CLI: except Exception as e: tb = traceback.format_exc() Console.error(str(e), tb) + Console.error('Run \'cpl help\'') def main(): diff --git a/src/sh_edraft/cli/cpl_cli/commands/new.py b/src/sh_edraft/cli/cpl_cli/commands/new.py index c9d63353..90ebb690 100644 --- a/src/sh_edraft/cli/cpl_cli/commands/new.py +++ b/src/sh_edraft/cli/cpl_cli/commands/new.py @@ -13,19 +13,23 @@ class New(CommandBase): rel_path = f'{os.path.dirname(__file__)}/../' if len(args) == 0: Console.error(f'Expected arguments {args}') + Console.error('Run \'cpl help\'') return elif len(args) != 2: Console.error(f'Invalid arguments {args}') + Console.error('Run \'cpl help\'') return if not os.path.isdir(f'{rel_path}/templates/{args[0]}'): Console.error(f'Unexpected argument {args[0]}') + Console.error('Run \'cpl help\'') sub_args = args[1:] if len(sub_args) != 1: Console.error(f'Unexpected argument {sub_args[1]}') + Console.error('Run \'cpl help\'') if not (sub_args[0].startswith('.') or sub_args[0].startswith('/')): full_path = f'./{sub_args[0]}' diff --git a/src/sh_edraft/cli/interpreter/interpreter.py b/src/sh_edraft/cli/interpreter/interpreter.py index 5a7f38d8..577989d8 100644 --- a/src/sh_edraft/cli/interpreter/interpreter.py +++ b/src/sh_edraft/cli/interpreter/interpreter.py @@ -24,5 +24,7 @@ class Interpreter: cmd.run(args) else: Console.error(f'Unexpected command {command}') + Console.error('Run \'cpl help\'') else: Console.error(f'Unexpected command {command}') + Console.error('Run \'cpl help\'') From e9c20061d183be520af8f0e1d09b24e61c039d84 Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Wed, 16 Dec 2020 15:13:46 +0100 Subject: [PATCH 09/20] Removed module template --- src/sh_edraft/cli/cpl_cli/templates/module/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/sh_edraft/cli/cpl_cli/templates/module/__init__.py diff --git a/src/sh_edraft/cli/cpl_cli/templates/module/__init__.py b/src/sh_edraft/cli/cpl_cli/templates/module/__init__.py deleted file mode 100644 index e69de29b..00000000 From 3374ffe8dbfa36c9db1d5b8dd9f21e6a32363385 Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Wed, 16 Dec 2020 16:47:31 +0100 Subject: [PATCH 10/20] Added build command to cli --- .../cli/command/base/command_base.py | 9 +- src/sh_edraft/cli/cpl_cli/cli.py | 38 +++++++- src/sh_edraft/cli/cpl_cli/cli_commands.py | 96 ------------------- src/sh_edraft/cli/cpl_cli/commands/build.py | 26 +++++ src/sh_edraft/cli/cpl_cli/commands/help.py | 7 +- src/sh_edraft/cli/cpl_cli/commands/version.py | 2 + src/sh_edraft/cli/cpl_cli/project.json | 22 +++++ src/sh_edraft/cli/interpreter/interpreter.py | 16 ++-- 8 files changed, 104 insertions(+), 112 deletions(-) delete mode 100644 src/sh_edraft/cli/cpl_cli/cli_commands.py create mode 100644 src/sh_edraft/cli/cpl_cli/commands/build.py create mode 100644 src/sh_edraft/cli/cpl_cli/project.json diff --git a/src/sh_edraft/cli/command/base/command_base.py b/src/sh_edraft/cli/command/base/command_base.py index 89bb476a..76319ba7 100644 --- a/src/sh_edraft/cli/command/base/command_base.py +++ b/src/sh_edraft/cli/command/base/command_base.py @@ -1,12 +1,15 @@ from abc import ABC, abstractmethod -from sh_edraft.console.console import Console - class CommandBase(ABC): @abstractmethod - def __init__(self): pass + def __init__(self): + self._aliases: list[str] = [] + + @property + def aliases(self): + return self._aliases @abstractmethod def run(self, args: list[str]): pass diff --git a/src/sh_edraft/cli/cpl_cli/cli.py b/src/sh_edraft/cli/cpl_cli/cli.py index ae63de86..798829f7 100644 --- a/src/sh_edraft/cli/cpl_cli/cli.py +++ b/src/sh_edraft/cli/cpl_cli/cli.py @@ -1,21 +1,52 @@ import sys import traceback +from typing import Optional +from sh_edraft.cli.cpl_cli.commands.build import Build from sh_edraft.cli.cpl_cli.commands.help import Help from sh_edraft.cli.cpl_cli.commands.new import New from sh_edraft.cli.cpl_cli.commands.version import Version from sh_edraft.cli.interpreter.interpreter import Interpreter +from sh_edraft.configuration.base import ConfigurationBase from sh_edraft.console.console import Console +from sh_edraft.hosting.application_host import ApplicationHost +from sh_edraft.hosting.base.application_base import ApplicationBase +from sh_edraft.logging.logger import Logger +from sh_edraft.logging.base.logger_base import LoggerBase +from sh_edraft.publishing.publisher import Publisher +from sh_edraft.publishing.base.publisher_base import PublisherBase +from sh_edraft.service.providing.service_provider import ServiceProviderBase -class CLI: +class CLI(ApplicationBase): def __init__(self): + ApplicationBase.__init__(self) + + self._app_host: Optional[ApplicationHost] = None + self._services: Optional[ServiceProviderBase] = None + self._configuration: Optional[ConfigurationBase] = None + self._logger: Optional[LoggerBase] = None + self._interpreter = Interpreter() + def create_application_host(self): + self._app_host = ApplicationHost() + self._configuration = self._app_host.configuration + self._services = self._app_host.services + + def create_configuration(self): + self._configuration.add_json_file(f'project.json') + + def create_services(self): + self._services.add_singleton(LoggerBase, Logger) + self._logger = self._services.get_service(LoggerBase) + self._services.add_singleton(PublisherBase, Publisher) + def setup(self): - self._interpreter.add_command(New()) + self._interpreter.add_command(Build(self._services, self._configuration)) self._interpreter.add_command(Help()) + self._interpreter.add_command(New()) self._interpreter.add_command(Version()) def main(self): @@ -30,6 +61,9 @@ class CLI: def main(): cli = CLI() + cli.create_application_host() + cli.create_configuration() + cli.create_services() cli.setup() cli.main() diff --git a/src/sh_edraft/cli/cpl_cli/cli_commands.py b/src/sh_edraft/cli/cpl_cli/cli_commands.py deleted file mode 100644 index 1d8d6765..00000000 --- a/src/sh_edraft/cli/cpl_cli/cli_commands.py +++ /dev/null @@ -1,96 +0,0 @@ -import os - - -class CLICommands: - - @classmethod - def new(cls, args: list[str]): - rel_path = os.path.dirname(__file__) - if not os.path.isdir(f'{rel_path}/templates/{args[0]}'): - cls.unexpected_command(args[0]) - - sub_args = args[1:] - - if len(sub_args) != 1: - cls.unexpected_argument(sub_args[1]) - - if not (sub_args[0].startswith('.') or sub_args[0].startswith('/')): - full_path = f'./{sub_args[0]}' - else: - full_path = sub_args[0] - - name = os.path.basename(full_path) - path = os.path.dirname(full_path) - - if args[0] in ['base', 'class', 'configmodel', 'enum', 'service']: - if not os.path.isdir(path): - os.makedirs(path) - else: - if not os.path.isdir(full_path): - os.makedirs(full_path) - - for r, d, f in os.walk(f'{rel_path}/templates/{args[0]}'): - for file in f: - template_content = '' - with open(f'{r}/{file}') as template: - template_content = template.read() - template.close() - - file = file.replace('txt', 'py') - if args[0] in ['base', 'class', 'configmodel', 'enum', 'service']: - suffix = None - - if args[0] == 'base': - suffix = 'base' - - elif args[0] == 'configmodel': - suffix = 'settings' - - elif args[0] == 'service': - suffix = 'service' - - if suffix is not None: - file_path = f'{path}/{name}_{suffix}.py' - else: - file_path = f'{path}/{name}.py' - else: - file_path = f'{full_path}/{file}' - - with open(file_path, 'w+') as pyfile: - if name[0].islower(): - name = f'{name[0].upper()}{name[1:]}' - - if args[0] == 'base': - template_content = template_content.replace('$Name', f'{name}Base') - pyfile.write(template_content) - - elif args[0] == 'configmodel': - template_content = template_content.replace('$Name', f'{name}Settings') - pyfile.write(template_content) - - elif args[0] == 'service': - template_content = template_content.replace('$Name', f'{name}Service') - template_content = template_content.replace('$Base', f'{name}Base') - pyfile.write(template_content) - - else: - template_content = template_content.replace('$Name', name) - pyfile.write(template_content) - - pyfile.close() - - @staticmethod - def help(*args): - print('Commands:') - - @classmethod - def unexpected_command(cls, command: str): - print(f'Unexpected command {command}') - cls.help() - exit() - - @classmethod - def unexpected_argument(cls, argument: str): - print(f'Unexpected argument {argument}') - cls.help() - exit() diff --git a/src/sh_edraft/cli/cpl_cli/commands/build.py b/src/sh_edraft/cli/cpl_cli/commands/build.py new file mode 100644 index 00000000..15653d15 --- /dev/null +++ b/src/sh_edraft/cli/cpl_cli/commands/build.py @@ -0,0 +1,26 @@ +from sh_edraft.cli.command.base.command_base import CommandBase +from sh_edraft.configuration.base.configuration_base import ConfigurationBase +from sh_edraft.console.console import Console +from sh_edraft.publishing.publisher import Publisher +from sh_edraft.publishing.base.publisher_base import PublisherBase +from sh_edraft.service.providing.service_provider import ServiceProviderBase + + +class Build(CommandBase): + + def __init__(self, services: ServiceProviderBase, config: ConfigurationBase): + CommandBase.__init__(self) + self._services = services + self._config = config + + self._aliases.append('-b') + self._aliases.append('-B') + self._publisher: Publisher = self._services.get_service(PublisherBase) + + def run(self, args: list[str]): + if len(args) > 0: + Console.error(f'Invalid arguments {args}') + Console.error('Run \'cpl help\'') + + self._publisher.create() + self._publisher.publish() diff --git a/src/sh_edraft/cli/cpl_cli/commands/help.py b/src/sh_edraft/cli/cpl_cli/commands/help.py index 7999bdb0..b9212479 100644 --- a/src/sh_edraft/cli/cpl_cli/commands/help.py +++ b/src/sh_edraft/cli/cpl_cli/commands/help.py @@ -6,13 +6,16 @@ class Help(CommandBase): def __init__(self): CommandBase.__init__(self) + self._aliases.append('-h') + self._aliases.append('-H') def run(self, args: list[str]): Console.write_line('Available Commands:') commands = [ - ['help', 'Lists available commands and their short descriptions.'], + ['build (-b|-B)', 'Prepares files for publishing into an output directory named dist/ at the given output path.Must be executed from within a workspace directory.'], + ['help (-h|-H)', 'Lists available commands and their short descriptions.'], ['new', 'Creates a new file or package.'], - ['version', 'Outputs CPL CLI version.'] + ['version (-v|-V)', 'Outputs CPL CLI version.'] ] for name, description in commands: Console.set_foreground_color('blue') diff --git a/src/sh_edraft/cli/cpl_cli/commands/version.py b/src/sh_edraft/cli/cpl_cli/commands/version.py index e514101f..61c95211 100644 --- a/src/sh_edraft/cli/cpl_cli/commands/version.py +++ b/src/sh_edraft/cli/cpl_cli/commands/version.py @@ -14,6 +14,8 @@ class Version(CommandBase): def __init__(self): CommandBase.__init__(self) + self._aliases.append('-v') + self._aliases.append('-V') def run(self, args: list[str]): Console.set_foreground_color('yellow') diff --git a/src/sh_edraft/cli/cpl_cli/project.json b/src/sh_edraft/cli/cpl_cli/project.json new file mode 100644 index 00000000..5d15af9e --- /dev/null +++ b/src/sh_edraft/cli/cpl_cli/project.json @@ -0,0 +1,22 @@ +{ + "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": "INFO", + "FileLogLevel": "TRACE" + }, + "PublishSettings": { + "SourcePath": "../", + "DistPath": "../../../../dist", + "Templates": [], + "IncludedFiles": [], + "ExcludedFiles": [], + "TemplateEnding": "_template.txt" + } +} diff --git a/src/sh_edraft/cli/interpreter/interpreter.py b/src/sh_edraft/cli/interpreter/interpreter.py index 577989d8..e1cf07ea 100644 --- a/src/sh_edraft/cli/interpreter/interpreter.py +++ b/src/sh_edraft/cli/interpreter/interpreter.py @@ -15,16 +15,14 @@ class Interpreter: def interpret(self, input_string: str): input_list = input_string.split(' ') - commands = [type(cmd).__name__.lower() for cmd in self._commands] command = input_list[0] - args = input_list[1:] if len(input_list) > 2 else [] - if command in commands: - cmd = next((cmd for cmd in self._commands if type(cmd).__name__.lower() == command), None) - if cmd is not None: - cmd.run(args) - else: - Console.error(f'Unexpected command {command}') - Console.error('Run \'cpl help\'') + args = input_list[1:] if len(input_list) > 1 else [] + + cmd = next( + (cmd for cmd in self._commands if type(cmd).__name__.lower() == command or command in cmd.aliases), + None) + if cmd is not None: + cmd.run(args) else: Console.error(f'Unexpected command {command}') Console.error('Run \'cpl help\'') From 9e3c631ac4c42972fa5432cfcb30f3ad8a1056dc Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Wed, 16 Dec 2020 17:37:43 +0100 Subject: [PATCH 11/20] Improved publish process --- src/build.json | 65 +++++++++++++++++++ src/sh_edraft/cli/command/__init__.py | 25 +++++++ src/sh_edraft/cli/command/base/__init__.py | 25 +++++++ src/sh_edraft/cli/cpl_cli/__init__.py | 25 +++++++ src/sh_edraft/cli/cpl_cli/cli.py | 37 +---------- .../cli/cpl_cli/commands/__init__.py | 25 +++++++ src/sh_edraft/cli/cpl_cli/commands/build.py | 26 -------- .../app/build.json} | 8 +-- src/sh_edraft/cli/interpreter/__init__.py | 25 +++++++ src/sh_edraft/logging/logger.py | 2 +- src/sh_edraft/publishing/publisher.py | 31 +++++++-- 11 files changed, 225 insertions(+), 69 deletions(-) create mode 100644 src/build.json delete mode 100644 src/sh_edraft/cli/cpl_cli/commands/build.py rename src/sh_edraft/cli/cpl_cli/{project.json => templates/app/build.json} (79%) diff --git a/src/build.json b/src/build.json new file mode 100644 index 00000000..da1551cc --- /dev/null +++ b/src/build.json @@ -0,0 +1,65 @@ +{ + "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": "../build/logs/", + "Filename": "log_$start_time.log", + "ConsoleLogLevel": "INFO", + "FileLogLevel": "TRACE" + }, + "PublishSettings": { + "SourcePath": "./", + "DistPath": "../build/dist", + "Templates": [ + { + "TemplatePath": "../publish_templates/all_template.txt", + "Name": "all", + "Description": "", + "LongDescription": "", + "CopyrightDate": "2020", + "CopyrightName": "sh-edraft.de", + "LicenseName": "MIT", + "LicenseDescription": ", see LICENSE for more details.", + "Title": "", + "Author": "Sven Heidemann", + "Version": { + "Major": 2020, + "Minor": 12, + "Micro": 9 + } + }, + { + "TemplatePath": "../publish_templates/all_template.txt", + "Name": "sh_edraft", + "Description": "common python library", + "LongDescription": "Library to share common classes and models used at sh-edraft.de", + "CopyrightDate": "2020", + "CopyrightName": "sh-edraft.de", + "LicenseName": "MIT", + "LicenseDescription": ", see LICENSE for more details.", + "Title": "", + "Author": "Sven Heidemann", + "Version": { + "Major": 2020, + "Minor": 12, + "Micro": 9 + } + } + ], + "IncludedFiles": [ + "../LICENSE", + "../README.md", + "../requirements.txt", + "sh_edraft/cli/cpl_cli/templates" + ], + "ExcludedFiles": [ + "./tests", + "./tests_dev" + ], + "TemplateEnding": "_template.txt" + } +} diff --git a/src/sh_edraft/cli/command/__init__.py b/src/sh_edraft/cli/command/__init__.py index e69de29b..336d4a17 100644 --- a/src/sh_edraft/cli/command/__init__.py +++ b/src/sh_edraft/cli/command/__init__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- + +""" +sh_edraft.cli.command +~~~~~~~~~~~~~~~~~~~ + + + +:copyright: (c) 2020 sh-edraft.de +:license: MIT, see LICENSE for more details. + +""" + +__title__ = 'sh_edraft.cli.command' +__author__ = 'Sven Heidemann' +__license__ = 'MIT' +__copyright__ = 'Copyright (c) 2020 sh-edraft.de' +__version__ = '2020.12.9' + +from collections import namedtuple + +# imports: + +VersionInfo = namedtuple('VersionInfo', 'major minor micro') +version_info = VersionInfo(major=2020, minor=12, micro=9) diff --git a/src/sh_edraft/cli/command/base/__init__.py b/src/sh_edraft/cli/command/base/__init__.py index e69de29b..83d30e3e 100644 --- a/src/sh_edraft/cli/command/base/__init__.py +++ b/src/sh_edraft/cli/command/base/__init__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- + +""" +sh_edraft.cli.command.base +~~~~~~~~~~~~~~~~~~~ + + + +:copyright: (c) 2020 sh-edraft.de +:license: MIT, see LICENSE for more details. + +""" + +__title__ = 'sh_edraft.cli.command.base' +__author__ = 'Sven Heidemann' +__license__ = 'MIT' +__copyright__ = 'Copyright (c) 2020 sh-edraft.de' +__version__ = '2020.12.9' + +from collections import namedtuple + +# imports: + +VersionInfo = namedtuple('VersionInfo', 'major minor micro') +version_info = VersionInfo(major=2020, minor=12, micro=9) diff --git a/src/sh_edraft/cli/cpl_cli/__init__.py b/src/sh_edraft/cli/cpl_cli/__init__.py index e69de29b..1c8b1737 100644 --- a/src/sh_edraft/cli/cpl_cli/__init__.py +++ b/src/sh_edraft/cli/cpl_cli/__init__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- + +""" +sh_edraft.cli.cpl_cli +~~~~~~~~~~~~~~~~~~~ + + + +:copyright: (c) 2020 sh-edraft.de +:license: MIT, see LICENSE for more details. + +""" + +__title__ = 'sh_edraft.cli.cpl_cli' +__author__ = 'Sven Heidemann' +__license__ = 'MIT' +__copyright__ = 'Copyright (c) 2020 sh-edraft.de' +__version__ = '2020.12.9' + +from collections import namedtuple + +# imports: + +VersionInfo = namedtuple('VersionInfo', 'major minor micro') +version_info = VersionInfo(major=2020, minor=12, micro=9) diff --git a/src/sh_edraft/cli/cpl_cli/cli.py b/src/sh_edraft/cli/cpl_cli/cli.py index 798829f7..a1eb8a70 100644 --- a/src/sh_edraft/cli/cpl_cli/cli.py +++ b/src/sh_edraft/cli/cpl_cli/cli.py @@ -2,49 +2,21 @@ import sys import traceback from typing import Optional -from sh_edraft.cli.cpl_cli.commands.build import Build +from sh_edraft.cli.cpl_cli.commands.build.build import Build from sh_edraft.cli.cpl_cli.commands.help import Help from sh_edraft.cli.cpl_cli.commands.new import New from sh_edraft.cli.cpl_cli.commands.version import Version from sh_edraft.cli.interpreter.interpreter import Interpreter -from sh_edraft.configuration.base import ConfigurationBase from sh_edraft.console.console import Console -from sh_edraft.hosting.application_host import ApplicationHost -from sh_edraft.hosting.base.application_base import ApplicationBase -from sh_edraft.logging.logger import Logger -from sh_edraft.logging.base.logger_base import LoggerBase -from sh_edraft.publishing.publisher import Publisher -from sh_edraft.publishing.base.publisher_base import PublisherBase -from sh_edraft.service.providing.service_provider import ServiceProviderBase -class CLI(ApplicationBase): +class CLI: def __init__(self): - ApplicationBase.__init__(self) - - self._app_host: Optional[ApplicationHost] = None - self._services: Optional[ServiceProviderBase] = None - self._configuration: Optional[ConfigurationBase] = None - self._logger: Optional[LoggerBase] = None - self._interpreter = Interpreter() - def create_application_host(self): - self._app_host = ApplicationHost() - self._configuration = self._app_host.configuration - self._services = self._app_host.services - - def create_configuration(self): - self._configuration.add_json_file(f'project.json') - - def create_services(self): - self._services.add_singleton(LoggerBase, Logger) - self._logger = self._services.get_service(LoggerBase) - self._services.add_singleton(PublisherBase, Publisher) - def setup(self): - self._interpreter.add_command(Build(self._services, self._configuration)) + self._interpreter.add_command(Build()) self._interpreter.add_command(Help()) self._interpreter.add_command(New()) self._interpreter.add_command(Version()) @@ -61,9 +33,6 @@ class CLI(ApplicationBase): def main(): cli = CLI() - cli.create_application_host() - cli.create_configuration() - cli.create_services() cli.setup() cli.main() diff --git a/src/sh_edraft/cli/cpl_cli/commands/__init__.py b/src/sh_edraft/cli/cpl_cli/commands/__init__.py index e69de29b..8f0a8760 100644 --- a/src/sh_edraft/cli/cpl_cli/commands/__init__.py +++ b/src/sh_edraft/cli/cpl_cli/commands/__init__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- + +""" +sh_edraft.cli.cpl_cli.commands +~~~~~~~~~~~~~~~~~~~ + + + +:copyright: (c) 2020 sh-edraft.de +:license: MIT, see LICENSE for more details. + +""" + +__title__ = 'sh_edraft.cli.cpl_cli.commands' +__author__ = 'Sven Heidemann' +__license__ = 'MIT' +__copyright__ = 'Copyright (c) 2020 sh-edraft.de' +__version__ = '2020.12.9' + +from collections import namedtuple + +# imports: + +VersionInfo = namedtuple('VersionInfo', 'major minor micro') +version_info = VersionInfo(major=2020, minor=12, micro=9) diff --git a/src/sh_edraft/cli/cpl_cli/commands/build.py b/src/sh_edraft/cli/cpl_cli/commands/build.py deleted file mode 100644 index 15653d15..00000000 --- a/src/sh_edraft/cli/cpl_cli/commands/build.py +++ /dev/null @@ -1,26 +0,0 @@ -from sh_edraft.cli.command.base.command_base import CommandBase -from sh_edraft.configuration.base.configuration_base import ConfigurationBase -from sh_edraft.console.console import Console -from sh_edraft.publishing.publisher import Publisher -from sh_edraft.publishing.base.publisher_base import PublisherBase -from sh_edraft.service.providing.service_provider import ServiceProviderBase - - -class Build(CommandBase): - - def __init__(self, services: ServiceProviderBase, config: ConfigurationBase): - CommandBase.__init__(self) - self._services = services - self._config = config - - self._aliases.append('-b') - self._aliases.append('-B') - self._publisher: Publisher = self._services.get_service(PublisherBase) - - def run(self, args: list[str]): - if len(args) > 0: - Console.error(f'Invalid arguments {args}') - Console.error('Run \'cpl help\'') - - self._publisher.create() - self._publisher.publish() diff --git a/src/sh_edraft/cli/cpl_cli/project.json b/src/sh_edraft/cli/cpl_cli/templates/app/build.json similarity index 79% rename from src/sh_edraft/cli/cpl_cli/project.json rename to src/sh_edraft/cli/cpl_cli/templates/app/build.json index 5d15af9e..c6ea10bc 100644 --- a/src/sh_edraft/cli/cpl_cli/project.json +++ b/src/sh_edraft/cli/cpl_cli/templates/app/build.json @@ -6,14 +6,14 @@ "DateTimeLogFormat": "%Y-%m-%d_%H-%M-%S" }, "LoggingSettings": { - "Path": "logs/", + "Path": "build/logs/", "Filename": "log_$start_time.log", "ConsoleLogLevel": "INFO", - "FileLogLevel": "TRACE" + "FileLogLevel": "INFO" }, "PublishSettings": { - "SourcePath": "../", - "DistPath": "../../../../dist", + "SourcePath": "./", + "DistPath": "build/dist", "Templates": [], "IncludedFiles": [], "ExcludedFiles": [], diff --git a/src/sh_edraft/cli/interpreter/__init__.py b/src/sh_edraft/cli/interpreter/__init__.py index e69de29b..fdf21dc1 100644 --- a/src/sh_edraft/cli/interpreter/__init__.py +++ b/src/sh_edraft/cli/interpreter/__init__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- + +""" +sh_edraft.cli.interpreter +~~~~~~~~~~~~~~~~~~~ + + + +:copyright: (c) 2020 sh-edraft.de +:license: MIT, see LICENSE for more details. + +""" + +__title__ = 'sh_edraft.cli.interpreter' +__author__ = 'Sven Heidemann' +__license__ = 'MIT' +__copyright__ = 'Copyright (c) 2020 sh-edraft.de' +__version__ = '2020.12.9' + +from collections import namedtuple + +# imports: + +VersionInfo = namedtuple('VersionInfo', 'major minor micro') +version_info = VersionInfo(major=2020, minor=12, micro=9) diff --git a/src/sh_edraft/logging/logger.py b/src/sh_edraft/logging/logger.py index ec96469e..6668132e 100644 --- a/src/sh_edraft/logging/logger.py +++ b/src/sh_edraft/logging/logger.py @@ -48,7 +48,7 @@ class Logger(LoggerBase): try: # check if log file path exists if not os.path.exists(self._path): - os.mkdir(self._path) + os.makedirs(self._path) except Exception as e: self._fatal_console(__name__, 'Cannot create log dir', ex=e) diff --git a/src/sh_edraft/publishing/publisher.py b/src/sh_edraft/publishing/publisher.py index 2e922f36..d426ee5f 100644 --- a/src/sh_edraft/publishing/publisher.py +++ b/src/sh_edraft/publishing/publisher.py @@ -16,6 +16,8 @@ class Publisher(PublisherBase): self._logger: LoggerBase = logger self._publish_settings: PublishSettings = publish_settings + self._included_files: list[str] = [] + @property def source_path(self) -> str: return self._publish_settings.source_path @@ -53,10 +55,31 @@ class Publisher(PublisherBase): def _read_source_path(self): self._logger.trace(__name__, f'Started {__name__}._read_source_path') + included_files = self._publish_settings.included_files + for included in included_files: + if os.path.isdir(included): + self._publish_settings.included_files.remove(included) + + for r, d, f in os.walk(included): + for file in f: + file_path = os.path.join(self._publish_settings.source_path, r, file) + if os.path.isfile(file_path): + self._included_files.append(file_path) + else: + self._logger.fatal(__name__, f'File not found: {file}') + for r, d, f in os.walk(self._publish_settings.source_path): for file in f: - if file.endswith('.py') or file in self._publish_settings.included_files: - self._publish_settings.included_files.append(os.path.join(r, file)) + is_file_excluded = False + if os.path.join(r, file) in self._publish_settings.excluded_files: + is_file_excluded = True + else: + for excluded in self._publish_settings.excluded_files: + if os.path.join(r, file).__contains__(excluded): + is_file_excluded = True + + if not is_file_excluded and file.endswith('.py') or file in self._publish_settings.included_files: + self._included_files.append(os.path.join(r, file)) self._logger.trace(__name__, f'Stopped {__name__}._read_source_path') @@ -109,7 +132,7 @@ class Publisher(PublisherBase): def _write_templates(self): self._logger.trace(__name__, f'Started {__name__}._write_templates') for template in self._publish_settings.templates: - for file in self._publish_settings.included_files: + for file in self._included_files: if os.path.basename(file) == '__init__.py' and file not in self._publish_settings.excluded_files: template_name = template.name if template.name == 'all' or template.name == '': @@ -167,7 +190,7 @@ class Publisher(PublisherBase): if self._publish_settings.dist_path.endswith('/'): dist_path = dist_path[:len(dist_path) - 1] - for file in self._publish_settings.included_files: + for file in self._included_files: is_file_excluded = False if file in self._publish_settings.excluded_files: is_file_excluded = True From 09eb3a41d68109a4e7c1b80ab8a9955f57beadea Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Wed, 16 Dec 2020 17:54:29 +0100 Subject: [PATCH 12/20] Improved publish process --- src/build.json | 1 + src/sh_edraft/publishing/publisher.py | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/build.json b/src/build.json index da1551cc..d2ca1def 100644 --- a/src/build.json +++ b/src/build.json @@ -51,6 +51,7 @@ } ], "IncludedFiles": [ + "./MANIFEST.in", "../LICENSE", "../README.md", "../requirements.txt", diff --git a/src/sh_edraft/publishing/publisher.py b/src/sh_edraft/publishing/publisher.py index d426ee5f..7bb9fa87 100644 --- a/src/sh_edraft/publishing/publisher.py +++ b/src/sh_edraft/publishing/publisher.py @@ -68,6 +68,11 @@ class Publisher(PublisherBase): else: self._logger.fatal(__name__, f'File not found: {file}') + elif os.path.isfile(included): + self._included_files.append(os.path.join(self._publish_settings.source_path, included)) + else: + self._logger.fatal(__name__, f'File not found: {included}') + for r, d, f in os.walk(self._publish_settings.source_path): for file in f: is_file_excluded = False @@ -207,7 +212,11 @@ class Publisher(PublisherBase): elif file.startswith('.'): output_file = file.replace('.', '', 1) - output_file = f'{dist_path}{output_file}' + if output_file.__contains__('..'): + output_file = os.path.join(dist_path, os.path.basename(file)) + else: + output_file = f'{dist_path}{output_file}' + output_path = os.path.dirname(output_file) try: From a6122536a634fd2493b76cdb047cf59825540f22 Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Wed, 16 Dec 2020 18:14:11 +0100 Subject: [PATCH 13/20] Added publish command to cli --- src/sh_edraft/cli/cpl_cli/cli.py | 3 +- .../cli/cpl_cli/commands/publish/__init__.py | 25 ++++++++++ .../cli/cpl_cli/commands/publish/app.py | 48 +++++++++++++++++++ .../cli/cpl_cli/commands/publish/publish.py | 23 +++++++++ .../publishing/base/publisher_base.py | 5 +- src/sh_edraft/publishing/publisher.py | 15 +++++- src/tests_dev/publisher.py | 2 +- 7 files changed, 116 insertions(+), 5 deletions(-) create mode 100644 src/sh_edraft/cli/cpl_cli/commands/publish/__init__.py create mode 100644 src/sh_edraft/cli/cpl_cli/commands/publish/app.py create mode 100644 src/sh_edraft/cli/cpl_cli/commands/publish/publish.py diff --git a/src/sh_edraft/cli/cpl_cli/cli.py b/src/sh_edraft/cli/cpl_cli/cli.py index a1eb8a70..f0728d13 100644 --- a/src/sh_edraft/cli/cpl_cli/cli.py +++ b/src/sh_edraft/cli/cpl_cli/cli.py @@ -1,10 +1,10 @@ import sys import traceback -from typing import Optional from sh_edraft.cli.cpl_cli.commands.build.build import Build from sh_edraft.cli.cpl_cli.commands.help import Help from sh_edraft.cli.cpl_cli.commands.new import New +from sh_edraft.cli.cpl_cli.commands.publish.publish import Publish from sh_edraft.cli.cpl_cli.commands.version import Version from sh_edraft.cli.interpreter.interpreter import Interpreter from sh_edraft.console.console import Console @@ -19,6 +19,7 @@ class CLI: self._interpreter.add_command(Build()) self._interpreter.add_command(Help()) self._interpreter.add_command(New()) + self._interpreter.add_command(Publish()) self._interpreter.add_command(Version()) def main(self): diff --git a/src/sh_edraft/cli/cpl_cli/commands/publish/__init__.py b/src/sh_edraft/cli/cpl_cli/commands/publish/__init__.py new file mode 100644 index 00000000..3963f7a7 --- /dev/null +++ b/src/sh_edraft/cli/cpl_cli/commands/publish/__init__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- + +""" +sh_edraft.cli.cpl_cli.commands.publish +~~~~~~~~~~~~~~~~~~~ + + + +:copyright: (c) 2020 sh-edraft.de +:license: MIT, see LICENSE for more details. + +""" + +__title__ = 'sh_edraft.cli.cpl_cli.commands.publish' +__author__ = 'Sven Heidemann' +__license__ = 'MIT' +__copyright__ = 'Copyright (c) 2020 sh-edraft.de' +__version__ = '2020.12.9' + +from collections import namedtuple + +# imports: + +VersionInfo = namedtuple('VersionInfo', 'major minor micro') +version_info = VersionInfo(major=2020, minor=12, micro=9) diff --git a/src/sh_edraft/cli/cpl_cli/commands/publish/app.py b/src/sh_edraft/cli/cpl_cli/commands/publish/app.py new file mode 100644 index 00000000..c7ce661a --- /dev/null +++ b/src/sh_edraft/cli/cpl_cli/commands/publish/app.py @@ -0,0 +1,48 @@ +from typing import Optional + +from sh_edraft.configuration.base.configuration_base import ConfigurationBase +from sh_edraft.hosting.application_host import ApplicationHost +from sh_edraft.hosting.base.application_base import ApplicationBase +from sh_edraft.logging.logger import Logger +from sh_edraft.logging.base.logger_base import LoggerBase +from sh_edraft.publishing.publisher import Publisher +from sh_edraft.publishing.base.publisher_base import PublisherBase +from sh_edraft.service.providing.base.service_provider_base import ServiceProviderBase + + +class PublishApp(ApplicationBase): + + def __init__(self): + ApplicationBase.__init__(self) + + self._app_host: Optional[ApplicationHost] = None + self._services: Optional[ServiceProviderBase] = None + self._configuration: Optional[ConfigurationBase] = None + self._logger: Optional[LoggerBase] = None + self._publisher: Optional[PublisherBase] = None + + def create_application_host(self): + self._app_host = ApplicationHost() + self._configuration = self._app_host.configuration + self._services = self._app_host.services + + def create_configuration(self): + self._configuration.add_json_file(f'build.json') + + def create_services(self): + # Add and create logger + self._services.add_singleton(LoggerBase, Logger) + self._logger = self._services.get_service(LoggerBase) + + # Add and create publisher + self._services.add_singleton(PublisherBase, Publisher) + self._publisher: Publisher = self._services.get_service(PublisherBase) + + def main(self): + self._logger.header(f'{self._configuration.environment.application_name}:') + self._logger.debug(__name__, f'Host: {self._configuration.environment.host_name}') + self._logger.debug(__name__, f'Environment: {self._configuration.environment.environment_name}') + self._logger.debug(__name__, f'Customer: {self._configuration.environment.customer}') + self._publisher.create() + self._publisher.build() + self._publisher.publish() diff --git a/src/sh_edraft/cli/cpl_cli/commands/publish/publish.py b/src/sh_edraft/cli/cpl_cli/commands/publish/publish.py new file mode 100644 index 00000000..f21c331e --- /dev/null +++ b/src/sh_edraft/cli/cpl_cli/commands/publish/publish.py @@ -0,0 +1,23 @@ +from sh_edraft.cli.command.base.command_base import CommandBase +from sh_edraft.cli.cpl_cli.commands.publish.app import PublishApp +from sh_edraft.console.console import Console + + +class Publish(CommandBase): + + def __init__(self): + CommandBase.__init__(self) + self._app = PublishApp() + + self._aliases.append('-b') + self._aliases.append('-B') + + def run(self, args: list[str]): + if len(args) > 0: + Console.error(f'Invalid arguments {args}') + Console.error('Run \'cpl help\'') + + self._app.create_application_host() + self._app.create_configuration() + self._app.create_services() + self._app.main() diff --git a/src/sh_edraft/publishing/base/publisher_base.py b/src/sh_edraft/publishing/base/publisher_base.py index f3f899ca..092dec3d 100644 --- a/src/sh_edraft/publishing/base/publisher_base.py +++ b/src/sh_edraft/publishing/base/publisher_base.py @@ -24,4 +24,7 @@ class PublisherBase(ServiceBase): def exclude(self, path: str): pass @abstractmethod - def publish(self) -> str: pass + def build(self): pass + + @abstractmethod + def publish(self): pass diff --git a/src/sh_edraft/publishing/publisher.py b/src/sh_edraft/publishing/publisher.py index 7bb9fa87..9a9a1518 100644 --- a/src/sh_edraft/publishing/publisher.py +++ b/src/sh_edraft/publishing/publisher.py @@ -2,6 +2,8 @@ import os import shutil from string import Template as stringTemplate +from setuptools import sandbox + from sh_edraft.logging.base.logger_base import LoggerBase from sh_edraft.publishing.base.publisher_base import PublisherBase from sh_edraft.publishing.model.publish_settings_model import PublishSettings @@ -255,8 +257,17 @@ class Publisher(PublisherBase): self._create_dist_path() self._logger.trace(__name__, f'Stopped {__name__}.create') - def publish(self): - self._logger.trace(__name__, f'Started {__name__}.publish') + def build(self): + self._logger.trace(__name__, f'Started {__name__}.build') self._write_templates() self._copy_all_included_files() + self._logger.trace(__name__, f'Stopped {__name__}.build') + + def publish(self): + self._logger.trace(__name__, f'Started {__name__}.publish') + setup_py = os.path.join(self._publish_settings.dist_path, 'setup.py') + if not os.path.isfile(setup_py): + self._logger.fatal(__name__, f'setup.py not found in {self._publish_settings.dist_path}') + + sandbox.run_setup(os.path.abspath(setup_py), ['sdist', 'bdist_wheel']) self._logger.trace(__name__, f'Stopped {__name__}.publish') diff --git a/src/tests_dev/publisher.py b/src/tests_dev/publisher.py index f9eea080..06b75735 100644 --- a/src/tests_dev/publisher.py +++ b/src/tests_dev/publisher.py @@ -54,7 +54,7 @@ class Program(ApplicationBase): self._publisher.include('../../README.MD') self._publisher.include('../../requirements.txt') self._publisher.create() - self._publisher.publish() + self._publisher.build() if __name__ == '__main__': From 39ccc8430e41ac111f894eb05e3aeb0e25d6d492 Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Wed, 16 Dec 2020 18:16:26 +0100 Subject: [PATCH 14/20] Added imports to cli module --- src/sh_edraft/cli/command/base/__init__.py | 1 + src/sh_edraft/cli/cpl_cli/__init__.py | 1 + src/sh_edraft/cli/cpl_cli/commands/__init__.py | 3 +++ src/sh_edraft/cli/cpl_cli/commands/publish/__init__.py | 2 ++ src/sh_edraft/cli/interpreter/__init__.py | 1 + 5 files changed, 8 insertions(+) diff --git a/src/sh_edraft/cli/command/base/__init__.py b/src/sh_edraft/cli/command/base/__init__.py index 83d30e3e..13a5ebca 100644 --- a/src/sh_edraft/cli/command/base/__init__.py +++ b/src/sh_edraft/cli/command/base/__init__.py @@ -20,6 +20,7 @@ __version__ = '2020.12.9' from collections import namedtuple # imports: +from .command_base import CommandBase VersionInfo = namedtuple('VersionInfo', 'major minor micro') version_info = VersionInfo(major=2020, minor=12, micro=9) diff --git a/src/sh_edraft/cli/cpl_cli/__init__.py b/src/sh_edraft/cli/cpl_cli/__init__.py index 1c8b1737..9130756c 100644 --- a/src/sh_edraft/cli/cpl_cli/__init__.py +++ b/src/sh_edraft/cli/cpl_cli/__init__.py @@ -20,6 +20,7 @@ __version__ = '2020.12.9' from collections import namedtuple # imports: +from .cli import CLI VersionInfo = namedtuple('VersionInfo', 'major minor micro') version_info = VersionInfo(major=2020, minor=12, micro=9) diff --git a/src/sh_edraft/cli/cpl_cli/commands/__init__.py b/src/sh_edraft/cli/cpl_cli/commands/__init__.py index 8f0a8760..27f75a8b 100644 --- a/src/sh_edraft/cli/cpl_cli/commands/__init__.py +++ b/src/sh_edraft/cli/cpl_cli/commands/__init__.py @@ -20,6 +20,9 @@ __version__ = '2020.12.9' from collections import namedtuple # imports: +from .version import Version +from .help import Help +from .new import New VersionInfo = namedtuple('VersionInfo', 'major minor micro') version_info = VersionInfo(major=2020, minor=12, micro=9) diff --git a/src/sh_edraft/cli/cpl_cli/commands/publish/__init__.py b/src/sh_edraft/cli/cpl_cli/commands/publish/__init__.py index 3963f7a7..f4af0e65 100644 --- a/src/sh_edraft/cli/cpl_cli/commands/publish/__init__.py +++ b/src/sh_edraft/cli/cpl_cli/commands/publish/__init__.py @@ -20,6 +20,8 @@ __version__ = '2020.12.9' from collections import namedtuple # imports: +from .app import PublishApp +from .publish import Publish VersionInfo = namedtuple('VersionInfo', 'major minor micro') version_info = VersionInfo(major=2020, minor=12, micro=9) diff --git a/src/sh_edraft/cli/interpreter/__init__.py b/src/sh_edraft/cli/interpreter/__init__.py index fdf21dc1..ccd63b96 100644 --- a/src/sh_edraft/cli/interpreter/__init__.py +++ b/src/sh_edraft/cli/interpreter/__init__.py @@ -20,6 +20,7 @@ __version__ = '2020.12.9' from collections import namedtuple # imports: +from .interpreter import Interpreter VersionInfo = namedtuple('VersionInfo', 'major minor micro') version_info = VersionInfo(major=2020, minor=12, micro=9) From 4f03e5ae99dea354121a130c779f2a00e90157dd Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Wed, 16 Dec 2020 18:17:47 +0100 Subject: [PATCH 15/20] Improved help command --- src/sh_edraft/cli/cpl_cli/commands/help.py | 3 ++- src/sh_edraft/cli/cpl_cli/commands/publish/publish.py | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/sh_edraft/cli/cpl_cli/commands/help.py b/src/sh_edraft/cli/cpl_cli/commands/help.py index b9212479..3983cb59 100644 --- a/src/sh_edraft/cli/cpl_cli/commands/help.py +++ b/src/sh_edraft/cli/cpl_cli/commands/help.py @@ -12,9 +12,10 @@ class Help(CommandBase): def run(self, args: list[str]): Console.write_line('Available Commands:') commands = [ - ['build (-b|-B)', 'Prepares files for publishing into an output directory named dist/ at the given output path.Must be executed from within a workspace directory.'], + ['build (-b|-B)', 'Prepares files for publishing into an output directory named dist/ at the given output path. Must be executed from within a workspace directory.'], ['help (-h|-H)', 'Lists available commands and their short descriptions.'], ['new', 'Creates a new file or package.'], + ['publish (-p|-P)', 'Prepares files for publishing into an output directory named dist/ at the given output path and executes setup.py. Must be executed from within a workspace directory.'], ['version (-v|-V)', 'Outputs CPL CLI version.'] ] for name, description in commands: diff --git a/src/sh_edraft/cli/cpl_cli/commands/publish/publish.py b/src/sh_edraft/cli/cpl_cli/commands/publish/publish.py index f21c331e..7e72ae3a 100644 --- a/src/sh_edraft/cli/cpl_cli/commands/publish/publish.py +++ b/src/sh_edraft/cli/cpl_cli/commands/publish/publish.py @@ -9,8 +9,8 @@ class Publish(CommandBase): CommandBase.__init__(self) self._app = PublishApp() - self._aliases.append('-b') - self._aliases.append('-B') + self._aliases.append('-p') + self._aliases.append('-P') def run(self, args: list[str]): if len(args) > 0: From fcb57bd2ccc55762fd21c5f1c0d8104dcc9e73e3 Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Wed, 16 Dec 2020 18:20:39 +0100 Subject: [PATCH 16/20] Changed deps --- requirements.txt | 3 +++ src/setup.py | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 742e4085..afb24683 100644 --- a/requirements.txt +++ b/requirements.txt @@ -24,3 +24,6 @@ termcolor==1.1.0 urllib3==1.26.2 Werkzeug==1.0.1 yarl==1.5.1 +setuptools~=49.2.1 +pyfiglet~=0.8.post1 +tabulate~=0.8.7 \ No newline at end of file diff --git a/src/setup.py b/src/setup.py index 71cc0e2b..748df92d 100644 --- a/src/setup.py +++ b/src/setup.py @@ -16,7 +16,9 @@ setuptools.setup( 'flask', 'mysql-connector', 'SQLAlchemy', - 'termcolor' + 'termcolor', + 'pyfiglet', + 'tabulate' ], entry_points={ 'console_scripts': [ From c015780a8dafdbcdc543eb5ca285ba7cd323f740 Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Wed, 16 Dec 2020 18:23:34 +0100 Subject: [PATCH 17/20] Bugfixes --- src/sh_edraft/cli/cpl_cli/commands/version.py | 2 +- src/sh_edraft/console/console.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sh_edraft/cli/cpl_cli/commands/version.py b/src/sh_edraft/cli/cpl_cli/commands/version.py index 61c95211..737a69c7 100644 --- a/src/sh_edraft/cli/cpl_cli/commands/version.py +++ b/src/sh_edraft/cli/cpl_cli/commands/version.py @@ -25,7 +25,7 @@ class Version(CommandBase): Console.write_line(f'Python: {sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}') Console.write_line(f'OS: {platform.system()} {platform.processor()}') - Console.write_line('\nCPL:') + Console.write_line('CPL:') packages = [] for importer, modname, is_pkg in pkgutil.iter_modules(sh_edraft.__path__): module = importer.find_module(modname).load_module(modname) diff --git a/src/sh_edraft/console/console.py b/src/sh_edraft/console/console.py index b2b722da..c454eb81 100644 --- a/src/sh_edraft/console/console.py +++ b/src/sh_edraft/console/console.py @@ -153,6 +153,7 @@ class Console: table = tabulate(values, headers=header) Console.write_line(table) + Console.write('\n') @classmethod def write(cls, *args): From 299c63da07133e3ee221ecbdd4e1201241ba0cb1 Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Wed, 16 Dec 2020 18:25:02 +0100 Subject: [PATCH 18/20] Bugfixes --- src/sh_edraft/cli/cpl_cli/commands/help.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sh_edraft/cli/cpl_cli/commands/help.py b/src/sh_edraft/cli/cpl_cli/commands/help.py index 3983cb59..6ea89066 100644 --- a/src/sh_edraft/cli/cpl_cli/commands/help.py +++ b/src/sh_edraft/cli/cpl_cli/commands/help.py @@ -23,3 +23,5 @@ class Help(CommandBase): Console.write(f'\n\t{name} ') Console.set_foreground_color('default') Console.write(f'{description}') + + Console.write('\n') From d49aa30cb75d85610f4004a7119eec2e2b5619c5 Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Wed, 16 Dec 2020 18:26:52 +0100 Subject: [PATCH 19/20] Removed publisher.py --- src/tests_dev/publisher.py | 65 -------------------------------------- 1 file changed, 65 deletions(-) delete mode 100644 src/tests_dev/publisher.py diff --git a/src/tests_dev/publisher.py b/src/tests_dev/publisher.py deleted file mode 100644 index 06b75735..00000000 --- a/src/tests_dev/publisher.py +++ /dev/null @@ -1,65 +0,0 @@ -from typing import Optional - -from sh_edraft.configuration.base import ConfigurationBase -from sh_edraft.hosting import ApplicationHost -from sh_edraft.hosting.base import ApplicationBase -from sh_edraft.logging import Logger -from sh_edraft.logging.base import LoggerBase -from sh_edraft.publishing import Publisher -from sh_edraft.publishing.base import PublisherBase -from sh_edraft.service.providing.base import ServiceProviderBase - - -class Program(ApplicationBase): - - def __init__(self): - ApplicationBase.__init__(self) - - self._app_host: Optional[ApplicationHost] = None - self._services: Optional[ServiceProviderBase] = None - self._configuration: Optional[ConfigurationBase] = None - self._logger: Optional[LoggerBase] = None - self._publisher: Optional[PublisherBase] = None - - def create_application_host(self): - self._app_host = ApplicationHost() - self._configuration = self._app_host.configuration - self._services = self._app_host.services - - def create_configuration(self): - self._configuration.add_environment_variables('PYTHON_') - self._configuration.add_environment_variables('CPL_') - self._configuration.add_argument_variables() - self._configuration.add_json_file(f'appsettings.json') - self._configuration.add_json_file(f'appsettings.{self._configuration.environment.environment_name}.json') - self._configuration.add_json_file(f'appsettings.{self._configuration.environment.host_name}.json', optional=True) - - def create_services(self): - # Add and create logger - self._services.add_singleton(LoggerBase, Logger) - self._logger = self._services.get_service(LoggerBase) - - # Add and create publisher - self._services.add_singleton(PublisherBase, Publisher) - self._publisher: Publisher = self._services.get_service(PublisherBase) - - def main(self): - self._logger.header(f'{self._configuration.environment.application_name}:') - self._logger.debug(__name__, f'Host: {self._configuration.environment.host_name}') - self._logger.debug(__name__, f'Environment: {self._configuration.environment.environment_name}') - self._logger.debug(__name__, f'Customer: {self._configuration.environment.customer}') - self._publisher.exclude('../tests') - self._publisher.exclude('../tests_dev') - self._publisher.include('../../LICENSE') - self._publisher.include('../../README.MD') - self._publisher.include('../../requirements.txt') - self._publisher.create() - self._publisher.build() - - -if __name__ == '__main__': - program = Program() - program.create_application_host() - program.create_configuration() - program.create_services() - program.main() From ceec896718e74bbc3913637dd04dacdfac0f0410 Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Sat, 19 Dec 2020 14:17:50 +0100 Subject: [PATCH 20/20] Improved error handling --- src/sh_edraft/cli/interpreter/interpreter.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/sh_edraft/cli/interpreter/interpreter.py b/src/sh_edraft/cli/interpreter/interpreter.py index e1cf07ea..d3e580e4 100644 --- a/src/sh_edraft/cli/interpreter/interpreter.py +++ b/src/sh_edraft/cli/interpreter/interpreter.py @@ -16,6 +16,11 @@ class Interpreter: def interpret(self, input_string: str): input_list = input_string.split(' ') command = input_list[0] + if command is None or command == '': + Console.error(f'Expected command') + Console.error('Run \'cpl help\'') + return + args = input_list[1:] if len(input_list) > 1 else [] cmd = next(