quickscale-cli 0.57.1__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.
@@ -0,0 +1,24 @@
1
+ Metadata-Version: 2.1
2
+ Name: quickscale-cli
3
+ Version: 0.57.1
4
+ Summary: Command-line interface for QuickScale Django project generator
5
+ Home-page: https://github.com/Experto-AI/quickscale
6
+ License: Apache-2.0
7
+ Keywords: django,cli,project-generator,saas
8
+ Author: Experto AI
9
+ Author-email: victor@experto.ai
10
+ Requires-Python: >=3.10,<4.0
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Framework :: Django
13
+ Classifier: Framework :: Django :: 4.2
14
+ Classifier: Framework :: Django :: 5.0
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: License :: OSI Approved :: Apache Software License
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Requires-Dist: click (>=8.1.0,<9.0.0)
22
+ Requires-Dist: quickscale-core (>=0.57.1,<0.58.0)
23
+ Project-URL: Documentation, https://github.com/Experto-AI/quickscale/tree/main/docs
24
+ Project-URL: Repository, https://github.com/Experto-AI/quickscale
@@ -0,0 +1,107 @@
1
+ [tool.poetry]
2
+ name = "quickscale-cli"
3
+ version = "0.57.1"
4
+ description = "Command-line interface for QuickScale Django project generator"
5
+ authors = ["Experto AI <victor@experto.ai>"]
6
+ license = "Apache-2.0"
7
+ 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
+ classifiers = [
12
+ "Development Status :: 3 - Alpha",
13
+ "Intended Audience :: Developers",
14
+ "License :: OSI Approved :: Apache Software License",
15
+ "Programming Language :: Python :: 3",
16
+ "Programming Language :: Python :: 3.10",
17
+ "Programming Language :: Python :: 3.11",
18
+ "Programming Language :: Python :: 3.12",
19
+ "Framework :: Django",
20
+ "Framework :: Django :: 4.2",
21
+ "Framework :: Django :: 5.0",
22
+ ]
23
+ packages = [{include = "quickscale_cli", from = "src"}]
24
+
25
+ [tool.poetry.dependencies]
26
+ python = "^3.10"
27
+ click = "^8.1.0"
28
+ quickscale-core = "^0.57.1"
29
+
30
+ [tool.poetry.group.dev.dependencies]
31
+ pytest = "^7.4.0"
32
+ pytest-cov = "^4.1.0"
33
+ ruff = "^0.6.0"
34
+ mypy = "^1.8.0"
35
+
36
+ [tool.poetry.scripts]
37
+ quickscale = "quickscale_cli.main:cli"
38
+
39
+ [build-system]
40
+ requires = ["poetry-core"]
41
+ build-backend = "poetry.core.masonry.api"
42
+
43
+ [tool.pytest.ini_options]
44
+ testpaths = ["tests"]
45
+ python_files = ["test_*.py"]
46
+ python_classes = ["Test*"]
47
+ python_functions = ["test_*"]
48
+ addopts = [
49
+ "--strict-markers",
50
+ "--strict-config",
51
+ "--cov=quickscale_cli",
52
+ "--cov-report=term-missing",
53
+ "--cov-report=html",
54
+ ]
55
+
56
+ [tool.ruff]
57
+ line-length = 100
58
+ target-version = "py310"
59
+
60
+ [tool.ruff.lint]
61
+ select = [
62
+ "E", # pycodestyle errors
63
+ "W", # pycodestyle warnings
64
+ "F", # pyflakes
65
+ "I", # isort
66
+ "N", # pep8-naming
67
+ "UP", # pyupgrade
68
+ "D", # docstring rules
69
+ ]
70
+ ignore = [
71
+ "D100", # Missing docstring in public module
72
+ "D101", # Missing docstring in public class
73
+ "D102", # Missing docstring in public method
74
+ "D103", # Missing docstring in public function
75
+ "D105", # Missing docstring in magic method
76
+ "D107", # Missing docstring in __init__
77
+ "D203", # 1 blank line required before class docstring (incompatible with D211)
78
+ "D212", # Multi-line docstring summary should start at the first line (incompatible with D213)
79
+ "D400", # First line should end with a period
80
+ "D415", # First line should end with a period, question mark, or exclamation point
81
+ ]
82
+
83
+ [tool.ruff.lint.isort]
84
+ known-first-party = ["quickscale_cli", "quickscale_core"]
85
+
86
+ [tool.mypy]
87
+ python_version = "3.10"
88
+ warn_return_any = true
89
+ warn_unused_configs = true
90
+ disallow_untyped_defs = true
91
+ disallow_incomplete_defs = true
92
+ check_untyped_defs = true
93
+ disallow_untyped_decorators = true
94
+ no_implicit_optional = true
95
+ warn_redundant_casts = true
96
+ warn_unused_ignores = true
97
+ warn_no_return = true
98
+ warn_unreachable = true
99
+ strict_equality = true
100
+ show_error_codes = true
101
+
102
+ [[tool.mypy.overrides]]
103
+ module = "tests.*"
104
+ disallow_untyped_defs = false
105
+ check_untyped_defs = false
106
+
107
+
@@ -0,0 +1,34 @@
1
+ """QuickScale CLI package.
2
+
3
+ Reads the canonical version from the repository-level `VERSION` file so the CLI
4
+ stays in sync with other packages when the release is bumped in one place.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from pathlib import Path
10
+ from typing import Tuple
11
+
12
+ __author__ = "Experto AI"
13
+ __email__ = "victor@experto.ai"
14
+
15
+ # Prefer an embedded package-level `_version.py` if it exists (build step).
16
+ try:
17
+ from ._version import __version__ # type: ignore
18
+ except Exception:
19
+ _root = Path(__file__).resolve().parents[3]
20
+ _version_file = _root / "VERSION"
21
+ if _version_file.exists():
22
+ __version__ = _version_file.read_text(encoding="utf8").strip()
23
+ else:
24
+ __version__ = "0.0.0"
25
+
26
+ # Version tuple for programmatic access
27
+ parts = __version__.split("-")[0].split(".")
28
+ VERSION: Tuple[int, int, int] = (
29
+ int(parts[0]) if len(parts) > 0 else 0,
30
+ int(parts[1]) if len(parts) > 1 else 0,
31
+ int(parts[2]) if len(parts) > 2 else 0,
32
+ )
33
+
34
+ __all__ = ["__version__", "VERSION"]
@@ -0,0 +1,2 @@
1
+ # Auto-generated by scripts/version_tool.sh
2
+ __version__ = "0.57.0"
@@ -0,0 +1,81 @@
1
+ """QuickScale CLI - Main entry point for project generation commands."""
2
+
3
+ from pathlib import Path
4
+
5
+ import click
6
+
7
+ import quickscale_cli
8
+ import quickscale_core
9
+ from quickscale_core.generator import ProjectGenerator
10
+
11
+
12
+ @click.group()
13
+ @click.version_option(version=quickscale_cli.__version__, prog_name="quickscale")
14
+ def cli() -> None:
15
+ """QuickScale - Compose your Django SaaS."""
16
+ pass
17
+
18
+
19
+ @cli.command()
20
+ def version() -> None:
21
+ """Show version information for CLI and core packages."""
22
+ click.echo(f"QuickScale CLI v{quickscale_cli.__version__}")
23
+ click.echo(f"QuickScale Core v{quickscale_core.__version__}")
24
+
25
+
26
+ @cli.command()
27
+ @click.argument("project_name")
28
+ def init(project_name: str) -> None:
29
+ """Generate a new Django project with production-ready configurations."""
30
+ try:
31
+ # Initialize generator
32
+ generator = ProjectGenerator()
33
+
34
+ # Generate project in current directory
35
+ output_path = Path.cwd() / project_name
36
+
37
+ click.echo(f"šŸš€ Generating project: {project_name}")
38
+ generator.generate(project_name, output_path)
39
+
40
+ # Success message
41
+ click.secho(f"\nāœ… Created project: {project_name}", fg="green", bold=True)
42
+
43
+ # Next steps instructions
44
+ click.echo("\nšŸ“‹ Next steps:")
45
+ click.echo(f" cd {project_name}")
46
+ click.echo(" # Recommended: use Poetry for dependency management")
47
+ click.echo(" poetry install")
48
+ click.echo(" poetry run python manage.py migrate")
49
+ click.echo(" poetry run python manage.py runserver")
50
+ click.echo("\nšŸ“– See README.md for more details")
51
+
52
+ except ValueError as e:
53
+ # Invalid project name
54
+ click.secho(f"āŒ Error: {e}", fg="red", err=True)
55
+ click.echo("\nšŸ’” Tip: Project name must be a valid Python identifier", err=True)
56
+ click.echo(" - Use only letters, numbers, and underscores", err=True)
57
+ click.echo(" - Cannot start with a number", err=True)
58
+ click.echo(" - Cannot use Python reserved keywords", err=True)
59
+ raise click.Abort()
60
+ except FileExistsError as e:
61
+ # Directory already exists
62
+ click.secho(f"āŒ Error: {e}", fg="red", err=True)
63
+ click.echo(
64
+ "\nšŸ’” Tip: Choose a different project name or remove the existing directory", err=True
65
+ )
66
+ raise click.Abort()
67
+ except PermissionError as e:
68
+ # Permission issues
69
+ click.secho(f"āŒ Error: {e}", fg="red", err=True)
70
+ click.echo("\nšŸ’” Tip: Check directory permissions or try a different location", err=True)
71
+ raise click.Abort()
72
+ except Exception as e:
73
+ # Unexpected errors
74
+ click.secho(f"āŒ Unexpected error: {e}", fg="red", err=True)
75
+ click.echo("\nšŸ› This is a bug. Please report it at:", err=True)
76
+ click.echo(" https://github.com/Experto-AI/quickscale/issues", err=True)
77
+ raise
78
+
79
+
80
+ if __name__ == "__main__":
81
+ cli()