python-base-command 0.1.2__tar.gz → 0.1.3__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.
- {python_base_command-0.1.2 → python_base_command-0.1.3}/PKG-INFO +1 -1
- {python_base_command-0.1.2 → python_base_command-0.1.3}/pyproject.toml +1 -1
- {python_base_command-0.1.2 → python_base_command-0.1.3}/python_base_command/runner.py +22 -10
- python_base_command-0.1.3/usage_example/commands/registry_cmd.py +33 -0
- {python_base_command-0.1.2 → python_base_command-0.1.3}/.config/README.md +0 -0
- {python_base_command-0.1.2 → python_base_command-0.1.3}/.config/black.toml +0 -0
- {python_base_command-0.1.2 → python_base_command-0.1.3}/.config/pylintrc +0 -0
- {python_base_command-0.1.2 → python_base_command-0.1.3}/.config/pylintrc_tests +0 -0
- {python_base_command-0.1.2 → python_base_command-0.1.3}/.config/ruff.toml +0 -0
- {python_base_command-0.1.2 → python_base_command-0.1.3}/.github/CODEOWNERS +0 -0
- {python_base_command-0.1.2 → python_base_command-0.1.3}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {python_base_command-0.1.2 → python_base_command-0.1.3}/.github/instructions/IDE Agent/chat-titles.md +0 -0
- {python_base_command-0.1.2 → python_base_command-0.1.3}/.github/instructions/IDE Agent/claude-sonnet-4.md +0 -0
- {python_base_command-0.1.2 → python_base_command-0.1.3}/.github/instructions/IDE Agent/gemini-2.5-pro.md +0 -0
- {python_base_command-0.1.2 → python_base_command-0.1.3}/.github/instructions/IDE Agent/gpt-4.1.md +0 -0
- {python_base_command-0.1.2 → python_base_command-0.1.3}/.github/instructions/IDE Agent/gpt-4o.md +0 -0
- {python_base_command-0.1.2 → python_base_command-0.1.3}/.github/instructions/IDE Agent/gpt-5-mini.md +0 -0
- {python_base_command-0.1.2 → python_base_command-0.1.3}/.github/instructions/IDE Agent/gpt-5.md +0 -0
- {python_base_command-0.1.2 → python_base_command-0.1.3}/.github/instructions/IDE Agent/nes-tab-completion.md +0 -0
- {python_base_command-0.1.2 → python_base_command-0.1.3}/.github/instructions/IDE Agent/prompt.md +0 -0
- {python_base_command-0.1.2 → python_base_command-0.1.3}/.github/pull_request_template.md +0 -0
- {python_base_command-0.1.2 → python_base_command-0.1.3}/.github/workflows/lint.yml +0 -0
- {python_base_command-0.1.2 → python_base_command-0.1.3}/.github/workflows/publish_to_pypi.yml +0 -0
- {python_base_command-0.1.2 → python_base_command-0.1.3}/.github/workflows/tests.yml +0 -0
- {python_base_command-0.1.2 → python_base_command-0.1.3}/.gitignore +0 -0
- {python_base_command-0.1.2 → python_base_command-0.1.3}/.pre-commit-config.yaml +0 -0
- {python_base_command-0.1.2 → python_base_command-0.1.3}/CHANGELOG.md +0 -0
- {python_base_command-0.1.2 → python_base_command-0.1.3}/LICENSE +0 -0
- {python_base_command-0.1.2 → python_base_command-0.1.3}/MANIFEST.in +0 -0
- {python_base_command-0.1.2 → python_base_command-0.1.3}/README.md +0 -0
- {python_base_command-0.1.2 → python_base_command-0.1.3}/Taskfile.yml +0 -0
- {python_base_command-0.1.2 → python_base_command-0.1.3}/cli.py +0 -0
- {python_base_command-0.1.2 → python_base_command-0.1.3}/pytest.ini +0 -0
- {python_base_command-0.1.2 → python_base_command-0.1.3}/python_base_command/__init__.py +0 -0
- {python_base_command-0.1.2 → python_base_command-0.1.3}/python_base_command/base.py +0 -0
- {python_base_command-0.1.2 → python_base_command-0.1.3}/python_base_command/registry.py +0 -0
- {python_base_command-0.1.2 → python_base_command-0.1.3}/python_base_command/utils.py +0 -0
- {python_base_command-0.1.2 → python_base_command-0.1.3}/tests/__init__.py +0 -0
- {python_base_command-0.1.2 → python_base_command-0.1.3}/tests/test_base_command.py +0 -0
- {python_base_command-0.1.2 → python_base_command-0.1.3}/usage_example/__init__.py +0 -0
- {python_base_command-0.1.2 → python_base_command-0.1.3}/usage_example/commands/__init__.py +0 -0
- {python_base_command-0.1.2 → python_base_command-0.1.3}/usage_example/commands/greet.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-base-command
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.3
|
|
4
4
|
Summary: Django-style BaseCommand framework for standalone Python CLI tools
|
|
5
5
|
Project-URL: Homepage, https://github.com/aviz92/python-base-command
|
|
6
6
|
Project-URL: Repository, https://github.com/aviz92/python-base-command
|
|
@@ -48,6 +48,7 @@ from typing import Optional
|
|
|
48
48
|
|
|
49
49
|
from custom_python_logger import get_logger
|
|
50
50
|
|
|
51
|
+
from . import CommandRegistry
|
|
51
52
|
from .base import BaseCommand, CommandError
|
|
52
53
|
|
|
53
54
|
logger = get_logger("python-base-command")
|
|
@@ -78,8 +79,15 @@ class Runner:
|
|
|
78
79
|
|
|
79
80
|
def _discover(self) -> dict[str, type[BaseCommand]]:
|
|
80
81
|
"""
|
|
81
|
-
Walk ``self._commands_dir`` and import every non-private module
|
|
82
|
-
|
|
82
|
+
Walk ``self._commands_dir`` and import every non-private module.
|
|
83
|
+
|
|
84
|
+
Two conventions are supported per module:
|
|
85
|
+
|
|
86
|
+
1. **Classic** — a class literally named ``Command`` that subclasses
|
|
87
|
+
``BaseCommand``. The command name is the module's file stem.
|
|
88
|
+
2. **Registry** — one or more ``CommandRegistry`` instances defined at
|
|
89
|
+
module level. Every command registered on those instances is merged
|
|
90
|
+
in; the names come from the registry (not the file stem).
|
|
83
91
|
"""
|
|
84
92
|
commands: dict[str, type[BaseCommand]] = {}
|
|
85
93
|
|
|
@@ -94,15 +102,19 @@ class Runner:
|
|
|
94
102
|
if module is None:
|
|
95
103
|
continue
|
|
96
104
|
|
|
105
|
+
# --- 1. Classic: a top-level class named "Command" ---
|
|
97
106
|
command_class = getattr(module, "Command", None)
|
|
98
|
-
if command_class is None:
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
):
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
107
|
+
if command_class is not None and isinstance(command_class, type) and issubclass(command_class, BaseCommand):
|
|
108
|
+
commands[path.stem] = command_class
|
|
109
|
+
|
|
110
|
+
# --- 2. Registry: any CommandRegistry instances in the module ---
|
|
111
|
+
for attr_name in dir(module):
|
|
112
|
+
obj = getattr(module, attr_name)
|
|
113
|
+
if isinstance(obj, CommandRegistry):
|
|
114
|
+
for name in obj.list_commands():
|
|
115
|
+
cls = obj.get(name)
|
|
116
|
+
if cls is not None:
|
|
117
|
+
commands[name] = cls
|
|
106
118
|
|
|
107
119
|
return commands
|
|
108
120
|
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
from python_base_command import BaseCommand, CommandError, CommandRegistry
|
|
2
|
+
|
|
3
|
+
registry = CommandRegistry()
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@registry.register("greet2")
|
|
7
|
+
class Greet2Command(BaseCommand):
|
|
8
|
+
help = "Greet a user"
|
|
9
|
+
|
|
10
|
+
def add_arguments(self, parser):
|
|
11
|
+
parser.add_argument("name", type=str)
|
|
12
|
+
|
|
13
|
+
def handle(self, **kwargs):
|
|
14
|
+
self.logger.info(f"Hello, {kwargs['name']}!")
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@registry.register("export")
|
|
18
|
+
class ExportCommand(BaseCommand):
|
|
19
|
+
help = "Export data"
|
|
20
|
+
|
|
21
|
+
def add_arguments(self, parser):
|
|
22
|
+
parser.add_argument("--format", choices=["csv", "json"], default="csv")
|
|
23
|
+
parser.add_argument("--dry-run", action="store_true")
|
|
24
|
+
|
|
25
|
+
def handle(self, **kwargs):
|
|
26
|
+
if kwargs["dry_run"]:
|
|
27
|
+
self.logger.warning("Dry run — no files written.")
|
|
28
|
+
return
|
|
29
|
+
self.logger.info(f"Exported as {kwargs['format']}.")
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
if __name__ == "__main__":
|
|
33
|
+
registry.run()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_base_command-0.1.2 → python_base_command-0.1.3}/.github/ISSUE_TEMPLATE/bug_report.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_base_command-0.1.2 → python_base_command-0.1.3}/.github/instructions/IDE Agent/gpt-4.1.md
RENAMED
|
File without changes
|
{python_base_command-0.1.2 → python_base_command-0.1.3}/.github/instructions/IDE Agent/gpt-4o.md
RENAMED
|
File without changes
|
{python_base_command-0.1.2 → python_base_command-0.1.3}/.github/instructions/IDE Agent/gpt-5-mini.md
RENAMED
|
File without changes
|
{python_base_command-0.1.2 → python_base_command-0.1.3}/.github/instructions/IDE Agent/gpt-5.md
RENAMED
|
File without changes
|
|
File without changes
|
{python_base_command-0.1.2 → python_base_command-0.1.3}/.github/instructions/IDE Agent/prompt.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_base_command-0.1.2 → python_base_command-0.1.3}/.github/workflows/publish_to_pypi.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|