djangx 0.1.0.dev2__tar.gz → 0.1.0.dev3__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.
Files changed (31) hide show
  1. djangx-0.1.0.dev3/PKG-INFO +26 -0
  2. djangx-0.1.0.dev3/README.md +1 -0
  3. djangx-0.1.0.dev3/pyproject.toml +92 -0
  4. djangx-0.1.0.dev3/pyproject.toml.orig +79 -0
  5. djangx-0.1.0.dev3/src/djangx/__init__.py +9 -0
  6. djangx-0.1.0.dev3/src/djangx/core/__init__.py +27 -0
  7. djangx-0.1.0.dev3/src/djangx/core/apps.py +7 -0
  8. djangx-0.1.0.dev3/src/djangx/core/asgi.py +22 -0
  9. djangx-0.1.0.dev3/src/djangx/core/management/__init__.py +81 -0
  10. djangx-0.1.0.dev3/src/djangx/core/management/commands/__init__.py +9 -0
  11. djangx-0.1.0.dev3/src/djangx/core/utils/__init__.py +4 -0
  12. djangx-0.1.0.dev3/src/djangx/core/utils/enum.py +16 -0
  13. djangx-0.1.0.dev3/src/djangx/core/utils/platform.py +79 -0
  14. djangx-0.1.0.dev3/src/djangx/core/utils/pyproject.py +80 -0
  15. djangx-0.1.0.dev3/src/djangx/core/utils/version.py +87 -0
  16. djangx-0.1.0.dev3/src/djangx/core/wsgi.py +22 -0
  17. djangx-0.1.0.dev2/PKG-INFO +0 -12
  18. djangx-0.1.0.dev2/pyproject.toml +0 -48
  19. djangx-0.1.0.dev2/pyproject.toml.orig +0 -40
  20. djangx-0.1.0.dev2/src/djangx/conf/urls.py +0 -0
  21. djangx-0.1.0.dev2/src/djangx/entrypoints/__init__.py +0 -0
  22. djangx-0.1.0.dev2/src/djangx/entrypoints/asgi.py +0 -0
  23. djangx-0.1.0.dev2/src/djangx/entrypoints/cli.py +0 -6
  24. djangx-0.1.0.dev2/src/djangx/entrypoints/wsgi.py +0 -0
  25. {djangx-0.1.0.dev2 → djangx-0.1.0.dev3}/LICENSE +0 -0
  26. {djangx-0.1.0.dev2/src/djangx → djangx-0.1.0.dev3/src/djangx/components}/__init__.py +0 -0
  27. /djangx-0.1.0.dev2/README.md → /djangx-0.1.0.dev3/src/djangx/core/management/commands/cp.py +0 -0
  28. /djangx-0.1.0.dev2/src/djangx/components/__init__.py → /djangx-0.1.0.dev3/src/djangx/core/management/commands/platform.py +0 -0
  29. /djangx-0.1.0.dev2/src/djangx/conf/__init__.py → /djangx-0.1.0.dev3/src/djangx/core/management/commands/random.py +0 -0
  30. /djangx-0.1.0.dev2/src/djangx/conf/settings.py → /djangx-0.1.0.dev3/src/djangx/core/management/commands/rm.py +0 -0
  31. {djangx-0.1.0.dev2 → djangx-0.1.0.dev3}/src/djangx/py.typed +0 -0
