Merge pull request 'cli' (#199) from cli into dev
Some checks failed
Test before pr merge / test-lint (pull_request) Successful in 7s
Build on push / prepare (push) Successful in 13s
Build on push / core (push) Failing after 9s
Build on push / query (push) Failing after 10s
Build on push / api (push) Has been skipped
Build on push / application (push) Has been skipped
Build on push / auth (push) Has been skipped
Build on push / cli (push) Has been skipped
Build on push / database (push) Has been skipped
Build on push / dependency (push) Has been skipped
Build on push / mail (push) Has been skipped
Build on push / translation (push) Has been skipped

Reviewed-on: #199
This commit is contained in:
2025-10-19 14:40:45 +02:00
366 changed files with 2704 additions and 170 deletions

View File

@@ -33,6 +33,13 @@ jobs:
working_directory: src/cpl-auth
secrets: inherit
cli:
uses: ./.gitea/workflows/package.yaml
needs: [ prepare, core ]
with:
working_directory: src/cpl-cli
secrets: inherit
core:
uses: ./.gitea/workflows/package.yaml
needs: [prepare]

View File

@@ -36,6 +36,12 @@ jobs:
echo "Set version to $(cat /workspace/sh-edraft.de/cpl/version.txt)"
cat pyproject.toml
- name: Set package version
run: |
sed -i -E "s/^__version__ = \".*\"/__version__ = \"$(cat /workspace/sh-edraft.de/cpl/version.txt)\"/" cpl/*/__init__.py
echo "Set version to $(cat /workspace/sh-edraft.de/cpl/version.txt)"
cat cpl/*/__init__.py
- name: Set pip conf
run: |
cat > .pip.conf <<'EOF'

12
cpl.workspace.json Normal file
View File

@@ -0,0 +1,12 @@
{
"name": "cpl",
"projects": [
"src/cli/cpl.project.json",
"src/core/cpl.project.json",
"test/cpl.project.json"
],
"defaultProject": "cpl-cli",
"scripts": {
"format": "black src"
}
}

View File

@@ -3,8 +3,8 @@ from datetime import datetime
from cpl.core.console import Console
from cpl.core.time.cron import Cron
from cpl.dependency.hosted.cronjob import CronjobABC
from cpl.dependency.hosted.hosted_service import HostedService
from cpl.core.service.cronjob import CronjobABC
from cpl.core.service.hosted_service import HostedService
class Hosted(HostedService):

View File

@@ -2,3 +2,5 @@ from .error import APIError, AlreadyExists, EndpointNotImplemented, Forbidden, N
from .logger import APILogger
from .settings import ApiSettings
from .api_module import ApiModule
__version__ = "1.0.0"

View File

@@ -1,2 +1,4 @@
from .application_builder import ApplicationBuilder
from .host import Host
__version__ = "1.0.0"

View File

@@ -14,7 +14,7 @@ TApp = TypeVar("TApp", bound=ApplicationABC)
class ApplicationBuilder(Generic[TApp]):
def __init__(self, app: Type[ApplicationABC]):
def __init__(self, app: Type[TApp]):
assert app is not None, "app must not be None"
assert issubclass(app, ApplicationABC), "app must be an subclass of ApplicationABC or its subclass"

View File

@@ -1,7 +1,9 @@
import asyncio
from typing import Callable
from cpl.dependency import get_provider
from cpl.core.property import classproperty
from cpl.dependency.context import get_provider, use_root_provider
from cpl.dependency.service_collection import ServiceCollection
from cpl.dependency.hosted.startup_task import StartupTask
@@ -9,6 +11,24 @@ class Host:
_loop: asyncio.AbstractEventLoop | None = None
_tasks: dict = {}
_service_collection: ServiceCollection | None = None
@classproperty
def services(cls) -> ServiceCollection:
if cls._service_collection is None:
cls._service_collection = ServiceCollection()
return cls._service_collection
@classmethod
def get_provider(cls):
provider = get_provider()
if provider is None:
provider = cls.services.build()
use_root_provider(provider)
return provider
@classmethod
def get_loop(cls) -> asyncio.AbstractEventLoop:
if cls._loop is None:
@@ -18,7 +38,7 @@ class Host:
@classmethod
def run_start_tasks(cls):
provider = get_provider()
provider = cls.get_provider()
tasks = provider.get_services(StartupTask)
loop = cls.get_loop()
@@ -30,7 +50,7 @@ class Host:
@classmethod
def run_hosted_services(cls):
provider = get_provider()
provider = cls.get_provider()
services = provider.get_hosted_services()
loop = cls.get_loop()
@@ -49,6 +69,10 @@ class Host:
cls._tasks.clear()
@classmethod
async def wait_for_all(cls):
await asyncio.gather(*cls._tasks.values())
@classmethod
def run_app(cls, func: Callable, *args, **kwargs):
cls.run_start_tasks()

View File

@@ -4,3 +4,5 @@ from cpl.auth.keycloak.keycloak_client import KeycloakClient as _KeycloakClient
from .auth_module import AuthModule
from .keycloak_settings import KeycloakSettings
from .logger import AuthLogger
__version__ = "1.0.0"

29
src/cli/cpl.project.json Normal file
View File

@@ -0,0 +1,29 @@
{
"name": "cpl-cli",
"version": "0.1.0",
"type": "console",
"license": "MIT",
"author": "Sven Heidemann",
"description": "CLI for the CPL library",
"homepage": "",
"keywords": [],
"dependencies": {
"click": "~8.3.0"
},
"devDependencies": {
"black": "~25.9"
},
"references": [],
"main": "cpl/cli/main.py",
"directory": "cpl/cli",
"build": {
"include": [
"_templates/"
],
"exclude": [
"**/__pycache__",
"**/logs",
"**/tests"
]
}
}

View File

@@ -0,0 +1,9 @@
from abc import ABC
class <Name>ABC(ABC):
def __init__(self):
ABC.__init__(self)
print("<schematic> <multi_camelName> initialized")

View File

@@ -0,0 +1,16 @@
from cpl.application.abc import ApplicationABC
from cpl.core.environment import Environment
from cpl.core.log import LoggerABC
from cpl.dependency import ServiceProvider
from cpl.dependency.typing import Modules
class <Name>(ApplicationABC):
def __init__(self, services: ServiceProvider, modules: Modules):
ApplicationABC.__init__(self, services, modules)
self._logger = services.get_service(LoggerABC)
async def main(self):
self._logger.debug(f"Host: {Environment.get_host_name()}")
self._logger.debug(f"Environment: {Environment.get_environment()}")

View File

@@ -0,0 +1,10 @@
from cpl.core.configuration import ConfigurationModelABC
class <Name>Config(ConfigurationModelABC):
def __init__(
self,
src: dict = None,
):
ConfigurationModelABC.__init__(self, src)

View File

@@ -0,0 +1,9 @@
from cpl.core.console import Console
from cpl.core.service import CronjobABC
class CronJob(CronjobABC):
def __init__(self):
CronjobABC.__init__(self, Cron("*/1 * * * *"))
async def loop(self):
Console.write_line(f"[{datetime.now()}] Hello, World!")

View File

@@ -0,0 +1,9 @@
from cpl.database.abc import DbModelDaoABC
class <Name>Dao(DbModelDaoABC[<Name>]):
def __init__(self):
DbModelDaoABC.__init__(self, <Name>, "<multi_name>")
self.attribute(<Name>.name, str)

View File

@@ -0,0 +1,23 @@
from datetime import datetime
from typing import Self
from cpl.core.typing import SerialId
from cpl.database.abc import DbModelABC
class <Name>(DbModelABC[Self]):
def __init__(
self,
id: SerialId,
name: str,
deleted: bool = False,
editor_id: SerialId | None = None,
created: datetime | None = None,
updated: datetime | None = None,
):
DbModelABC.__init__(self, id, deleted, editor_id, created, updated)
self._name = name
@property
def name(self) -> str:
return self._name

View File

@@ -0,0 +1,29 @@
from datetime import datetime
from typing import Self
from cpl.core.typing import SerialId
from cpl.database.abc import DbJoinModelABC
class <Name>Join(DbJoinModelABC[Self]):
def __init__(
self,
id: SerialId,
source_id: SerialId,
reference_id: SerialId,
deleted: bool = False,
editor_id: SerialId | None = None,
created: datetime | None = None,
updated: datetime | None = None,
):
DbJoinModelABC.__init__(self, source_id, reference_id, id, deleted, editor_id, created, updated)
self._source_id = source_id
self._reference_id = reference_id
@property
def source_id(self) -> int:
return self._source_id
@property
def reference(self) -> int:
return self._reference_id

View File

@@ -0,0 +1,5 @@
from enum import Enum
class <Name>Enum(Enum):
KEY = "value"

View File

@@ -0,0 +1,13 @@
from cpl.core.console import Console
from cpl.core.service import HostedService
class <Name>(HostedService):
def __init__(self):
HostedService.__init__(self)
async def start(self):
Console.write_line("Hello, World!")
async def stop(self):
Console.write_line("Goodbye, World!")

View File

@@ -0,0 +1,7 @@
from cpl.core.log.wrapped_logger import WrappedLogger
class <Name>Logger(WrappedLogger):
def __init__(self):
WrappedLogger.__init__(self, "<name>")

View File

@@ -0,0 +1,17 @@
from cpl.dependency import ServiceCollection, ServiceProvider
from cpl.dependency.module import Module
class <Name>Module(Module):
dependencies = []
configuration = []
singleton = []
scoped = []
transient = []
hosted = []
@staticmethod
def register(collection: ServiceCollection): ...
@staticmethod
def configure(provider: ServiceProvider): ...

View File

@@ -0,0 +1,9 @@
import multiprocessing
class <Name>(multiprocessing.Process):
def __init__(self):
multiprocessing.Process.__init__(self)
def run(self): ...

View File

@@ -0,0 +1,11 @@
from cpl.core.pipes import PipeABC
from cpl.core.typing import T
class <Name>Pipe(PipeABC):
@staticmethod
def to_str(value: T, *args) -> str: ...
@staticmethod
def from_str(value: str, *args) -> T: ...

View File

@@ -0,0 +1,9 @@
import threading
class <Name>(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self): ...

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