Compare commits
30 Commits
2025.10.08
...
2025.10.19
| Author | SHA1 | Date | |
|---|---|---|---|
| 0a9b7b81be | |||
| 21c88bc442 | |||
| 04e0884e1c | |||
| 2ac7fa4568 | |||
| 43947055e5 | |||
| ba9edfa3fc | |||
| 6d3e435da6 | |||
| 76b44ca517 | |||
| 8ebac05dd8 | |||
| 98ed458d7c | |||
| 8d0bc13cc0 | |||
| 33728cdec3 | |||
| f1604f1477 | |||
| a02c101438 | |||
| 9647923647 | |||
| 883fa2d691 | |||
| 3c26c73b41 | |||
| faedf328cb | |||
| 849dd7a733 | |||
| 6e0ae1f25e | |||
| 45dcb400da | |||
| 104b736778 | |||
| 90ff8d466d | |||
| f1aaaf2a5b | |||
| 5f8519d4b3 | |||
| c4334f32ed | |||
| 0a6a17acf6 | |||
| c02903b009 | |||
| b6cf5962aa | |||
| d3084041a9 |
@@ -16,61 +16,68 @@ jobs:
|
||||
uses: ./.gitea/workflows/package.yaml
|
||||
needs: [ prepare, application, auth, core, dependency ]
|
||||
with:
|
||||
working_directory: src/cpl-api
|
||||
working_directory: src/api
|
||||
secrets: inherit
|
||||
|
||||
application:
|
||||
uses: ./.gitea/workflows/package.yaml
|
||||
needs: [ prepare, core, dependency ]
|
||||
with:
|
||||
working_directory: src/cpl-application
|
||||
working_directory: src/application
|
||||
secrets: inherit
|
||||
|
||||
auth:
|
||||
uses: ./.gitea/workflows/package.yaml
|
||||
needs: [ prepare, core, dependency, database ]
|
||||
with:
|
||||
working_directory: src/cpl-auth
|
||||
working_directory: src/auth
|
||||
secrets: inherit
|
||||
|
||||
cli:
|
||||
uses: ./.gitea/workflows/package.yaml
|
||||
needs: [ prepare, core ]
|
||||
with:
|
||||
working_directory: src/cli
|
||||
secrets: inherit
|
||||
|
||||
core:
|
||||
uses: ./.gitea/workflows/package.yaml
|
||||
needs: [prepare]
|
||||
with:
|
||||
working_directory: src/cpl-core
|
||||
working_directory: src/core
|
||||
secrets: inherit
|
||||
|
||||
database:
|
||||
uses: ./.gitea/workflows/package.yaml
|
||||
needs: [ prepare, core, dependency ]
|
||||
with:
|
||||
working_directory: src/cpl-database
|
||||
working_directory: src/database
|
||||
secrets: inherit
|
||||
|
||||
dependency:
|
||||
uses: ./.gitea/workflows/package.yaml
|
||||
needs: [ prepare, core ]
|
||||
with:
|
||||
working_directory: src/cpl-dependency
|
||||
working_directory: src/dependency
|
||||
secrets: inherit
|
||||
|
||||
mail:
|
||||
uses: ./.gitea/workflows/package.yaml
|
||||
needs: [ prepare, core, dependency ]
|
||||
with:
|
||||
working_directory: src/cpl-mail
|
||||
working_directory: src/mail
|
||||
secrets: inherit
|
||||
|
||||
query:
|
||||
uses: ./.gitea/workflows/package.yaml
|
||||
needs: [prepare]
|
||||
with:
|
||||
working_directory: src/cpl-query
|
||||
working_directory: src/query
|
||||
secrets: inherit
|
||||
|
||||
translation:
|
||||
uses: ./.gitea/workflows/package.yaml
|
||||
needs: [ prepare, core, dependency ]
|
||||
with:
|
||||
working_directory: src/cpl-translation
|
||||
working_directory: src/translation
|
||||
secrets: inherit
|
||||
@@ -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'
|
||||
|
||||
22
README.md
22
README.md
@@ -0,0 +1,22 @@
|
||||
## Prepare for development
|
||||
|
||||
After cloning the repository, run the following commands to set up your development environment:
|
||||
|
||||
```bash
|
||||
python -m venv .venv
|
||||
source .venv/bin/activate
|
||||
# On Windows use `.venv\Scripts\activate`
|
||||
# On Windows with git bash use `source .venv/Scripts/activate`
|
||||
bash install.sh
|
||||
```
|
||||
|
||||
Install cpl-cli as a development package:
|
||||
|
||||
```bash
|
||||
pip install -e src/core
|
||||
pip install -e src/cli
|
||||
# test with:
|
||||
cpl v
|
||||
```
|
||||
|
||||
When using Pycharm, mark all directories under `src/` as "Sources Root" and `exa` to ensure proper module resolution.
|
||||
12
cpl.workspace.json
Normal file
12
cpl.workspace.json
Normal 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"
|
||||
}
|
||||
}
|
||||
@@ -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):
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Find and combine requirements from src/cpl-*/requirements.txt,
|
||||
# Find and combine requirements from src/*/requirements.txt,
|
||||
# filtering out lines whose *package name* starts with "cpl-".
|
||||
# Works with pinned versions, extras, markers, editable installs, and VCS refs.
|
||||
|
||||
shopt -s nullglob
|
||||
|
||||
req_files=(src/cpl-*/requirements.txt)
|
||||
req_files=(src/*/requirements.txt)
|
||||
if ((${#req_files[@]} == 0)); then
|
||||
echo "No requirements files found at src/cpl-*/requirements.txt" >&2
|
||||
echo "No requirements files found at src/*/requirements.txt" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
@@ -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"
|
||||
@@ -1,2 +1,4 @@
|
||||
from .application_builder import ApplicationBuilder
|
||||
from .host import Host
|
||||
|
||||
__version__ = "1.0.0"
|
||||
@@ -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"
|
||||
|
||||
@@ -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()
|
||||
@@ -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
29
src/cli/cpl.project.json
Normal 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"
|
||||
]
|
||||
}
|
||||
}
|
||||
9
src/cli/cpl/cli/.cpl/generate/abc.py.schematic
Normal file
9
src/cli/cpl/cli/.cpl/generate/abc.py.schematic
Normal file
@@ -0,0 +1,9 @@
|
||||
from abc import ABC
|
||||
|
||||
|
||||
class <Name>ABC(ABC):
|
||||
|
||||
def __init__(self):
|
||||
ABC.__init__(self)
|
||||
|
||||
print("<schematic> <multi_camelName> initialized")
|
||||
16
src/cli/cpl/cli/.cpl/generate/app.py.schematic
Normal file
16
src/cli/cpl/cli/.cpl/generate/app.py.schematic
Normal 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()}")
|
||||
10
src/cli/cpl/cli/.cpl/generate/config.py.schematic
Normal file
10
src/cli/cpl/cli/.cpl/generate/config.py.schematic
Normal 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)
|
||||
9
src/cli/cpl/cli/.cpl/generate/cron_job.py.schematic
Normal file
9
src/cli/cpl/cli/.cpl/generate/cron_job.py.schematic
Normal 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!")
|
||||
@@ -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)
|
||||
23
src/cli/cpl/cli/.cpl/generate/db_model.py.schematic
Normal file
23
src/cli/cpl/cli/.cpl/generate/db_model.py.schematic
Normal 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
|
||||
29
src/cli/cpl/cli/.cpl/generate/db_model_join.py.schematic
Normal file
29
src/cli/cpl/cli/.cpl/generate/db_model_join.py.schematic
Normal 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
|
||||
5
src/cli/cpl/cli/.cpl/generate/enum.py.schematic
Normal file
5
src/cli/cpl/cli/.cpl/generate/enum.py.schematic
Normal file
@@ -0,0 +1,5 @@
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class <Name>Enum(Enum):
|
||||
KEY = "value"
|
||||
13
src/cli/cpl/cli/.cpl/generate/hosted_service.py.schematic
Normal file
13
src/cli/cpl/cli/.cpl/generate/hosted_service.py.schematic
Normal 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!")
|
||||
7
src/cli/cpl/cli/.cpl/generate/logger.py.schematic
Normal file
7
src/cli/cpl/cli/.cpl/generate/logger.py.schematic
Normal file
@@ -0,0 +1,7 @@
|
||||
from cpl.core.log.wrapped_logger import WrappedLogger
|
||||
|
||||
|
||||
class <Name>Logger(WrappedLogger):
|
||||
|
||||
def __init__(self):
|
||||
WrappedLogger.__init__(self, "<name>")
|
||||
17
src/cli/cpl/cli/.cpl/generate/module.py.schematic
Normal file
17
src/cli/cpl/cli/.cpl/generate/module.py.schematic
Normal 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): ...
|
||||
9
src/cli/cpl/cli/.cpl/generate/multiprocess.py.schematic
Normal file
9
src/cli/cpl/cli/.cpl/generate/multiprocess.py.schematic
Normal file
@@ -0,0 +1,9 @@
|
||||
import multiprocessing
|
||||
|
||||
|
||||
class <Name>(multiprocessing.Process):
|
||||
|
||||
def __init__(self):
|
||||
multiprocessing.Process.__init__(self)
|
||||
|
||||
def run(self): ...
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user