quickscale-cli 0.75.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.79.0/PKG-INFO +60 -0
- quickscale_cli-0.79.0/README.md +37 -0
- {quickscale_cli-0.75.0 → quickscale_cli-0.79.0}/pyproject.toml +18 -19
- {quickscale_cli-0.75.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.75.0 → quickscale_cli-0.79.0}/src/quickscale_cli/commands/apply_command.py +522 -28
- {quickscale_cli-0.75.0 → quickscale_cli-0.79.0}/src/quickscale_cli/commands/deployment_commands.py +6 -1
- {quickscale_cli-0.75.0 → quickscale_cli-0.79.0}/src/quickscale_cli/commands/development_commands.py +122 -2
- {quickscale_cli-0.75.0 → quickscale_cli-0.79.0}/src/quickscale_cli/commands/module_commands.py +79 -3
- quickscale_cli-0.79.0/src/quickscale_cli/commands/module_config.py +1939 -0
- quickscale_cli-0.79.0/src/quickscale_cli/commands/module_wiring_specs.py +634 -0
- {quickscale_cli-0.75.0 → quickscale_cli-0.79.0}/src/quickscale_cli/commands/plan_command.py +217 -63
- {quickscale_cli-0.75.0 → quickscale_cli-0.79.0}/src/quickscale_cli/commands/status_command.py +1 -1
- {quickscale_cli-0.75.0 → quickscale_cli-0.79.0}/src/quickscale_cli/module_catalog.py +20 -0
- quickscale_cli-0.79.0/src/quickscale_cli/notifications_contract.py +296 -0
- {quickscale_cli-0.75.0 → quickscale_cli-0.79.0}/src/quickscale_cli/schema/config_schema.py +17 -3
- {quickscale_cli-0.75.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.75.0 → quickscale_cli-0.79.0}/src/quickscale_cli/utils/dependency_utils.py +7 -3
- {quickscale_cli-0.75.0 → quickscale_cli-0.79.0}/src/quickscale_cli/utils/docker_utils.py +12 -4
- {quickscale_cli-0.75.0 → quickscale_cli-0.79.0}/src/quickscale_cli/utils/module_wiring_manager.py +7 -1
- {quickscale_cli-0.75.0 → quickscale_cli-0.79.0}/src/quickscale_cli/utils/railway_utils.py +52 -12
- quickscale_cli-0.75.0/PKG-INFO +0 -380
- quickscale_cli-0.75.0/README.md +0 -354
- quickscale_cli-0.75.0/src/quickscale_cli/commands/module_config.py +0 -969
- quickscale_cli-0.75.0/src/quickscale_cli/commands/module_wiring_specs.py +0 -199
- {quickscale_cli-0.75.0 → quickscale_cli-0.79.0}/src/quickscale_cli/__init__.py +0 -0
- {quickscale_cli-0.75.0 → quickscale_cli-0.79.0}/src/quickscale_cli/commands/__init__.py +0 -0
- {quickscale_cli-0.75.0 → quickscale_cli-0.79.0}/src/quickscale_cli/commands/remove_command.py +0 -0
- {quickscale_cli-0.75.0 → quickscale_cli-0.79.0}/src/quickscale_cli/main.py +0 -0
- {quickscale_cli-0.75.0 → quickscale_cli-0.79.0}/src/quickscale_cli/schema/__init__.py +0 -0
- {quickscale_cli-0.75.0 → quickscale_cli-0.79.0}/src/quickscale_cli/schema/delta.py +0 -0
- {quickscale_cli-0.75.0 → quickscale_cli-0.79.0}/src/quickscale_cli/utils/__init__.py +0 -0
- {quickscale_cli-0.75.0 → quickscale_cli-0.79.0}/src/quickscale_cli/utils/project_identity.py +0 -0
- {quickscale_cli-0.75.0 → quickscale_cli-0.79.0}/src/quickscale_cli/utils/project_manager.py +0 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: quickscale-cli
|
|
3
|
+
Version: 0.79.0
|
|
4
|
+
Summary: Command-line interface for QuickScale Django project generator
|
|
5
|
+
License-Expression: Apache-2.0
|
|
6
|
+
Keywords: django,cli,project-generator,saas
|
|
7
|
+
Author: Experto AI
|
|
8
|
+
Author-email: victor@experto.ai
|
|
9
|
+
Requires-Python: >=3.14,<4.0
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
14
|
+
Classifier: Framework :: Django
|
|
15
|
+
Classifier: Framework :: Django :: 6.0
|
|
16
|
+
Requires-Dist: click (>=8.3.1,<9.0.0)
|
|
17
|
+
Requires-Dist: quickscale-core (>=0.79.0,<0.80.0)
|
|
18
|
+
Project-URL: Documentation, https://github.com/Experto-AI/quickscale/tree/main/docs
|
|
19
|
+
Project-URL: Homepage, https://github.com/Experto-AI/quickscale
|
|
20
|
+
Project-URL: Repository, https://github.com/Experto-AI/quickscale
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
|
|
23
|
+
# quickscale-cli
|
|
24
|
+
|
|
25
|
+
Command-line interface package for QuickScale.
|
|
26
|
+
|
|
27
|
+
This package exposes the `quickscale` command used to plan, apply, inspect, and operate generated projects.
|
|
28
|
+
|
|
29
|
+
## Command groups
|
|
30
|
+
|
|
31
|
+
- Project lifecycle: `plan`, `apply`, `status`, `remove`
|
|
32
|
+
- Local development: `up`, `down`, `ps`, `logs`, `shell`, `manage`
|
|
33
|
+
- Deployment: `deploy`
|
|
34
|
+
- Module workflows: `update`, `push`
|
|
35
|
+
|
|
36
|
+
## Relationship to other packages
|
|
37
|
+
|
|
38
|
+
- `quickscale-cli` is the command surface
|
|
39
|
+
- `quickscale-core` contains the underlying scaffolding and template logic
|
|
40
|
+
- `quickscale` installs both together for convenience
|
|
41
|
+
|
|
42
|
+
## Install
|
|
43
|
+
|
|
44
|
+
Usually installed via the meta-package:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pip install quickscale
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Standalone package installs can use this package's published metadata and dependency constraints.
|
|
51
|
+
|
|
52
|
+
## Documentation
|
|
53
|
+
|
|
54
|
+
- Repository overview: [QuickScale README](https://github.com/Experto-AI/quickscale/blob/main/README.md)
|
|
55
|
+
- Start guide: [START_HERE.md](https://github.com/Experto-AI/quickscale/blob/main/START_HERE.md)
|
|
56
|
+
- Technical decisions: [docs/technical/decisions.md](https://github.com/Experto-AI/quickscale/blob/main/docs/technical/decisions.md)
|
|
57
|
+
- CLI source entrypoint: [src/quickscale_cli/main.py](https://github.com/Experto-AI/quickscale/blob/main/quickscale_cli/src/quickscale_cli/main.py)
|
|
58
|
+
|
|
59
|
+
This README is package-local context only. Root documentation remains authoritative for repo-wide policy and scope.
|
|
60
|
+
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# quickscale-cli
|
|
2
|
+
|
|
3
|
+
Command-line interface package for QuickScale.
|
|
4
|
+
|
|
5
|
+
This package exposes the `quickscale` command used to plan, apply, inspect, and operate generated projects.
|
|
6
|
+
|
|
7
|
+
## Command groups
|
|
8
|
+
|
|
9
|
+
- Project lifecycle: `plan`, `apply`, `status`, `remove`
|
|
10
|
+
- Local development: `up`, `down`, `ps`, `logs`, `shell`, `manage`
|
|
11
|
+
- Deployment: `deploy`
|
|
12
|
+
- Module workflows: `update`, `push`
|
|
13
|
+
|
|
14
|
+
## Relationship to other packages
|
|
15
|
+
|
|
16
|
+
- `quickscale-cli` is the command surface
|
|
17
|
+
- `quickscale-core` contains the underlying scaffolding and template logic
|
|
18
|
+
- `quickscale` installs both together for convenience
|
|
19
|
+
|
|
20
|
+
## Install
|
|
21
|
+
|
|
22
|
+
Usually installed via the meta-package:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install quickscale
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Standalone package installs can use this package's published metadata and dependency constraints.
|
|
29
|
+
|
|
30
|
+
## Documentation
|
|
31
|
+
|
|
32
|
+
- Repository overview: [QuickScale README](https://github.com/Experto-AI/quickscale/blob/main/README.md)
|
|
33
|
+
- Start guide: [START_HERE.md](https://github.com/Experto-AI/quickscale/blob/main/START_HERE.md)
|
|
34
|
+
- Technical decisions: [docs/technical/decisions.md](https://github.com/Experto-AI/quickscale/blob/main/docs/technical/decisions.md)
|
|
35
|
+
- CLI source entrypoint: [src/quickscale_cli/main.py](https://github.com/Experto-AI/quickscale/blob/main/quickscale_cli/src/quickscale_cli/main.py)
|
|
36
|
+
|
|
37
|
+
This README is package-local context only. Root documentation remains authoritative for repo-wide policy and scope.
|
|
@@ -1,39 +1,42 @@
|
|
|
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
|
+
readme = "README.md"
|
|
6
7
|
license = "Apache-2.0"
|
|
8
|
+
authors = [{name = "Experto AI", email = "victor@experto.ai"}]
|
|
7
9
|
keywords = ["django", "cli", "project-generator", "saas"]
|
|
8
|
-
homepage = "https://github.com/Experto-AI/quickscale"
|
|
9
|
-
repository = "https://github.com/Experto-AI/quickscale"
|
|
10
|
-
documentation = "https://github.com/Experto-AI/quickscale/tree/main/docs"
|
|
11
|
-
readme = "README.md"
|
|
12
10
|
classifiers = [
|
|
13
11
|
"Development Status :: 3 - Alpha",
|
|
14
12
|
"Intended Audience :: Developers",
|
|
15
|
-
"License :: OSI Approved :: Apache Software License",
|
|
16
13
|
"Programming Language :: Python :: 3",
|
|
17
|
-
"Programming Language :: Python :: 3.12",
|
|
18
|
-
"Programming Language :: Python :: 3.13",
|
|
19
14
|
"Programming Language :: Python :: 3.14",
|
|
20
15
|
"Framework :: Django",
|
|
21
16
|
"Framework :: Django :: 6.0",
|
|
22
17
|
]
|
|
18
|
+
dynamic = ["dependencies"]
|
|
19
|
+
|
|
20
|
+
[project.urls]
|
|
21
|
+
Homepage = "https://github.com/Experto-AI/quickscale"
|
|
22
|
+
Repository = "https://github.com/Experto-AI/quickscale"
|
|
23
|
+
Documentation = "https://github.com/Experto-AI/quickscale/tree/main/docs"
|
|
24
|
+
|
|
25
|
+
[project.scripts]
|
|
26
|
+
quickscale = "quickscale_cli.main:cli"
|
|
27
|
+
|
|
28
|
+
[tool.poetry]
|
|
23
29
|
packages = [{include = "quickscale_cli", from = "src"}]
|
|
24
30
|
|
|
25
31
|
[tool.poetry.dependencies]
|
|
26
|
-
python = "^3.
|
|
32
|
+
python = "^3.14"
|
|
27
33
|
click = "^8.3.1"
|
|
28
|
-
quickscale-core = "^0.
|
|
34
|
+
quickscale-core = "^0.79.0"
|
|
29
35
|
|
|
30
36
|
[tool.poetry.group.dev.dependencies]
|
|
31
37
|
# Dev dependencies centralized in root pyproject.toml
|
|
32
38
|
# Use: poetry install from repository root
|
|
33
39
|
|
|
34
|
-
[tool.poetry.scripts]
|
|
35
|
-
quickscale = "quickscale_cli.main:cli"
|
|
36
|
-
|
|
37
40
|
[build-system]
|
|
38
41
|
requires = ["poetry-core"]
|
|
39
42
|
build-backend = "poetry.core.masonry.api"
|
|
@@ -46,10 +49,6 @@ python_functions = ["test_*"]
|
|
|
46
49
|
addopts = [
|
|
47
50
|
"--strict-markers",
|
|
48
51
|
"--strict-config",
|
|
49
|
-
"--cov=quickscale_cli",
|
|
50
|
-
"--cov-report=term-missing",
|
|
51
|
-
"--cov-report=html",
|
|
52
|
-
"--cov-fail-under=90",
|
|
53
52
|
"-m", "not e2e", # Skip E2E tests by default (run with: pytest -m e2e)
|
|
54
53
|
]
|
|
55
54
|
markers = [
|
|
@@ -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
|
+
]
|