arclith-cli 0.14.0__tar.gz → 0.15.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {arclith_cli-0.14.0 → arclith_cli-0.15.0}/PKG-INFO +2 -2
- arclith_cli-0.15.0/arclith_cli/__init__.py +1 -0
- {arclith_cli-0.14.0 → arclith_cli-0.15.0}/arclith_cli/adapter_templates.py +46 -4
- {arclith_cli-0.14.0 → arclith_cli-0.15.0}/arclith_cli/capabilities.py +97 -4
- {arclith_cli-0.14.0 → arclith_cli-0.15.0}/pyproject.toml +2 -2
- {arclith_cli-0.14.0 → arclith_cli-0.15.0}/tests/e2e_manual.sh +1 -1
- {arclith_cli-0.14.0 → arclith_cli-0.15.0}/tests/test_add_adapter.py +421 -175
- {arclith_cli-0.14.0 → arclith_cli-0.15.0}/tests/test_capabilities.py +209 -53
- {arclith_cli-0.14.0 → arclith_cli-0.15.0}/tests/test_core_scaffold.py +1 -1
- {arclith_cli-0.14.0 → arclith_cli-0.15.0}/uv.lock +6 -3
- arclith_cli-0.14.0/arclith_cli/__init__.py +0 -1
- {arclith_cli-0.14.0 → arclith_cli-0.15.0}/.gitignore +0 -0
- {arclith_cli-0.14.0 → arclith_cli-0.15.0}/LICENSE +0 -0
- {arclith_cli-0.14.0 → arclith_cli-0.15.0}/Makefile +0 -0
- {arclith_cli-0.14.0 → arclith_cli-0.15.0}/README.md +0 -0
- {arclith_cli-0.14.0 → arclith_cli-0.15.0}/arclith_cli/add_adapter.py +0 -0
- {arclith_cli-0.14.0 → arclith_cli-0.15.0}/arclith_cli/core_scaffold.py +0 -0
- {arclith_cli-0.14.0 → arclith_cli-0.15.0}/arclith_cli/entity_scanner.py +0 -0
- {arclith_cli-0.14.0 → arclith_cli-0.15.0}/arclith_cli/export_config.py +0 -0
- {arclith_cli-0.14.0 → arclith_cli-0.15.0}/arclith_cli/init_project.py +0 -0
- {arclith_cli-0.14.0 → arclith_cli-0.15.0}/arclith_cli/main.py +0 -0
- {arclith_cli-0.14.0 → arclith_cli-0.15.0}/arclith_cli/project_paths.py +0 -0
- {arclith_cli-0.14.0 → arclith_cli-0.15.0}/arclith_cli/rename.py +0 -0
- {arclith_cli-0.14.0 → arclith_cli-0.15.0}/arclith_cli/runtime_templates.py +0 -0
- {arclith_cli-0.14.0 → arclith_cli-0.15.0}/arclith_cli/scaffold.py +0 -0
- {arclith_cli-0.14.0 → arclith_cli-0.15.0}/arclith_cli/updater.py +0 -0
- {arclith_cli-0.14.0 → arclith_cli-0.15.0}/tests/__init__.py +0 -0
- {arclith_cli-0.14.0 → arclith_cli-0.15.0}/tests/test_e2e_scaffold.py +0 -0
- {arclith_cli-0.14.0 → arclith_cli-0.15.0}/tests/test_project_paths.py +0 -0
- {arclith_cli-0.14.0 → arclith_cli-0.15.0}/tests/test_rename.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: arclith-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.15.0
|
|
4
4
|
Summary: CLI scaffolding tool for arclith — hexagonal architecture framework
|
|
5
5
|
Author-email: Killian KOPP <killiankopp@gmail.com>
|
|
6
6
|
License: Apache License
|
|
@@ -186,7 +186,7 @@ License: Apache License
|
|
|
186
186
|
License-File: LICENSE
|
|
187
187
|
Keywords: arclith,cli,ddd,hexagonal-architecture,scaffold
|
|
188
188
|
Requires-Python: >=3.13
|
|
189
|
-
Requires-Dist: arclith>=0.
|
|
189
|
+
Requires-Dist: arclith>=0.18.0
|
|
190
190
|
Requires-Dist: httpx>=0.27.0
|
|
191
191
|
Requires-Dist: rich>=13.0.0
|
|
192
192
|
Requires-Dist: typer>=0.15.0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.15.0"
|
|
@@ -66,6 +66,20 @@ class MariaDB{pascal}Repository(MariaDBRepository[{pascal}], {pascal}Repository)
|
|
|
66
66
|
|
|
67
67
|
# TODO: add custom query methods here
|
|
68
68
|
""",
|
|
69
|
+
"postgresql": """\
|
|
70
|
+
from arclith.adapters.outbound.postgresql.config import PostgreSQLConfig
|
|
71
|
+
from arclith.adapters.outbound.postgresql.repository import PostgreSQLRepository
|
|
72
|
+
from arclith.domain.ports.outbound.logger import Logger
|
|
73
|
+
from {domain_import}.models.{snake} import {pascal}
|
|
74
|
+
from {domain_import}.ports.outbound.{snake}_repository import {pascal}Repository
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class PostgreSQL{pascal}Repository(PostgreSQLRepository[{pascal}], {pascal}Repository):
|
|
78
|
+
def __init__(self, config: PostgreSQLConfig, logger: Logger) -> None:
|
|
79
|
+
super().__init__(config, {pascal}, logger)
|
|
80
|
+
|
|
81
|
+
# TODO: add custom query methods here
|
|
82
|
+
""",
|
|
69
83
|
}
|
|
70
84
|
|
|
71
85
|
# ── repository.py re-export template ─────────────────────────────────────────
|
|
@@ -90,6 +104,11 @@ __all__ = ["DuckDB{pascal}Repository"]
|
|
|
90
104
|
from {adapters_import}.outbound.mariadb.repositories.{snake}_repository import MariaDB{pascal}Repository
|
|
91
105
|
|
|
92
106
|
__all__ = ["MariaDB{pascal}Repository"]
|
|
107
|
+
""",
|
|
108
|
+
"postgresql": """\
|
|
109
|
+
from {adapters_import}.outbound.postgresql.repositories.{snake}_repository import PostgreSQL{pascal}Repository
|
|
110
|
+
|
|
111
|
+
__all__ = ["PostgreSQL{pascal}Repository"]
|
|
93
112
|
""",
|
|
94
113
|
}
|
|
95
114
|
|
|
@@ -152,6 +171,29 @@ def _build_mariadb(cfg: AppConfig, _entity_class: type[{pascal}], log: Logger) -
|
|
|
152
171
|
log,
|
|
153
172
|
)
|
|
154
173
|
|
|
174
|
+
""",
|
|
175
|
+
"postgresql": """\
|
|
176
|
+
def _build_postgresql(cfg: AppConfig, _entity_class: type[{pascal}], log: Logger) -> {pascal}Repository:
|
|
177
|
+
from {adapters_import}.outbound.postgresql.repository import PostgreSQL{pascal}Repository
|
|
178
|
+
from arclith.adapters.outbound.postgresql.config import PostgreSQLConfig
|
|
179
|
+
postgresql = cfg.adapters.postgresql
|
|
180
|
+
if postgresql is None:
|
|
181
|
+
raise ValueError("PostgreSQL settings are required when repository=postgresql")
|
|
182
|
+
return PostgreSQL{pascal}Repository(
|
|
183
|
+
PostgreSQLConfig(
|
|
184
|
+
url=postgresql.url,
|
|
185
|
+
host=postgresql.host,
|
|
186
|
+
port=postgresql.port,
|
|
187
|
+
database=postgresql.database,
|
|
188
|
+
user=postgresql.user,
|
|
189
|
+
password=postgresql.password,
|
|
190
|
+
schema=postgresql.schema_name,
|
|
191
|
+
driver=postgresql.driver,
|
|
192
|
+
table_prefix=postgresql.table_prefix,
|
|
193
|
+
),
|
|
194
|
+
log,
|
|
195
|
+
)
|
|
196
|
+
|
|
155
197
|
""",
|
|
156
198
|
}
|
|
157
199
|
|
|
@@ -169,7 +211,9 @@ def build_{snake}_service(arclith: Arclith) -> tuple[{pascal}Service, Logger]:
|
|
|
169
211
|
"""
|
|
170
212
|
|
|
171
213
|
|
|
172
|
-
def render_container(
|
|
214
|
+
def render_container(
|
|
215
|
+
pascal: str, snake: str, installed_adapters: list[str], import_vars: dict[str, str]
|
|
216
|
+
) -> str:
|
|
173
217
|
"""Generate the full container file content for a given entity and its adapters."""
|
|
174
218
|
# memory is always included (arclith built-in, needs no extra files)
|
|
175
219
|
adapters = list(dict.fromkeys(["memory"] + installed_adapters))
|
|
@@ -182,9 +226,7 @@ def render_container(pascal: str, snake: str, installed_adapters: list[str], imp
|
|
|
182
226
|
if a in _CONTAINER_FACTORY
|
|
183
227
|
)
|
|
184
228
|
registrations = "\n".join(
|
|
185
|
-
f
|
|
186
|
-
for a in adapters
|
|
187
|
-
if a in _CONTAINER_FACTORY
|
|
229
|
+
f' .register("{a}", _build_{a})' for a in adapters if a in _CONTAINER_FACTORY
|
|
188
230
|
)
|
|
189
231
|
footer = _CONTAINER_FOOTER.format(**vars, registrations=registrations)
|
|
190
232
|
return header + factories + footer
|
|
@@ -108,10 +108,16 @@ class AdapterSpec:
|
|
|
108
108
|
"layer": self.layer,
|
|
109
109
|
"description": self.description,
|
|
110
110
|
"config_path": self.config_path,
|
|
111
|
-
"merge_config_templates": [
|
|
111
|
+
"merge_config_templates": [
|
|
112
|
+
file_template.to_dict() for file_template in self.merge_config_templates
|
|
113
|
+
],
|
|
112
114
|
"env_path": self.env_path,
|
|
113
|
-
"file_templates": [
|
|
114
|
-
|
|
115
|
+
"file_templates": [
|
|
116
|
+
file_template.to_dict() for file_template in self.file_templates
|
|
117
|
+
],
|
|
118
|
+
"secret_mappings": [
|
|
119
|
+
secret_mapping.to_dict() for secret_mapping in self.secret_mappings
|
|
120
|
+
],
|
|
115
121
|
"secret_resolver": self.secret_resolver,
|
|
116
122
|
"secret_config_template": bool(self.secret_config_template),
|
|
117
123
|
"gitignore_entries": list(self.gitignore_entries),
|
|
@@ -284,6 +290,85 @@ multitenant: false
|
|
|
284
290
|
),
|
|
285
291
|
),
|
|
286
292
|
),
|
|
293
|
+
AdapterSpec(
|
|
294
|
+
name="postgresql",
|
|
295
|
+
capability="repository",
|
|
296
|
+
layer="outbound",
|
|
297
|
+
description="Repository PostgreSQL async optionnel, pilote par SQLAlchemy et asyncpg, avec payload JSONB generique.",
|
|
298
|
+
config_path="config/adapters/outbound/postgresql.yaml",
|
|
299
|
+
config_template="""\
|
|
300
|
+
url: null # à mapper via config/secrets.yaml ou resolver env/vault si vous fournissez une URL complète
|
|
301
|
+
host: {host}
|
|
302
|
+
port: {port}
|
|
303
|
+
database: {database}
|
|
304
|
+
user: {user}
|
|
305
|
+
password: null # à mapper via config/secrets.yaml ou resolver env/vault
|
|
306
|
+
schema: {schema}
|
|
307
|
+
driver: {driver}
|
|
308
|
+
table_prefix: "{table_prefix}"
|
|
309
|
+
multitenant: {multitenant}
|
|
310
|
+
""",
|
|
311
|
+
secret_mappings=(
|
|
312
|
+
SecretMappingSpec(
|
|
313
|
+
field_path="adapters.postgresql.url",
|
|
314
|
+
secret_key="POSTGRESQL_URL",
|
|
315
|
+
),
|
|
316
|
+
SecretMappingSpec(
|
|
317
|
+
field_path="adapters.postgresql.password",
|
|
318
|
+
secret_key="POSTGRESQL_PASSWORD",
|
|
319
|
+
),
|
|
320
|
+
),
|
|
321
|
+
parameters=(
|
|
322
|
+
ParameterSpec(
|
|
323
|
+
name="host",
|
|
324
|
+
kind="string",
|
|
325
|
+
prompt="host",
|
|
326
|
+
default="127.0.0.1",
|
|
327
|
+
),
|
|
328
|
+
ParameterSpec(
|
|
329
|
+
name="port",
|
|
330
|
+
kind="string",
|
|
331
|
+
prompt="port",
|
|
332
|
+
default="5432",
|
|
333
|
+
),
|
|
334
|
+
ParameterSpec(
|
|
335
|
+
name="database",
|
|
336
|
+
kind="string",
|
|
337
|
+
prompt="database",
|
|
338
|
+
default_from_project_name=True,
|
|
339
|
+
),
|
|
340
|
+
ParameterSpec(
|
|
341
|
+
name="user",
|
|
342
|
+
kind="string",
|
|
343
|
+
prompt="user",
|
|
344
|
+
default="app",
|
|
345
|
+
),
|
|
346
|
+
ParameterSpec(
|
|
347
|
+
name="schema",
|
|
348
|
+
kind="string",
|
|
349
|
+
prompt="schema",
|
|
350
|
+
default="public",
|
|
351
|
+
),
|
|
352
|
+
ParameterSpec(
|
|
353
|
+
name="driver",
|
|
354
|
+
kind="string",
|
|
355
|
+
prompt="driver",
|
|
356
|
+
default="asyncpg",
|
|
357
|
+
),
|
|
358
|
+
ParameterSpec(
|
|
359
|
+
name="table_prefix",
|
|
360
|
+
kind="string",
|
|
361
|
+
prompt="table_prefix",
|
|
362
|
+
default="",
|
|
363
|
+
),
|
|
364
|
+
ParameterSpec(
|
|
365
|
+
name="multitenant",
|
|
366
|
+
kind="boolean",
|
|
367
|
+
prompt="multitenant",
|
|
368
|
+
default=False,
|
|
369
|
+
),
|
|
370
|
+
),
|
|
371
|
+
),
|
|
287
372
|
),
|
|
288
373
|
)
|
|
289
374
|
|
|
@@ -1549,7 +1634,15 @@ agent = arclith.langgraph(AgentState, register_agent, name="{graph_name}")
|
|
|
1549
1634
|
kind="string",
|
|
1550
1635
|
prompt="Mode(s) de streaming LangGraph",
|
|
1551
1636
|
default="updates",
|
|
1552
|
-
choices=(
|
|
1637
|
+
choices=(
|
|
1638
|
+
"values",
|
|
1639
|
+
"updates",
|
|
1640
|
+
"custom",
|
|
1641
|
+
"messages",
|
|
1642
|
+
"checkpoints",
|
|
1643
|
+
"tasks",
|
|
1644
|
+
"debug",
|
|
1645
|
+
),
|
|
1553
1646
|
csv_choices=True,
|
|
1554
1647
|
),
|
|
1555
1648
|
),
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "arclith-cli"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.15.0"
|
|
8
8
|
description = "CLI scaffolding tool for arclith — hexagonal architecture framework"
|
|
9
9
|
license = { file = "LICENSE" }
|
|
10
10
|
requires-python = ">=3.13"
|
|
@@ -16,7 +16,7 @@ dependencies = [
|
|
|
16
16
|
"typer>=0.15.0",
|
|
17
17
|
"rich>=13.0.0",
|
|
18
18
|
"httpx>=0.27.0",
|
|
19
|
-
"arclith>=0.
|
|
19
|
+
"arclith>=0.18.0",
|
|
20
20
|
]
|
|
21
21
|
|
|
22
22
|
[tool.uv.sources]
|
|
@@ -39,7 +39,7 @@ if grep -q '\[tool\.uv\.sources\]' pyproject.toml; then
|
|
|
39
39
|
fi
|
|
40
40
|
|
|
41
41
|
ARCLITH_VERSION=$(grep 'arclith\[' pyproject.toml | grep -oE '[0-9]+\.[0-9]+\.[0-9]+')
|
|
42
|
-
MIN_ARCLITH_VERSION="0.
|
|
42
|
+
MIN_ARCLITH_VERSION="0.18.0"
|
|
43
43
|
if version_lt "$ARCLITH_VERSION" "$MIN_ARCLITH_VERSION"; then
|
|
44
44
|
echo -e "${RED}✗ FAIL: arclith version < $MIN_ARCLITH_VERSION (found: $ARCLITH_VERSION)${NC}"
|
|
45
45
|
exit 1
|