16 Commits

Author SHA1 Message Date
68e01afb5b Release 2022.12.0 2022-12-04 00:12:40 +01:00
2e0a8bb1ff Minor fixes to cpl query 2022-12-04 00:08:16 +01:00
b02aebef35 Improved set-version tool & set version 2022-12-03 23:42:23 +01:00
099a51ed93 Merge pull request 'Fixed invalid output after console spinner #122' (#132) from #122 into 2022.12
Reviewed-on: #132
Closes #122
2022-12-03 23:31:20 +01:00
e4aedb354b Fixed invalid output after console spinner #122 2022-12-03 23:30:54 +01:00
301768b842 Merge pull request 'cpl start & run - Bessere Einbindung mit den Build-Tools #124' (#131) from #124 into 2022.12
Reviewed-on: #131
Closes #124
2022-12-03 23:25:11 +01:00
856960d799 Added logic to run build code to cpl start #124 2022-12-02 19:38:03 +01:00
d0877a4ea6 Added logic to run build code to cpl run #124 2022-12-02 18:41:58 +01:00
3c20ab296a Added --dev flag to cpl run & start #124 2022-12-02 17:48:35 +01:00
4dc7ee3314 Merge pull request 'cpl query Enumerable quatsch #129' (#130) from #129 into 2022.12
Reviewed-on: #130
Closes #129
2022-12-01 23:43:01 +01:00
05bd5e8593 Improved query performance test #129 2022-12-01 23:41:06 +01:00
2fe3912a07 Fixed version test #129 2022-12-01 23:34:00 +01:00
2840628443 Improved tests #129 2022-12-01 23:23:48 +01:00
f0f79e7e3b Refactored cpl-query Iterable & Enumerable #129 2022-12-01 21:09:39 +01:00
e8ae635c88 Improved tests #129 2022-12-01 17:00:17 +01:00
d8f7e03815 Added group by & refactored Iterable #129 2022-12-01 16:27:29 +01:00
115 changed files with 1033 additions and 1356 deletions

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_cli'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.10.1.post1' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -28,4 +28,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='2022', minor='10', micro='1.post1') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_cli._templates'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.10.1.post1' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -23,4 +23,4 @@ from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='1.post1') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_cli._templates.build'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.10.1.post1' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -23,4 +23,4 @@ from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='1.post1') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_cli._templates.generate'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.10.1.post1' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -23,4 +23,4 @@ from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='1.post1') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_cli._templates.new'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.10.1.post1' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -23,4 +23,4 @@ from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='1.post1') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_cli._templates.new.console'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.10.1.post1' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -23,4 +23,4 @@ from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='1.post1') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_cli._templates.new.console.source'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.10.1.post1' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -23,4 +23,4 @@ from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='1.post1') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_cli._templates.new.console.source.name'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.10.1.post1' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -23,4 +23,4 @@ from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='1.post1') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_cli._templates.new.console.source.tests'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.10.1.post1' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -23,4 +23,4 @@ from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='1.post1') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_cli._templates.new.library'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.10.1.post1' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -23,4 +23,4 @@ from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='1.post1') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_cli._templates.new.library.source'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.10.1.post1' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -23,4 +23,4 @@ from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='1.post1') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_cli._templates.new.library.source.name'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.10.1.post1' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -23,4 +23,4 @@ from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='1.post1') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_cli._templates.new.library.source.tests'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.10.1.post1' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -23,4 +23,4 @@ from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='1.post1') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_cli._templates.new.unittest'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.10.1.post1' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -23,4 +23,4 @@ from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='1.post1') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_cli._templates.new.unittest.source'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.10.1.post1' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -23,4 +23,4 @@ from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='1.post1') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_cli._templates.new.unittest.source.name'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.10.1.post1' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -23,4 +23,4 @@ from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='1.post1') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_cli._templates.publish'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.10.1.post1' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -23,4 +23,4 @@ from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='1.post1') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_cli.command'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.10.1.post1' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -29,4 +29,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='2022', minor='10', micro='1.post1') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -8,10 +8,12 @@ from cpl_cli.configuration import WorkspaceSettings
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.live_server.start_executable import StartExecutable from cpl_cli.live_server.start_executable import StartExecutable
from cpl_cli.publish import PublisherService
from cpl_core.configuration import ConfigurationABC from cpl_core.configuration import ConfigurationABC
from cpl_core.console.console import Console from cpl_core.console.console import Console
from cpl_core.dependency_injection import ServiceProviderABC from cpl_core.dependency_injection import ServiceProviderABC
from cpl_core.environment.application_environment_abc import ApplicationEnvironmentABC from cpl_core.environment.application_environment_abc import ApplicationEnvironmentABC
from cpl_core.utils import String
class RunService(CommandABC): class RunService(CommandABC):
@@ -22,7 +24,8 @@ class RunService(CommandABC):
services: ServiceProviderABC, services: ServiceProviderABC,
project_settings: ProjectSettings, project_settings: ProjectSettings,
build_settings: BuildSettings, build_settings: BuildSettings,
workspace: WorkspaceSettings workspace: WorkspaceSettings,
publisher: PublisherService,
): ):
""" """
Service for the CLI command start Service for the CLI command start
@@ -41,8 +44,10 @@ class RunService(CommandABC):
self._project_settings = project_settings self._project_settings = project_settings
self._build_settings = build_settings self._build_settings = build_settings
self._workspace = workspace self._workspace = workspace
self._publisher = publisher
self._src_dir = os.path.join(self._env.working_directory, self._build_settings.source_path) self._src_dir = os.path.join(self._env.working_directory, self._build_settings.source_path)
self._is_dev = False
@property @property
def help_message(self) -> str: def help_message(self) -> str:
@@ -80,16 +85,36 @@ class RunService(CommandABC):
self._src_dir = os.path.dirname(json_file) self._src_dir = os.path.dirname(json_file)
def _build(self):
if self._is_dev:
return
self._env.set_working_directory(self._src_dir)
self._publisher.build()
self._src_dir = os.path.abspath(os.path.join(
self._src_dir,
self._build_settings.output_path,
self._project_settings.name,
'build',
String.convert_to_snake_case(self._project_settings.name)
))
def execute(self, args: list[str]): def execute(self, args: list[str]):
""" """
Entry point of command Entry point of command
:param args: :param args:
:return: :return:
""" """
if 'dev' in args:
self._is_dev = True
args.remove('dev')
if len(args) >= 1: if len(args) >= 1:
self._set_project_by_args(args[0]) self._set_project_by_args(args[0])
args.remove(args[0]) args.remove(args[0])
self._build()
start_service = StartExecutable(self._env, self._build_settings) start_service = StartExecutable(self._env, self._build_settings)
start_service.run(args, self._project_settings.python_executable, self._src_dir, output=False) start_service.run(args, self._project_settings.python_executable, self._src_dir, output=False)
Console.write_line() Console.write_line()

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_cli.configuration'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.10.1.post1' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -31,4 +31,4 @@ from .workspace_settings import WorkspaceSettings
from .workspace_settings_name_enum import WorkspaceSettingsNameEnum from .workspace_settings_name_enum import WorkspaceSettingsNameEnum
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='1.post1') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -3,8 +3,8 @@
"Name": "cpl-cli", "Name": "cpl-cli",
"Version": { "Version": {
"Major": "2022", "Major": "2022",
"Minor": "10", "Minor": "12",
"Micro": "1.post1" "Micro": "0"
}, },
"Author": "Sven Heidemann", "Author": "Sven Heidemann",
"AuthorEmail": "sven.heidemann@sh-edraft.de", "AuthorEmail": "sven.heidemann@sh-edraft.de",
@@ -16,7 +16,7 @@
"LicenseName": "MIT", "LicenseName": "MIT",
"LicenseDescription": "MIT, see LICENSE for more details.", "LicenseDescription": "MIT, see LICENSE for more details.",
"Dependencies": [ "Dependencies": [
"cpl-core>=2022.10.0" "cpl-core>=2022.12.0"
], ],
"DevDependencies": [], "DevDependencies": [],
"PythonVersion": ">=3.10", "PythonVersion": ">=3.10",

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_cli.live_server'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.10.1.post1' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -23,4 +23,4 @@ from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='1.post1') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -6,17 +6,24 @@ 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_cli.publish import PublisherService
from cpl_core.console.console import Console from cpl_core.console.console import Console
from cpl_core.environment.application_environment_abc import ApplicationEnvironmentABC from cpl_core.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.live_server.live_server_thread import LiveServerThread from cpl_cli.live_server.live_server_thread import LiveServerThread
from cpl_core.utils import String
class LiveServerService(FileSystemEventHandler): class LiveServerService(FileSystemEventHandler):
def __init__(self, env: ApplicationEnvironmentABC, project_settings: ProjectSettings, def __init__(
build_settings: BuildSettings): self,
env: ApplicationEnvironmentABC,
project_settings: ProjectSettings,
build_settings: BuildSettings,
publisher: PublisherService,
):
""" """
Service for the live development server Service for the live development server
:param env: :param env:
@@ -28,12 +35,15 @@ class LiveServerService(FileSystemEventHandler):
self._env = env self._env = env
self._project_settings = project_settings self._project_settings = project_settings
self._build_settings = build_settings self._build_settings = build_settings
self._publisher = publisher
self._src_dir = os.path.join(self._env.working_directory, self._build_settings.source_path) self._src_dir = os.path.join(self._env.working_directory, self._build_settings.source_path)
self._wd = self._src_dir
self._ls_thread = None self._ls_thread = None
self._observer = None self._observer = None
self._args: list[str] = [] self._args: list[str] = []
self._is_dev = False
def _start_observer(self): def _start_observer(self):
""" """
@@ -75,10 +85,11 @@ class LiveServerService(FileSystemEventHandler):
self._restart() self._restart()
def _start(self): def _start(self):
self._build()
self._start_observer() self._start_observer()
self._ls_thread = LiveServerThread( self._ls_thread = LiveServerThread(
self._project_settings.python_executable, self._project_settings.python_executable,
self._src_dir, self._wd,
self._args, self._args,
self._env, self._env,
self._build_settings self._build_settings
@@ -87,6 +98,22 @@ class LiveServerService(FileSystemEventHandler):
self._ls_thread.join() self._ls_thread.join()
Console.close() Console.close()
def _build(self):
if self._is_dev:
return
self._env.set_working_directory(self._src_dir)
Console.disable()
self._publisher.build()
Console.enable()
self._wd = os.path.abspath(os.path.join(
self._src_dir,
self._build_settings.output_path,
self._project_settings.name,
'build',
String.convert_to_snake_case(self._project_settings.name)
))
def start(self, args: list[str]): def start(self, args: list[str]):
""" """
Starts the CPL live development server Starts the CPL live development server
@@ -97,6 +124,10 @@ class LiveServerService(FileSystemEventHandler):
Console.error('Project has no entry point.') Console.error('Project has no entry point.')
return return
if 'dev' in args:
self._is_dev = True
args.remove('dev')
self._args = args self._args = args
Console.write_line('** CPL live development server is running **') Console.write_line('** CPL live development server is running **')
self._start() self._start()

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_cli.migrations'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.10.1.post1' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -23,4 +23,4 @@ from collections import namedtuple
# imports # imports
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='1.post1') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_cli.migrations.base'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.10.1.post1' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -23,4 +23,4 @@ from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='1.post1') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_cli.migrations.service'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.10.1.post1' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -23,4 +23,4 @@ from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='1.post1') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_cli.publish'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.10.1.post1' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -25,4 +25,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='2022', minor='10', micro='1.post1') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_cli.source_creator'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.10.1.post1' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -23,4 +23,4 @@ from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='1.post1') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -60,8 +60,10 @@ class StartupArgumentExtension(StartupExtensionABC):
config.create_console_argument(ArgumentTypeEnum.Executable, '', 'publish', ['p', 'P'], PublishService, True, validators=[ProjectValidator]) config.create_console_argument(ArgumentTypeEnum.Executable, '', 'publish', ['p', 'P'], PublishService, True, validators=[ProjectValidator])
config.create_console_argument(ArgumentTypeEnum.Executable, '', 'remove', ['r', 'R'], RemoveService, True, validators=[WorkspaceValidator]) \ config.create_console_argument(ArgumentTypeEnum.Executable, '', 'remove', ['r', 'R'], RemoveService, True, validators=[WorkspaceValidator]) \
.add_console_argument(ArgumentTypeEnum.Flag, '--', 'simulate', ['s', 'S']) .add_console_argument(ArgumentTypeEnum.Flag, '--', 'simulate', ['s', 'S'])
config.create_console_argument(ArgumentTypeEnum.Executable, '', 'run', [], RunService, True, validators=[ProjectValidator]) config.create_console_argument(ArgumentTypeEnum.Executable, '', 'run', [], RunService, True, validators=[ProjectValidator]) \
config.create_console_argument(ArgumentTypeEnum.Executable, '', 'start', ['s', 'S'], StartService, True, validators=[ProjectValidator]) .add_console_argument(ArgumentTypeEnum.Flag, '--', 'dev', ['d', 'D'])
config.create_console_argument(ArgumentTypeEnum.Executable, '', 'start', ['s', 'S'], StartService, True, validators=[ProjectValidator]) \
.add_console_argument(ArgumentTypeEnum.Flag, '--', 'dev', ['d', 'D'])
config.create_console_argument(ArgumentTypeEnum.Executable, '', 'uninstall', ['ui', 'UI'], UninstallService, True, validators=[ProjectValidator]) \ config.create_console_argument(ArgumentTypeEnum.Executable, '', 'uninstall', ['ui', 'UI'], UninstallService, True, validators=[ProjectValidator]) \
.add_console_argument(ArgumentTypeEnum.Flag, '--', 'dev', ['d', 'D']) \ .add_console_argument(ArgumentTypeEnum.Flag, '--', 'dev', ['d', 'D']) \
.add_console_argument(ArgumentTypeEnum.Flag, '--', 'virtual', ['v', 'V']) \ .add_console_argument(ArgumentTypeEnum.Flag, '--', 'virtual', ['v', 'V']) \

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_cli.validators'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.10.1.post1' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -23,4 +23,4 @@ from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='1.post1') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_core'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.10.0.post9' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -23,4 +23,4 @@ from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='0.post9') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_core.application'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.10.0.post9' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -29,4 +29,4 @@ from .startup_abc import StartupABC
from .startup_extension_abc import StartupExtensionABC from .startup_extension_abc import StartupExtensionABC
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='0.post9') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_core.configuration'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.10.0.post9' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -35,4 +35,4 @@ from .validator_abc import ValidatorABC
from .variable_argument import VariableArgument from .variable_argument import VariableArgument
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='0.post9') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_core.console'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.10.0.post9' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -28,4 +28,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='2022', minor='10', micro='0.post9') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -500,7 +500,7 @@ class Console:
return return
if cls._hold_back: if cls._hold_back:
cls._hold_back_calls.append(ConsoleCall(cls.write, args)) cls._hold_back_calls.append(ConsoleCall(cls.write, *args))
return return
string = ' '.join(map(str, args)) string = ' '.join(map(str, args))
@@ -523,7 +523,7 @@ class Console:
return return
if cls._hold_back: if cls._hold_back:
cls._hold_back_calls.append(ConsoleCall(cls.write_at, x, y, args)) cls._hold_back_calls.append(ConsoleCall(cls.write_at, x, y, *args))
return return
string = ' '.join(map(str, args)) string = ' '.join(map(str, args))
@@ -542,7 +542,7 @@ class Console:
return return
if cls._hold_back: if cls._hold_back:
cls._hold_back_calls.append(ConsoleCall(cls.write_line, args)) cls._hold_back_calls.append(ConsoleCall(cls.write_line, *args))
return return
string = ' '.join(map(str, args)) string = ' '.join(map(str, args))
@@ -567,7 +567,7 @@ class Console:
return return
if cls._hold_back: if cls._hold_back:
cls._hold_back_calls.append(ConsoleCall(cls.write_line_at, x, y, args)) cls._hold_back_calls.append(ConsoleCall(cls.write_line_at, x, y, *args))
return return
string = ' '.join(map(str, args)) string = ' '.join(map(str, args))

