magicbox-dk 0.0.2.dev1__tar.gz → 1.0.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.
- magicbox_dk-1.0.0/.bumpversion.toml +39 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/CLAUDE.md +33 -12
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/PKG-INFO +62 -1
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/README.md +61 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/commands/_base.py +33 -1
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/commands/dashboard.py +2 -2
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/commands/logs.py +35 -9
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/commands/prepare.py +102 -5
- magicbox_dk-0.0.2.dev1/cli/commands/update.py → magicbox_dk-1.0.0/cli/commands/pull.py +4 -4
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/commands/show.py +77 -25
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/commands/start.py +17 -6
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/commands/stop.py +20 -6
- magicbox_dk-1.0.0/cli/commands/update.py +140 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/compose/__init__.py +13 -0
- magicbox_dk-1.0.0/cli/compose/build_state.py +281 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/compose/builder.py +166 -40
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/compose/healthcheck.py +21 -43
- magicbox_dk-1.0.0/cli/compose/logfmt.py +461 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/compose/network.py +63 -12
- magicbox_dk-1.0.0/cli/compose/reload.py +117 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/compose/runtime.py +98 -32
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/core/context.py +3 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/core/paths.py +7 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/editors/env.py +111 -4
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/editors/frontend.py +10 -35
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/editors/profile.py +84 -71
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/editors/runnable.py +79 -124
- magicbox_dk-1.0.0/cli/editors/sdk.py +190 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/editors/settings.py +79 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/main.py +39 -4
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/models/profile.py +33 -13
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/runner/base.py +24 -4
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/runner/docker.py +37 -4
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/settings.py +65 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/ui.py +95 -34
- magicbox_dk-1.0.0/cli/version_check.py +149 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/configs/profile.base.yaml +12 -4
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/configs/services/back.config.yml +7 -4
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/configs/settings.base.yaml +21 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/docker/redis/docker-compose.yml +10 -1
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/docker/s3/docker-compose.yml +7 -1
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/docker/surrealdb/docker-compose.yml +7 -1
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/profile.example.yaml +13 -6
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/pyproject.toml +1 -1
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/uv.lock +1 -1
- magicbox_dk-0.0.2.dev1/.bumpversion.toml +0 -53
- magicbox_dk-0.0.2.dev1/cli/commands/version.py +0 -30
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/.github/workflows/ci.yml +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/.github/workflows/cleanup-prereleases.yml +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/.github/workflows/release.yml +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/.gitignore +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/LICENSE +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/__init__.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/cleanup.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/commands/__init__.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/commands/clean.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/commands/create.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/commands/credentials.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/commands/delete.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/commands/doctor.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/commands/edit.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/commands/env.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/commands/init.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/commands/list.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/commands/restart.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/commands/settings.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/commands/shell.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/commands/status.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/commands/switch.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/commands/validate.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/compose/templates.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/core/__init__.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/core/cmd.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/core/profile_io.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/debug.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/editors/__init__.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/editors/_readiness.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/editors/_state.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/editors/infra.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/editors/kin.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/editors/profile_meta.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/env/__init__.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/env/dotenv.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/env/loaders.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/env/regenerate.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/env/resolver.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/models/__init__.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/models/env.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/models/service.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/runner/__init__.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/runner/binaries.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/runner/git.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/runner/process.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/cli/runner/redaction.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/configs/credentials.base.yaml +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/configs/globals.base.yaml +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/configs/services/chainlit.config.yml +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/configs/services/horizon.config.yml +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/configs/services/module.config.yml +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/configs/services/node-service-provider.config.yml +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/configs/services/s3.config.yml +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/configs/services/surrealdb.config.yml +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/docker/archetypes/docker-compose.yml +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/docker/back/docker-compose.yml +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/docker/chainlit/docker-compose.yml +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/docker/docker-compose.yml +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/docker/horizon/docker-compose.yml +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/docker/node-service-provider/docker-compose.yml +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/services/chainlit/Dockerfile/Dockerfile +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/services/chainlit/Dockerfile/digitalkin-1.0.0.dev0.tar.gz +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/services/chainlit/Dockerfile/entrypoint.sh +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/services/chainlit/Dockerfile/generate_certificates.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/services/chainlit/README.md +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/services/chainlit/__init__.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/services/chainlit/application.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/services/chainlit/config.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/services/chainlit/handlers/__init__.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/services/chainlit/handlers/input_factory.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/services/chainlit/handlers/output_handler.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/services/chainlit/main.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/services/chainlit/models/__init__.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/services/chainlit/models/config.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/services/chainlit/models/protocols.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/services/chainlit/pyproject.toml +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/services/chainlit/services/__init__.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/services/chainlit/services/filesystem.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/services/chainlit/services/gateway_client.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/services/chainlit/services/module_client.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/services/chainlit/services/registry.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/services/chainlit/services/setup.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/services/chainlit/uv.lock +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/services/horizon/Dockerfile/Dockerfile +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/services/horizon/Dockerfile/nginx.conf +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/tests/conftest.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/tests/test_base.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/tests/test_binaries.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/tests/test_docker.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/tests/test_docker_validators.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/tests/test_git.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/tests/test_git_repo_ops.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/tests/test_git_validators.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/tests/test_process.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/tests/test_redaction.py +0 -0
- {magicbox_dk-0.0.2.dev1 → magicbox_dk-1.0.0}/tests/test_settings.py +0 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# bump-my-version configuration
|
|
2
|
+
# Semantic Versioning : major.minor.patch — https://semver.org
|
|
3
|
+
# Docs : https://callowayproject.github.io/bump-my-version/
|
|
4
|
+
|
|
5
|
+
[tool.bumpversion]
|
|
6
|
+
current_version = "1.0.0"
|
|
7
|
+
|
|
8
|
+
allow_dirty = false # Require a clean working tree
|
|
9
|
+
commit = true # Auto-commit the version bump
|
|
10
|
+
tag = true # Auto-create the git tag
|
|
11
|
+
sign_tags = true # GPG-sign the tag (git tag -s, uses user.signingkey)
|
|
12
|
+
tag_name = "v{new_version}" # e.g. v0.0.5
|
|
13
|
+
|
|
14
|
+
# Plain major.minor.patch — no pre-release / build metadata.
|
|
15
|
+
parse = '(?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)'
|
|
16
|
+
serialize = ["{major}.{minor}.{patch}"]
|
|
17
|
+
|
|
18
|
+
# --- Files kept in sync on every bump ------------------------------------
|
|
19
|
+
|
|
20
|
+
# pyproject.toml : [project] version. (The bump-my-version config lives in
|
|
21
|
+
# this separate file, so [project].version is NOT touched natively — this
|
|
22
|
+
# explicit block matches the single unambiguous line.)
|
|
23
|
+
[[tool.bumpversion.files]]
|
|
24
|
+
filename = "pyproject.toml"
|
|
25
|
+
search = 'version = "{current_version}"'
|
|
26
|
+
replace = 'version = "{new_version}"'
|
|
27
|
+
|
|
28
|
+
# uv.lock : the editable magicbox-dk package entry.
|
|
29
|
+
[[tool.bumpversion.files]]
|
|
30
|
+
filename = "uv.lock"
|
|
31
|
+
regex = true
|
|
32
|
+
search = 'name = "magicbox-dk"\nversion = "{current_version}"'
|
|
33
|
+
replace = 'name = "magicbox-dk"\nversion = "{new_version}"'
|
|
34
|
+
|
|
35
|
+
# Usage:
|
|
36
|
+
# bump-my-version bump patch # 0.0.4 -> 0.0.5
|
|
37
|
+
# bump-my-version bump minor # 0.0.4 -> 0.1.0
|
|
38
|
+
# bump-my-version bump major # 0.0.4 -> 1.0.0
|
|
39
|
+
# bump-my-version show-bump # preview the next versions
|
|
@@ -42,7 +42,8 @@ The CLI is organized in thematic sub-packages — no flat catch-all. Each packag
|
|
|
42
42
|
`INFRA_PORTS`/`INFRA_SCHEMES`/`INFRA_PATH_SUFFIXES`) AND user-configurable
|
|
43
43
|
values (instance fields : `ports` — **uniquement** `frontend_host` (port hôte unique partagé Chainlit/Horizon) +
|
|
44
44
|
`archetype_pool_start`/`_end` ;
|
|
45
|
-
`timeouts`, `docker`, `start`, `
|
|
45
|
+
`timeouts`, `docker`, `start`, `logs` (champs affichés par `dk logs` — modèle `LogDisplay`, tous `True` par défaut ;
|
|
46
|
+
conteneur + message toujours affichés), `service_repos`, `env`, `surrealdb_logins`,
|
|
46
47
|
`s3_accounts`). Type aliases `Mode`, `InfraMode`, `Section` and base class `_Strict` are exported here. Models `SurrealdbLogin` and `S3Account`
|
|
47
48
|
(credentials profiles shared across profiles) live here too. `Settings.load(yaml_path)` / `Settings.save(yaml_path)` round-trip a snapshot of
|
|
48
49
|
configurable fields to `<config_root>/settings.yaml`.
|
|
@@ -77,10 +78,12 @@ secrets, nettoyage des PID sur signaux.
|
|
|
77
78
|
Point d'entrée : `from cli.runner import docker, git` (singletons).
|
|
78
79
|
|
|
79
80
|
- `cli/runner/base.py` — `Cmd` (ABC) + `CmdError` + `CmdResult`.
|
|
80
|
-
`_run(args, *, timeout, check, capture, cwd, on_progress, progress_re)` avec 4 modes
|
|
81
|
+
`_run(args, *, timeout, check, capture, cwd, on_progress, progress_re, on_output, on_interrupt, on_line)` avec 4 modes
|
|
81
82
|
de capture : `query` (capture stdout+stderr ; echo en debug), `drain` (thread drainer anti-deadlock), `pty` (
|
|
82
83
|
pseudo-TTY pour la progression BuildKit,
|
|
83
|
-
POSIX ; fallback `drain` sur Windows), `inherit` (sortie directe, interactif).
|
|
84
|
+
POSIX ; fallback `drain` sur Windows), `inherit` (sortie directe, interactif). `on_line` (mode `drain`) : callback
|
|
85
|
+
**par ligne** au fil de l'eau, **sans** accumulation (mémoire bornée pour un flux non borné, ex. `logs --follow`
|
|
86
|
+
reformaté par `LogPrettifier`) ; préserve `drain` même en debug.
|
|
84
87
|
- `cli/runner/binaries.py` — `resolve_binary(tool)` (candidats absolus par OS → `shutil.which` fallback, cache) +
|
|
85
88
|
`sanitized_path(binary)`. Auto-détection
|
|
86
89
|
seule (pas d'override settings).
|
|
@@ -118,7 +121,7 @@ Point d'entrée : `from cli.runner import docker, git` (singletons).
|
|
|
118
121
|
schéma non autorisé). Primitives validées
|
|
119
122
|
(`status_porcelain`, `head_branch`, `rev_list_counts`…, `clone`/`fetch`/`checkout`/`pull_ff`) **et** orchestration UI
|
|
120
123
|
repliée depuis l'ancien `git_ops`
|
|
121
|
-
(`sync_repo`/`pull_repo`/`repo_status` + `RepoStatus`/`report_repo_statuses`). Consommé par `dk prepare`/`
|
|
124
|
+
(`sync_repo`/`pull_repo`/`repo_status` + `RepoStatus`/`report_repo_statuses`). Consommé par `dk prepare`/`pull`/
|
|
122
125
|
`start`.
|
|
123
126
|
|
|
124
127
|
### `cli/core/` — runtime state
|
|
@@ -176,7 +179,22 @@ All models inherit from `cli.settings._Strict` (one shared base with `extra="for
|
|
|
176
179
|
`project_built_images`/`compose_config_images`/`container_restart_counts` (parsing des sorties docker), health
|
|
177
180
|
snapshot, `wait_until_healthy`,
|
|
178
181
|
`report_compose_failure` (masque les secrets via `cli.runner.redaction`), `compute_compose_env`/`compose_env_context`,
|
|
179
|
-
`follow_logs`/`dump_logs
|
|
182
|
+
`follow_logs`/`dump_logs` (branchent la surcouche `LogPrettifier` par défaut ; `raw=True` = sortie docker brute).
|
|
183
|
+
- `cli/compose/logfmt.py` — `LogPrettifier` : **surcouche d'affichage** des logs Compose. Réassemble le JSON structuré
|
|
184
|
+
multi-lignes **par conteneur** (dé-multiplexage via les préfixes `<name> |` de `docker compose logs` ; parse en
|
|
185
|
+
`json.loads(strict=False)` — les tracebacks du champ `exception` ont de **vrais retours à la ligne**, JSON
|
|
186
|
+
techniquement
|
|
187
|
+
invalide). Le **nom du conteneur est toujours en tête** (façon `docker`), **padé à une largeur commune** (plafonnée) →
|
|
188
|
+
le `│` séparateur tombe à la **même colonne pour tous les conteneurs** et se répète en tête des lignes de
|
|
189
|
+
continuation.
|
|
190
|
+
Ligne principale (`conteneur │ heure · niveau · source sdk/module · module · fichier:ligne · fonction · extra` — méta
|
|
191
|
+
primaire ET secondaire), puis ligne(s) message **en gras** (JSON embarqué → indenté) et traceback (`│` de
|
|
192
|
+
continuation).
|
|
193
|
+
Le non-JSON (infra, watcher hot reload `dk-reload`/entrypoint en dev) est rendu au même format `conteneur │ texte`.
|
|
194
|
+
Colore par niveau ET par conteneur (couleur stable). Les champs (sauf conteneur/message) sont pilotés par
|
|
195
|
+
`settings.logs` (`LogDisplay`) — `dk settings → Logs`. Laisse passer le non-JSON (infra) en brut. Stateful : une
|
|
196
|
+
instance par flux, `feed(ligne)` branché sur le `on_line` du runner (cf. `Docker.compose_logs`), `flush()` en fin de
|
|
197
|
+
flux.
|
|
180
198
|
- `cli/compose/network.py` — ports + allocators (`find_free_port`, `port_is_free`, `allocate_api_port`, `allocate_archetype_port`), Docker naming (
|
|
181
199
|
`docker_safe_name`, `container_name`), Pydantic `Network`/`ServiceAddress`, `build_network`, `address_env_vars`, `reserved_var_names`,
|
|
182
200
|
`write_network_yaml`/`read_network_yaml`. Constants from `Settings.ports`, the CLI-managed infra ClassVars (
|
|
@@ -205,7 +223,8 @@ the top of each menu :
|
|
|
205
223
|
- `cli/editors/env.py` — `run_env_editor` (the `<entry>.yml` editor — 4 sections, secret masking, Jinja resolution
|
|
206
224
|
preview, network
|
|
207
225
|
read-only). Keyboard shortcuts a/g/i/d/D/r/?/h/b/Esc preserved.
|
|
208
|
-
- `cli/editors/settings.py` — `SettingsEditor(ctx).run()` covers Env globales, Start defaults,
|
|
226
|
+
- `cli/editors/settings.py` — `SettingsEditor(ctx).run()` covers Env globales, Start defaults, Logs (champs affichés par
|
|
227
|
+
`dk logs`), Ports, Timeouts, Docker, Infra. All editable via menus,
|
|
209
228
|
persisted via `ctx.save_settings()`.
|
|
210
229
|
- `cli/editors/_state.py` — internal helpers shared by editors (`_PendingEnv`, `_fmt_value`, diff utilities).
|
|
211
230
|
|
|
@@ -238,16 +257,16 @@ class DeleteCommand(BaseCommand):
|
|
|
238
257
|
`cli` est **l'unique méthode publique** : elle construit l'instance depuis la CLI
|
|
239
258
|
et déclenche `_dispatch()` (le cycle de vie partagé). `BaseCommand` fournit un
|
|
240
259
|
**`cli` par défaut** (classmethod `cls()._dispatch()`) : une commande **sans
|
|
241
|
-
argument** (`
|
|
260
|
+
argument** (`dashboard`, `settings`) ne redéfinit pas `cli`, elle
|
|
242
261
|
hérite du défaut (on passe `help=` au montage pour garder une description
|
|
243
|
-
distincte : `app.command("
|
|
262
|
+
distincte : `app.command("dashboard", help="…")(DashboardCommand.cli)`). Toute
|
|
244
263
|
commande avec arguments/options **redéfinit** `cli` en `@staticmethod` typée.
|
|
245
264
|
|
|
246
265
|
- `cli/commands/_base.py` — `BaseCommand` (ABC). Cycle de vie via attributs de
|
|
247
266
|
classe surchargeables : `requires_profile` (bootstrap vs bootstrap_no_profile),
|
|
248
267
|
`require_existing`, `require_prepared`, `requires_init` (False ⇒ pas de
|
|
249
268
|
`require_initialized`, ex. `init`/`dashboard`/`doctor`), `loads_context`
|
|
250
|
-
(False ⇒ aucun contexte, ex. `
|
|
269
|
+
(False ⇒ aucun contexte, ex. `update`). `_dispatch()` fait le préambule +
|
|
251
270
|
`run()`, et enveloppe `run()` d'une **frontière `CmdError`** (échec d'une
|
|
252
271
|
commande externe `check=True` → panneau d'erreur, sortie déjà masquée).
|
|
253
272
|
Helpers : `fail(msg, code=, cause=)`, `confirm(msg, yes=)`,
|
|
@@ -293,12 +312,14 @@ Verbs (with aliases) :
|
|
|
293
312
|
| `list, ls` | List profiles (`--json` supported). |
|
|
294
313
|
| `show, info [profile]` | Compact profile config view (`--json` supported). |
|
|
295
314
|
| `status, stats, ps` | Container state, section by section. |
|
|
296
|
-
| `logs [service]` | `docker compose logs
|
|
315
|
+
| `logs [service]` | `docker compose logs` reformatés/colorés (JSON structuré → 2 lignes) ; `--raw` = brut. |
|
|
297
316
|
| `shell, exec <service>` | `docker exec -it` into a container of the active profile. |
|
|
298
|
-
| `
|
|
317
|
+
| `pull, sync [name...]` | `git pull --ff-only` on clones of the active profile. |
|
|
299
318
|
| `validate [profile]` | Validate YAML (Pydantic), no side effects. |
|
|
300
319
|
| `doctor` | Check Docker, Compose, git, user structure. |
|
|
301
|
-
| `
|
|
320
|
+
| `update [--check]` | Update the CLI itself (`magicbox-dk`) from PyPI. |
|
|
321
|
+
|
|
322
|
+
The root `dk --version` (`-V`) prints the current CLI version and exits (there is no `version` sub-command).
|
|
302
323
|
|
|
303
324
|
The entrypoint `dk = "cli.main:app"` is declared in `pyproject.toml`.
|
|
304
325
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: magicbox-dk
|
|
3
|
-
Version: 0.0
|
|
3
|
+
Version: 1.0.0
|
|
4
4
|
Summary: Magicbox for help DigitalKin developpers.
|
|
5
5
|
Author-email: Alexandre TRESALLET <a.tresall@digitalkin.ai>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -41,6 +41,7 @@ stack — le tout stocké hors du repo, dans le dossier de config standard de vo
|
|
|
41
41
|
- [Settings, globals & credentials](#settings-globals--credentials)
|
|
42
42
|
- [Multi-profils](#multi-profils)
|
|
43
43
|
- [Auth git](#auth-git)
|
|
44
|
+
- [Versioning & release](#versioning--release)
|
|
44
45
|
- [Dépannage](#dépannage)
|
|
45
46
|
- [License](#license)
|
|
46
47
|
|
|
@@ -304,6 +305,66 @@ Magicbox délègue l'authentification au système : configurez votre credential
|
|
|
304
305
|
|
|
305
306
|
---
|
|
306
307
|
|
|
308
|
+
## Versioning & release
|
|
309
|
+
|
|
310
|
+
Le versionnage suit **PEP 440** : `major.minor.patch` avec un pré-release `.devN` optionnel,
|
|
311
|
+
piloté par [`bump-my-version`](https://github.com/callowayproject/bump-my-version) (config dans
|
|
312
|
+
`.bumpversion.toml`). Chaque `bump` met à jour `pyproject.toml` **et** `uv.lock`, puis **commit +
|
|
313
|
+
tag** automatiquement (`commit = true`, `tag = true`).
|
|
314
|
+
|
|
315
|
+
> Le binaire Homebrew de `bump-my-version` peut être cassé (interpréteur Python obsolète) —
|
|
316
|
+
> préfixe les commandes par `uv run` pour utiliser celui du venv.
|
|
317
|
+
|
|
318
|
+
**Règle d'or** : un `.devN` est toujours un pré-release de la **prochaine** version pas encore
|
|
319
|
+
sortie (`0.0.2.dev1 < 0.0.2`). La base `major.minor.patch` ne fait que **monter** — on ne colle
|
|
320
|
+
jamais un `.dev` sur une version déjà publiée.
|
|
321
|
+
|
|
322
|
+
### Les cas
|
|
323
|
+
|
|
324
|
+
| Cas | Commande | Exemple |
|
|
325
|
+
|-----------------------------------------------|------------------------------------|-----------------------------|
|
|
326
|
+
| **Ouvrir un cycle dev** (depuis une finale) | `bump patch` \| `minor` \| `major` | `0.0.1` → `0.0.2.dev1` |
|
|
327
|
+
| **Itérer en dev** | `bump dev` | `0.0.2.dev1` → `0.0.2.dev2` |
|
|
328
|
+
| **Passer d'une dev à la release** (finaliser) | `bump --new-version X.Y.Z` | `0.0.2.dev2` → `0.0.2` |
|
|
329
|
+
|
|
330
|
+
> `bump dev` depuis une **finale** échoue (`value 0 is lower than the first value 1`) : c'est voulu
|
|
331
|
+
> (`first_value = 1`). Depuis une finale, on ouvre le cycle avec `patch`/`minor`/`major`, jamais `dev`.
|
|
332
|
+
> Et « finaliser » (retirer le `.dev`) se fait avec `--new-version`, car un compteur `.dev` ne peut
|
|
333
|
+
> pas redescendre à 0 tout seul.
|
|
334
|
+
|
|
335
|
+
### Procédure complète (pour chaque version)
|
|
336
|
+
|
|
337
|
+
```bash
|
|
338
|
+
# 1. bump : édite pyproject.toml + uv.lock, commit + tag automatiques
|
|
339
|
+
uv run bump-my-version bump patch # 0.0.1 → 0.0.2.dev1
|
|
340
|
+
|
|
341
|
+
# 2. pousse le commit ET son tag
|
|
342
|
+
git push --follow-tags origin main
|
|
343
|
+
|
|
344
|
+
# 3. crée la GitHub Release → déclenche la publication (.github/workflows/release.yml)
|
|
345
|
+
gh release create v0.0.2.dev1 --prerelease --generate-notes # --prerelease pour un .dev
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
Exemple d'un cycle complet `0.0.1 → 0.0.2` :
|
|
349
|
+
|
|
350
|
+
```bash
|
|
351
|
+
uv run bump-my-version bump patch # 0.0.1 → 0.0.2.dev1
|
|
352
|
+
git push --follow-tags origin main
|
|
353
|
+
gh release create v0.0.2.dev1 --prerelease --generate-notes
|
|
354
|
+
|
|
355
|
+
uv run bump-my-version bump dev # 0.0.2.dev1 → 0.0.2.dev2
|
|
356
|
+
git push --follow-tags origin main
|
|
357
|
+
gh release create v0.0.2.dev2 --prerelease --generate-notes
|
|
358
|
+
|
|
359
|
+
uv run bump-my-version bump --new-version 0.0.2 # finalise : 0.0.2.dev2 → 0.0.2
|
|
360
|
+
git push --follow-tags origin main
|
|
361
|
+
gh release create v0.0.2 --generate-notes # release finale (sans --prerelease)
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
`bump-my-version show-bump` affiche à tout moment les transitions possibles depuis la version courante.
|
|
365
|
+
|
|
366
|
+
---
|
|
367
|
+
|
|
307
368
|
## Dépannage
|
|
308
369
|
|
|
309
370
|
| Symptôme | Remède |
|
|
@@ -24,6 +24,7 @@ stack — le tout stocké hors du repo, dans le dossier de config standard de vo
|
|
|
24
24
|
- [Settings, globals & credentials](#settings-globals--credentials)
|
|
25
25
|
- [Multi-profils](#multi-profils)
|
|
26
26
|
- [Auth git](#auth-git)
|
|
27
|
+
- [Versioning & release](#versioning--release)
|
|
27
28
|
- [Dépannage](#dépannage)
|
|
28
29
|
- [License](#license)
|
|
29
30
|
|
|
@@ -287,6 +288,66 @@ Magicbox délègue l'authentification au système : configurez votre credential
|
|
|
287
288
|
|
|
288
289
|
---
|
|
289
290
|
|
|
291
|
+
## Versioning & release
|
|
292
|
+
|
|
293
|
+
Le versionnage suit **PEP 440** : `major.minor.patch` avec un pré-release `.devN` optionnel,
|
|
294
|
+
piloté par [`bump-my-version`](https://github.com/callowayproject/bump-my-version) (config dans
|
|
295
|
+
`.bumpversion.toml`). Chaque `bump` met à jour `pyproject.toml` **et** `uv.lock`, puis **commit +
|
|
296
|
+
tag** automatiquement (`commit = true`, `tag = true`).
|
|
297
|
+
|
|
298
|
+
> Le binaire Homebrew de `bump-my-version` peut être cassé (interpréteur Python obsolète) —
|
|
299
|
+
> préfixe les commandes par `uv run` pour utiliser celui du venv.
|
|
300
|
+
|
|
301
|
+
**Règle d'or** : un `.devN` est toujours un pré-release de la **prochaine** version pas encore
|
|
302
|
+
sortie (`0.0.2.dev1 < 0.0.2`). La base `major.minor.patch` ne fait que **monter** — on ne colle
|
|
303
|
+
jamais un `.dev` sur une version déjà publiée.
|
|
304
|
+
|
|
305
|
+
### Les cas
|
|
306
|
+
|
|
307
|
+
| Cas | Commande | Exemple |
|
|
308
|
+
|-----------------------------------------------|------------------------------------|-----------------------------|
|
|
309
|
+
| **Ouvrir un cycle dev** (depuis une finale) | `bump patch` \| `minor` \| `major` | `0.0.1` → `0.0.2.dev1` |
|
|
310
|
+
| **Itérer en dev** | `bump dev` | `0.0.2.dev1` → `0.0.2.dev2` |
|
|
311
|
+
| **Passer d'une dev à la release** (finaliser) | `bump --new-version X.Y.Z` | `0.0.2.dev2` → `0.0.2` |
|
|
312
|
+
|
|
313
|
+
> `bump dev` depuis une **finale** échoue (`value 0 is lower than the first value 1`) : c'est voulu
|
|
314
|
+
> (`first_value = 1`). Depuis une finale, on ouvre le cycle avec `patch`/`minor`/`major`, jamais `dev`.
|
|
315
|
+
> Et « finaliser » (retirer le `.dev`) se fait avec `--new-version`, car un compteur `.dev` ne peut
|
|
316
|
+
> pas redescendre à 0 tout seul.
|
|
317
|
+
|
|
318
|
+
### Procédure complète (pour chaque version)
|
|
319
|
+
|
|
320
|
+
```bash
|
|
321
|
+
# 1. bump : édite pyproject.toml + uv.lock, commit + tag automatiques
|
|
322
|
+
uv run bump-my-version bump patch # 0.0.1 → 0.0.2.dev1
|
|
323
|
+
|
|
324
|
+
# 2. pousse le commit ET son tag
|
|
325
|
+
git push --follow-tags origin main
|
|
326
|
+
|
|
327
|
+
# 3. crée la GitHub Release → déclenche la publication (.github/workflows/release.yml)
|
|
328
|
+
gh release create v0.0.2.dev1 --prerelease --generate-notes # --prerelease pour un .dev
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
Exemple d'un cycle complet `0.0.1 → 0.0.2` :
|
|
332
|
+
|
|
333
|
+
```bash
|
|
334
|
+
uv run bump-my-version bump patch # 0.0.1 → 0.0.2.dev1
|
|
335
|
+
git push --follow-tags origin main
|
|
336
|
+
gh release create v0.0.2.dev1 --prerelease --generate-notes
|
|
337
|
+
|
|
338
|
+
uv run bump-my-version bump dev # 0.0.2.dev1 → 0.0.2.dev2
|
|
339
|
+
git push --follow-tags origin main
|
|
340
|
+
gh release create v0.0.2.dev2 --prerelease --generate-notes
|
|
341
|
+
|
|
342
|
+
uv run bump-my-version bump --new-version 0.0.2 # finalise : 0.0.2.dev2 → 0.0.2
|
|
343
|
+
git push --follow-tags origin main
|
|
344
|
+
gh release create v0.0.2 --generate-notes # release finale (sans --prerelease)
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
`bump-my-version show-bump` affiche à tout moment les transitions possibles depuis la version courante.
|
|
348
|
+
|
|
349
|
+
---
|
|
350
|
+
|
|
290
351
|
## Dépannage
|
|
291
352
|
|
|
292
353
|
| Symptôme | Remède |
|
|
@@ -21,6 +21,7 @@ est délégué à :class:`cli.ui.StepReporter` exposé via ``self.steps``.
|
|
|
21
21
|
from __future__ import annotations
|
|
22
22
|
|
|
23
23
|
import itertools
|
|
24
|
+
import sys
|
|
24
25
|
import threading
|
|
25
26
|
import time
|
|
26
27
|
from abc import ABC, abstractmethod
|
|
@@ -32,6 +33,7 @@ from typing import Annotated, Any, NoReturn, TypeVar
|
|
|
32
33
|
import questionary
|
|
33
34
|
import typer
|
|
34
35
|
|
|
36
|
+
from cli import version_check
|
|
35
37
|
from cli.core.cmd import bootstrap, bootstrap_no_profile, resolve_target
|
|
36
38
|
from cli.core.context import MagicboxContext
|
|
37
39
|
from cli.debug import dlog, set_debug, set_verbose
|
|
@@ -77,6 +79,10 @@ class BaseCommand(ABC):
|
|
|
77
79
|
#: commandes « profil courant » (``start``/``edit``/``prepare``…) gardent
|
|
78
80
|
#: ``False`` (défaut → profil actif, pas de prompt).
|
|
79
81
|
picks_profile: bool = False
|
|
82
|
+
#: ``True`` ⇒ affiche (sur stderr, TTY uniquement) une ligne d'info si une
|
|
83
|
+
#: version plus récente est publiée sur PyPI. Désactivé sur ``version`` (qui
|
|
84
|
+
#: l'affiche à sa façon) et ``update`` (c'est déjà la mise à jour du CLI).
|
|
85
|
+
notifies_upgrade: bool = True
|
|
80
86
|
|
|
81
87
|
def __init__(
|
|
82
88
|
self, profile: str | None = None, *,
|
|
@@ -119,6 +125,13 @@ class BaseCommand(ABC):
|
|
|
119
125
|
# Verbose déroule le détail des étapes (cf. ``-v/--verbose``) — posé avant
|
|
120
126
|
# tout pour couvrir aussi le préambule. ``set_debug`` est géré par bootstrap.
|
|
121
127
|
set_verbose(self.verbose)
|
|
128
|
+
# Vérif de version : uniquement en terminal interactif (jamais en
|
|
129
|
+
# script/CI/pipe). Le rafraîchissement du cache est lancé en tâche de
|
|
130
|
+
# fond ici (max de temps pour finir pendant `run`) ; la notice, lue au
|
|
131
|
+
# cache, est affichée après un `run` réussi.
|
|
132
|
+
notify_upgrade = self.notifies_upgrade and sys.stderr.isatty()
|
|
133
|
+
if notify_upgrade:
|
|
134
|
+
version_check.trigger_background_refresh()
|
|
122
135
|
if self.requires_profile:
|
|
123
136
|
self.ctx, self.profile_id = bootstrap(
|
|
124
137
|
self.profile_name,
|
|
@@ -140,6 +153,10 @@ class BaseCommand(ABC):
|
|
|
140
153
|
|
|
141
154
|
try:
|
|
142
155
|
self.run()
|
|
156
|
+
if notify_upgrade:
|
|
157
|
+
notice = version_check.notice_if_outdated()
|
|
158
|
+
if notice:
|
|
159
|
+
typer.secho(notice, fg=typer.colors.YELLOW, err=True)
|
|
143
160
|
except CmdError as exc:
|
|
144
161
|
# Échec d'une commande externe en mode ``check=True`` (git/docker).
|
|
145
162
|
# ``exc.output`` est déjà masqué des secrets par le runner.
|
|
@@ -151,7 +168,13 @@ class BaseCommand(ABC):
|
|
|
151
168
|
# sous-process encore vivants, puis on indique CLAIREMENT ce qui s'est
|
|
152
169
|
# passé (l'utilisateur ne doit pas se demander si ça tourne en fond).
|
|
153
170
|
process.terminate_all(grace=2.0)
|
|
154
|
-
|
|
171
|
+
# Le terminal a échoté ``^C`` à la position du curseur : on efface la
|
|
172
|
+
# ligne courante (retour chariot + clear) avant le panneau, sinon son
|
|
173
|
+
# cadre est décalé de 2 colonnes (TTY uniquement).
|
|
174
|
+
if sys.stdout.isatty():
|
|
175
|
+
sys.stdout.write("\r\033[K")
|
|
176
|
+
sys.stdout.flush()
|
|
177
|
+
self._render_interrupt()
|
|
155
178
|
raise typer.Exit(code=130) from None
|
|
156
179
|
|
|
157
180
|
@abstractmethod
|
|
@@ -169,6 +192,15 @@ class BaseCommand(ABC):
|
|
|
169
192
|
"""
|
|
170
193
|
return None
|
|
171
194
|
|
|
195
|
+
def _render_interrupt(self) -> None:
|
|
196
|
+
"""Panneau affiché sur Ctrl+C. Par défaut : ``⚠ Interrompu`` (jaune) + note.
|
|
197
|
+
|
|
198
|
+
Surchargeable pour changer le ton (titre / couleur / détail). Ex. ``dk
|
|
199
|
+
logs`` où Ctrl+C est la fermeture **volontaire** du flux : un panneau
|
|
200
|
+
neutre sans note suffit (cf. ``LogsCommand._render_interrupt``).
|
|
201
|
+
"""
|
|
202
|
+
self.steps.panel_warn("Interrompu", self._interrupt_note())
|
|
203
|
+
|
|
172
204
|
def resolve_target(self) -> str:
|
|
173
205
|
"""Résout le profil ciblé pour une commande à résolution manuelle.
|
|
174
206
|
|
|
@@ -14,9 +14,9 @@ import typer
|
|
|
14
14
|
import yaml
|
|
15
15
|
|
|
16
16
|
from cli.commands._base import BaseCommand
|
|
17
|
-
from cli.commands.version import package_version
|
|
18
17
|
from cli.core.context import MagicboxContext
|
|
19
18
|
from cli.ui import GREY_FG, Report, short_home_path
|
|
19
|
+
from cli.version_check import current_version
|
|
20
20
|
|
|
21
21
|
# Sous-commandes mises en avant dans le mémo de démarrage (verbe → résumé).
|
|
22
22
|
QUICK_COMMANDS: tuple[tuple[str, str], ...] = (
|
|
@@ -42,7 +42,7 @@ class DashboardCommand(BaseCommand):
|
|
|
42
42
|
# ── En-tête : titre + description ─────────────────────────────────── #
|
|
43
43
|
r.blank()
|
|
44
44
|
title = typer.style("Magicbox", fg=typer.colors.CYAN, bold=True)
|
|
45
|
-
ver = typer.style(f"v{
|
|
45
|
+
ver = typer.style(f"v{current_version()}", fg=GREY_FG)
|
|
46
46
|
typer.echo(f" {title} · {ver}")
|
|
47
47
|
r.detail(
|
|
48
48
|
"Orchestrateur d'environnements de dev pour les services & archetypes DigitalKin.",
|
|
@@ -35,14 +35,18 @@ class LogsCommand(BaseCommand):
|
|
|
35
35
|
services: list[str] | None = None,
|
|
36
36
|
follow: bool = True,
|
|
37
37
|
tail: int = 0,
|
|
38
|
+
raw: bool = False,
|
|
38
39
|
debug: bool = False,
|
|
39
40
|
) -> None:
|
|
40
41
|
super().__init__(profile, profile_id=profile_id, debug=debug)
|
|
41
42
|
self.services = list(services or [])
|
|
42
43
|
self.follow = follow
|
|
43
44
|
self.tail = tail
|
|
45
|
+
self.raw = raw
|
|
44
46
|
|
|
45
47
|
def run(self) -> None:
|
|
48
|
+
from cli.compose.logfmt import LogPrettifier
|
|
49
|
+
|
|
46
50
|
profile = load_profile(self.ctx, self.profile_id)
|
|
47
51
|
|
|
48
52
|
# Rien fourni en argument : sur un terminal interactif, on ouvre un
|
|
@@ -55,18 +59,33 @@ class LogsCommand(BaseCommand):
|
|
|
55
59
|
typer.echo("Annulé.")
|
|
56
60
|
return
|
|
57
61
|
|
|
62
|
+
# Surcouche lisible par défaut ; ``--raw`` rend la sortie docker brute.
|
|
63
|
+
# Les champs affichés suivent ``settings.logs`` (dk settings → Logs).
|
|
64
|
+
prettifier = None if self.raw else LogPrettifier(self.ctx.settings.logs)
|
|
65
|
+
on_line = prettifier.feed if prettifier is not None else None
|
|
66
|
+
|
|
58
67
|
project = self.ctx.compose_project(self.profile_id)
|
|
59
68
|
files, profiles = compose_args_for(
|
|
60
69
|
profile, self.ctx.paths.profile_overrides_dir(self.profile_id),
|
|
61
70
|
)
|
|
62
71
|
compose_env = compute_compose_env(self.ctx, profile, self.profile_id)
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
72
|
+
try:
|
|
73
|
+
with compose_env_context(compose_env):
|
|
74
|
+
docker.compose_logs(
|
|
75
|
+
project, files, profiles,
|
|
76
|
+
follow=self.follow,
|
|
77
|
+
tail=self.tail if self.tail > 0 else None,
|
|
78
|
+
services=services or None,
|
|
79
|
+
on_line=on_line,
|
|
80
|
+
)
|
|
81
|
+
finally:
|
|
82
|
+
if prettifier is not None:
|
|
83
|
+
prettifier.flush()
|
|
84
|
+
|
|
85
|
+
def _render_interrupt(self) -> None:
|
|
86
|
+
# Ctrl+C sur `dk logs` = fermeture volontaire du flux, pas un incident :
|
|
87
|
+
# panneau neutre « Interrompu » sans description (couleur ≠ jaune d'alerte).
|
|
88
|
+
self.steps.panel_info("Interrompu")
|
|
70
89
|
|
|
71
90
|
@staticmethod
|
|
72
91
|
def cli(
|
|
@@ -95,12 +114,19 @@ class LogsCommand(BaseCommand):
|
|
|
95
114
|
int,
|
|
96
115
|
typer.Option("--tail", "-n", help="Lignes depuis la fin."),
|
|
97
116
|
] = 0,
|
|
117
|
+
raw: Annotated[
|
|
118
|
+
bool,
|
|
119
|
+
typer.Option("--raw", help="Sortie docker brute (désactive la mise en forme lisible)."),
|
|
120
|
+
] = False,
|
|
98
121
|
debug: Annotated[
|
|
99
122
|
bool,
|
|
100
123
|
typer.Option("--debug", "-d", help="Logs détaillés."),
|
|
101
124
|
] = False,
|
|
102
125
|
) -> None:
|
|
103
|
-
"""Suit les logs Compose du profil
|
|
126
|
+
"""Suit les logs Compose du profil, reformatés pour la lisibilité.
|
|
127
|
+
|
|
128
|
+
Les logs JSON structurés des modules sont recomposés en deux lignes
|
|
129
|
+
(méta colorée + message) ; ``--raw`` rend la sortie docker brute.
|
|
104
130
|
|
|
105
131
|
``dk logs`` sans argument ouvre un menu multi-sélection des services
|
|
106
132
|
(ou « Tous ») sur un terminal interactif. ``dk logs back node-service-provider``
|
|
@@ -108,7 +134,7 @@ class LogsCommand(BaseCommand):
|
|
|
108
134
|
"""
|
|
109
135
|
LogsCommand(
|
|
110
136
|
profile_name, profile_id=profile_id, services=services, follow=follow,
|
|
111
|
-
tail=tail, debug=debug,
|
|
137
|
+
tail=tail, raw=raw, debug=debug,
|
|
112
138
|
)._dispatch()
|
|
113
139
|
|
|
114
140
|
|