quickscale-cli 0.76.0__tar.gz → 0.79.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.
- {quickscale_cli-0.76.0 → quickscale_cli-0.79.0}/PKG-INFO +2 -2
- {quickscale_cli-0.76.0 → quickscale_cli-0.79.0}/pyproject.toml +2 -2
- {quickscale_cli-0.76.0 → quickscale_cli-0.79.0}/src/quickscale_cli/_version.py +1 -1
- quickscale_cli-0.79.0/src/quickscale_cli/backups_contract.py +128 -0
- {quickscale_cli-0.76.0 → quickscale_cli-0.79.0}/src/quickscale_cli/commands/apply_command.py +451 -6
- {quickscale_cli-0.76.0 → quickscale_cli-0.79.0}/src/quickscale_cli/commands/module_commands.py +10 -1
- {quickscale_cli-0.76.0 → quickscale_cli-0.79.0}/src/quickscale_cli/commands/module_config.py +605 -0
- quickscale_cli-0.79.0/src/quickscale_cli/commands/module_wiring_specs.py +634 -0
- {quickscale_cli-0.76.0 → quickscale_cli-0.79.0}/src/quickscale_cli/commands/plan_command.py +3 -0
- {quickscale_cli-0.76.0 → quickscale_cli-0.79.0}/src/quickscale_cli/module_catalog.py +15 -0
- quickscale_cli-0.79.0/src/quickscale_cli/notifications_contract.py +296 -0
- {quickscale_cli-0.76.0 → quickscale_cli-0.79.0}/src/quickscale_cli/schema/state_schema.py +11 -2
- quickscale_cli-0.79.0/src/quickscale_cli/social_contract.py +483 -0
- {quickscale_cli-0.76.0 → quickscale_cli-0.79.0}/src/quickscale_cli/utils/dependency_utils.py +5 -1
- {quickscale_cli-0.76.0 → quickscale_cli-0.79.0}/src/quickscale_cli/utils/docker_utils.py +10 -2
- {quickscale_cli-0.76.0 → quickscale_cli-0.79.0}/src/quickscale_cli/utils/module_wiring_manager.py +7 -1
- {quickscale_cli-0.76.0 → quickscale_cli-0.79.0}/src/quickscale_cli/utils/railway_utils.py +50 -10
- quickscale_cli-0.76.0/src/quickscale_cli/commands/module_wiring_specs.py +0 -291
- {quickscale_cli-0.76.0 → quickscale_cli-0.79.0}/README.md +0 -0
- {quickscale_cli-0.76.0 → quickscale_cli-0.79.0}/src/quickscale_cli/__init__.py +0 -0
- {quickscale_cli-0.76.0 → quickscale_cli-0.79.0}/src/quickscale_cli/commands/__init__.py +0 -0
- {quickscale_cli-0.76.0 → quickscale_cli-0.79.0}/src/quickscale_cli/commands/deployment_commands.py +0 -0
- {quickscale_cli-0.76.0 → quickscale_cli-0.79.0}/src/quickscale_cli/commands/development_commands.py +0 -0
- {quickscale_cli-0.76.0 → quickscale_cli-0.79.0}/src/quickscale_cli/commands/remove_command.py +0 -0
- {quickscale_cli-0.76.0 → quickscale_cli-0.79.0}/src/quickscale_cli/commands/status_command.py +0 -0
- {quickscale_cli-0.76.0 → quickscale_cli-0.79.0}/src/quickscale_cli/main.py +0 -0
- {quickscale_cli-0.76.0 → quickscale_cli-0.79.0}/src/quickscale_cli/schema/__init__.py +0 -0
- {quickscale_cli-0.76.0 → quickscale_cli-0.79.0}/src/quickscale_cli/schema/config_schema.py +0 -0
- {quickscale_cli-0.76.0 → quickscale_cli-0.79.0}/src/quickscale_cli/schema/delta.py +0 -0
- {quickscale_cli-0.76.0 → quickscale_cli-0.79.0}/src/quickscale_cli/utils/__init__.py +0 -0
- {quickscale_cli-0.76.0 → quickscale_cli-0.79.0}/src/quickscale_cli/utils/project_identity.py +0 -0
- {quickscale_cli-0.76.0 → quickscale_cli-0.79.0}/src/quickscale_cli/utils/project_manager.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: quickscale-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.79.0
|
|
4
4
|
Summary: Command-line interface for QuickScale Django project generator
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
Keywords: django,cli,project-generator,saas
|
|
@@ -14,7 +14,7 @@ Classifier: Programming Language :: Python :: 3.14
|
|
|
14
14
|
Classifier: Framework :: Django
|
|
15
15
|
Classifier: Framework :: Django :: 6.0
|
|
16
16
|
Requires-Dist: click (>=8.3.1,<9.0.0)
|
|
17
|
-
Requires-Dist: quickscale-core (>=0.
|
|
17
|
+
Requires-Dist: quickscale-core (>=0.79.0,<0.80.0)
|
|
18
18
|
Project-URL: Documentation, https://github.com/Experto-AI/quickscale/tree/main/docs
|
|
19
19
|
Project-URL: Homepage, https://github.com/Experto-AI/quickscale
|
|
20
20
|
Project-URL: Repository, https://github.com/Experto-AI/quickscale
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "quickscale-cli"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.79.0"
|
|
4
4
|
description = "Command-line interface for QuickScale Django project generator"
|
|
5
5
|
requires-python = ">=3.14,<4.0"
|
|
6
6
|
readme = "README.md"
|
|
@@ -31,7 +31,7 @@ packages = [{include = "quickscale_cli", from = "src"}]
|
|
|
31
31
|
[tool.poetry.dependencies]
|
|
32
32
|
python = "^3.14"
|
|
33
33
|
click = "^8.3.1"
|
|
34
|
-
quickscale-core = "^0.
|
|
34
|
+
quickscale-core = "^0.79.0"
|
|
35
35
|
|
|
36
36
|
[tool.poetry.group.dev.dependencies]
|
|
37
37
|
# Dev dependencies centralized in root pyproject.toml
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# Auto-generated by scripts/version_tool.sh
|
|
2
|
-
__version__ = "0.
|
|
2
|
+
__version__ = "0.79.0"
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"""Shared backups-module configuration helpers.
|
|
2
|
+
|
|
3
|
+
This module centralizes the non-secret configuration contract used by the
|
|
4
|
+
planner, apply flow, and state persistence for the backups module.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from collections.abc import Mapping
|
|
10
|
+
import re
|
|
11
|
+
from typing import Any
|
|
12
|
+
|
|
13
|
+
from quickscale_cli.notifications_contract import normalize_notifications_module_options
|
|
14
|
+
from quickscale_cli.social_contract import normalize_social_module_options
|
|
15
|
+
|
|
16
|
+
DEFAULT_BACKUPS_REMOTE_ACCESS_KEY_ID_ENV_VAR = "QUICKSCALE_BACKUPS_REMOTE_ACCESS_KEY_ID"
|
|
17
|
+
DEFAULT_BACKUPS_REMOTE_SECRET_ACCESS_KEY_ENV_VAR = (
|
|
18
|
+
"QUICKSCALE_BACKUPS_REMOTE_SECRET_ACCESS_KEY"
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
BACKUPS_REMOTE_ACCESS_KEY_ID_ENV_VAR_OPTION = "remote_access_key_id_env_var"
|
|
22
|
+
BACKUPS_REMOTE_SECRET_ACCESS_KEY_ENV_VAR_OPTION = "remote_secret_access_key_env_var"
|
|
23
|
+
|
|
24
|
+
_LEGACY_BACKUPS_SECRET_OPTIONS = {
|
|
25
|
+
"remote_access_key_id": DEFAULT_BACKUPS_REMOTE_ACCESS_KEY_ID_ENV_VAR,
|
|
26
|
+
"remote_secret_access_key": DEFAULT_BACKUPS_REMOTE_SECRET_ACCESS_KEY_ENV_VAR,
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
_BACKUPS_ENV_VAR_NAME_PATTERN = re.compile(r"^[A-Z][A-Z0-9_]*$")
|
|
30
|
+
_LIKELY_AWS_ACCESS_KEY_ID_PATTERN = re.compile(r"^(?:AKIA|ASIA)[A-Z0-9]{16}$")
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def normalize_backups_module_options(
|
|
34
|
+
options: Mapping[str, Any] | None,
|
|
35
|
+
) -> dict[str, Any]:
|
|
36
|
+
"""Return backups options with legacy raw-secret keys removed.
|
|
37
|
+
|
|
38
|
+
Legacy raw credential values are converted into conventional environment-variable
|
|
39
|
+
references so downstream persistence layers never re-store the secret values.
|
|
40
|
+
"""
|
|
41
|
+
normalized = dict(options or {})
|
|
42
|
+
|
|
43
|
+
legacy_access_key_id = str(normalized.pop("remote_access_key_id", "")).strip()
|
|
44
|
+
legacy_secret_access_key = str(
|
|
45
|
+
normalized.pop("remote_secret_access_key", "")
|
|
46
|
+
).strip()
|
|
47
|
+
|
|
48
|
+
access_key_env_var = str(
|
|
49
|
+
normalized.get(BACKUPS_REMOTE_ACCESS_KEY_ID_ENV_VAR_OPTION, "")
|
|
50
|
+
).strip()
|
|
51
|
+
secret_access_key_env_var = str(
|
|
52
|
+
normalized.get(BACKUPS_REMOTE_SECRET_ACCESS_KEY_ENV_VAR_OPTION, "")
|
|
53
|
+
).strip()
|
|
54
|
+
|
|
55
|
+
if legacy_access_key_id and not access_key_env_var:
|
|
56
|
+
normalized[BACKUPS_REMOTE_ACCESS_KEY_ID_ENV_VAR_OPTION] = (
|
|
57
|
+
DEFAULT_BACKUPS_REMOTE_ACCESS_KEY_ID_ENV_VAR
|
|
58
|
+
)
|
|
59
|
+
if legacy_secret_access_key and not secret_access_key_env_var:
|
|
60
|
+
normalized[BACKUPS_REMOTE_SECRET_ACCESS_KEY_ENV_VAR_OPTION] = (
|
|
61
|
+
DEFAULT_BACKUPS_REMOTE_SECRET_ACCESS_KEY_ENV_VAR
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
return normalized
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def has_legacy_backups_secret_values(options: Mapping[str, Any] | None) -> bool:
|
|
68
|
+
"""Return whether backups options still include legacy raw-secret keys."""
|
|
69
|
+
if not options:
|
|
70
|
+
return False
|
|
71
|
+
|
|
72
|
+
for option_name in _LEGACY_BACKUPS_SECRET_OPTIONS:
|
|
73
|
+
if str(options.get(option_name, "")).strip():
|
|
74
|
+
return True
|
|
75
|
+
return False
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def validate_backups_env_var_reference(option_name: str, value: Any) -> str | None:
|
|
79
|
+
"""Validate a backups env-var reference field.
|
|
80
|
+
|
|
81
|
+
Returns an actionable error string when the value is not a safe environment
|
|
82
|
+
variable name or appears to be a literal credential value.
|
|
83
|
+
"""
|
|
84
|
+
candidate = str(value).strip()
|
|
85
|
+
if not candidate:
|
|
86
|
+
return None
|
|
87
|
+
|
|
88
|
+
qualified_option = f"modules.backups.{option_name}"
|
|
89
|
+
if not _BACKUPS_ENV_VAR_NAME_PATTERN.fullmatch(candidate):
|
|
90
|
+
return (
|
|
91
|
+
f"{qualified_option} must be an environment variable name matching "
|
|
92
|
+
"^[A-Z][A-Z0-9_]*$"
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
if option_name == BACKUPS_REMOTE_ACCESS_KEY_ID_ENV_VAR_OPTION:
|
|
96
|
+
if _LIKELY_AWS_ACCESS_KEY_ID_PATTERN.fullmatch(candidate):
|
|
97
|
+
return (
|
|
98
|
+
f"{qualified_option} must reference an environment variable name, "
|
|
99
|
+
"not a literal AWS access key id"
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
return None
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def sanitize_module_options(
|
|
106
|
+
module_name: str,
|
|
107
|
+
options: Mapping[str, Any] | None,
|
|
108
|
+
) -> dict[str, Any]:
|
|
109
|
+
"""Return module options safe for config/state persistence."""
|
|
110
|
+
if module_name == "backups":
|
|
111
|
+
return normalize_backups_module_options(options)
|
|
112
|
+
if module_name == "notifications":
|
|
113
|
+
return normalize_notifications_module_options(options)
|
|
114
|
+
if module_name == "social":
|
|
115
|
+
return normalize_social_module_options(dict(options or {}))
|
|
116
|
+
return dict(options or {})
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
__all__ = [
|
|
120
|
+
"BACKUPS_REMOTE_ACCESS_KEY_ID_ENV_VAR_OPTION",
|
|
121
|
+
"BACKUPS_REMOTE_SECRET_ACCESS_KEY_ENV_VAR_OPTION",
|
|
122
|
+
"DEFAULT_BACKUPS_REMOTE_ACCESS_KEY_ID_ENV_VAR",
|
|
123
|
+
"DEFAULT_BACKUPS_REMOTE_SECRET_ACCESS_KEY_ENV_VAR",
|
|
124
|
+
"has_legacy_backups_secret_values",
|
|
125
|
+
"normalize_backups_module_options",
|
|
126
|
+
"sanitize_module_options",
|
|
127
|
+
"validate_backups_env_var_reference",
|
|
128
|
+
]
|