View File

@@ -3,8 +3,8 @@
"Name": "cpl-core", "Name": "cpl-core",
"Version": { "Version": {
"Major": "2022", "Major": "2022",
"Minor": "10", "Minor": "12",
"Micro": "0.post9" "Micro": "0"
}, },
"Author": "Sven Heidemann", "Author": "Sven Heidemann",
"AuthorEmail": "sven.heidemann@sh-edraft.de", "AuthorEmail": "sven.heidemann@sh-edraft.de",

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_core.database'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.10.0.post9' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -26,4 +26,4 @@ from .database_settings import DatabaseSettings
from .table_abc import TableABC from .table_abc import TableABC
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='0.post9') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_core.database.connection'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.10.0.post9' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -25,4 +25,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='2022', minor='10', micro='0.post9') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_core.database.context'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.10.0.post9' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -25,4 +25,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='2022', minor='10', micro='0.post9') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_core.dependency_injection'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.10.0.post9' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -31,4 +31,4 @@ 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='2022', minor='10', micro='0.post9') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_core.environment'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.10.0.post9' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -26,4 +26,4 @@ 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='2022', minor='10', micro='0.post9') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_core.logging'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.10.0.post9' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -28,4 +28,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='2022', minor='10', micro='0.post9') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_core.mailing'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.10.0.post9' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -28,4 +28,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='2022', minor='10', micro='0.post9') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_core.pipes'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.10.0.post9' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -30,4 +30,4 @@ from .to_camel_case_pipe import ToCamelCasePipe
from .to_snake_case_pipe import ToSnakeCasePipe from .to_snake_case_pipe import ToSnakeCasePipe
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='0.post9') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_core.time'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.10.0.post9' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -25,4 +25,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='2022', minor='10', micro='0.post9') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_core.utils'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de'
__version__ = '2022.10.0.post9' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -26,4 +26,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='2022', minor='10', micro='0.post9') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_discord'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2021 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2021 - 2022 sh-edraft.de'
__version__ = '2022.10.0.post6' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -55,4 +55,4 @@ def get_discord_collection(services: 'ServiceCollectionABC') -> 'DiscordCollecti
# build-ignore-end # build-ignore-end
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='0.post6') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_discord.application'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2021 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2021 - 2022 sh-edraft.de'
__version__ = '2022.10.0.post6' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -24,4 +24,4 @@ from collections import namedtuple
from .discord_bot_application_abc import DiscordBotApplicationABC from .discord_bot_application_abc import DiscordBotApplicationABC
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='0.post6') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_discord.command'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2021 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2021 - 2022 sh-edraft.de'
__version__ = '2022.10.0.post6' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -25,4 +25,4 @@ from .discord_command_abc import DiscordCommandABC
from .discord_commands_meta import DiscordCogMeta from .discord_commands_meta import DiscordCogMeta
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='0.post6') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_discord.configuration'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2021 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2021 - 2022 sh-edraft.de'
__version__ = '2022.10.0.post6' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -24,4 +24,4 @@ from collections import namedtuple
from .discord_bot_settings import DiscordBotSettings from .discord_bot_settings import DiscordBotSettings
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='0.post6') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_discord.container'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2021 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2021 - 2022 sh-edraft.de'
__version__ = '2022.10.0.post6' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -31,4 +31,4 @@ from .thread import Thread
from .voice_channel import VoiceChannel from .voice_channel import VoiceChannel
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='0.post6') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -3,8 +3,8 @@
"Name": "cpl-discord", "Name": "cpl-discord",
"Version": { "Version": {
"Major": "2022", "Major": "2022",
"Minor": "10", "Minor": "12",
"Micro": "0.post6" "Micro": "0"
}, },
"Author": "Sven Heidemann", "Author": "Sven Heidemann",
"AuthorEmail": "sven.heidemann@sh-edraft.de", "AuthorEmail": "sven.heidemann@sh-edraft.de",
@@ -16,12 +16,12 @@
"LicenseName": "MIT", "LicenseName": "MIT",
"LicenseDescription": "MIT, see LICENSE for more details.", "LicenseDescription": "MIT, see LICENSE for more details.",
"Dependencies": [ "Dependencies": [
"cpl-core>=2022.10.0", "cpl-core>=2022.12.0",
"discord.py==2.0.1", "discord.py==2.1.0",
"cpl-query>=2022.10.0" "cpl-query>=2022.12.0"
], ],
"DevDependencies": [ "DevDependencies": [
"cpl-cli>=2022.10.0" "cpl-cli>=2022.12.0"
], ],
"PythonVersion": ">=3.10.4", "PythonVersion": ">=3.10.4",
"PythonPath": {}, "PythonPath": {},

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_discord.events'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2021 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2021 - 2022 sh-edraft.de'
__version__ = '2022.10.0.post6' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -69,4 +69,4 @@ from .on_voice_state_update_abc import OnVoiceStateUpdateABC
from .on_webhooks_update_abc import OnWebhooksUpdateABC from .on_webhooks_update_abc import OnWebhooksUpdateABC
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='0.post6') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_discord.helper'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2021 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2021 - 2022 sh-edraft.de'
__version__ = '2022.10.0.post6' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -24,4 +24,4 @@ from collections import namedtuple
from .to_containers_converter import ToContainersConverter from .to_containers_converter import ToContainersConverter
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='0.post6') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_discord.service'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2021 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2021 - 2022 sh-edraft.de'
__version__ = '2022.10.0.post6' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -29,4 +29,4 @@ from .discord_service import DiscordService
from .discord_service_abc import DiscordServiceABC from .discord_service_abc import DiscordServiceABC
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='0.post6') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_query'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2021 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2021 - 2022 sh-edraft.de'
__version__ = '2022.10.0.post2' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -23,4 +23,4 @@ from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='0.post2') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_query.base'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2021 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2021 - 2022 sh-edraft.de'
__version__ = '2022.10.0.post2' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -23,4 +23,4 @@ from collections import namedtuple
# imports: # imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='0.post2') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -0,0 +1,2 @@
def default_lambda(x: object):
return x

View File

@@ -0,0 +1,34 @@
from collections.abc import Callable
from cpl_query.base.ordered_queryable_abc import OrderedQueryableABC
from cpl_query.exceptions import ArgumentNoneException, ExceptionArgument
from cpl_query.iterable.iterable import Iterable
class OrderedQueryable(OrderedQueryableABC):
r"""Implementation of :class: `cpl_query.extension.Iterable` `cpl_query.extension.OrderedIterableABC`
"""
def __init__(self, _t: type, _values: Iterable = None, _func: Callable = None):
OrderedQueryableABC.__init__(self, _t, _values, _func)
def then_by(self: OrderedQueryableABC, _func: Callable) -> OrderedQueryableABC:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _func is None:
raise ArgumentNoneException(ExceptionArgument.func)
self._funcs.append(_func)
return OrderedQueryable(self.type, sorted(self, key=lambda *args: [f(*args) for f in self._funcs]), _func)
def then_by_descending(self: OrderedQueryableABC, _func: Callable) -> OrderedQueryableABC:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _func is None:
raise ArgumentNoneException(ExceptionArgument.func)
self._funcs.append(_func)
return OrderedQueryable(self.type, sorted(self, key=lambda *args: [f(*args) for f in self._funcs], reverse=True), _func)

View File

@@ -2,20 +2,20 @@ from abc import abstractmethod
from collections.abc import Callable from collections.abc import Callable
from typing import Iterable from typing import Iterable
from cpl_query.iterable.iterable_abc import IterableABC from cpl_query.base.queryable_abc import QueryableABC
class OrderedIterableABC(IterableABC): class OrderedQueryableABC(QueryableABC):
@abstractmethod @abstractmethod
def __init__(self, _t: type, _func: Callable = None, _values: Iterable = None): def __init__(self, _t: type, _values: Iterable = None, _func: Callable = None):
IterableABC.__init__(self, _t, _values) QueryableABC.__init__(self, _t, _values)
self._funcs: list[Callable] = [] self._funcs: list[Callable] = []
if _func is not None: if _func is not None:
self._funcs.append(_func) self._funcs.append(_func)
@abstractmethod @abstractmethod
def then_by(self, func: Callable) -> 'OrderedIterableABC': def then_by(self, func: Callable) -> 'OrderedQueryableABC':
r"""Sorts OrderedList in ascending order by function r"""Sorts OrderedList in ascending order by function
Parameter Parameter
@@ -29,7 +29,7 @@ class OrderedIterableABC(IterableABC):
pass pass
@abstractmethod @abstractmethod
def then_by_descending(self, func: Callable) -> 'OrderedIterableABC': def then_by_descending(self, func: Callable) -> 'OrderedQueryableABC':
r"""Sorts OrderedList in descending order by function r"""Sorts OrderedList in descending order by function
Parameter Parameter

View File