@@ -0,0 +1,26 @@
1
+ Metadata-Version: 2.4
2
+ Name: djangX
3
+ Version: 0.1.0.dev3
4
+ Summary:
5
+ Author: Kevin Wakhisi
6
+ Author-email: Kevin Wakhisi <kevin@treeolive.tech>
7
+ License-Expression: MIT
8
+ License-File: LICENSE
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Programming Language :: Python :: 3.14
12
+ Classifier: Operating System :: OS Independent
13
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
14
+ Requires-Dist: django>=6.1.2
15
+ Requires-Dist: pillow>=13.0.0
16
+ Requires-Dist: python-dotenv>=1.2.4
17
+ Requires-Dist: psycopg[binary,pool]>=3.3.6 ; extra == 'postgres'
18
+ Requires-Dist: psycopg[binary,pool]>=3.3.6 ; extra == 'vercel'
19
+ Requires-Dist: vercel>=0.12.0 ; extra == 'vercel'
20
+ Requires-Python: >=3.14
21
+ Project-URL: repository, https://github.com/treeolive-tech/djangX.git
22
+ Provides-Extra: postgres
23
+ Provides-Extra: vercel
24
+ Description-Content-Type: text/markdown
25
+
26
+ # djangX
@@ -0,0 +1 @@
1
+ # djangX
@@ -0,0 +1,92 @@
1
+ [project]
2
+ name = "djangX"
3
+ version = "0.1.0.dev3"
4
+ description = ""
5
+ readme = "README.md"
6
+ license = "MIT"
7
+ license-files = ["LICENSE"]
8
+ requires-python = ">=3.14"
9
+ classifiers = [
10
+ "Development Status :: 4 - Beta",
11
+ "Intended Audience :: Developers",
12
+ "Programming Language :: Python :: 3.14",
13
+ "Operating System :: OS Independent",
14
+ "Topic :: Software Development :: Libraries :: Python Modules",
15
+ ]
16
+ dependencies = [
17
+ "django>=6.1.2",
18
+ "pillow>=13.0.0",
19
+ "python-dotenv>=1.2.4",
20
+ ]
21
+
22
+ [project.urls]
23
+ repository = "https://github.com/treeolive-tech/djangX.git"
24
+
25
+ [[project.authors]]
26
+ name = "Kevin Wakhisi"
27
+ email = "kevin@treeolive.tech"
28
+
29
+ [project.optional-dependencies]
30
+ postgres = ["psycopg[binary,pool]>=3.3.6"]
31
+ vercel = [
32
+ "psycopg[binary,pool]>=3.3.6",
33
+ "vercel>=0.12.0",
34
+ ]
35
+
36
+ [project.scripts]
37
+ djangx = "djangx.core.management:main"
38
+ djx = "djangx.core.management:main"
39
+
40
+ [dependency-groups]
41
+ dev = [
42
+ "django-browser-reload>=1.21.0",
43
+ "django-http-compression[brotli]>=1.4.0",
44
+ "django-minify-html>=1.14.0",
45
+ "django-stubs>=6.1.2",
46
+ "djlint>=1.47.0",
47
+ "poethepoet>=0.49.0",
48
+ "psycopg[binary,pool]>=3.3.6",
49
+ "vercel>=0.12.0",
50
+ "djangorestframework>=3.18.3",
51
+ "django-filter>=26.2",
52
+ "markdown>=3.11.2",
53
+ ]
54
+
55
+ [build-system]
56
+ requires = ["uv_build>=0.13.4,<0.14.0"]
57
+ build-backend = "uv_build"
58
+
59
+ [tool.uv]
60
+ preview-features = [
61
+ "format-command",
62
+ "check-command",
63
+ ]
64
+
65
+ [[tool.uv.index]]
66
+ name = "testpypi"
67
+ url = "https://test.pypi.org/simple/"
68
+ publish-url = "https://test.pypi.org/legacy/"
69
+ explicit = true
70
+
71
+ [[tool.poe.tasks.format.sequence]]
72
+ cmd = "uv format"
73
+
74
+ [[tool.poe.tasks.lint.sequence]]
75
+ cmd = "uv format --check"
76
+
77
+ [[tool.poe.tasks.lint.sequence]]
78
+ cmd = "uv lock --check"
79
+
80
+ [[tool.poe.tasks.lint.sequence]]
81
+ cmd = "uv check"
82
+
83
+ [tool.djlint]
84
+ format_css = true
85
+ format_js = true
86
+ custom_blocks = "body,aside,header,footer,main,section,list"
87
+ blank_line_before_tag = "block,list"
88
+ blank_line_after_tag = "endblock,endlist"
89
+ ignore = "H016,H030,H031"
90
+
91
+ [tool.ruff]
92
+ exclude = ["*/migrations/*"]
@@ -0,0 +1,79 @@
1
+ [project.urls]
2
+ repository = "https://github.com/treeolive-tech/djangX.git"
3
+
4
+ [project]
5
+ name = "djangX"
6
+ version = "0.1.0.dev3"
7
+ description = ""
8
+ readme = "README.md"
9
+ license = "MIT"
10
+ license-files = ["LICENSE"]
11
+ authors = [{ name = "Kevin Wakhisi", email = "kevin@treeolive.tech" }]
12
+ requires-python = ">=3.14"
13
+ classifiers = [
14
+ "Development Status :: 4 - Beta",
15
+ "Intended Audience :: Developers",
16
+ "Programming Language :: Python :: 3.14",
17
+ "Operating System :: OS Independent",
18
+ "Topic :: Software Development :: Libraries :: Python Modules",
19
+ ]
20
+ dependencies = ["django>=6.1.2", "pillow>=13.0.0", "python-dotenv>=1.2.4"]
21
+
22
+ [project.optional-dependencies]
23
+ postgres = ["psycopg[binary,pool]>=3.3.6"]
24
+ vercel = ["psycopg[binary,pool]>=3.3.6", "vercel>=0.12.0"]
25
+
26
+ [dependency-groups]
27
+ dev = [
28
+ "django-browser-reload>=1.21.0",
29
+ "django-http-compression[brotli]>=1.4.0",
30
+ "django-minify-html>=1.14.0",
31
+ "django-stubs>=6.1.2",
32
+ "djlint>=1.47.0",
33
+ "poethepoet>=0.49.0",
34
+ "psycopg[binary,pool]>=3.3.6",
35
+ "vercel>=0.12.0",
36
+
37
+ # rest framework
38
+ "djangorestframework>=3.18.3",
39
+ "django-filter>=26.2",
40
+ "markdown>=3.11.2",
41
+ ]
42
+
43
+ [project.scripts]
44
+ djangx = "djangx.core.management:main"
45
+ djx = "djangx.core.management:main"
46
+
47
+ [build-system]
48
+ requires = ["uv_build>=0.13.4,<0.14.0"]
49
+ build-backend = "uv_build"
50
+
51
+ [tool.uv]
52
+ preview-features = ["format-command", "check-command"]
53
+
54
+ [tool.poe.tasks.format]
55
+ sequence = [{ cmd = "uv format" }]
56
+
57
+ [tool.poe.tasks.lint]
58
+ sequence = [
59
+ { cmd = "uv format --check" },
60
+ { cmd = "uv lock --check" },
61
+ { cmd = "uv check" },
62
+ ]
63
+
64
+ [tool.djlint]
65
+ format_css = true
66
+ format_js = true
67
+ custom_blocks = "body,aside,header,footer,main,section,list"
68
+ blank_line_before_tag = "block,list"
69
+ blank_line_after_tag = "endblock,endlist"
70
+ ignore = "H016,H030,H031"
71
+
72
+ [tool.ruff]
73
+ exclude = ["*/migrations/*"]
74
+
75
+ [[tool.uv.index]]
76
+ name = "testpypi"
77
+ url = "https://test.pypi.org/simple/"
78
+ publish-url = "https://test.pypi.org/legacy/"
79
+ explicit = true
@@ -0,0 +1,9 @@
1
+ from pathlib import Path
2
+ from typing import Final
3
+
4
+
5
+ class Package:
6
+ name: Final[str] = Path(__file__).resolve().parent.name # djangx
7
+ verbose_name: Final[str] = name[:-1] + name[-1].upper() # djangX
8
+ core: Final[str] = f"{name}.core"
9
+ components: Final[str] = f"{name}.components"
@@ -0,0 +1,27 @@
1
+ from pathlib import Path
2
+ from sys import argv
3
+
4
+ from .. import Package
5
+ from .utils import ExitCode, PyProject
6
+
7
+ DJANGO_SETTINGS_MODULE: str | None = PyProject(Path.cwd() / "pyproject.toml").settings
8
+
9
+
10
+ def print_help_message() -> None:
11
+ """Print built-in help, or an error and exit if the command is unknown."""
12
+ from .management.commands import HELP_COMMANDS
13
+
14
+ match argv[1]:
15
+ case cmd if cmd in HELP_COMMANDS:
16
+ print(
17
+ f"No pyproject.toml found (or it's missing [tool.{Package.name}] `settings` key), "
18
+ "so only built-in commands are shown below.\n\n"
19
+ "To see project-specific commands, run this from the root of a "
20
+ f"{Package.verbose_name} project, or add to your pyproject.toml:\n\n"
21
+ f" [tool.{Package.name}]\n"
22
+ ' settings = "app.settings"'
23
+ )
24
+
25
+ case _:
26
+ print(f"Unknown command: '{cmd}'\nType '{Package.name} help' for usage.")
27
+ raise SystemExit(ExitCode.ERROR)
@@ -0,0 +1,7 @@
1
+ from django.apps import AppConfig
2
+
3
+ from .. import Package
4
+
5
+
6
+ class CoreConfig(AppConfig):
7
+ name = Package.core
@@ -0,0 +1,22 @@
1
+ """
2
+ ASGI config.
3
+
4
+ It exposes the ASGI callable as a module-level variable named ``app``.
5
+
6
+ For more information on this file, see
7
+ https://docs.djangoproject.com/en/6.0/howto/deployment/asgi/
8
+ """
9
+
10
+ from . import DJANGO_SETTINGS_MODULE
11
+
12
+ if DJANGO_SETTINGS_MODULE is None:
13
+ from . import print_help_message
14
+
15
+ print_help_message()
16
+ else:
17
+ from os import environ
18
+
19
+ from django.core.asgi import get_asgi_application
20
+
21
+ environ.setdefault("DJANGO_SETTINGS_MODULE", DJANGO_SETTINGS_MODULE)
22
+ application = get_asgi_application()
@@ -0,0 +1,81 @@
1
+ """Command-line entry point."""
2
+
3
+ from sys import argv
4
+
5
+ from .commands import BUILTIN_COMMANDS, HELP_COMMANDS
6
+
7
+
8
+ def _run_builtin() -> None:
9
+ """Run a built-in command with a minimal Django setup and no Django core commands."""
10
+ from django import setup
11
+ from django.conf import settings
12
+ from django.core.management import execute_from_command_line, get_commands
13
+
14
+ from ..apps import CoreConfig
15
+
16
+ if not settings.configured:
17
+ settings.configure(INSTALLED_APPS=[CoreConfig.name])
18
+ setup()
19
+
20
+ commands = get_commands()
21
+ for name, app in list(commands.items()):
22
+ if app == "django.core":
23
+ del commands[name]
24
+
25
+ execute_from_command_line(argv)
26
+
27
+
28
+ def _run_project_or_help(command: str) -> None:
29
+ """Run a command against the project's settings, or show help if none is found."""
30
+
31
+ from .. import DJANGO_SETTINGS_MODULE, print_help_message
32
+
33
+ if DJANGO_SETTINGS_MODULE:
34
+ from os import environ
35
+ from pathlib import Path
36
+ from sys import path
37
+
38
+ from django.core.management import execute_from_command_line
39
+ from dotenv import load_dotenv
40
+
41
+ base_dir = Path.cwd()
42
+ path.insert(0, str(base_dir))
43
+ environ.setdefault("DJANGO_SETTINGS_MODULE", DJANGO_SETTINGS_MODULE)
44
+ dotenv = base_dir / ".env.local"
45
+
46
+ if dotenv.is_file():
47
+ load_dotenv(dotenv)
48
+
49
+ execute_from_command_line(argv)
50
+ return
51
+
52
+ print_help_message()
53
+ if command in HELP_COMMANDS:
54
+ _run_builtin()
55
+
56
+
57
+ def main() -> None:
58
+ """Dispatch the CLI command."""
59
+ command: str | None = argv[1] if len(argv) > 1 else None
60
+
61
+ match command:
62
+ case None:
63
+ print(
64
+ "...but the people who know their God shall be strong and do exploits. — Daniel 11:32"
65
+ )
66
+
67
+ case "-v" | "--version" | "version":
68
+ from ... import Package
69
+ from ..utils import print_version
70
+
71
+ raise SystemExit(print_version(Package.name))
72
+
73
+ case _ if command in BUILTIN_COMMANDS:
74
+ _run_builtin()
75
+
76
+ case _:
77
+ _run_project_or_help(command)
78
+
79
+
80
+ if __name__ == "__main__":
81
+ main()
@@ -0,0 +1,9 @@
1
+ from pathlib import Path
2
+
3
+ BUILTIN_COMMANDS: set[str] = {
4
+ path.stem
5
+ for path in Path(__file__).resolve().parent.glob("*.py")
6
+ if path.name != "__init__.py"
7
+ }
8
+
9
+ HELP_COMMANDS: set[str] = {"help", "-h"}
@@ -0,0 +1,4 @@
1
+ from .enum import *
2
+ from .platform import *
3
+ from .pyproject import *
4
+ from .version import *
@@ -0,0 +1,16 @@
1
+ from enum import IntEnum
2
+
3
+ __all__: list[str] = ["ExitCode"]
4
+
5
+
6
+ class ExitCode(IntEnum):
7
+ """Standard process exit codes following Unix conventions.
8
+
9
+ Examples::
10
+
11
+ raise SystemExit(ExitCode.ERROR) # exits with code 1
12
+ raise SystemExit(ExitCode.SUCCESS) # exits with code 0
13
+ """
14
+
15
+ SUCCESS = 0 # Command completed without errors.
16
+ ERROR = 1 # Command encountered an error.
@@ -0,0 +1,79 @@
1
+ """Platform and architecture detection utilities."""
2
+
3
+ from platform import machine, system
4
+ from typing import Final
5
+
6
+ __all__: list[str] = ["Platform"]
7
+
8
+
9
+ class Platform:
10
+ """Detect the current OS and CPU architecture as normalised codes.
11
+
12
+ Raises:
13
+ OSError: If the OS is unsupported.
14
+ ValueError: If the CPU architecture is unsupported.
15
+
16
+ Examples::
17
+
18
+ p = Platform()
19
+ str(p) # "macos-arm64"
20
+ p.os_name # "macos"
21
+ p.architecture # "arm64"
22
+ """
23
+
24
+ _PLATFORM_MAP: Final[dict[str, str]] = {
25
+ "darwin": "macos",
26
+ "linux": "linux",
27
+ "windows": "windows",
28
+ "android": "android",
29
+ }
30
+
31
+ _ARCH_MAP: Final[dict[str, str]] = {
32
+ "x86_64": "x64",
33
+ "amd64": "x64",
34
+ "x64": "x64",
35
+ "arm64": "arm64",
36
+ "aarch64": "arm64",
37
+ "armv8": "arm64",
38
+ "armv7l": "arm",
39
+ "armv7": "arm",
40
+ "armv6l": "arm",
41
+ }
42
+
43
+ def __init__(self) -> None:
44
+ """Detect the current OS and architecture and store them on the instance."""
45
+ self.os_name: str = self._detect_os()
46
+ self.architecture: str = self._detect_architecture()
47
+
48
+ def _detect_os(self) -> str:
49
+ """Normalise :func:`platform.system`, e.g. ``"Darwin"`` -> ``"macos"``."""
50
+ system_platform: str = system().lower()
51
+ platform_name: str | None = self._PLATFORM_MAP.get(system_platform)
52
+ if not platform_name:
53
+ supported: str = ", ".join(dict.fromkeys(self._PLATFORM_MAP.values()))
54
+ raise OSError(
55
+ f"Unsupported operating system: {system_platform}. Supported: {supported}"
56
+ )
57
+ return platform_name
58
+
59
+ def _detect_architecture(self) -> str:
60
+ """Normalise :func:`platform.machine`, e.g. ``"aarch64"`` -> ``"arm64"``."""
61
+ machine_platform: str = machine().lower()
62
+ architecture: str | None = self._ARCH_MAP.get(machine_platform)
63
+ if not architecture:
64
+ supported: str = ", ".join(dict.fromkeys(self._ARCH_MAP.values()))
65
+ raise ValueError(
66
+ f"Unsupported architecture: {machine_platform}. Supported: {supported}"
67
+ )
68
+ return architecture
69
+
70
+ def __str__(self) -> str:
71
+ """Return ``"<os_name>-<architecture>"``.
72
+
73
+ Examples::
74
+
75
+ str(Platform()) # "linux-x64"
76
+ f"{Platform()}" # "macos-arm64"
77
+ print(Platform()) # windows-x64
78
+ """
79
+ return f"{self.os_name}-{self.architecture}"
@@ -0,0 +1,80 @@
1
+ """Read ``pyproject.toml`` data and the project's settings module."""
2
+
3
+ from pathlib import Path
4
+ from typing import Any
5
+
6
+ from ... import Package
7
+
8
+ __all__: list[str] = ["PyProject"]
9
+
10
+
11
+ class PyProject:
12
+ """Read-only view of a parsed ``pyproject.toml`` file.
13
+
14
+ Args:
15
+ toml_path: Path to the ``pyproject.toml`` file.
16
+
17
+ Raises:
18
+ FileNotFoundError: If *toml_path* does not exist.
19
+ tomllib.TOMLDecodeError: If the file contains invalid TOML.
20
+
21
+ Examples::
22
+
23
+ p = PyProject(Path("pyproject.toml"))
24
+ p.name # "my-project"
25
+ p.version # "0.1.0"
26
+ p.data # the full parsed dict
27
+ """
28
+
29
+ def __init__(self, toml_path: Path) -> None:
30
+ """Parse *toml_path* and store the result."""
31
+ from tomllib import load
32
+
33
+ self.path: Path = toml_path
34
+
35
+ with open(file=self.path, mode="rb") as f:
36
+ self._data: dict[str, Any] = load(f)
37
+
38
+ @property
39
+ def name(self) -> str:
40
+ """The ``[project] name`` value.
41
+
42
+ Raises:
43
+ KeyError: If ``[project]`` or ``name`` is missing.
44
+ """
45
+ return self._data["project"]["name"]
46
+
47
+ @property
48
+ def version(self) -> str:
49
+ """The ``[project] version`` value.
50
+
51
+ Raises:
52
+ KeyError: If ``[project]`` or ``version`` is missing.
53
+ """
54
+ return self._data["project"]["version"]
55
+
56
+ @property
57
+ def description(self) -> str | None:
58
+ """The ``[project] description`` value, or ``None`` if not set."""
59
+ return self._data["project"].get("description")
60
+
61
+ @property
62
+ def settings(self) -> str | None:
63
+ """The ``[tool.<package>] settings`` value, or ``None`` if missing or blank.
64
+
65
+ Examples::
66
+
67
+ # [tool.djangx]
68
+ # settings = "app.settings"
69
+ p.settings # "app.settings"
70
+ """
71
+ try:
72
+ value: Any = self._data["tool"][Package.name]["settings"]
73
+ return value if isinstance(value, str) and value.strip() else None
74
+ except KeyError:
75
+ return None
76
+
77
+ @property
78
+ def data(self) -> dict[str, Any]:
79
+ """The full parsed TOML as a dict."""
80
+ return self._data
@@ -0,0 +1,87 @@
1
+ """Version lookup utilities."""
2
+
3
+ from typing import Literal, NamedTuple, final
4
+
5
+ from .enum import ExitCode
6
+
7
+ __all__: list[str] = ["Version", "VersionResult", "print_version"]
8
+
9
+
10
+ class VersionResult(NamedTuple):
11
+ """A version string paired with an error message (empty on success).
12
+
13
+ Examples::
14
+
15
+ output, error = Version.get("django")
16
+ Version.get("django").output
17
+ """
18
+
19
+ output: str
20
+ error: str
21
+
22
+
23
+ @final
24
+ class Version:
25
+ """Namespace for looking up installed package versions.
26
+
27
+ Examples::
28
+
29
+ Version.get("django").output # "5.1.0"
30
+ """
31
+
32
+ __slots__ = ()
33
+
34
+ def __new__(cls):
35
+ raise TypeError(f"{cls.__name__} cannot be instantiated.")
36
+
37
+ @staticmethod
38
+ def placeholder() -> Literal["X.Y.Z"]:
39
+ """Return the placeholder used when a version cannot be found.
40
+
41
+ Examples::
42
+
43
+ Version.placeholder() # "X.Y.Z"
44
+ """
45
+ return "X.Y.Z"
46
+
47
+ @staticmethod
48
+ def get(package: str) -> VersionResult:
49
+ """Return the installed version of *package*, or a placeholder on failure.
50
+
51
+ Examples::
52
+
53
+ Version.get("django") # VersionResult("5.1.0", "")
54
+ Version.get("not-installed-pkg") # VersionResult("X.Y.Z", "Package ... not installed ...")
55
+ """
56
+ try:
57
+ from importlib.metadata import PackageNotFoundError, version
58
+
59
+ return VersionResult(version(distribution_name=package), error="")
60
+ except PackageNotFoundError:
61
+ return VersionResult(
62
+ output=Version.placeholder(),
63
+ error=f"Package '{package}' is not installed or could not be found.",
64
+ )
65
+ except Exception as e: # noqa: BLE001 - must always return a VersionResult
66
+ return VersionResult(
67
+ output=Version.placeholder(),
68
+ error=f"Could not determine version for '{package}': {type(e).__name__}: {e}",
69
+ )
70
+
71
+
72
+ def print_version(package: str) -> ExitCode:
73
+ """Print the installed version of *package* and return an exit code.
74
+
75
+ Examples::
76
+
77
+ print_version("django") # prints "5.1.0", returns ExitCode.SUCCESS
78
+ print_version("nope") # prints an error, returns ExitCode.ERROR
79
+ """
80
+ result: VersionResult = Version.get(package)
81
+
82
+ if result.error:
83
+ print(f"Could not determine version for package '{package}'.\n{result.error}")
84
+ return ExitCode.ERROR
85
+ else:
86
+ print(result.output)
87
+ return ExitCode.SUCCESS
@@ -0,0 +1,22 @@
1
+ """
2
+ WSGI config.
3
+
4
+ It exposes the WSGI callable as a module-level variable named ``app``.
5
+
6
+ For more information on this file, see
7
+ https://docs.djangoproject.com/en/6.0/howto/deployment/wsgi/
8
+ """
9
+
10
+ from . import DJANGO_SETTINGS_MODULE
11
+
12
+ if DJANGO_SETTINGS_MODULE is None:
13
+ from . import print_help_message
14
+
15
+ print_help_message()
16
+ else:
17
+ from os import environ
18
+
19
+ from django.core.wsgi import get_wsgi_application
20
+
21
+ environ.setdefault("DJANGO_SETTINGS_MODULE", DJANGO_SETTINGS_MODULE)
22
+ application = get_wsgi_application()
@@ -1,12 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: djangX
3
- Version: 0.1.0.dev2
4
- Summary: Add your description here
5
- Author: Kevin Wakhisi
6
- Author-email: Kevin Wakhisi <kevin@treeolive.tech>
7
- License-Expression: MIT
8
- License-File: LICENSE
9
- Requires-Dist: django>=6.1.2
10
- Requires-Python: >=3.14
11
- Description-Content-Type: text/markdown
12
-
@@ -1,48 +0,0 @@
1
- [project]
2
- name = "djangX"
3
- version = "0.1.0.dev2"
4
- description = "Add your description here"
5
- readme = "README.md"
6
- license = "MIT"
7
- license-files = ["LICENSE"]
8
- requires-python = ">=3.14"
9
- dependencies = ["django>=6.1.2"]
10
-
11
- [[project.authors]]
12
- name = "Kevin Wakhisi"
13
- email = "kevin@treeolive.tech"
14
-
15
- [project.scripts]
16
- djangx = "djangx.entrypoints.cli:main"
17
- djx = "djangx.entrypoints.cli:main"
18
-
19
- [build-system]
20
- requires = ["uv_build>=0.13.4,<0.14.0"]
21
- build-backend = "uv_build"
22
-
23
- [dependency-groups]
24
- dev = ["poethepoet>=0.49.0"]
25
-
26
- [tool.uv]
27
- preview-features = [
28
- "format-command",
29
- "check-command",
30
- ]
31
-
32
- [[tool.uv.index]]
33
- name = "testpypi"
34
- url = "https://test.pypi.org/simple/"
35
- publish-url = "https://test.pypi.org/legacy/"
36
- explicit = true
37
-
38
- [[tool.poe.tasks.format.sequence]]
39
- cmd = "uv format"
40
-
41
- [[tool.poe.tasks.lint.sequence]]
42
- cmd = "uv format --check"
43
-
44
- [[tool.poe.tasks.lint.sequence]]
45
- cmd = "uv lock --check"
46
-
47
- [[tool.poe.tasks.lint.sequence]]
48
- cmd = "uv check"
@@ -1,40 +0,0 @@
1
- [project]
2
- name = "djangX"
3
- version = "0.1.0.dev2"
4
- description = "Add your description here"
5
- readme = "README.md"
6
- license = "MIT"
7
- license-files = ["LICENSE"]
8
- authors = [{ name = "Kevin Wakhisi", email = "kevin@treeolive.tech" }]
9
- requires-python = ">=3.14"
10
- dependencies = ["django>=6.1.2"]
11
-
12
- [project.scripts]
13
- djangx = "djangx.entrypoints.cli:main"
14
- djx = "djangx.entrypoints.cli:main"
15
-
16
- [build-system]
17
- requires = ["uv_build>=0.13.4,<0.14.0"]
18
- build-backend = "uv_build"
19
-
20
- [dependency-groups]
21
- dev = ["poethepoet>=0.49.0"]
22
-
23
- [tool.uv]
24
- preview-features = ["format-command", "check-command"]
25
-
26
- [tool.poe.tasks.format]
27
- sequence = [{ cmd = "uv format" }]
28
-
29
- [tool.poe.tasks.lint]
30
- sequence = [
31
- { cmd = "uv format --check" },
32
- { cmd = "uv lock --check" },
33
- { cmd = "uv check" },
34
- ]
35
-
36
- [[tool.uv.index]]
37
- name = "testpypi"
38
- url = "https://test.pypi.org/simple/"
39
- publish-url = "https://test.pypi.org/legacy/"
40
- explicit = true
File without changes
File without changes
File without changes
@@ -1,6 +0,0 @@
1
- def main() -> None:
2
- print("Hello from djangX!")
3
-
4
-
5
- if __name__ == "__main__":
6
- main()
File without changes
File without changes