xgic-payload-cms-cli 0.2.1__tar.gz → 0.2.2__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.
- {xgic_payload_cms_cli-0.2.1 → xgic_payload_cms_cli-0.2.2}/PKG-INFO +15 -8
- {xgic_payload_cms_cli-0.2.1 → xgic_payload_cms_cli-0.2.2}/README.md +14 -7
- {xgic_payload_cms_cli-0.2.1 → xgic_payload_cms_cli-0.2.2}/pyproject.toml +1 -1
- {xgic_payload_cms_cli-0.2.1 → xgic_payload_cms_cli-0.2.2}/src/xgic/cli/payload/__init__.py +3 -1
- {xgic_payload_cms_cli-0.2.1 → xgic_payload_cms_cli-0.2.2}/src/xgic/cli/payload/commands/dev.py +2 -2
- {xgic_payload_cms_cli-0.2.1 → xgic_payload_cms_cli-0.2.2}/src/xgic/cli/payload/config.py +62 -1
- {xgic_payload_cms_cli-0.2.1 → xgic_payload_cms_cli-0.2.2}/src/xgic/cli/payload/project.py +16 -11
- {xgic_payload_cms_cli-0.2.1 → xgic_payload_cms_cli-0.2.2}/.gitignore +0 -0
- {xgic_payload_cms_cli-0.2.1 → xgic_payload_cms_cli-0.2.2}/LICENSE +0 -0
- {xgic_payload_cms_cli-0.2.1 → xgic_payload_cms_cli-0.2.2}/NOTICE +0 -0
- {xgic_payload_cms_cli-0.2.1 → xgic_payload_cms_cli-0.2.2}/src/xgic/cli/payload/commands/__init__.py +0 -0
- {xgic_payload_cms_cli-0.2.1 → xgic_payload_cms_cli-0.2.2}/src/xgic/cli/payload/commands/payload_env.py +0 -0
- {xgic_payload_cms_cli-0.2.1 → xgic_payload_cms_cli-0.2.2}/src/xgic/cli/payload/commands/reset.py +0 -0
- {xgic_payload_cms_cli-0.2.1 → xgic_payload_cms_cli-0.2.2}/src/xgic/cli/payload/commands/schema.py +0 -0
- {xgic_payload_cms_cli-0.2.1 → xgic_payload_cms_cli-0.2.2}/src/xgic/cli/payload/commands/setup.py +0 -0
- {xgic_payload_cms_cli-0.2.1 → xgic_payload_cms_cli-0.2.2}/src/xgic/cli/payload/env_helpers.py +0 -0
- {xgic_payload_cms_cli-0.2.1 → xgic_payload_cms_cli-0.2.2}/src/xgic/cli/payload/layout.py +0 -0
- {xgic_payload_cms_cli-0.2.1 → xgic_payload_cms_cli-0.2.2}/src/xgic/cli/payload/plugin.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: xgic-payload-cms-cli
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: XGIC CLI Payload CMS module - product commands and helpers (xgic.cli.payload).
|
|
5
5
|
Project-URL: Homepage, https://github.com/xgic/payload-cms-cli
|
|
6
6
|
Project-URL: Repository, https://github.com/xgic/payload-cms-cli
|
|
@@ -90,7 +90,7 @@ One brand (`xgic`), clear ownership, and dry-run-friendly destructive paths.
|
|
|
90
90
|
uv pip install \
|
|
91
91
|
"xgic-cli>=0.2.0,<0.3" \
|
|
92
92
|
"xgic-dev-cli>=0.2.0,<0.3" \
|
|
93
|
-
"xgic-payload-cms-cli>=0.2.
|
|
93
|
+
"xgic-payload-cms-cli>=0.2.2,<0.3"
|
|
94
94
|
xgic payload --help
|
|
95
95
|
```
|
|
96
96
|
|
|
@@ -105,14 +105,21 @@ xgic payload --help
|
|
|
105
105
|
|
|
106
106
|
### Typical Payload session (inside a Dev Container)
|
|
107
107
|
|
|
108
|
+
**First session** (one setup command — creates `.devcontainer/.env` if missing, starts the DB profile, scaffolds the app):
|
|
109
|
+
|
|
108
110
|
```bash
|
|
109
|
-
xgic
|
|
110
|
-
xgic payload env --regenerate --yes # once
|
|
111
|
-
xgic payload setup # scaffold app (layout from config)
|
|
112
|
-
xgic up --profile postgres # DB if needed
|
|
111
|
+
xgic payload setup
|
|
113
112
|
xgic payload dev
|
|
114
113
|
```
|
|
115
114
|
|
|
115
|
+
**Daily** (after the app exists):
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
xgic payload dev
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Optional: `xgic payload env` (status), `xgic payload env --regenerate --yes` (rotate credentials only — not required for first setup).
|
|
122
|
+
|
|
116
123
|
Prefer the end-user template for application work: [payload-cms](https://github.com/xgic/payload-cms).
|
|
117
124
|
|
|
118
125
|
---
|
|
@@ -124,9 +131,9 @@ All product commands nest under **`xgic payload`**:
|
|
|
124
131
|
| Command | Purpose |
|
|
125
132
|
|---------|---------|
|
|
126
133
|
| `xgic payload dev` | **Primary daily command** — smart start (up if needed, DB check, `pnpm dev`) |
|
|
127
|
-
| `xgic payload setup [--quiet]` |
|
|
134
|
+
| `xgic payload setup [--quiet]` | **First-run one-shot:** env (if missing) + DB profile + scaffold (idempotent) |
|
|
128
135
|
| `xgic payload env [--json]` | Product env status (project name, `.env`, services) |
|
|
129
|
-
| `xgic payload env --regenerate --yes` |
|
|
136
|
+
| `xgic payload env --regenerate --yes` | Rotate credentials in `.devcontainer/.env` (optional; setup creates env when absent) |
|
|
130
137
|
| `xgic payload schema` | Run template schema generator when present |
|
|
131
138
|
| `xgic payload reset` | Fast targeted reset (project folder + active DB volume) |
|
|
132
139
|
|
|
@@ -55,7 +55,7 @@ One brand (`xgic`), clear ownership, and dry-run-friendly destructive paths.
|
|
|
55
55
|
uv pip install \
|
|
56
56
|
"xgic-cli>=0.2.0,<0.3" \
|
|
57
57
|
"xgic-dev-cli>=0.2.0,<0.3" \
|
|
58
|
-
"xgic-payload-cms-cli>=0.2.
|
|
58
|
+
"xgic-payload-cms-cli>=0.2.2,<0.3"
|
|
59
59
|
xgic payload --help
|
|
60
60
|
```
|
|
61
61
|
|
|
@@ -70,14 +70,21 @@ xgic payload --help
|
|
|
70
70
|
|
|
71
71
|
### Typical Payload session (inside a Dev Container)
|
|
72
72
|
|
|
73
|
+
**First session** (one setup command — creates `.devcontainer/.env` if missing, starts the DB profile, scaffolds the app):
|
|
74
|
+
|
|
73
75
|
```bash
|
|
74
|
-
xgic
|
|
75
|
-
xgic payload env --regenerate --yes # once
|
|
76
|
-
xgic payload setup # scaffold app (layout from config)
|
|
77
|
-
xgic up --profile postgres # DB if needed
|
|
76
|
+
xgic payload setup
|
|
78
77
|
xgic payload dev
|
|
79
78
|
```
|
|
80
79
|
|
|
80
|
+
**Daily** (after the app exists):
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
xgic payload dev
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Optional: `xgic payload env` (status), `xgic payload env --regenerate --yes` (rotate credentials only — not required for first setup).
|
|
87
|
+
|
|
81
88
|
Prefer the end-user template for application work: [payload-cms](https://github.com/xgic/payload-cms).
|
|
82
89
|
|
|
83
90
|
---
|
|
@@ -89,9 +96,9 @@ All product commands nest under **`xgic payload`**:
|
|
|
89
96
|
| Command | Purpose |
|
|
90
97
|
|---------|---------|
|
|
91
98
|
| `xgic payload dev` | **Primary daily command** — smart start (up if needed, DB check, `pnpm dev`) |
|
|
92
|
-
| `xgic payload setup [--quiet]` |
|
|
99
|
+
| `xgic payload setup [--quiet]` | **First-run one-shot:** env (if missing) + DB profile + scaffold (idempotent) |
|
|
93
100
|
| `xgic payload env [--json]` | Product env status (project name, `.env`, services) |
|
|
94
|
-
| `xgic payload env --regenerate --yes` |
|
|
101
|
+
| `xgic payload env --regenerate --yes` | Rotate credentials in `.devcontainer/.env` (optional; setup creates env when absent) |
|
|
95
102
|
| `xgic payload schema` | Run template schema generator when present |
|
|
96
103
|
| `xgic payload reset` | Fast targeted reset (project folder + active DB volume) |
|
|
97
104
|
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "xgic-payload-cms-cli"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.2"
|
|
8
8
|
description = "XGIC CLI Payload CMS module - product commands and helpers (xgic.cli.payload)."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "Apache-2.0" }
|
|
@@ -5,6 +5,7 @@ from xgic.cli.payload.config import (
|
|
|
5
5
|
DEFAULT_CONFIG_FILE,
|
|
6
6
|
DEFAULT_PRIMARY_SERVICE,
|
|
7
7
|
db_ready,
|
|
8
|
+
get_compose_project_name,
|
|
8
9
|
get_db_config,
|
|
9
10
|
get_db_profile,
|
|
10
11
|
get_payload_project_name,
|
|
@@ -20,7 +21,7 @@ from xgic.cli.payload.project import (
|
|
|
20
21
|
load_create_payload_config,
|
|
21
22
|
)
|
|
22
23
|
|
|
23
|
-
__version__ = "0.2.
|
|
24
|
+
__version__ = "0.2.2"
|
|
24
25
|
|
|
25
26
|
__all__ = [
|
|
26
27
|
"DEFAULT_COMPOSE_PROJECT",
|
|
@@ -30,6 +31,7 @@ __all__ = [
|
|
|
30
31
|
"db_ready",
|
|
31
32
|
"ensure_payload_project",
|
|
32
33
|
"generate_fresh_env_content",
|
|
34
|
+
"get_compose_project_name",
|
|
33
35
|
"get_db_config",
|
|
34
36
|
"get_db_profile",
|
|
35
37
|
"get_payload_project_name",
|
{xgic_payload_cms_cli-0.2.1 → xgic_payload_cms_cli-0.2.2}/src/xgic/cli/payload/commands/dev.py
RENAMED
|
@@ -8,9 +8,9 @@ from pathlib import Path
|
|
|
8
8
|
from xgic.cli.app import CommandContext
|
|
9
9
|
from xgic.cli.core.environment import EnvironmentType
|
|
10
10
|
from xgic.cli.payload.config import (
|
|
11
|
-
DEFAULT_COMPOSE_PROJECT,
|
|
12
11
|
DEFAULT_PRIMARY_SERVICE,
|
|
13
12
|
db_ready,
|
|
13
|
+
get_compose_project_name,
|
|
14
14
|
get_db_profile,
|
|
15
15
|
make_payload_docker_controller,
|
|
16
16
|
)
|
|
@@ -49,7 +49,7 @@ def run_dev(ctx: CommandContext) -> int:
|
|
|
49
49
|
print_info(f"App location: {display_project_location(project_dir)}")
|
|
50
50
|
|
|
51
51
|
docker = make_payload_docker_controller(env)
|
|
52
|
-
docker.project_name =
|
|
52
|
+
docker.project_name = get_compose_project_name()
|
|
53
53
|
profile = get_db_profile()
|
|
54
54
|
|
|
55
55
|
# Never recreate the primary Dev Container service; only ensure DB.
|
|
@@ -35,6 +35,67 @@ def get_payload_project_name(
|
|
|
35
35
|
return "my-payload-cms"
|
|
36
36
|
|
|
37
37
|
|
|
38
|
+
def _is_compose_safe_name(name: str) -> bool:
|
|
39
|
+
"""Return True if *name* looks safe for Docker Compose project names."""
|
|
40
|
+
if not name or not name[0].isalnum():
|
|
41
|
+
return False
|
|
42
|
+
return all(c.isalnum() or c in "_-" for c in name) and len(name) <= 63
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _compose_name_from_file(
|
|
46
|
+
compose_path: Path = Path(DEFAULT_COMPOSE_FILE),
|
|
47
|
+
) -> str | None:
|
|
48
|
+
"""Parse top-level ``name:`` from a Compose file (best-effort)."""
|
|
49
|
+
if not compose_path.is_file():
|
|
50
|
+
return None
|
|
51
|
+
try:
|
|
52
|
+
for line in compose_path.read_text(encoding="utf-8").splitlines():
|
|
53
|
+
stripped = line.strip()
|
|
54
|
+
if stripped.startswith("#") or not stripped.startswith("name:"):
|
|
55
|
+
continue
|
|
56
|
+
raw = stripped.split(":", 1)[1].strip().strip("\"'")
|
|
57
|
+
if raw and _is_compose_safe_name(raw.lower()):
|
|
58
|
+
return raw.lower()
|
|
59
|
+
except OSError:
|
|
60
|
+
return None
|
|
61
|
+
return None
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def get_compose_project_name(
|
|
65
|
+
config_file: Path = DEFAULT_CONFIG_FILE,
|
|
66
|
+
) -> str:
|
|
67
|
+
"""Return Docker Compose project name for this workspace.
|
|
68
|
+
|
|
69
|
+
Precedence:
|
|
70
|
+
1. ``XGIC_COMPOSE_PROJECT`` environment variable
|
|
71
|
+
2. ``composeProjectName`` in create-payload-config.json
|
|
72
|
+
3. Top-level ``name:`` in ``.devcontainer/docker-compose.yml``
|
|
73
|
+
4. ``DEFAULT_COMPOSE_PROJECT`` (producer template default)
|
|
74
|
+
"""
|
|
75
|
+
import os
|
|
76
|
+
|
|
77
|
+
env_name = os.environ.get("XGIC_COMPOSE_PROJECT", "").strip().lower()
|
|
78
|
+
if env_name and _is_compose_safe_name(env_name):
|
|
79
|
+
return env_name
|
|
80
|
+
|
|
81
|
+
if config_file.exists():
|
|
82
|
+
try:
|
|
83
|
+
with open(config_file, encoding="utf-8") as f:
|
|
84
|
+
data: dict[str, Any] = json.load(f)
|
|
85
|
+
raw = data.get("composeProjectName")
|
|
86
|
+
if isinstance(raw, str) and raw.strip():
|
|
87
|
+
name = raw.strip().lower()
|
|
88
|
+
if _is_compose_safe_name(name):
|
|
89
|
+
return name
|
|
90
|
+
except (json.JSONDecodeError, OSError):
|
|
91
|
+
pass
|
|
92
|
+
|
|
93
|
+
from_file = _compose_name_from_file()
|
|
94
|
+
if from_file:
|
|
95
|
+
return from_file
|
|
96
|
+
|
|
97
|
+
return DEFAULT_COMPOSE_PROJECT
|
|
98
|
+
|
|
38
99
|
def get_payload_project_dir(
|
|
39
100
|
config_file: Path = DEFAULT_CONFIG_FILE,
|
|
40
101
|
) -> Path:
|
|
@@ -101,7 +162,7 @@ def make_payload_docker_controller(
|
|
|
101
162
|
return DockerComposeController(
|
|
102
163
|
env=env,
|
|
103
164
|
compose_file=DEFAULT_COMPOSE_FILE,
|
|
104
|
-
project_name=
|
|
165
|
+
project_name=get_compose_project_name(),
|
|
105
166
|
primary_service=DEFAULT_PRIMARY_SERVICE,
|
|
106
167
|
)
|
|
107
168
|
|
|
@@ -13,9 +13,9 @@ from typing import Any
|
|
|
13
13
|
|
|
14
14
|
from xgic.cli.payload.config import (
|
|
15
15
|
DEFAULT_COMPOSE_FILE,
|
|
16
|
-
DEFAULT_COMPOSE_PROJECT,
|
|
17
16
|
DEFAULT_CONFIG_FILE,
|
|
18
17
|
db_ready,
|
|
18
|
+
get_compose_project_name,
|
|
19
19
|
get_db_profile,
|
|
20
20
|
make_payload_docker_controller,
|
|
21
21
|
)
|
|
@@ -35,6 +35,7 @@ def load_create_payload_config(
|
|
|
35
35
|
"projectName": "my-payload-cms",
|
|
36
36
|
"projectDir": None,
|
|
37
37
|
"layout": "auto",
|
|
38
|
+
"composeProjectName": None,
|
|
38
39
|
"template": "website",
|
|
39
40
|
"dbAdapter": "postgres",
|
|
40
41
|
"agent": "none",
|
|
@@ -269,9 +270,8 @@ def ensure_db_services(*, quiet: bool = False, wait_seconds: float = 45.0) -> in
|
|
|
269
270
|
|
|
270
271
|
env = EnvironmentContext.detect()
|
|
271
272
|
docker = make_payload_docker_controller(env)
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
docker.project_name = DEFAULT_COMPOSE_PROJECT
|
|
273
|
+
compose_project = get_compose_project_name()
|
|
274
|
+
docker.project_name = compose_project
|
|
275
275
|
profile = get_db_profile()
|
|
276
276
|
|
|
277
277
|
if db_ready(docker):
|
|
@@ -281,11 +281,14 @@ def ensure_db_services(*, quiet: bool = False, wait_seconds: float = 45.0) -> in
|
|
|
281
281
|
|
|
282
282
|
if not quiet:
|
|
283
283
|
print_info(
|
|
284
|
-
f"Starting database service only:
|
|
285
|
-
f"
|
|
284
|
+
f"Starting database service only: service={profile!r} "
|
|
285
|
+
f"(project {compose_project!r})"
|
|
286
286
|
)
|
|
287
287
|
try:
|
|
288
|
-
|
|
288
|
+
# Start the named service without forcing --profile. Services that use
|
|
289
|
+
# profiles still start when listed by name if already enabled; services
|
|
290
|
+
# without profiles (e.g. always-on postgres) work without a profile flag.
|
|
291
|
+
docker.up(services=[profile])
|
|
289
292
|
except FileNotFoundError:
|
|
290
293
|
print_warning(
|
|
291
294
|
"docker not found. Run setup inside the Dev Container "
|
|
@@ -329,15 +332,17 @@ def ensure_payload_project(*, quiet: bool = False) -> int:
|
|
|
329
332
|
project_dir = resolve_project_dir(cfg)
|
|
330
333
|
target = create_payload_target_arg(project_dir)
|
|
331
334
|
|
|
335
|
+
# First-run: create .devcontainer/.env when missing (no separate
|
|
336
|
+
# `xgic payload env --regenerate --yes` step required).
|
|
332
337
|
env_rc = ensure_devcontainer_env(quiet=quiet)
|
|
333
338
|
if env_rc != 0:
|
|
334
339
|
return env_rc
|
|
335
340
|
|
|
336
|
-
#
|
|
337
|
-
|
|
338
|
-
if sync_compose_project_name(
|
|
341
|
+
# Compose project name from config (composeProjectName), not npm projectName.
|
|
342
|
+
compose_project = get_compose_project_name()
|
|
343
|
+
if sync_compose_project_name(compose_project) and not quiet:
|
|
339
344
|
print_info(
|
|
340
|
-
f"Docker Compose project name set to {
|
|
345
|
+
f"Docker Compose project name set to {compose_project!r} "
|
|
341
346
|
f"in {DEFAULT_COMPOSE_FILE}"
|
|
342
347
|
)
|
|
343
348
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{xgic_payload_cms_cli-0.2.1 → xgic_payload_cms_cli-0.2.2}/src/xgic/cli/payload/commands/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{xgic_payload_cms_cli-0.2.1 → xgic_payload_cms_cli-0.2.2}/src/xgic/cli/payload/commands/reset.py
RENAMED
|
File without changes
|
{xgic_payload_cms_cli-0.2.1 → xgic_payload_cms_cli-0.2.2}/src/xgic/cli/payload/commands/schema.py
RENAMED
|
File without changes
|
{xgic_payload_cms_cli-0.2.1 → xgic_payload_cms_cli-0.2.2}/src/xgic/cli/payload/commands/setup.py
RENAMED
|
File without changes
|
{xgic_payload_cms_cli-0.2.1 → xgic_payload_cms_cli-0.2.2}/src/xgic/cli/payload/env_helpers.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|