@@ -1,10 +1,19 @@
from abc import abstractmethod, ABC
from typing import Optional, Callable, Union from typing import Optional, Callable, Union
from cpl_query._helper import is_number
from cpl_query.base.sequence_abc import SequenceABC
from cpl_query.exceptions import InvalidTypeException, ArgumentNoneException, ExceptionArgument, IndexOutOfRangeException
class QueryableABC(ABC):
@abstractmethod def _default_lambda(x: object):
return x
class QueryableABC(SequenceABC):
def __init__(self, t: type = None, values: list = None):
SequenceABC.__init__(self, t, values)
def all(self, _func: Callable = None) -> bool: def all(self, _func: Callable = None) -> bool:
r"""Checks if every element of list equals result found by function r"""Checks if every element of list equals result found by function
@@ -17,9 +26,11 @@ class QueryableABC(ABC):
------- -------
bool bool
""" """
pass if _func is None:
_func = _default_lambda
return self.count(_func) == self.count()
@abstractmethod
def any(self, _func: Callable = None) -> bool: def any(self, _func: Callable = None) -> bool:
r"""Checks if list contains result found by function r"""Checks if list contains result found by function
@@ -32,9 +43,11 @@ class QueryableABC(ABC):
------- -------
bool bool
""" """
pass if _func is None:
_func = _default_lambda
return self.where(_func).count() > 0
@abstractmethod
def average(self, _func: Callable = None) -> Union[int, float, complex]: def average(self, _func: Callable = None) -> Union[int, float, complex]:
r"""Returns average value of list r"""Returns average value of list
@@ -47,10 +60,12 @@ class QueryableABC(ABC):
------- -------
Union[int, float, complex] Union[int, float, complex]
""" """
pass if _func is None and not is_number(self.type):
raise InvalidTypeException()
@abstractmethod return self.sum(_func) / self.count()
def contains(self, value: object) -> bool:
def contains(self, _value: object) -> bool:
r"""Checks if list contains value given by function r"""Checks if list contains value given by function
Parameter Parameter
@@ -62,9 +77,11 @@ class QueryableABC(ABC):
------- -------
bool bool
""" """
pass if _value is None:
raise ArgumentNoneException(ExceptionArgument.value)
return self.where(lambda x: x == _value).count() > 0
@abstractmethod
def count(self, _func: Callable = None) -> int: def count(self, _func: Callable = None) -> int:
r"""Returns length of list or count of found elements r"""Returns length of list or count of found elements
@@ -77,9 +94,11 @@ class QueryableABC(ABC):
------- -------
int int
""" """
pass if _func is None:
return self.__len__()
return self.where(_func).__len__()
@abstractmethod
def distinct(self, _func: Callable = None) -> 'QueryableABC': def distinct(self, _func: Callable = None) -> 'QueryableABC':
r"""Returns list without redundancies r"""Returns list without redundancies
@@ -92,39 +111,62 @@ class QueryableABC(ABC):
------- -------
:class: `cpl_query.base.queryable_abc.QueryableABC` :class: `cpl_query.base.queryable_abc.QueryableABC`
""" """
pass if _func is None:
_func = _default_lambda
@abstractmethod result = []
def element_at(self, index: int) -> any: known_values = []
for element in self:
value = _func(element)
if value in known_values:
continue
known_values.append(value)
result.append(element)
return type(self)(self._type, result)
def element_at(self, _index: int) -> any:
r"""Returns element at given index r"""Returns element at given index
Parameter Parameter
--------- ---------
index: :class:`int` _index: :class:`int`
index index
Returns Returns
------- -------
Value at index: any Value at _index: any
""" """
pass if _index is None:
raise ArgumentNoneException(ExceptionArgument.index)
@abstractmethod result = self[_index]
def element_at_or_default(self, index: int) -> Optional[any]: if result is None:
raise IndexOutOfRangeException
return result
def element_at_or_default(self, _index: int) -> Optional[any]:
r"""Returns element at given index or None r"""Returns element at given index or None
Parameter Parameter
--------- ---------
index: :class:`int` _index: :class:`int`
index index
Returns Returns
------- -------
Value at index: Optional[any] Value at _index: Optional[any]
""" """
pass if _index is None:
raise ArgumentNoneException(ExceptionArgument.index)
try:
return self[_index]
except IndexError:
return None
@abstractmethod
def first(self) -> any: def first(self) -> any:
r"""Returns first element r"""Returns first element
@@ -132,9 +174,11 @@ class QueryableABC(ABC):
------- -------
First element of list: any First element of list: any
""" """
pass if len(self) == 0:
raise IndexOutOfRangeException()
return self[0]
@abstractmethod
def first_or_default(self) -> any: def first_or_default(self) -> any:
r"""Returns first element or None r"""Returns first element or None
@@ -142,9 +186,11 @@ class QueryableABC(ABC):
------- -------
First element of list: Optional[any] First element of list: Optional[any]
""" """
pass if len(self) == 0:
return None
return self[0]
@abstractmethod
def for_each(self, _func: Callable = None): def for_each(self, _func: Callable = None):
r"""Runs given function for each element of list r"""Runs given function for each element of list
@@ -153,9 +199,36 @@ class QueryableABC(ABC):
func: :class: `Callable` func: :class: `Callable`
function to call function to call
""" """
pass if _func is not None:
for element in self:
_func(element)
return self
def group_by(self, _func: Callable = None) -> 'QueryableABC':
r"""Groups by func
Returns
-------
Grouped list[list[any]]: any
"""
if _func is None:
_func = _default_lambda
groups = {}
for v in self:
value = _func(v)
if v not in groups:
groups[value] = []
groups[value].append(v)
v = []
for g in groups.values():
v.append(type(self)(None, g))
x = type(self)(type(self), v)
return x
@abstractmethod
def last(self) -> any: def last(self) -> any:
r"""Returns last element r"""Returns last element
@@ -163,9 +236,11 @@ class QueryableABC(ABC):
------- -------
Last element of list: any Last element of list: any
""" """
pass if len(self) == 0:
raise IndexOutOfRangeException()
return self[len(self) - 1]
@abstractmethod
def last_or_default(self) -> any: def last_or_default(self) -> any:
r"""Returns last element or None r"""Returns last element or None
@@ -173,9 +248,11 @@ class QueryableABC(ABC):
------- -------
Last element of list: Optional[any] Last element of list: Optional[any]
""" """
pass if len(self) == 0:
return None
return self[len(self) - 1]
@abstractmethod
def max(self, _func: Callable = None) -> Union[int, float, complex]: def max(self, _func: Callable = None) -> Union[int, float, complex]:
r"""Returns the highest value r"""Returns the highest value
@@ -188,19 +265,33 @@ class QueryableABC(ABC):
------- -------
Union[int, float, complex] Union[int, float, complex]
""" """
pass if _func is None and not is_number(self.type):
raise InvalidTypeException()
@abstractmethod if _func is None:
def median(self) -> Union[int, float]: _func = _default_lambda
return _func(max(self, key=_func))
def median(self, _func=None) -> Union[int, float]:
r"""Return the median value of data elements r"""Return the median value of data elements
Returns Returns
------- -------
Union[int, float] Union[int, float]
""" """
pass if _func is None:
_func = _default_lambda
result = self.order_by(_func).select(_func).to_list()
length = len(result)
i = int(length / 2)
return (
result[i]
if length % 2 == 1
else (float(result[i - 1]) + float(result[i])) / float(2)
)
@abstractmethod
def min(self, _func: Callable = None) -> Union[int, float, complex]: def min(self, _func: Callable = None) -> Union[int, float, complex]:
r"""Returns the lowest value r"""Returns the lowest value
@@ -213,9 +304,14 @@ class QueryableABC(ABC):
------- -------
Union[int, float, complex] Union[int, float, complex]
""" """
pass if _func is None and not is_number(self.type):
raise InvalidTypeException()
if _func is None:
_func = _default_lambda
return _func(min(self, key=_func))
@abstractmethod
def order_by(self, _func: Callable = None) -> 'QueryableABC': def order_by(self, _func: Callable = None) -> 'QueryableABC':
r"""Sorts elements by function in ascending order r"""Sorts elements by function in ascending order
@@ -228,9 +324,12 @@ class QueryableABC(ABC):
------- -------
:class: `cpl_query.base.queryable_abc.QueryableABC` :class: `cpl_query.base.queryable_abc.QueryableABC`
""" """
pass if _func is None:
_func = _default_lambda
from cpl_query.base.ordered_queryable import OrderedQueryable
return OrderedQueryable(self.type, sorted(self, key=_func), _func)
@abstractmethod
def order_by_descending(self, _func: Callable = None) -> 'QueryableABC': def order_by_descending(self, _func: Callable = None) -> 'QueryableABC':
r"""Sorts elements by function in descending order r"""Sorts elements by function in descending order
@@ -243,9 +342,12 @@ class QueryableABC(ABC):
------- -------
:class: `cpl_query.base.queryable_abc.QueryableABC` :class: `cpl_query.base.queryable_abc.QueryableABC`
""" """
pass if _func is None:
_func = _default_lambda
from cpl_query.base.ordered_queryable import OrderedQueryable
return OrderedQueryable(self.type, sorted(self, key=_func, reverse=True), _func)
@abstractmethod
def reverse(self) -> 'QueryableABC': def reverse(self) -> 'QueryableABC':
r"""Reverses list r"""Reverses list
@@ -253,29 +355,31 @@ class QueryableABC(ABC):
------- -------
:class: `cpl_query.base.queryable_abc.QueryableABC` :class: `cpl_query.base.queryable_abc.QueryableABC`
""" """
pass return type(self)(self._type, list(reversed(self)))
@abstractmethod def select(self, _func: Callable) -> 'QueryableABC':
def select(self, _f: Callable) -> 'QueryableABC':
r"""Formats each element of list to a given format r"""Formats each element of list to a given format
Returns Returns
------- -------
:class: `cpl_query.base.queryable_abc.QueryableABC` :class: `cpl_query.base.queryable_abc.QueryableABC`
""" """
pass if _func is None:
_func = _default_lambda
@abstractmethod return type(self)(any, [_func(_o) for _o in self])
def select_many(self, _f: Callable) -> 'QueryableABC':
def select_many(self, _func: Callable) -> 'QueryableABC':
r"""Flattens resulting lists to one r"""Flattens resulting lists to one
Returns Returns
------- -------
:class: `cpl_query.base.queryable_abc.QueryableABC` :class: `cpl_query.base.queryable_abc.QueryableABC`
""" """
pass # The line below is pain. I don't understand anything of it...
# written on 09.11.2022 by Sven Heidemann
return type(self)(any, [_a for _o in self for _a in _func(_o)])
@abstractmethod
def single(self) -> any: def single(self) -> any:
r"""Returns one single element of list r"""Returns one single element of list
@@ -288,9 +392,13 @@ class QueryableABC(ABC):
ArgumentNoneException: when argument is None ArgumentNoneException: when argument is None
Exception: when argument is None or found more than one element Exception: when argument is None or found more than one element
""" """
pass if len(self) > 1:
raise Exception('Found more than one element')
elif len(self) == 0:
raise Exception('Found no element')
return self[0]
@abstractmethod
def single_or_default(self) -> Optional[any]: def single_or_default(self) -> Optional[any]:
r"""Returns one single element of list r"""Returns one single element of list
@@ -298,39 +406,48 @@ class QueryableABC(ABC):
------- -------
Found value: Optional[any] Found value: Optional[any]
""" """
pass if len(self) > 1:
raise Exception('Index out of range')
elif len(self) == 0:
return None
@abstractmethod return self[0]
def skip(self, index: int) -> 'QueryableABC':
def skip(self, _index: int) -> 'QueryableABC':
r"""Skips all elements from index r"""Skips all elements from index
Parameter Parameter
--------- ---------
index: :class:`int` _index: :class:`int`
index index
Returns Returns
------- -------
:class: `cpl_query.base.queryable_abc.QueryableABC` :class: `cpl_query.base.queryable_abc.QueryableABC`
""" """
pass if _index is None:
raise ArgumentNoneException(ExceptionArgument.index)
@abstractmethod return type(self)(self.type, values=self[_index:])
def skip_last(self, index: int) -> 'QueryableABC':
def skip_last(self, _index: int) -> 'QueryableABC':
r"""Skips all elements after index r"""Skips all elements after index
Parameter Parameter
--------- ---------
index: :class:`int` _index: :class:`int`
index index
Returns Returns
------- -------
:class: `cpl_query.base.queryable_abc.QueryableABC` :class: `cpl_query.base.queryable_abc.QueryableABC`
""" """
pass if _index is None:
raise ArgumentNoneException(ExceptionArgument.index)
index = len(self) - _index
return type(self)(self._type, self[:index])
@abstractmethod
def sum(self, _func: Callable = None) -> Union[int, float, complex]: def sum(self, _func: Callable = None) -> Union[int, float, complex]:
r"""Sum of all values r"""Sum of all values
@@ -343,39 +460,54 @@ class QueryableABC(ABC):
------- -------
Union[int, float, complex] Union[int, float, complex]
""" """
pass if _func is None and not is_number(self.type):
raise InvalidTypeException()
@abstractmethod if _func is None:
def take(self, index: int) -> 'QueryableABC': _func = _default_lambda
result = 0
for x in self:
result += _func(x)
return result
def take(self, _index: int) -> 'QueryableABC':
r"""Takes all elements from index r"""Takes all elements from index
Parameter Parameter
--------- ---------
index: :class:`int` _index: :class:`int`
index index
Returns Returns
------- -------
:class: `cpl_query.base.queryable_abc.QueryableABC` :class: `cpl_query.base.queryable_abc.QueryableABC`
""" """
pass if _index is None:
raise ArgumentNoneException(ExceptionArgument.index)
@abstractmethod return type(self)(self._type, self[:_index])
def take_last(self, index: int) -> 'QueryableABC':
def take_last(self, _index: int) -> 'QueryableABC':
r"""Takes all elements after index r"""Takes all elements after index
Parameter Parameter
--------- ---------
index: :class:`int` _index: :class:`int`
index index
Returns Returns
------- -------
:class: `cpl_query.base.queryable_abc.QueryableABC` :class: `cpl_query.base.queryable_abc.QueryableABC`
""" """
pass index = len(self) - _index
if index >= len(self) or index < 0:
raise IndexOutOfRangeException()
return type(self)(self._type, self[index:])
@abstractmethod
def where(self, _func: Callable = None) -> 'QueryableABC': def where(self, _func: Callable = None) -> 'QueryableABC':
r"""Select element by function r"""Select element by function
@@ -388,4 +520,15 @@ class QueryableABC(ABC):
------- -------
:class: `cpl_query.base.queryable_abc.QueryableABC` :class: `cpl_query.base.queryable_abc.QueryableABC`
""" """
pass if _func is None:
raise ArgumentNoneException(ExceptionArgument.func)
if _func is None:
_func = _default_lambda
result = []
for element in self:
if _func(element):
result.append(element)
return type(self)(self.type, result)

View File

@@ -0,0 +1,116 @@
from abc import ABC, abstractmethod
from itertools import islice
from cpl_query.base.sequence_values import SequenceValues
class SequenceABC(ABC):
@abstractmethod
def __init__(self, t: type = None, values: list = None):
ABC.__init__(self)
if values is None:
values = []
if t is None and len(values) > 0:
t = type(values[0])
if t is None:
t = any
self._type = t
self._set_values(values)
@classmethod
def __class_getitem__(cls, _t: type):
return _t
def __len__(self):
return len(self._values)
def __iter__(self):
return iter(self._values)
def next(self):
return next(self._values)
def __next__(self):
return self.next()
def __getitem__(self, n):
values = [x for x in self]
if isinstance(n, slice):
try:
return values[n]
except Exception as e:
raise e
for i in range(len(values)):
if i == n:
return values[i]
def __repr__(self):
return f'<{type(self).__name__} {list(self).__repr__()}>'
@property
def type(self) -> type:
return self._type
def _check_type(self, __object: any):
if self._type == any:
return
if self._type is not None and type(__object) != self._type and not isinstance(type(__object), self._type) and not issubclass(type(__object), self._type):
raise Exception(f'Unexpected type: {type(__object)}\nExpected type: {self._type}')
def _set_values(self, values: list):
self._values = SequenceValues(values, self._type)
def to_list(self) -> list:
r"""Converts :class: `cpl_query.base.sequence_abc.SequenceABC` to :class: `list`
Returns
-------
:class: `list`
"""
return [x for x in self]
def copy(self) -> 'SequenceABC':
r"""Creates a copy of sequence
Returns
-------
SequenceABC
"""
return type(self)(self._type, self.to_list())
@classmethod
def empty(cls) -> 'SequenceABC':
r"""Returns an empty sequence
Returns
-------
Sequence object that contains no elements
"""
return cls()
def index(self, _object: object) -> int:
r"""Returns the index of given element
Returns
-------
Index of object
Raises
-------
IndexError if object not in sequence
"""
for i, o in enumerate(self):
if o == _object:
return i
raise IndexError
@classmethod
def range(cls, start: int, length: int) -> 'SequenceABC':
return cls(int, list(range(start, length)))

