xgic-payload-cms-cli 0.2.4__tar.gz → 0.2.5__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.4 → xgic_payload_cms_cli-0.2.5}/PKG-INFO +2 -2
- {xgic_payload_cms_cli-0.2.4 → xgic_payload_cms_cli-0.2.5}/README.md +1 -1
- {xgic_payload_cms_cli-0.2.4 → xgic_payload_cms_cli-0.2.5}/pyproject.toml +1 -1
- {xgic_payload_cms_cli-0.2.4 → xgic_payload_cms_cli-0.2.5}/src/xgic/cli/payload/__init__.py +1 -1
- {xgic_payload_cms_cli-0.2.4 → xgic_payload_cms_cli-0.2.5}/src/xgic/cli/payload/commands/reset.py +30 -10
- {xgic_payload_cms_cli-0.2.4 → xgic_payload_cms_cli-0.2.5}/src/xgic/cli/payload/config.py +5 -1
- {xgic_payload_cms_cli-0.2.4 → xgic_payload_cms_cli-0.2.5}/src/xgic/cli/payload/env_helpers.py +5 -0
- {xgic_payload_cms_cli-0.2.4 → xgic_payload_cms_cli-0.2.5}/src/xgic/cli/payload/layout.py +6 -1
- {xgic_payload_cms_cli-0.2.4 → xgic_payload_cms_cli-0.2.5}/src/xgic/cli/payload/project.py +49 -4
- {xgic_payload_cms_cli-0.2.4 → xgic_payload_cms_cli-0.2.5}/.gitignore +0 -0
- {xgic_payload_cms_cli-0.2.4 → xgic_payload_cms_cli-0.2.5}/LICENSE +0 -0
- {xgic_payload_cms_cli-0.2.4 → xgic_payload_cms_cli-0.2.5}/NOTICE +0 -0
- {xgic_payload_cms_cli-0.2.4 → xgic_payload_cms_cli-0.2.5}/src/xgic/cli/payload/commands/__init__.py +0 -0
- {xgic_payload_cms_cli-0.2.4 → xgic_payload_cms_cli-0.2.5}/src/xgic/cli/payload/commands/dev.py +0 -0
- {xgic_payload_cms_cli-0.2.4 → xgic_payload_cms_cli-0.2.5}/src/xgic/cli/payload/commands/payload_env.py +0 -0
- {xgic_payload_cms_cli-0.2.4 → xgic_payload_cms_cli-0.2.5}/src/xgic/cli/payload/commands/schema.py +0 -0
- {xgic_payload_cms_cli-0.2.4 → xgic_payload_cms_cli-0.2.5}/src/xgic/cli/payload/commands/setup.py +0 -0
- {xgic_payload_cms_cli-0.2.4 → xgic_payload_cms_cli-0.2.5}/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.5
|
|
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.5,<0.3"
|
|
94
94
|
xgic payload --help
|
|
95
95
|
```
|
|
96
96
|
|
|
@@ -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.5,<0.3"
|
|
59
59
|
xgic payload --help
|
|
60
60
|
```
|
|
61
61
|
|
|
@@ -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.5"
|
|
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" }
|
{xgic_payload_cms_cli-0.2.4 → xgic_payload_cms_cli-0.2.5}/src/xgic/cli/payload/commands/reset.py
RENAMED
|
@@ -3,23 +3,31 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import shutil
|
|
6
|
-
from pathlib import Path
|
|
7
6
|
|
|
8
7
|
from xgic.cli.app import CommandContext
|
|
9
8
|
from xgic.cli.payload.config import (
|
|
10
9
|
get_db_config,
|
|
11
10
|
get_db_profile,
|
|
12
|
-
get_payload_project_name,
|
|
13
11
|
make_payload_docker_controller,
|
|
14
12
|
)
|
|
15
13
|
from xgic.cli.payload.env_helpers import perform_env_regenerate
|
|
16
|
-
from xgic.cli.payload.
|
|
14
|
+
from xgic.cli.payload.layout import (
|
|
15
|
+
display_project_location,
|
|
16
|
+
is_workspace_root,
|
|
17
|
+
resolve_project_dir,
|
|
18
|
+
)
|
|
19
|
+
from xgic.cli.payload.project import (
|
|
20
|
+
ensure_payload_project,
|
|
21
|
+
load_create_payload_config,
|
|
22
|
+
)
|
|
17
23
|
from xgic.cli.utils.output import print_info, print_success, print_warning
|
|
18
24
|
|
|
19
25
|
|
|
20
26
|
def run_reset(ctx: CommandContext) -> int:
|
|
21
27
|
"""Delete generated project folder and reset the active DB volume.
|
|
22
28
|
|
|
29
|
+
Uses ``projectDir`` (same resolver as setup), not ``projectName``.
|
|
30
|
+
App-root layout (workspace ``.``) is never ``rmtree``'d.
|
|
23
31
|
Credentials in ``.env`` are left alone unless ``--rotate-credentials``.
|
|
24
32
|
"""
|
|
25
33
|
dry_run = bool(getattr(ctx.args, "dry_run", False))
|
|
@@ -27,13 +35,20 @@ def run_reset(ctx: CommandContext) -> int:
|
|
|
27
35
|
rotate = bool(getattr(ctx.args, "rotate_credentials", False))
|
|
28
36
|
|
|
29
37
|
docker = make_payload_docker_controller(ctx.env)
|
|
30
|
-
|
|
31
|
-
|
|
38
|
+
project_dir = resolve_project_dir(load_create_payload_config())
|
|
39
|
+
skip_dir = is_workspace_root(project_dir)
|
|
40
|
+
location = display_project_location(project_dir)
|
|
32
41
|
db_service = get_db_profile()
|
|
33
42
|
db_volume = docker.db_volume_name(db_service)
|
|
34
43
|
|
|
35
44
|
print_info("Planned actions for reset:")
|
|
36
|
-
|
|
45
|
+
if skip_dir:
|
|
46
|
+
print_info(
|
|
47
|
+
" - Skip project directory delete "
|
|
48
|
+
f"({location} is the workspace; not removing .git / .devcontainer)"
|
|
49
|
+
)
|
|
50
|
+
else:
|
|
51
|
+
print_info(f" - Delete directory: {location}")
|
|
37
52
|
print_info(f" - Remove Docker volume: {db_volume}")
|
|
38
53
|
if rotate:
|
|
39
54
|
print_warning(" - ALSO rotate database credentials (DANGEROUS)")
|
|
@@ -50,11 +65,16 @@ def run_reset(ctx: CommandContext) -> int:
|
|
|
50
65
|
|
|
51
66
|
print_info("Performing reset...")
|
|
52
67
|
|
|
53
|
-
if
|
|
54
|
-
|
|
55
|
-
|
|
68
|
+
if skip_dir:
|
|
69
|
+
print_info(
|
|
70
|
+
"App-root layout: left workspace files in place. "
|
|
71
|
+
"Remove generated app sources manually if you need a clean scaffold."
|
|
72
|
+
)
|
|
73
|
+
elif project_dir.exists():
|
|
74
|
+
shutil.rmtree(project_dir)
|
|
75
|
+
print_success(f"Deleted project directory: {location}")
|
|
56
76
|
else:
|
|
57
|
-
print_info(f"Project directory {
|
|
77
|
+
print_info(f"Project directory {location} did not exist.")
|
|
58
78
|
|
|
59
79
|
docker.rm_service(db_service, force=True, stop=True, remove_volumes=False)
|
|
60
80
|
|
|
@@ -191,8 +191,10 @@ def db_ready(
|
|
|
191
191
|
except Exception:
|
|
192
192
|
return False
|
|
193
193
|
|
|
194
|
-
|
|
194
|
+
db_name, db_user = get_db_config(config_file)
|
|
195
195
|
try:
|
|
196
|
+
# -d is required: libpq defaults the database name to the user
|
|
197
|
+
# (POSTGRES_USER=payload) while POSTGRES_DB is payload_db.
|
|
196
198
|
result = docker._run_compose( # noqa: SLF001
|
|
197
199
|
"exec",
|
|
198
200
|
"-T",
|
|
@@ -200,6 +202,8 @@ def db_ready(
|
|
|
200
202
|
"pg_isready",
|
|
201
203
|
"-U",
|
|
202
204
|
db_user,
|
|
205
|
+
"-d",
|
|
206
|
+
db_name,
|
|
203
207
|
capture_output=True,
|
|
204
208
|
check=False,
|
|
205
209
|
)
|
{xgic_payload_cms_cli-0.2.4 → xgic_payload_cms_cli-0.2.5}/src/xgic/cli/payload/env_helpers.py
RENAMED
|
@@ -53,9 +53,14 @@ DATABASE_URL=mongodb://{db_user}:{mongo_pass}@mongodb:27017/{db_name}?authSource
|
|
|
53
53
|
"""
|
|
54
54
|
|
|
55
55
|
pg_pass = secrets.token_hex(16)
|
|
56
|
+
# PGUSER/PGDATABASE are libpq defaults. Without them, `pg_isready -U payload`
|
|
57
|
+
# and other clients open a database named after the user (`payload`) while
|
|
58
|
+
# POSTGRES_DB is `payload_db`.
|
|
56
59
|
return f"""POSTGRES_USER={db_user}
|
|
57
60
|
POSTGRES_PASSWORD={pg_pass}
|
|
58
61
|
POSTGRES_DB={db_name}
|
|
62
|
+
PGUSER={db_user}
|
|
63
|
+
PGDATABASE={db_name}
|
|
59
64
|
PAYLOAD_SECRET={payload_secret}
|
|
60
65
|
DATABASE_URL=postgres://{db_user}:{pg_pass}@postgres:5432/{db_name}
|
|
61
66
|
"""
|
|
@@ -83,8 +83,13 @@ def create_payload_target_arg(project_dir: Path) -> str:
|
|
|
83
83
|
return project_dir.as_posix().strip("/")
|
|
84
84
|
|
|
85
85
|
|
|
86
|
+
def is_workspace_root(project_dir: Path) -> bool:
|
|
87
|
+
"""Return True when *project_dir* is the workspace root (app-root layout)."""
|
|
88
|
+
return project_dir == Path(".") or str(project_dir).strip() in (".", "./", "")
|
|
89
|
+
|
|
90
|
+
|
|
86
91
|
def display_project_location(project_dir: Path) -> str:
|
|
87
92
|
"""Human-readable location for logs."""
|
|
88
|
-
if project_dir
|
|
93
|
+
if is_workspace_root(project_dir):
|
|
89
94
|
return "workspace root (.)"
|
|
90
95
|
return f"{project_dir.as_posix()}/"
|
|
@@ -100,6 +100,25 @@ def pnpx_allow_build_args(
|
|
|
100
100
|
return [f"--allow-build={name}" for name in packages]
|
|
101
101
|
|
|
102
102
|
|
|
103
|
+
def detect_pnpm_major() -> int | None:
|
|
104
|
+
"""Return the major version of ``pnpm`` on PATH, or None if unknown."""
|
|
105
|
+
try:
|
|
106
|
+
result = subprocess.run(
|
|
107
|
+
["pnpm", "--version"],
|
|
108
|
+
check=False,
|
|
109
|
+
capture_output=True,
|
|
110
|
+
text=True,
|
|
111
|
+
)
|
|
112
|
+
except OSError:
|
|
113
|
+
return None
|
|
114
|
+
if result.returncode != 0:
|
|
115
|
+
return None
|
|
116
|
+
first = result.stdout.strip().split(".", 1)[0]
|
|
117
|
+
if first.isdigit():
|
|
118
|
+
return int(first)
|
|
119
|
+
return None
|
|
120
|
+
|
|
121
|
+
|
|
103
122
|
def merge_package_json_only_built(
|
|
104
123
|
text: str, names: tuple[str, ...] = NATIVE_PNPM_BUILDS
|
|
105
124
|
) -> str:
|
|
@@ -117,6 +136,20 @@ def merge_package_json_only_built(
|
|
|
117
136
|
return json.dumps(data, indent=2) + "\n"
|
|
118
137
|
|
|
119
138
|
|
|
139
|
+
def strip_package_json_only_built(text: str) -> str:
|
|
140
|
+
"""Remove ``pnpm.onlyBuiltDependencies`` (pnpm 11+ ignores that field)."""
|
|
141
|
+
data = json.loads(text)
|
|
142
|
+
pnpm = data.get("pnpm")
|
|
143
|
+
if not isinstance(pnpm, dict) or "onlyBuiltDependencies" not in pnpm:
|
|
144
|
+
return text
|
|
145
|
+
pnpm.pop("onlyBuiltDependencies", None)
|
|
146
|
+
if pnpm:
|
|
147
|
+
data["pnpm"] = pnpm
|
|
148
|
+
else:
|
|
149
|
+
data.pop("pnpm", None)
|
|
150
|
+
return json.dumps(data, indent=2) + "\n"
|
|
151
|
+
|
|
152
|
+
|
|
120
153
|
def yaml_map_key(name: str) -> str:
|
|
121
154
|
"""Quote YAML mapping keys that are not plain scalars (e.g. ``@swc/core``)."""
|
|
122
155
|
if not name or name[0] in "@`&*!|>%{}[]'\"" or any(
|
|
@@ -179,20 +212,32 @@ def merge_workspace_allow_builds(
|
|
|
179
212
|
def ensure_native_pnpm_builds(
|
|
180
213
|
project_dir: Path, *, quiet: bool = False
|
|
181
214
|
) -> None:
|
|
182
|
-
"""Allow-list native install scripts in a generated Payload CMS app.
|
|
215
|
+
"""Allow-list native install scripts in a generated Payload CMS app.
|
|
216
|
+
|
|
217
|
+
pnpm 10 reads ``package.json#pnpm.onlyBuiltDependencies``. pnpm 11+
|
|
218
|
+
ignores that field and uses ``pnpm-workspace.yaml`` ``allowBuilds``.
|
|
219
|
+
"""
|
|
183
220
|
changed = False
|
|
184
221
|
workspace = project_dir / "pnpm-workspace.yaml"
|
|
185
222
|
package_json = project_dir / "package.json"
|
|
223
|
+
major = detect_pnpm_major()
|
|
186
224
|
try:
|
|
187
|
-
if workspace.is_file():
|
|
188
|
-
old =
|
|
225
|
+
if workspace.is_file() or (major is not None and major >= 11):
|
|
226
|
+
old = (
|
|
227
|
+
workspace.read_text(encoding="utf-8")
|
|
228
|
+
if workspace.is_file()
|
|
229
|
+
else ""
|
|
230
|
+
)
|
|
189
231
|
new = merge_workspace_allow_builds(old)
|
|
190
232
|
if new != old:
|
|
191
233
|
workspace.write_text(new, encoding="utf-8")
|
|
192
234
|
changed = True
|
|
193
235
|
if package_json.is_file():
|
|
194
236
|
old = package_json.read_text(encoding="utf-8")
|
|
195
|
-
|
|
237
|
+
if major is not None and major >= 11:
|
|
238
|
+
new = strip_package_json_only_built(old)
|
|
239
|
+
else:
|
|
240
|
+
new = merge_package_json_only_built(old)
|
|
196
241
|
if new != old:
|
|
197
242
|
package_json.write_text(new, encoding="utf-8")
|
|
198
243
|
changed = True
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{xgic_payload_cms_cli-0.2.4 → xgic_payload_cms_cli-0.2.5}/src/xgic/cli/payload/commands/__init__.py
RENAMED
|
File without changes
|
{xgic_payload_cms_cli-0.2.4 → xgic_payload_cms_cli-0.2.5}/src/xgic/cli/payload/commands/dev.py
RENAMED
|
File without changes
|
|
File without changes
|
{xgic_payload_cms_cli-0.2.4 → xgic_payload_cms_cli-0.2.5}/src/xgic/cli/payload/commands/schema.py
RENAMED
|
File without changes
|
{xgic_payload_cms_cli-0.2.4 → xgic_payload_cms_cli-0.2.5}/src/xgic/cli/payload/commands/setup.py
RENAMED
|
File without changes
|
|
File without changes
|