usecli 0.1.56__tar.gz → 0.1.58__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.
- {usecli-0.1.56 → usecli-0.1.58}/PKG-INFO +1 -1
- {usecli-0.1.56 → usecli-0.1.58}/pyproject.toml +1 -1
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/__init__.py +11 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/services/command_service.py +7 -3
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/shared/config/manager.py +45 -2
- {usecli-0.1.56 → usecli-0.1.58}/LICENSE +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/README.md +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/__init__.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/commands/README.md +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/commands/__init__.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/commands/custom/README.md +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/commands/custom/__init__.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/commands/defaults/__init__.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/commands/defaults/base/__init__.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/commands/defaults/base/about_command.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/commands/defaults/base/help_command.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/commands/defaults/base/inspire_command.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/commands/defaults/base/internal/__init__.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/commands/defaults/base/internal/fzf_command.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/commands/defaults/core/__init__.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/commands/defaults/core/utils.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/commands/defaults/make/__init__.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/commands/defaults/make/make_command.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/commands/defaults/make/make_theme_command.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/commands/init_command.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/config/__init__.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/config/colors.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/core/__init__.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/core/base_command.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/core/error/__init__.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/core/error/handler.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/core/error/utils.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/core/exceptions/__init__.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/core/exceptions/base.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/core/exceptions/config.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/core/exceptions/usage.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/core/exceptions/validation.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/core/ui/__init__.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/core/ui/list.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/core/ui/title.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/core/ui/title.txt +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/core/validators/__init__.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/core/validators/network.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/core/validators/numeric.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/core/validators/path.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/core/validators/string.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/services/__init__.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/templates/command.py.j2 +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/templates/theme.toml.j2 +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/templates/usecli.config.toml.j2 +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/themes/ayu_dark.toml +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/themes/catppuccin_frappe.toml +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/themes/catppuccin_latte.toml +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/themes/catppuccin_macchiato.toml +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/themes/catppuccin_mocha.toml +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/themes/default.toml +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/themes/dracula.toml +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/themes/gruvbox_dark.toml +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/themes/nord.toml +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/themes/tokyo_night.toml +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/utils/__init__.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/utils/interactive/__init__.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/utils/interactive/terminal_menu.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/menu.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/params.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/shared/__init__.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/shared/config/__init__.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/shared/config/globals.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/ui.py +0 -0
- {usecli-0.1.56 → usecli-0.1.58}/src/usecli/usecli.config.toml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "usecli"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.58"
|
|
4
4
|
description = "A powerful Python CLI framework for building beautiful, developer-friendly command-line tools."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
authors = [{ name = "Edward Boswell", email = "thememium@gmail.com" }]
|
|
@@ -310,6 +310,17 @@ def run_app(
|
|
|
310
310
|
|
|
311
311
|
def main() -> None:
|
|
312
312
|
"""Run the CLI application with custom error handling."""
|
|
313
|
+
config = get_config()
|
|
314
|
+
command_name = config._get_command_name()
|
|
315
|
+
if command_name == "usecli" and not config.is_usecli_direct_dependency():
|
|
316
|
+
console.print(
|
|
317
|
+
"[bold red]Error:[/bold red] usecli is not a direct dependency of this project."
|
|
318
|
+
)
|
|
319
|
+
console.print(
|
|
320
|
+
"Add it to your [cyan]pyproject.toml[/cyan] dependencies or dependency-groups."
|
|
321
|
+
)
|
|
322
|
+
sys.exit(1)
|
|
323
|
+
|
|
313
324
|
try:
|
|
314
325
|
app()
|
|
315
326
|
except Exit:
|
|
@@ -41,10 +41,14 @@ class CommandService:
|
|
|
41
41
|
def load_commands(self) -> None:
|
|
42
42
|
"""Load all commands from the commands directory and project directories."""
|
|
43
43
|
self._load_version()
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
config = get_config()
|
|
45
|
+
|
|
46
|
+
if config.is_usecli_direct_dependency():
|
|
47
|
+
package_commands_dir = (PACKAGE_ROOT / "cli/commands").resolve()
|
|
48
|
+
self._load_from_dir(package_commands_dir)
|
|
46
49
|
|
|
47
|
-
project_commands_dir =
|
|
50
|
+
project_commands_dir = config.get_project_commands_dir().resolve()
|
|
51
|
+
package_commands_dir = (PACKAGE_ROOT / "cli/commands").resolve()
|
|
48
52
|
if project_commands_dir == package_commands_dir:
|
|
49
53
|
return
|
|
50
54
|
try:
|
|
@@ -139,7 +139,12 @@ class ConfigManager:
|
|
|
139
139
|
):
|
|
140
140
|
detected_root = config_parent
|
|
141
141
|
self.project_root: Path = (detected_root or start_dir).resolve()
|
|
142
|
-
|
|
142
|
+
# Only override project_root for the framework itself (usecli).
|
|
143
|
+
# Downstream packages (usechange, userun, etc.) legitimately live
|
|
144
|
+
# inside .venv when installed as dependencies — don't break them.
|
|
145
|
+
command_name = self._get_command_name()
|
|
146
|
+
is_framework = command_name == "usecli" if command_name else True
|
|
147
|
+
if is_framework and self._is_in_venv(self.project_root):
|
|
143
148
|
self.project_root = start_dir.resolve()
|
|
144
149
|
self._config: dict[str, Any] = {}
|
|
145
150
|
self._overrides: dict[str, Any] = {}
|
|
@@ -214,8 +219,9 @@ class ConfigManager:
|
|
|
214
219
|
current = parent
|
|
215
220
|
|
|
216
221
|
search_root = find_project_root(start_dir) or start_dir.resolve()
|
|
222
|
+
is_framework = command_name == "usecli" if command_name else True
|
|
217
223
|
recursive_match = cls._find_usecli_config_in_tree(
|
|
218
|
-
search_root, start_dir, skip_venv=
|
|
224
|
+
search_root, start_dir, skip_venv=is_framework
|
|
219
225
|
)
|
|
220
226
|
if recursive_match:
|
|
221
227
|
return recursive_match
|
|
@@ -649,6 +655,43 @@ class ConfigManager:
|
|
|
649
655
|
"""Check if running in production environment."""
|
|
650
656
|
return self.get("environment", "prod") == "prod"
|
|
651
657
|
|
|
658
|
+
def is_usecli_direct_dependency(self) -> bool:
|
|
659
|
+
"""Check if usecli is a direct dependency of the current project.
|
|
660
|
+
|
|
661
|
+
Returns True when:
|
|
662
|
+
- The current project IS usecli (name matches)
|
|
663
|
+
- usecli appears in pyproject.toml [project.dependencies]
|
|
664
|
+
- usecli appears in pyproject.toml [dependency-groups]
|
|
665
|
+
"""
|
|
666
|
+
if not self.pyproject_path.exists():
|
|
667
|
+
return False
|
|
668
|
+
|
|
669
|
+
try:
|
|
670
|
+
with open(self.pyproject_path, "rb") as f:
|
|
671
|
+
data = tomllib.load(f)
|
|
672
|
+
except (tomllib.TOMLDecodeError, OSError):
|
|
673
|
+
return False
|
|
674
|
+
|
|
675
|
+
project_name = data.get("project", {}).get("name", "")
|
|
676
|
+
if isinstance(project_name, str) and project_name.strip().lower() == "usecli":
|
|
677
|
+
return True
|
|
678
|
+
|
|
679
|
+
for dep in data.get("project", {}).get("dependencies", []):
|
|
680
|
+
if isinstance(dep, str) and dep.strip().lower().startswith("usecli"):
|
|
681
|
+
return True
|
|
682
|
+
|
|
683
|
+
for group_deps in data.get("dependency-groups", {}).values():
|
|
684
|
+
if not isinstance(group_deps, list):
|
|
685
|
+
continue
|
|
686
|
+
for dep in group_deps:
|
|
687
|
+
dep_str = dep if isinstance(dep, str) else dep.get("dependency", "")
|
|
688
|
+
if isinstance(dep_str, str) and dep_str.strip().lower().startswith(
|
|
689
|
+
"usecli"
|
|
690
|
+
):
|
|
691
|
+
return True
|
|
692
|
+
|
|
693
|
+
return False
|
|
694
|
+
|
|
652
695
|
def reload(self) -> None:
|
|
653
696
|
"""Reload configuration from disk."""
|
|
654
697
|
self.usecli_config_path = self._find_usecli_config(self.start_dir) or (
|
|
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
|
{usecli-0.1.56 → usecli-0.1.58}/src/usecli/cli/commands/defaults/base/internal/fzf_command.py
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
|
|
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
|
|
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
|