View File

@@ -5,15 +5,13 @@ from cpl_query.exceptions import IndexOutOfRangeException
class SequenceValues: class SequenceValues:
def __init__(self, data, _t: type): def __init__(self, data: list, _t: type):
if data is None:
data = []
if len(data) > 0: if len(data) > 0:
def type_check(_t: type, _l: list): def type_check(_t: type, _l: list):
return all(isinstance(x, _t) for x in _l) return all([_t == any or isinstance(x, _t) for x in _l])
if not type_check(_t, data): if not type_check(_t, data):
print([type(x) for x in data])
raise Exception(f'Unexpected type\nExpected type: {_t}') raise Exception(f'Unexpected type\nExpected type: {_t}')
if not hasattr(data, '__iter__'): if not hasattr(data, '__iter__'):
@@ -30,7 +28,7 @@ class SequenceValues:
def __iter__(self): def __iter__(self):
i = 0 i = 0
while i < len(self): while i < self._len():
yield next(self._cycle) yield next(self._cycle)
i += 1 i += 1

View File

@@ -3,8 +3,8 @@
"Name": "cpl-query", "Name": "cpl-query",
"Version": { "Version": {
"Major": "2022", "Major": "2022",
"Minor": "10", "Minor": "12",
"Micro": "0.post2" "Micro": "0"
}, },
"Author": "Sven Heidemann", "Author": "Sven Heidemann",
"AuthorEmail": "sven.heidemann@sh-edraft.de", "AuthorEmail": "sven.heidemann@sh-edraft.de",

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_query.enumerable'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2021 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2021 - 2022 sh-edraft.de'
__version__ = '2022.10.0.post2' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -23,8 +23,6 @@ from collections import namedtuple
# imports: # imports:
from .enumerable import Enumerable from .enumerable import Enumerable
from .enumerable_abc import EnumerableABC from .enumerable_abc import EnumerableABC
from .ordered_enumerable import OrderedEnumerable
from .ordered_enumerable_abc import OrderedEnumerableABC
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='0.post2') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -1,9 +1,4 @@
from typing import Union, Callable, Optional
from cpl_query._helper import is_number
from cpl_query.enumerable.enumerable_abc import EnumerableABC from cpl_query.enumerable.enumerable_abc import EnumerableABC
from cpl_query.enumerable.ordered_enumerable_abc import OrderedEnumerableABC
from cpl_query.exceptions import ArgumentNoneException, ExceptionArgument, InvalidTypeException, IndexOutOfRangeException
def _default_lambda(x: object): def _default_lambda(x: object):
@@ -14,294 +9,5 @@ class Enumerable(EnumerableABC):
r"""Implementation of :class: `cpl_query.enumerable.enumerable_abc.EnumerableABC` r"""Implementation of :class: `cpl_query.enumerable.enumerable_abc.EnumerableABC`
""" """
def __init__(self, t: type = None, values: Union[list, iter] = None): def __init__(self, t: type = None, values: list = None):
EnumerableABC.__init__(self, t, values) EnumerableABC.__init__(self, t, values)
def all(self, _func: Callable = None) -> bool:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _func is None:
_func = _default_lambda
result = self.where(_func)
return len(result) == len(self)
def any(self, _func: Callable = None) -> bool:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _func is None:
_func = _default_lambda
result = self.where(_func)
return len(result) > 0
def average(self, _func: Callable = None) -> Union[int, float, complex]:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _func is None and not is_number(self.type):
raise InvalidTypeException()
if _func is None:
_func = _default_lambda
return float(self.sum(_func)) / float(self.count())
def contains(self, _value: object) -> bool:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _value is None:
raise ArgumentNoneException(ExceptionArgument.value)
return self.where(lambda x: x == _value).count() > 0
def count(self, _func: Callable = None) -> int:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _func is None:
return len(self)
return len(self.where(_func))
def distinct(self, _func: Callable = None) -> EnumerableABC:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _func is None:
_func = _default_lambda
result = Enumerable()
known_values = []
for element in self:
value = _func(element)
if value in known_values:
continue
known_values.append(value)
result.add(element)
return result
def element_at(self, _index: int) -> any:
self._values.reset()
while _index >= 0:
current = self.next()
if _index == 0:
return current
_index -= 1
def element_at_or_default(self, _index: int) -> any:
try:
return self.element_at(_index)
except IndexOutOfRangeException:
return None
@staticmethod
def empty() -> 'EnumerableABC':
r"""Returns an empty enumerable
Returns
-------
Enumerable object that contains no elements
"""
return Enumerable()
def first(self: EnumerableABC, _func=None) -> any:
if _func is not None:
return self.where(_func).element_at(0)
return self.element_at(0)
def first_or_default(self: EnumerableABC, _func=None) -> Optional[any]:
if _func is not None:
return self.where(_func).element_at_or_default(0)
return self.element_at_or_default(0)
def for_each(self, _func: Callable = None):
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _func is None:
_func = _default_lambda
for element in self:
_func(element)
def last(self: EnumerableABC) -> any:
return self.element_at(self.count() - 1)
def last_or_default(self: EnumerableABC) -> Optional[any]:
return self.element_at_or_default(self.count() - 1)
def max(self, _func: Callable = None) -> Union[int, float, complex]:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _func is None and not is_number(self.type):
raise InvalidTypeException()
if _func is None:
_func = _default_lambda
return _func(max(self, key=_func))
def median(self, _func=None) -> Union[int, float]:
if _func is None:
_func = _default_lambda
result = self.order_by(_func).select(_func).to_list()
length = len(result)
i = int(length / 2)
return (
result[i]
if length % 2 == 1
else (float(result[i - 1]) + float(result[i])) / float(2)
)
def min(self, _func: Callable = None) -> Union[int, float, complex]:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _func is None and not is_number(self.type):
raise InvalidTypeException()
if _func is None:
_func = _default_lambda
return _func(min(self, key=_func))
def order_by(self, _func: Callable = None) -> OrderedEnumerableABC:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _func is None:
_func = _default_lambda
from cpl_query.enumerable.ordered_enumerable import OrderedEnumerable
return OrderedEnumerable(self.type, _func, sorted(self, key=_func))
def order_by_descending(self, _func: Callable = None) -> OrderedEnumerableABC:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _func is None:
_func = _default_lambda
from cpl_query.enumerable.ordered_enumerable import OrderedEnumerable
return OrderedEnumerable(self.type, _func, sorted(self, key=_func, reverse=True))
@staticmethod
def range(start: int, length: int) -> 'EnumerableABC':
return Enumerable(int, range(start, length))
def reverse(self: EnumerableABC) -> EnumerableABC:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
return Enumerable(self.type, list(reversed(self.to_list())))
def select(self, _func: Callable = None) -> EnumerableABC:
if _func is None:
_func = _default_lambda
_l = [_func(_o) for _o in self]
return Enumerable(self._type if len(_l) < 1 else type(_l[0]), _l)
def select_many(self, _func: Callable = None) -> EnumerableABC:
if _func is None:
_func = _default_lambda
# The line below is pain. I don't understand anything of the list comprehension...
# written on 09.11.2022 by Sven Heidemann
_l = [_a for _o in self for _a in _func(_o)]
return Enumerable(self._type if len(_l) < 1 else type(_l[0]), _l)
def single(self: EnumerableABC) -> any:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if len(self) > 1:
raise IndexError('Found more than one element')
elif len(self) == 0:
raise IndexOutOfRangeException(f'{type(self).__name__} is empty')
return self.element_at(0)
def single_or_default(self: EnumerableABC) -> Optional[any]:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if len(self) > 1:
raise IndexError('Found more than one element')
elif len(self) == 0:
return None
return self.element_at(0)
def skip(self, _index: int) -> EnumerableABC:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _index is None:
raise ArgumentNoneException(ExceptionArgument.index)
_list = self.to_list()
return Enumerable(self.type, _list[_index:])
def skip_last(self, _index: int) -> EnumerableABC:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _index is None:
raise ArgumentNoneException(ExceptionArgument.index)
index = len(self) - _index
return self.take(len(self) - _index)
def take(self, _index: int) -> EnumerableABC:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _index is None:
raise ArgumentNoneException(ExceptionArgument.index)
_list = self.to_list()
return Enumerable(self.type, _list[:_index])
def take_last(self, _index: int) -> EnumerableABC:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _index is None:
raise ArgumentNoneException(ExceptionArgument.index)
_list = self.to_list()
index = len(_list) - _index
return self.skip(index)
def sum(self, _func: Callable = None) -> Union[int, float, complex]:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _func is None and not is_number(self.type):
raise InvalidTypeException()
if _func is None:
_func = _default_lambda
return sum([_func(x) for x in self])
def where(self, _func: Callable = None) -> EnumerableABC:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _func is None:
raise ArgumentNoneException(ExceptionArgument.func)
return Enumerable(self.type, list(filter(_func, self._values)))

View File

@@ -1,8 +1,6 @@
from abc import abstractmethod from abc import abstractmethod
from typing import Iterable
from cpl_query.base.queryable_abc import QueryableABC from cpl_query.base.queryable_abc import QueryableABC
from cpl_query.base.sequence_values import SequenceValues
class EnumerableABC(QueryableABC): class EnumerableABC(QueryableABC):
@@ -11,81 +9,15 @@ class EnumerableABC(QueryableABC):
@abstractmethod @abstractmethod
def __init__(self, t: type = None, values: list = None): def __init__(self, t: type = None, values: list = None):
if t == any or t is None and values is not None: QueryableABC.__init__(self, t, values)
t = type(values[0])
self._type, self._values, self._remove_error_check = t, SequenceValues(values, t), True self._remove_error_check = True
def __len__(self):
return len(self._values)
def __iter__(self):
return iter(self._values)
def next(self):
return next(self._values)
def __next__(self):
return self.next()
def __repr__(self):
return f'<{type(self).__name__} {list(self).__repr__()}>'
@property
def type(self) -> type:
return self._type
def set_remove_error_check(self, _value: bool): def set_remove_error_check(self, _value: bool):
r"""Set flag to check if element exists before removing r"""Set flag to check if element exists before removing
""" """
self._remove_error_check = _value self._remove_error_check = _value
def add(self, __object: object) -> None:
r"""Adds an element to the enumerable.
"""
if self._type is not None and type(__object) != self._type and not isinstance(type(__object), self._type) and not issubclass(type(__object), self._type):
raise Exception(f'Unexpected type: {type(__object)}\nExpected type: {self._type}')
if len(self) == 0 and self._type is None:
self._type = type(__object)
self._values = SequenceValues([*self._values, __object], self._type)
def clear(self):
r"""Removes all elements
"""
del self._values
self._values = []
def extend(self, __list: Iterable) -> 'EnumerableABC':
r"""Adds elements of given list to enumerable
Parameter
---------
__enumerable: :class: `cpl_query.enumerable.enumerable_abc.EnumerableABC`
index
"""
self._values = SequenceValues([*self._values, *__list], self._type)
return self
def remove(self, __object: object) -> None:
r"""Removes element from list
Parameter
---------
__object: :class:`object`
value
Raises
---------
`Element not found` when element does not exist. Check can be deactivated by calling <enumerable>.set_remove_error_check(False)
"""
if self._remove_error_check and __object not in self._values:
raise Exception('Element not found')
# self._values.remove(__object)
self._values = SequenceValues([x for x in self.to_list() if x != __object], self._type)
def to_iterable(self) -> 'IterableABC': def to_iterable(self) -> 'IterableABC':
r"""Converts :class: `cpl_query.enumerable.enumerable_abc.EnumerableABC` to :class: `cpl_query.iterable.iterable_abc.IterableABC` r"""Converts :class: `cpl_query.enumerable.enumerable_abc.EnumerableABC` to :class: `cpl_query.iterable.iterable_abc.IterableABC`
@@ -95,12 +27,3 @@ class EnumerableABC(QueryableABC):
""" """
from cpl_query.iterable.iterable import Iterable from cpl_query.iterable.iterable import Iterable
return Iterable(self._type, self.to_list()) return Iterable(self._type, self.to_list())
def to_list(self) -> list:
r"""Converts :class: `cpl_query.base.sequence_abc.SequenceABC` to :class: `list`
Returns
-------
:class: `list`
"""
return [x for x in self]

View File

@@ -1,36 +0,0 @@
from collections.abc import Callable
from typing import Iterable
from cpl_query.enumerable.enumerable import Enumerable
from cpl_query.enumerable.ordered_enumerable_abc import OrderedEnumerableABC
from cpl_query.exceptions import ArgumentNoneException, ExceptionArgument
class OrderedEnumerable(Enumerable, OrderedEnumerableABC):
r"""Implementation of :class: `cpl_query.extension.Enumerable` `cpl_query.extension.OrderedEnumerableABC`
"""
def __init__(self, _t: type, _func: Callable = None, _values: Iterable = None):
Enumerable.__init__(self, _t)
OrderedEnumerableABC.__init__(self, _t, _func, _values)
def then_by(self: OrderedEnumerableABC, _func: Callable) -> OrderedEnumerableABC:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _func is None:
raise ArgumentNoneException(ExceptionArgument.func)
self._funcs.append(_func)
return OrderedEnumerable(self.type, _func, sorted(self, key=lambda *args: [f(*args) for f in self._funcs]))
def then_by_descending(self: OrderedEnumerableABC, _func: Callable) -> OrderedEnumerableABC:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _func is None:
raise ArgumentNoneException(ExceptionArgument.func)
self._funcs.append(_func)
return OrderedEnumerable(self.type, _func, sorted(self, key=lambda *args: [f(*args) for f in self._funcs], reverse=True))

View File

@@ -1,43 +0,0 @@
from abc import abstractmethod
from collections.abc import Callable
from typing import Iterable
from cpl_query.enumerable.enumerable_abc import EnumerableABC
class OrderedEnumerableABC(EnumerableABC):
@abstractmethod
def __init__(self, _t: type, _func: Callable = None, _values: Iterable = None):
EnumerableABC.__init__(self, _t, _values)
self._funcs: list[Callable] = []
if _func is not None:
self._funcs.append(_func)
@abstractmethod
def then_by(self, func: Callable) -> 'OrderedEnumerableABC':
r"""Sorts OrderedList in ascending order by function
Parameter
---------
func: :class:`Callable`
Returns
-------
list of :class:`cpl_query.extension.OrderedEnumerableABC`
"""
pass
@abstractmethod
def then_by_descending(self, func: Callable) -> 'OrderedEnumerableABC':
r"""Sorts OrderedList in descending order by function
Parameter
---------
func: :class:`Callable`
Returns
-------
list of :class:`cpl_query.extension.OrderedEnumerableABC`
"""
pass

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_query.extension'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2021 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2021 - 2022 sh-edraft.de'
__version__ = '2022.10.0.post2' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -24,4 +24,4 @@ from collections import namedtuple
from .list import List from .list import List
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='0.post2') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_query.iterable'
__author__ = 'Sven Heidemann' __author__ = 'Sven Heidemann'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright (c) 2021 - 2022 sh-edraft.de' __copyright__ = 'Copyright (c) 2021 - 2022 sh-edraft.de'
__version__ = '2022.10.0.post2' __version__ = '2022.12.0'
from collections import namedtuple from collections import namedtuple
@@ -23,8 +23,6 @@ from collections import namedtuple
# imports: # imports:
from .iterable_abc import IterableABC from .iterable_abc import IterableABC
from .iterable import Iterable from .iterable import Iterable
from .ordered_iterable_abc import OrderedIterableABC
from .ordered_iterable import OrderedIterable
VersionInfo = namedtuple('VersionInfo', 'major minor micro') VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2022', minor='10', micro='0.post2') version_info = VersionInfo(major='2022', minor='12', micro='0')

View File

@@ -1,9 +1,6 @@
from typing import Callable, Optional, Union, Iterable as IterableType from typing import Iterable as IterableType
from cpl_query._helper import is_number
from cpl_query.exceptions import ArgumentNoneException, ExceptionArgument, InvalidTypeException, IndexOutOfRangeException
from cpl_query.iterable.iterable_abc import IterableABC from cpl_query.iterable.iterable_abc import IterableABC
from cpl_query.iterable.ordered_iterable_abc import OrderedIterableABC
def _default_lambda(x: object): def _default_lambda(x: object):
@@ -14,318 +11,3 @@ class Iterable(IterableABC):
def __init__(self, t: type = None, values: IterableType = None): def __init__(self, t: type = None, values: IterableType = None):
IterableABC.__init__(self, t, values) IterableABC.__init__(self, t, values)
def all(self, _func: Callable = None) -> bool:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _func is None:
_func = _default_lambda
result = self.where(_func)
return len(result) == len(self)
def any(self, _func: Callable = None) -> bool:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _func is None:
_func = _default_lambda
result = self.where(_func)
return len(result) > 0
def average(self, _func: Callable = None) -> Union[int, float, complex]:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _func is None and not is_number(self.type):
raise InvalidTypeException()
if _func is None:
_func = _default_lambda
return float(self.sum(_func)) / float(self.count())
def contains(self, _value: object) -> bool:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _value is None:
raise ArgumentNoneException(ExceptionArgument.value)
return self.where(lambda x: x == _value).count() > 0
def count(self, _func: Callable = None) -> int:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _func is None:
return len(self)
return len(self.where(_func))
def distinct(self, _func: Callable = None) -> IterableABC:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _func is None:
_func = _default_lambda
result = Iterable()
known_values = []
for element in self:
value = _func(element)
if value in known_values:
continue
known_values.append(value)
result.append(element)
return result
def element_at(self, _index: int) -> any:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _index is None:
raise ArgumentNoneException(ExceptionArgument.index)
return self[_index]
def element_at_or_default(self, _index: int) -> any:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _index is None:
raise ArgumentNoneException(ExceptionArgument.index)
try:
return self[_index]
except IndexError:
return None
def first(self: IterableABC) -> any:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if len(self) == 0:
raise IndexOutOfRangeException()
return self[0]
def first_or_default(self: IterableABC) -> Optional[any]:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if len(self) == 0:
return None
return self[0]
def last(self: IterableABC) -> any:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if len(self) == 0:
raise IndexOutOfRangeException()
return self[len(self) - 1]
def last_or_default(self: IterableABC) -> Optional[any]:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if len(self) == 0:
return None
return self[len(self) - 1]
def for_each(self, _func: Callable = None):
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _func is None:
_func = _default_lambda
for element in self:
_func(element)
def max(self, _func: Callable = None) -> Union[int, float, complex]:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _func is None and not is_number(self.type):
raise InvalidTypeException()
if _func is None:
_func = _default_lambda
return _func(max(self, key=_func))
def median(self, _func=None) -> Union[int, float]:
if _func is None:
_func = _default_lambda
result = self.order_by(_func).select(_func).to_list()
length = len(result)
i = int(length / 2)
return (
result[i]
if length % 2 == 1
else (float(result[i - 1]) + float(result[i])) / float(2)
)
def min(self, _func: Callable = None) -> Union[int, float, complex]:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _func is None and not is_number(self.type):
raise InvalidTypeException()
if _func is None:
_func = _default_lambda
return _func(min(self, key=_func))
def order_by(self, _func: Callable = None) -> OrderedIterableABC:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _func is None:
_func = _default_lambda
from cpl_query.iterable.ordered_iterable import OrderedIterable
return OrderedIterable(self.type, _func, sorted(self, key=_func))
def order_by_descending(self, _func: Callable = None) -> OrderedIterableABC:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _func is None:
_func = _default_lambda
from cpl_query.iterable.ordered_iterable import OrderedIterable
return OrderedIterable(self.type, _func, sorted(self, key=_func, reverse=True))
def reverse(self: IterableABC) -> IterableABC:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
return Iterable().extend(reversed(self.to_list()))
def select(self, _func: Callable = None) -> IterableABC:
if _func is None:
_func = _default_lambda
result = Iterable()
result.extend(_func(_o) for _o in self)
return result
def select_many(self, _func: Callable = None) -> IterableABC:
if _func is None:
_func = _default_lambda
result = Iterable()
# The line below is pain. I don't understand anything of it...
# written on 09.11.2022 by Sven Heidemann
elements = [_a for _o in self for _a in _func(_o)]
result.extend(elements)
return result
def single(self: IterableABC) -> any:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if len(self) > 1:
raise Exception('Found more than one element')
elif len(self) == 0:
raise Exception('Found no element')
return self[0]
def single_or_default(self: IterableABC) -> Optional[any]:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if len(self) > 1:
raise Exception('Index out of range')
elif len(self) == 0:
return None
return self[0]
def skip(self, _index: int) -> IterableABC:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _index is None:
raise ArgumentNoneException(ExceptionArgument.index)
return Iterable(self.type, values=self[_index:])
def skip_last(self, _index: int) -> IterableABC:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _index is None:
raise ArgumentNoneException(ExceptionArgument.index)
index = len(self) - _index
result = Iterable()
result.extend(self[:index])
return result
def take(self, _index: int) -> IterableABC:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _index is None:
raise ArgumentNoneException(ExceptionArgument.index)
result = Iterable()
result.extend(self[:_index])
return result
def take_last(self, _index: int) -> IterableABC:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
index = len(self) - _index
if index >= len(self) or index < 0:
raise IndexOutOfRangeException()
result = Iterable()
result.extend(self[index:])
return result
def sum(self, _func: Callable = None) -> Union[int, float, complex]:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _func is None and not is_number(self.type):
raise InvalidTypeException()
if _func is None:
_func = _default_lambda
return sum([_func(x) for x in self])
def where(self, _func: Callable = None) -> IterableABC:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _func is None:
raise ArgumentNoneException(ExceptionArgument.func)
if _func is None:
_func = _default_lambda
result = Iterable(self.type)
for element in self:
if _func(element):
result.append(element)
return result

View File

@@ -4,54 +4,45 @@ from typing import Iterable
from cpl_query.base.queryable_abc import QueryableABC from cpl_query.base.queryable_abc import QueryableABC
class IterableABC(list, QueryableABC): class IterableABC(QueryableABC):
r"""ABC to define functions on list r"""ABC to define functions on list
""" """
@abstractmethod @abstractmethod
def __init__(self, t: type = None, values: Iterable = None): def __init__(self, t: type = None, values: Iterable = None):
values = [] if values is None else values QueryableABC.__init__(self, t, values)
list.__init__(self, values)
if t is None and len(values) > 0: def __setitem__(self, i, val):
t = type(values[0]) self._check_type(val)
values = [*self._values]
values[i] = val
self._set_values(values)
self._type = t def __delitem__(self, i):
values = [*self._values]
def __repr__(self): del values[i]
return f'<{type(self).__name__} {list(self).__repr__()}>' self._set_values(values)
@property @property
def type(self) -> type: def type(self) -> type:
return self._type return self._type
def to_list(self) -> list:
r"""Converts :class: `cpl_query.base.sequence_abc.SequenceABC` to :class: `list`
Returns
-------
:class: `list`
"""
return [x for x in self]
def __str__(self): def __str__(self):
return str(self.to_list()) return str(self.to_list())
def append(self, __object: object) -> None: def append(self, _object: object):
self.add(_object)
def add(self, _object: object):
r"""Adds element to list r"""Adds element to list
Parameter Parameter
--------- ---------
__object: :class:`object` _object: :class:`object`
value value
""" """
if self._type is not None and type(__object) != self._type and not isinstance(type(__object), self._type) and not issubclass(type(__object), self._type): self._check_type(_object)
raise Exception(f'Unexpected type: {type(__object)}\nExpected type: {self._type}') values = [*self._values, _object]
self._set_values(values)
if len(self) == 0 and self._type is None:
self._type = type(__object)
# self._values = SequenceValues([*self._values, __object], self._type)
super().append(__object)
def extend(self, __iterable: Iterable) -> 'IterableABC': def extend(self, __iterable: Iterable) -> 'IterableABC':
r"""Adds elements of given list to list r"""Adds elements of given list to list
@@ -65,6 +56,20 @@ class IterableABC(list, QueryableABC):
return self return self
def remove(self, _object: object):
r"""Removes element from list
Parameter
---------
_object: :class:`object`
value
"""
if _object not in self:
raise ValueError
values = [*self._values]
values.remove(_object)
self._set_values(values)
def to_enumerable(self) -> 'EnumerableABC': def to_enumerable(self) -> 'EnumerableABC':
r"""Converts :class: `cpl_query.iterable.iterable_abc.IterableABC` to :class: `cpl_query.enumerable.enumerable_abc.EnumerableABC` r"""Converts :class: `cpl_query.iterable.iterable_abc.IterableABC` to :class: `cpl_query.enumerable.enumerable_abc.EnumerableABC`

View File

@@ -1,35 +0,0 @@
from collections.abc import Callable
from cpl_query.exceptions import ArgumentNoneException, ExceptionArgument
from cpl_query.iterable.iterable import Iterable
from cpl_query.iterable.ordered_iterable_abc import OrderedIterableABC
class OrderedIterable(Iterable, OrderedIterableABC):
r"""Implementation of :class: `cpl_query.extension.Iterable` `cpl_query.extension.OrderedIterableABC`
"""
def __init__(self, _t: type, _func: Callable = None, _values: Iterable = None):
Iterable.__init__(self, _t)
OrderedIterableABC.__init__(self, _t, _func, _values)
def then_by(self: OrderedIterableABC, _func: Callable) -> OrderedIterableABC:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _func is None:
raise ArgumentNoneException(ExceptionArgument.func)
self._funcs.append(_func)
return OrderedIterable(self.type, _func, sorted(self, key=lambda *args: [f(*args) for f in self._funcs]))
def then_by_descending(self: OrderedIterableABC, _func: Callable) -> OrderedIterableABC:
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if _func is None:
raise ArgumentNoneException(ExceptionArgument.func)
self._funcs.append(_func)
return OrderedIterable(self.type, _func, sorted(self, key=lambda *args: [f(*args) for f in self._funcs], reverse=True))

View File

@@ -16,10 +16,10 @@
"LicenseName": "MIT", "LicenseName": "MIT",
"LicenseDescription": "MIT, see LICENSE for more details.", "LicenseDescription": "MIT, see LICENSE for more details.",
"Dependencies": [ "Dependencies": [
"cpl-core>=2022.10.0" "cpl-core>=2022.12.0"
], ],
"DevDependencies": [ "DevDependencies": [
"cpl-cli>=2022.10.0" "cpl-cli>=2022.12.0"
], ],
"PythonVersion": ">=3.10.4", "PythonVersion": ">=3.10.4",
"PythonPath": { "PythonPath": {

View File

@@ -3,7 +3,12 @@ from cpl_core.console import Console, ForegroundColorEnum
def test_spinner(): def test_spinner():
Console.write_line('test1')
Console.write_line('test2', 2)
Console.write_line('test3', 2, 3)
Console.write_line('test4', 2, 3, 4)
time.sleep(2) time.sleep(2)
Console.write_line('test5')
def test_console(): def test_console():
@@ -17,22 +22,22 @@ def test_console():
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, text_foreground_color='green') Console.spinner('Test:', test_spinner, spinner_foreground_color=ForegroundColorEnum.cyan, text_foreground_color='green')
opts = [ # opts = [
'Option 1', # 'Option 1',
'Option 2', # 'Option 2',
'Option 3', # 'Option 3',
'Option 4' # 'Option 4'
] # ]
selected = Console.select( # selected = Console.select(
'>', # '>',
'Select item:', # 'Select item:',
opts, # opts,
header_foreground_color=ForegroundColorEnum.blue, # header_foreground_color=ForegroundColorEnum.blue,
option_foreground_color=ForegroundColorEnum.green, # option_foreground_color=ForegroundColorEnum.green,
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() # # test_console()
#
Console.write_line() # Console.write_line()

View File

@@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
"""
general 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__ = 'general.arguments'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1'
from collections import namedtuple
# imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01')

View File

@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" """
sh_cpl sh-edraft Common Python library general sh-edraft Common Python library
~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~
sh-edraft Common Python library sh-edraft Common Python library
@@ -11,7 +11,7 @@ sh-edraft Common Python library
""" """
__title__ = 'tests.db' __title__ = 'general.db'
__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'
@@ -19,7 +19,8 @@ __version__ = '2021.4.1'
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=4, micro=1) version_info = VersionInfo(major='2021', minor='04', micro='01')

View File

@@ -16,12 +16,12 @@
"LicenseName": "MIT", "LicenseName": "MIT",
"LicenseDescription": "MIT, see LICENSE for more details.", "LicenseDescription": "MIT, see LICENSE for more details.",
"Dependencies": [ "Dependencies": [
"cpl-core==2022.10rc2", "cpl-core==2022.10.0.post9",
"cpl-translation==2022.10rc2", "cpl-translation==2022.10.0.post2",
"cpl-query==2022.10rc2" "cpl-query==2022.10.0.post2"
], ],
"DevDependencies": [ "DevDependencies": [
"cpl-cli==2022.10.rc2" "cpl-cli==2022.10"
], ],
"PythonVersion": ">=3.10", "PythonVersion": ">=3.10",
"PythonPath": { "PythonPath": {

View File

@@ -3,7 +3,7 @@
"Name": "set-pip-urls", "Name": "set-pip-urls",
"Version": { "Version": {
"Major": "2022", "Major": "2022",
"Minor": "6", "Minor": "12",
"Micro": "0" "Micro": "0"
}, },
"Author": "Sven Heidemann", "Author": "Sven Heidemann",
@@ -16,7 +16,7 @@
"LicenseName": "MIT", "LicenseName": "MIT",
"LicenseDescription": "MIT, see LICENSE for more details.", "LicenseDescription": "MIT, see LICENSE for more details.",
"Dependencies": [ "Dependencies": [
"cpl-core>=2022.10.0" "cpl-core>=2022.12.0"
], ],
"PythonVersion": ">=3.10.4", "PythonVersion": ">=3.10.4",
"PythonPath": {}, "PythonPath": {},

View File

@@ -1,6 +1,7 @@
import os import os
import traceback import traceback
from cpl_cli.configuration import ProjectSettings
from cpl_core.utils import String from cpl_core.utils import String
from cpl_cli.configuration.version_settings_name_enum import VersionSettingsNameEnum from cpl_cli.configuration.version_settings_name_enum import VersionSettingsNameEnum
@@ -45,51 +46,64 @@ class Application(ApplicationABC):
return return
if len(args) == 1: if len(args) == 1:
suffix = f'.{args[0]}' suffix = args[0]
try: try:
branch = self._git_service.get_active_branch_name() branch = self._git_service.get_active_branch_name()
Console.write_line(f'Found branch: {branch}') Console.write_line(f'Found branch: {branch}')
except Exception as e: except Exception as e:
Console.error('Branch could not be found', traceback.format_exc()) Console.error('Branch not found', traceback.format_exc())
return return
try: try:
if branch.startswith('#'):
self._configuration.add_json_file(self._workspace.projects[self._workspace.default_project], optional=False, output=False)
ps: ProjectSettings = self._configuration.get_configuration(ProjectSettings)
version[VersionSettingsNameEnum.major.value] = branch.split('.')[0] version[VersionSettingsNameEnum.major.value] = ps.version.major
version[VersionSettingsNameEnum.minor.value] = branch.split('.')[1] version[VersionSettingsNameEnum.minor.value] = ps.version.minor
if len(branch.split('.')) == 2: version[VersionSettingsNameEnum.micro.value] = f'dev{branch.split("#")[1]}'
version[VersionSettingsNameEnum.micro.value] = f'0{suffix}'
else: else:
branch_version = branch.split(".")[2] version[VersionSettingsNameEnum.major.value] = branch.split('.')[0]
if '-#' in branch_version: version[VersionSettingsNameEnum.minor.value] = branch.split('.')[1]
branch_version = branch_version.split('-#')[0] if len(branch.split('.')) == 2:
version[VersionSettingsNameEnum.micro.value] = f'{branch_version}{suffix}' if suffix == '':
suffix = '0'
version[VersionSettingsNameEnum.micro.value] = f'{suffix}'
else:
if not suffix.startswith('.') and suffix != '':
suffix = f'.{suffix}'
version[VersionSettingsNameEnum.micro.value] = f'{branch.split(".")[2]}{suffix}'
except Exception as e: except Exception as e:
Console.error(f'Branch {branch} does not contain valid version') Console.error(f'Branch {branch} does not contain valid version')
return return
diff_paths = [] diff_paths = []
for file in self._git_service.get_diff_files(): for file in self._git_service.get_diff_files():
if file.startswith('tools'):
continue
if '/' in file: if '/' in file:
diff_paths.append(file.split('/')[1]) file = file.split('/')[1]
else: else:
diff_paths.append(os.path.basename(os.path.dirname(file))) file = os.path.basename(os.path.dirname(file))
if file in diff_paths:
continue
diff_paths.append(file)
try: try:
skipped = [] skipped = []
for project in self._workspace.projects: for project in self._workspace.projects:
if project not in diff_paths and String.convert_to_snake_case(project) not in diff_paths and not force: if project not in diff_paths and String.convert_to_snake_case(project) not in diff_paths and not force:
Console.write_line(f'Skipping {project} due to missing changes') # Console.write_line(f'Skipping {project} due to missing changes')
skipped.append(project) skipped.append(project)
continue continue
Console.write_line(f'Set dependencies {self._version_pipe.transform(version)} for {project}') Console.write_line(f'Set dependencies {self._version_pipe.transform(version)} for {project}')
self._version_setter.set_dependencies(self._workspace.projects[project], version, 'Dependencies', skipped=skipped) self._version_setter.set_dependencies(self._workspace.projects[project], version, 'Dependencies', skipped=skipped)
self._version_setter.set_dependencies(self._workspace.projects[project], version, 'DevDependencies', skipped=skipped) self._version_setter.set_dependencies(self._workspace.projects[project], version, 'DevDependencies', skipped=skipped)
if not project.startswith('cpl') and not project.startswith('unittest'):
Console.write_line(f'Skipping {project}')
continue
Console.write_line(f'Set version {self._version_pipe.transform(version)} for {project}') Console.write_line(f'Set version {self._version_pipe.transform(version)} for {project}')
self._version_setter.set_version(self._workspace.projects[project], version) self._version_setter.set_version(self._workspace.projects[project], version)

View File

@@ -1,6 +1,7 @@
from git import Repo, DiffIndex import os
from cpl_core.environment import ApplicationEnvironmentABC from cpl_core.environment import ApplicationEnvironmentABC
from git import Repo
class GitService: class GitService:

View File

@@ -3,7 +3,7 @@
"Name": "set-version", "Name": "set-version",
"Version": { "Version": {
"Major": "2022", "Major": "2022",
"Minor": "7", "Minor": "12",
"Micro": "0" "Micro": "0"
}, },
"Author": "Sven Heidemann", "Author": "Sven Heidemann",
@@ -16,7 +16,7 @@
"LicenseName": "MIT", "LicenseName": "MIT",
"LicenseDescription": "MIT, see LICENSE for more details.", "LicenseDescription": "MIT, see LICENSE for more details.",
"Dependencies": [ "Dependencies": [
"cpl-core>=2022.10.0", "cpl-core>=2022.12.0",
"gitpython==3.1.27" "gitpython==3.1.27"
], ],
"PythonVersion": ">=3.10.4", "PythonVersion": ">=3.10.4",

View File

@@ -3,7 +3,7 @@
"Name": "unittests", "Name": "unittests",
"Version": { "Version": {
"Major": "2022", "Major": "2022",
"Minor": "10", "Minor": "12",
"Micro": "0" "Micro": "0"
}, },
"Author": "", "Author": "",
@@ -16,7 +16,7 @@
"LicenseName": "", "LicenseName": "",
"LicenseDescription": "", "LicenseDescription": "",
"Dependencies": [ "Dependencies": [
"cpl-core>=2022.10.0" "cpl-core>=2022.12.0"
], ],
"PythonVersion": ">=3.10.4", "PythonVersion": ">=3.10.4",
"PythonPath": {}, "PythonPath": {},

View File

View File

@@ -0,0 +1,35 @@
import os
import shutil
import traceback
import unittest
from unittests_cli.constants import PLAYGROUND_PATH
class CommandTestCase(unittest.TestCase):
def __init__(self, method_name: str):
unittest.TestCase.__init__(self, method_name)
@classmethod
def setUpClass(cls):
try:
if os.path.exists(PLAYGROUND_PATH):
shutil.rmtree(os.path.abspath(os.path.join(PLAYGROUND_PATH)))
os.makedirs(PLAYGROUND_PATH)
os.chdir(PLAYGROUND_PATH)
except Exception as e:
print(f'Setup of {__name__} failed: {traceback.format_exc()}')
def setUp(self):
os.chdir(PLAYGROUND_PATH)
@classmethod
def tearDownClass(cls):
try:
if os.path.exists(PLAYGROUND_PATH):
shutil.rmtree(os.path.abspath(os.path.join(PLAYGROUND_PATH)))
except Exception as e:
print(f'Cleanup of {__name__} failed: {traceback.format_exc()}')

View File

@@ -1,18 +1,16 @@
import json import json
import os import os
import shutil
import unittest
from cpl_core.utils import String from cpl_core.utils import String
from unittests_cli.abc.command_test_case import CommandTestCase
from unittests_cli.constants import PLAYGROUND_PATH from unittests_cli.constants import PLAYGROUND_PATH
from unittests_shared.cli_commands import CLICommands from unittests_shared.cli_commands import CLICommands
class AddTestCase(unittest.TestCase): class AddTestCase(CommandTestCase):
def __init__(self, methodName: str): def __init__(self, method_name: str):
unittest.TestCase.__init__(self, methodName) CommandTestCase.__init__(self, method_name)
self._source = 'add-test-project' self._source = 'add-test-project'
self._target = 'add-test-library' self._target = 'add-test-library'
self._project_file = f'src/{String.convert_to_snake_case(self._source)}/{self._source}.json' self._project_file = f'src/{String.convert_to_snake_case(self._source)}/{self._source}.json'
@@ -26,19 +24,12 @@ class AddTestCase(unittest.TestCase):
return project_json return project_json
def setUp(self): def setUp(self):
os.chdir(os.path.abspath(PLAYGROUND_PATH)) os.chdir(PLAYGROUND_PATH)
# create projects # create projects
CLICommands.new('console', self._source, '--ab', '--s') CLICommands.new('console', self._source, '--ab', '--s')
os.chdir(os.path.join(os.getcwd(), self._source)) os.chdir(os.path.join(os.getcwd(), self._source))
CLICommands.new('console', self._target, '--ab', '--s') CLICommands.new('console', self._target, '--ab', '--s')
def cleanUp(self):
# remove projects
if not os.path.exists(os.path.abspath(os.path.join(PLAYGROUND_PATH, self._source))):
return
shutil.rmtree(os.path.abspath(os.path.join(PLAYGROUND_PATH, self._source)))
def test_add(self): def test_add(self):
CLICommands.add(self._source, self._target) CLICommands.add(self._source, self._target)
settings = self._get_project_settings() settings = self._get_project_settings()

View File

@@ -2,18 +2,17 @@ import filecmp
import json import json
import os import os
import shutil import shutil
import unittest
from cpl_core.utils import String from cpl_core.utils import String
from unittests_cli.abc.command_test_case import CommandTestCase
from unittests_cli.constants import PLAYGROUND_PATH from unittests_cli.constants import PLAYGROUND_PATH
from unittests_shared.cli_commands import CLICommands from unittests_shared.cli_commands import CLICommands
class BuildTestCase(unittest.TestCase): class BuildTestCase(CommandTestCase):
def __init__(self, methodName: str): def __init__(self, method_name: str):
unittest.TestCase.__init__(self, methodName) CommandTestCase.__init__(self, method_name)
self._source = 'build-test-source' self._source = 'build-test-source'
self._project_file = f'src/{String.convert_to_snake_case(self._source)}/{self._source}.json' self._project_file = f'src/{String.convert_to_snake_case(self._source)}/{self._source}.json'
@@ -31,18 +30,14 @@ class BuildTestCase(unittest.TestCase):
project_file.close() project_file.close()
def setUp(self): def setUp(self):
os.chdir(os.path.abspath(PLAYGROUND_PATH)) if not os.path.exists(PLAYGROUND_PATH):
os.makedirs(PLAYGROUND_PATH)
os.chdir(PLAYGROUND_PATH)
# create projects # create projects
CLICommands.new('console', self._source, '--ab', '--s') CLICommands.new('console', self._source, '--ab', '--s')
os.chdir(os.path.join(os.getcwd(), self._source)) os.chdir(os.path.join(os.getcwd(), self._source))
def cleanUp(self):
# remove projects
if not os.path.exists(os.path.abspath(os.path.join(PLAYGROUND_PATH, self._source))):
return
shutil.rmtree(os.path.abspath(os.path.join(PLAYGROUND_PATH, self._source)))
def _are_dir_trees_equal(self, dir1, dir2): def _are_dir_trees_equal(self, dir1, dir2):
""" """
found at https://stackoverflow.com/questions/4187564/recursively-compare-two-directories-to-ensure-they-have-the-same-files-and-subdi found at https://stackoverflow.com/questions/4187564/recursively-compare-two-directories-to-ensure-they-have-the-same-files-and-subdi

View File

@@ -75,4 +75,9 @@ class CLITestSuite(unittest.TestSuite):
def run(self, *args): def run(self, *args):
self._setup() self._setup()
self._result = super().run(*args) self._result = super().run(*args)
# self._cleanup() self._cleanup()
if __name__ == "__main__":
runner = unittest.TextTestRunner()
runner.run(CLITestSuite())

View File

@@ -1,5 +1,9 @@
import os import os
PLAYGROUND_PATH = os.path.abspath(os.path.join(os.getcwd(), '../test_cli_playground')) base = ''
TRANSLATION_PATH = os.path.abspath(os.path.join(os.getcwd(), '../unittests_translation')) if not os.getcwd().endswith('unittests'):
CLI_PATH = os.path.abspath(os.path.join(os.getcwd(), '../../src/cpl_cli/main.py')) base = '../'
PLAYGROUND_PATH = os.path.abspath(os.path.join(os.getcwd(), f'{base}test_cli_playground'))
TRANSLATION_PATH = os.path.abspath(os.path.join(os.getcwd(), f'{base}unittests_translation'))
CLI_PATH = os.path.abspath(os.path.join(os.getcwd(), f'{base}../src/cpl_cli/main.py'))

View File

@@ -1,7 +1,7 @@
import unittest from unittests_cli.abc.command_test_case import CommandTestCase
class CustomTestCase(unittest.TestCase): class CustomTestCase(CommandTestCase):
def setUp(self): def setUp(self):
pass pass

View File

@@ -1,17 +1,18 @@
import os.path import os.path
import unittest
from cpl_core.utils import String from cpl_core.utils import String
from unittests_cli.abc.command_test_case import CommandTestCase
from unittests_cli.constants import PLAYGROUND_PATH from unittests_cli.constants import PLAYGROUND_PATH
from unittests_shared.cli_commands import CLICommands from unittests_shared.cli_commands import CLICommands
class GenerateTestCase(unittest.TestCase): class GenerateTestCase(CommandTestCase):
_project = 'test-console' _project = 'test-console'
_t_path = 'test' _t_path = 'test'
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
CommandTestCase.setUpClass()
CLICommands.new('console', cls._project, '--ab', '--s', '--venv') CLICommands.new('console', cls._project, '--ab', '--s', '--venv')
def setUp(self): def setUp(self):

View File

@@ -6,14 +6,15 @@ import sys
import unittest import unittest
from cpl_core.utils import String from cpl_core.utils import String
from unittests_cli.abc.command_test_case import CommandTestCase
from unittests_cli.constants import PLAYGROUND_PATH from unittests_cli.constants import PLAYGROUND_PATH
from unittests_shared.cli_commands import CLICommands from unittests_shared.cli_commands import CLICommands
class InstallTestCase(unittest.TestCase): class InstallTestCase(CommandTestCase):
def __init__(self, methodName: str): def __init__(self, method_name: str):
unittest.TestCase.__init__(self, methodName) CommandTestCase.__init__(self, method_name)
self._source = 'install-test-source' self._source = 'install-test-source'
self._project_file = f'src/{String.convert_to_snake_case(self._source)}/{self._source}.json' self._project_file = f'src/{String.convert_to_snake_case(self._source)}/{self._source}.json'
@@ -31,18 +32,14 @@ class InstallTestCase(unittest.TestCase):
project_file.close() project_file.close()
def setUp(self): def setUp(self):
os.chdir(os.path.abspath(PLAYGROUND_PATH)) if not os.path.exists(PLAYGROUND_PATH):
os.makedirs(PLAYGROUND_PATH)
os.chdir(PLAYGROUND_PATH)
# create projects # create projects
CLICommands.new('console', self._source, '--ab', '--s') CLICommands.new('console', self._source, '--ab', '--s')
os.chdir(os.path.join(os.getcwd(), self._source)) os.chdir(os.path.join(os.getcwd(), self._source))
def cleanUp(self):
# remove projects
if not os.path.exists(os.path.abspath(os.path.join(PLAYGROUND_PATH, self._source))):
return
shutil.rmtree(os.path.abspath(os.path.join(PLAYGROUND_PATH, self._source)))
def _get_installed_packages(self) -> dict: def _get_installed_packages(self) -> dict:
reqs = subprocess.check_output([sys.executable, '-m', 'pip', 'freeze']) reqs = subprocess.check_output([sys.executable, '-m', 'pip', 'freeze'])
return dict([tuple(r.decode().split('==')) for r in reqs.split()]) return dict([tuple(r.decode().split('==')) for r in reqs.split()])

View File

@@ -1,16 +1,16 @@
import json import json
import os import os
import unittest
from cpl_core.utils import String from cpl_core.utils import String
from unittests_cli.abc.command_test_case import CommandTestCase
from unittests_cli.constants import PLAYGROUND_PATH from unittests_cli.constants import PLAYGROUND_PATH
from unittests_shared.cli_commands import CLICommands from unittests_shared.cli_commands import CLICommands
class NewTestCase(unittest.TestCase): class NewTestCase(CommandTestCase):
def setUp(self): def __init__(self, method_name: str):
os.chdir(os.path.abspath(PLAYGROUND_PATH)) CommandTestCase.__init__(self, method_name)
def _test_project(self, project_type: str, name: str, *args, test_venv=False, without_ws=False): def _test_project(self, project_type: str, name: str, *args, test_venv=False, without_ws=False):
CLICommands.new(project_type, name, *args) CLICommands.new(project_type, name, *args)
@@ -70,7 +70,6 @@ class NewTestCase(unittest.TestCase):
project_path = os.path.abspath(os.path.join(PLAYGROUND_PATH, workspace_name, base, String.convert_to_snake_case(name))) project_path = os.path.abspath(os.path.join(PLAYGROUND_PATH, workspace_name, base, String.convert_to_snake_case(name)))
self.assertTrue(os.path.exists(project_path)) self.assertTrue(os.path.exists(project_path))
self.assertTrue(os.path.join(project_path, f'{name}.json')) self.assertTrue(os.path.join(project_path, f'{name}.json'))
os.chdir(os.path.abspath(os.path.join(os.getcwd(), '../')))
def _test_sub_directory_project(self, project_type: str, directory: str, name: str, workspace_name: str, *args): def _test_sub_directory_project(self, project_type: str, directory: str, name: str, workspace_name: str, *args):
os.chdir(os.path.abspath(os.path.join(os.getcwd(), workspace_name))) os.chdir(os.path.abspath(os.path.join(os.getcwd(), workspace_name)))
@@ -96,8 +95,6 @@ class NewTestCase(unittest.TestCase):
self.assertEqual(build_settings['Main'], f'{String.convert_to_snake_case(name)}.main') self.assertEqual(build_settings['Main'], f'{String.convert_to_snake_case(name)}.main')
self.assertEqual(build_settings['EntryPoint'], name) self.assertEqual(build_settings['EntryPoint'], name)
os.chdir(os.path.abspath(os.path.join(os.getcwd(), '../')))
def test_console(self): def test_console(self):
self._test_project('console', 'test-console', '--ab', '--s', '--venv', test_venv=True) self._test_project('console', 'test-console', '--ab', '--s', '--venv', test_venv=True)

View File

@@ -5,15 +5,16 @@ import shutil
import unittest import unittest
from cpl_core.utils import String from cpl_core.utils import String
from unittests_cli.abc.command_test_case import CommandTestCase
from unittests_cli.constants import PLAYGROUND_PATH from unittests_cli.constants import PLAYGROUND_PATH
from unittests_shared.cli_commands import CLICommands from unittests_shared.cli_commands import CLICommands
class PublishTestCase(unittest.TestCase): class PublishTestCase(CommandTestCase):
def __init__(self, methodName: str): def __init__(self, method_name: str):
unittest.TestCase.__init__(self, methodName) CommandTestCase.__init__(self, method_name)
self._source = 'publish-test-source' self._source = 'publish-test-source'
self._project_file = f'src/{String.convert_to_snake_case(self._source)}/{self._source}.json' self._project_file = f'src/{String.convert_to_snake_case(self._source)}/{self._source}.json'
@@ -31,18 +32,14 @@ class PublishTestCase(unittest.TestCase):
project_file.close() project_file.close()
def setUp(self): def setUp(self):
os.chdir(os.path.abspath(PLAYGROUND_PATH)) if not os.path.exists(PLAYGROUND_PATH):
os.makedirs(PLAYGROUND_PATH)
os.chdir(PLAYGROUND_PATH)
# create projects # create projects
CLICommands.new('console', self._source, '--ab', '--s') CLICommands.new('console', self._source, '--ab', '--s')
os.chdir(os.path.join(os.getcwd(), self._source)) os.chdir(os.path.join(os.getcwd(), self._source))
def cleanUp(self):
# remove projects
if not os.path.exists(os.path.abspath(os.path.join(PLAYGROUND_PATH, self._source))):
return
shutil.rmtree(os.path.abspath(os.path.join(PLAYGROUND_PATH, self._source)))
def _are_dir_trees_equal(self, dir1, dir2): def _are_dir_trees_equal(self, dir1, dir2):
""" """
found at https://stackoverflow.com/questions/4187564/recursively-compare-two-directories-to-ensure-they-have-the-same-files-and-subdi found at https://stackoverflow.com/questions/4187564/recursively-compare-two-directories-to-ensure-they-have-the-same-files-and-subdi

View File

@@ -3,14 +3,15 @@ import os
import unittest import unittest
from cpl_core.utils import String from cpl_core.utils import String
from unittests_cli.abc.command_test_case import CommandTestCase
from unittests_cli.constants import PLAYGROUND_PATH from unittests_cli.constants import PLAYGROUND_PATH
from unittests_shared.cli_commands import CLICommands from unittests_shared.cli_commands import CLICommands
class RemoveTestCase(unittest.TestCase): class RemoveTestCase(CommandTestCase):
def __init__(self, methodName: str): def __init__(self, method_name: str):
unittest.TestCase.__init__(self, methodName) CommandTestCase.__init__(self, method_name)
self._source = 'add-test-project' self._source = 'add-test-project'
self._target = 'add-test-library' self._target = 'add-test-library'
self._project_file = f'src/{String.convert_to_snake_case(self._source)}/{self._source}.json' self._project_file = f'src/{String.convert_to_snake_case(self._source)}/{self._source}.json'
@@ -24,7 +25,10 @@ class RemoveTestCase(unittest.TestCase):
return project_json return project_json
def setUp(self): def setUp(self):
os.chdir(os.path.abspath(PLAYGROUND_PATH)) if not os.path.exists(PLAYGROUND_PATH):
os.makedirs(PLAYGROUND_PATH)
os.chdir(PLAYGROUND_PATH)
# create projects # create projects
CLICommands.new('console', self._source, '--ab', '--s') CLICommands.new('console', self._source, '--ab', '--s')
os.chdir(os.path.join(os.getcwd(), self._source)) os.chdir(os.path.join(os.getcwd(), self._source))

View File

@@ -1,28 +1,24 @@
import json import json
import os import os
import shutil import shutil
import subprocess
import sys
import unittest import unittest
import pkg_resources
from cpl_core.utils import String from cpl_core.utils import String
from unittests_cli.abc.command_test_case import CommandTestCase
from unittests_cli.constants import PLAYGROUND_PATH from unittests_cli.constants import PLAYGROUND_PATH
from unittests_shared.cli_commands import CLICommands from unittests_shared.cli_commands import CLICommands
class RunTestCase(unittest.TestCase): class RunTestCase(CommandTestCase):
def __init__(self, methodName: str): def __init__(self, method_name: str):
unittest.TestCase.__init__(self, methodName) CommandTestCase.__init__(self, method_name)
self._source = 'run-test' self._source = 'run-test'
self._project_file = f'src/{String.convert_to_snake_case(self._source)}/{self._source}.json' self._project_file = f'src/{String.convert_to_snake_case(self._source)}/{self._source}.json'
self._appsettings = f'src/{String.convert_to_snake_case(self._source)}/appsettings.json'
self._application = f'src/{String.convert_to_snake_case(self._source)}/application.py' self._application = f'src/{String.convert_to_snake_case(self._source)}/application.py'
self._test_code = f""" self._test_code = f"""
import json import json
import os
settings = dict() settings = dict()
with open('appsettings.json', 'r', encoding='utf-8') as cfg: with open('appsettings.json', 'r', encoding='utf-8') as cfg:
# load json # load json
@@ -30,14 +26,19 @@ class RunTestCase(unittest.TestCase):
cfg.close() cfg.close()
settings['RunTest']['WasStarted'] = 'True' settings['RunTest']['WasStarted'] = 'True'
settings['RunTest']['Path'] = os.path.dirname(os.path.realpath(__file__))
with open('appsettings.json', 'w', encoding='utf-8') as project_file: with open('appsettings.json', 'w', encoding='utf-8') as project_file:
project_file.write(json.dumps(settings, indent=2)) project_file.write(json.dumps(settings, indent=2))
project_file.close() project_file.close()
""" """
def _get_appsettings(self): def _get_appsettings(self, is_dev=False):
with open(os.path.join(os.getcwd(), self._appsettings), 'r', encoding='utf-8') as cfg: appsettings = f'dist/{self._source}/build/{String.convert_to_snake_case(self._source)}/appsettings.json'
if is_dev:
appsettings = f'src/{String.convert_to_snake_case(self._source)}/appsettings.json'
with open(os.path.join(os.getcwd(), appsettings), 'r', encoding='utf-8') as cfg:
# load json # load json
project_json = json.load(cfg) project_json = json.load(cfg)
cfg.close() cfg.close()
@@ -45,12 +46,12 @@ class RunTestCase(unittest.TestCase):
return project_json return project_json
def _save_appsettings(self, settings: dict): def _save_appsettings(self, settings: dict):
with open(os.path.join(os.getcwd(), self._appsettings), 'w', encoding='utf-8') as project_file: with open(os.path.join(os.getcwd(), f'src/{String.convert_to_snake_case(self._source)}/appsettings.json'), 'w', encoding='utf-8') as project_file:
project_file.write(json.dumps(settings, indent=2)) project_file.write(json.dumps(settings, indent=2))
project_file.close() project_file.close()
def setUp(self): def setUp(self):
os.chdir(os.path.abspath(PLAYGROUND_PATH)) os.chdir(PLAYGROUND_PATH)
# create projects # create projects
CLICommands.new('console', self._source, '--ab', '--s') CLICommands.new('console', self._source, '--ab', '--s')
os.chdir(os.path.join(os.getcwd(), self._source)) os.chdir(os.path.join(os.getcwd(), self._source))
@@ -60,13 +61,6 @@ class RunTestCase(unittest.TestCase):
file.write(f'\t\t{self._test_code}') file.write(f'\t\t{self._test_code}')
file.close() file.close()
def cleanUp(self):
# remove projects
if not os.path.exists(os.path.abspath(os.path.join(PLAYGROUND_PATH, self._source))):
return
shutil.rmtree(os.path.abspath(os.path.join(PLAYGROUND_PATH, self._source)))
def test_run(self): def test_run(self):
CLICommands.run() CLICommands.run()
settings = self._get_appsettings() settings = self._get_appsettings()
@@ -77,9 +71,16 @@ class RunTestCase(unittest.TestCase):
'True', 'True',
settings['RunTest']['WasStarted'] settings['RunTest']['WasStarted']
) )
self.assertNotEqual(
os.path.join(os.getcwd(), f'src/{String.convert_to_snake_case(self._source)}'),
settings['RunTest']['Path']
)
self.assertEqual(
os.path.join(os.getcwd(), f'dist/{self._source}/build/{String.convert_to_snake_case(self._source)}'),
settings['RunTest']['Path']
)
def test_run_by_project(self): def test_run_by_project(self):
os.chdir(os.path.join(os.getcwd()))
CLICommands.run(self._source) CLICommands.run(self._source)
settings = self._get_appsettings() settings = self._get_appsettings()
self.assertNotEqual(settings, {}) self.assertNotEqual(settings, {})
@@ -89,3 +90,41 @@ class RunTestCase(unittest.TestCase):
'True', 'True',
settings['RunTest']['WasStarted'] settings['RunTest']['WasStarted']
) )
self.assertNotEqual(
os.path.join(os.getcwd(), f'src/{String.convert_to_snake_case(self._source)}'),
settings['RunTest']['Path']
)
self.assertEqual(
os.path.join(os.getcwd(), f'dist/{self._source}/build/{String.convert_to_snake_case(self._source)}'),
settings['RunTest']['Path']
)
def test_run_dev(self):
CLICommands.run(is_dev=True)
settings = self._get_appsettings(is_dev=True)
self.assertNotEqual(settings, {})
self.assertIn('RunTest', settings)
self.assertIn('WasStarted', settings['RunTest'])
self.assertEqual(
'True',
settings['RunTest']['WasStarted']
)
self.assertEqual(
os.path.join(os.getcwd(), f'src/{String.convert_to_snake_case(self._source)}'),
settings['RunTest']['Path']
)
def test_run_dev_by_project(self):
CLICommands.run(self._source, is_dev=True)
settings = self._get_appsettings(is_dev=True)
self.assertNotEqual(settings, {})
self.assertIn('RunTest', settings)
self.assertIn('WasStarted', settings['RunTest'])
self.assertEqual(
'True',
settings['RunTest']['WasStarted']
)
self.assertEqual(
os.path.join(os.getcwd(), f'src/{String.convert_to_snake_case(self._source)}'),
settings['RunTest']['Path']
)

View File

@@ -5,21 +5,23 @@ import time
import unittest import unittest
from cpl_core.utils import String from cpl_core.utils import String
from unittests_cli.abc.command_test_case import CommandTestCase
from unittests_cli.constants import PLAYGROUND_PATH from unittests_cli.constants import PLAYGROUND_PATH
from unittests_cli.threads.start_test_thread import StartTestThread from unittests_cli.threads.start_test_thread import StartTestThread
from unittests_shared.cli_commands import CLICommands from unittests_shared.cli_commands import CLICommands
class StartTestCase(unittest.TestCase): class StartTestCase(CommandTestCase):
def __init__(self, methodName: str): def __init__(self, method_name: str):
unittest.TestCase.__init__(self, methodName) CommandTestCase.__init__(self, method_name)
self._source = 'start-test' self._source = 'start-test'
self._project_file = f'src/{String.convert_to_snake_case(self._source)}/{self._source}.json' self._project_file = f'src/{String.convert_to_snake_case(self._source)}/{self._source}.json'
self._appsettings = f'src/{String.convert_to_snake_case(self._source)}/appsettings.json' self._appsettings = f'src/{String.convert_to_snake_case(self._source)}/appsettings.json'
self._application = f'src/{String.convert_to_snake_case(self._source)}/application.py' self._application = f'src/{String.convert_to_snake_case(self._source)}/application.py'
self._test_code = f""" self._test_code = f"""
import json import json
import os
settings = dict() settings = dict()
with open('appsettings.json', 'r', encoding='utf-8') as cfg: with open('appsettings.json', 'r', encoding='utf-8') as cfg:
# load json # load json
@@ -30,14 +32,19 @@ class StartTestCase(unittest.TestCase):
settings['RunTest']['WasRestarted'] = 'True' settings['RunTest']['WasRestarted'] = 'True'
settings['RunTest']['WasStarted'] = 'True' settings['RunTest']['WasStarted'] = 'True'
settings['RunTest']['Path'] = os.path.dirname(os.path.realpath(__file__))
with open('appsettings.json', 'w', encoding='utf-8') as project_file: with open('appsettings.json', 'w', encoding='utf-8') as project_file:
project_file.write(json.dumps(settings, indent=2)) project_file.write(json.dumps(settings, indent=2))
project_file.close() project_file.close()
""" """
def _get_appsettings(self): def _get_appsettings(self, is_dev=False):
with open(os.path.join(os.getcwd(), self._appsettings), 'r', encoding='utf-8') as cfg: appsettings = f'dist/{self._source}/build/{String.convert_to_snake_case(self._source)}/appsettings.json'
if is_dev:
appsettings = f'src/{String.convert_to_snake_case(self._source)}/appsettings.json'
with open(os.path.join(os.getcwd(), appsettings), 'r', encoding='utf-8') as cfg:
# load json # load json
project_json = json.load(cfg) project_json = json.load(cfg)
cfg.close() cfg.close()
@@ -45,12 +52,15 @@ class StartTestCase(unittest.TestCase):
return project_json return project_json
def _save_appsettings(self, settings: dict): def _save_appsettings(self, settings: dict):
with open(os.path.join(os.getcwd(), self._appsettings), 'w', encoding='utf-8') as project_file: with open(os.path.join(os.getcwd(), f'src/{String.convert_to_snake_case(self._source)}/appsettings.json'), 'w', encoding='utf-8') as project_file:
project_file.write(json.dumps(settings, indent=2)) project_file.write(json.dumps(settings, indent=2))
project_file.close() project_file.close()
def setUp(self): def setUp(self):
os.chdir(os.path.abspath(PLAYGROUND_PATH)) if not os.path.exists(PLAYGROUND_PATH):
os.makedirs(PLAYGROUND_PATH)
os.chdir(PLAYGROUND_PATH)
# create projects # create projects
CLICommands.new('console', self._source, '--ab', '--s') CLICommands.new('console', self._source, '--ab', '--s')
os.chdir(os.path.join(os.getcwd(), self._source)) os.chdir(os.path.join(os.getcwd(), self._source))
@@ -60,16 +70,42 @@ class StartTestCase(unittest.TestCase):
file.write(f'\t\t{self._test_code}') file.write(f'\t\t{self._test_code}')
file.close() file.close()
def cleanUp(self):
# remove projects
if not os.path.exists(os.path.abspath(os.path.join(PLAYGROUND_PATH, self._source))):
return
shutil.rmtree(os.path.abspath(os.path.join(PLAYGROUND_PATH, self._source)))
def test_start(self): def test_start(self):
thread = StartTestThread() thread = StartTestThread()
thread.start() thread.start()
time.sleep(5)
settings = self._get_appsettings()
self.assertNotEqual(settings, {})
self.assertIn('RunTest', settings)
self.assertIn('WasStarted', settings['RunTest'])
self.assertEqual(
'True',
settings['RunTest']['WasStarted']
)
with open(os.path.join(os.getcwd(), self._application), 'a', encoding='utf-8') as file:
file.write(f'# trigger restart (comment generated by unittest)')
file.close()
time.sleep(5)
settings = self._get_appsettings()
self.assertNotEqual(settings, {})
self.assertIn('RunTest', settings)
self.assertIn('WasStarted', settings['RunTest'])
self.assertIn('WasRestarted', settings['RunTest'])
self.assertEqual(
'True',
settings['RunTest']['WasStarted']
)
self.assertEqual(
'True',
settings['RunTest']['WasRestarted']
)
def test_start_dev(self):
thread = StartTestThread(is_dev=True)
thread.start()
time.sleep(1) time.sleep(1)
settings = self._get_appsettings() settings = self._get_appsettings()
self.assertNotEqual(settings, {}) self.assertNotEqual(settings, {})
@@ -86,7 +122,7 @@ class StartTestCase(unittest.TestCase):
time.sleep(1) time.sleep(1)
settings = self._get_appsettings() settings = self._get_appsettings(is_dev=True)
self.assertNotEqual(settings, {}) self.assertNotEqual(settings, {})
self.assertIn('RunTest', settings) self.assertIn('RunTest', settings)
self.assertIn('WasStarted', settings['RunTest']) self.assertIn('WasStarted', settings['RunTest'])

View File

@@ -5,8 +5,9 @@ from unittests_shared.cli_commands import CLICommands
class StartTestThread(threading.Thread): class StartTestThread(threading.Thread):
def __init__(self): def __init__(self, is_dev=False):
threading.Thread.__init__(self, daemon=True) threading.Thread.__init__(self, daemon=True)
self._is_dev = is_dev
def run(self): def run(self):
CLICommands.start(True) CLICommands.start(is_dev=self._is_dev, output=True)

View File

@@ -6,14 +6,15 @@ import sys
import unittest import unittest
from cpl_core.utils import String from cpl_core.utils import String
from unittests_cli.abc.command_test_case import CommandTestCase
from unittests_cli.constants import PLAYGROUND_PATH from unittests_cli.constants import PLAYGROUND_PATH
from unittests_shared.cli_commands import CLICommands from unittests_shared.cli_commands import CLICommands
class UninstallTestCase(unittest.TestCase): class UninstallTestCase(CommandTestCase):
def __init__(self, methodName: str): def __init__(self, method_name: str):
unittest.TestCase.__init__(self, methodName) CommandTestCase.__init__(self, method_name)
self._source = 'uninstall-test-source' self._source = 'uninstall-test-source'
self._project_file = f'src/{String.convert_to_snake_case(self._source)}/{self._source}.json' self._project_file = f'src/{String.convert_to_snake_case(self._source)}/{self._source}.json'
self._version = '1.7.3' self._version = '1.7.3'
@@ -29,18 +30,14 @@ class UninstallTestCase(unittest.TestCase):
return project_json return project_json
def setUp(self): def setUp(self):
os.chdir(os.path.abspath(PLAYGROUND_PATH)) if not os.path.exists(PLAYGROUND_PATH):
os.makedirs(PLAYGROUND_PATH)
os.chdir(PLAYGROUND_PATH)
# create projects # create projects
CLICommands.new('console', self._source, '--ab', '--s') CLICommands.new('console', self._source, '--ab', '--s')
os.chdir(os.path.join(os.getcwd(), self._source)) os.chdir(os.path.join(os.getcwd(), self._source))
def cleanUp(self):
# remove projects
if not os.path.exists(os.path.abspath(os.path.join(PLAYGROUND_PATH, self._source))):
return
shutil.rmtree(os.path.abspath(os.path.join(PLAYGROUND_PATH, self._source)))
def _get_installed_packages(self) -> dict: def _get_installed_packages(self) -> dict:
reqs = subprocess.check_output([sys.executable, '-m', 'pip', 'freeze']) reqs = subprocess.check_output([sys.executable, '-m', 'pip', 'freeze'])
return dict([tuple(r.decode().split('==')) for r in reqs.split()]) return dict([tuple(r.decode().split('==')) for r in reqs.split()])

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